diff --git a/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/actions.ts b/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/actions.ts index 54bdcabb3e..a71c8d70dd 100644 --- a/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/actions.ts +++ b/apps/web/app/(app)/environments/[environmentId]/(actionsAndAttributes)/attributes/actions.ts @@ -1,10 +1,20 @@ "use server"; +import { getServerSession } from "next-auth"; +import { AuthorizationError } from "@formbricks/types/v1/errors"; +import { authOptions } from "@formbricks/lib/authOptions"; import { getSurveysByAttributeClassId } from "@formbricks/lib/survey/service"; +import { canUserAccessAttributeClass } from "@formbricks/lib/attributeClass/auth"; export const GetActiveInactiveSurveysAction = async ( attributeClassId: string ): Promise<{ activeSurveys: string[]; inactiveSurveys: string[] }> => { + const session = await getServerSession(authOptions); + if (!session) throw new AuthorizationError("Not authorized"); + + const isAuthorized = await canUserAccessAttributeClass(session.user.id, attributeClassId); + if (!isAuthorized) throw new AuthorizationError("Not authorized"); + const surveys = await getSurveysByAttributeClassId(attributeClassId); const response = { activeSurveys: surveys.filter((s) => s.status === "inProgress").map((survey) => survey.name), diff --git a/packages/lib/attributeClass/auth.ts b/packages/lib/attributeClass/auth.ts new file mode 100644 index 0000000000..740de9fb13 --- /dev/null +++ b/packages/lib/attributeClass/auth.ts @@ -0,0 +1,30 @@ +import "server-only"; + +import { ZId } from "@formbricks/types/v1/environment"; +import { validateInputs } from "../utils/validate"; +import { hasUserEnvironmentAccess } from "../environment/auth"; +import { getAttributeClass } from "./service"; +import { unstable_cache } from "next/cache"; +import { SERVICES_REVALIDATION_INTERVAL } from "../constants"; + +export const canUserAccessAttributeClass = async ( + userId: string, + attributeClassId: string +): Promise => + await unstable_cache( + async () => { + validateInputs([userId, ZId], [attributeClassId, ZId]); + if (!userId) return false; + + const attributeClass = await getAttributeClass(attributeClassId); + if (!attributeClass) return false; + + const hasAccessToEnvironment = await hasUserEnvironmentAccess(userId, attributeClass.environmentId); + if (!hasAccessToEnvironment) return false; + + return true; + }, + + [`users-${userId}-attributeClasses-${attributeClassId}`], + { revalidate: SERVICES_REVALIDATION_INTERVAL, tags: [`attributeClasses-${attributeClassId}`] } + )();