chore: Move all server action to new authorization approach (#2999)

This commit is contained in:
Piyush Gupta
2024-08-19 12:37:37 +05:30
committed by GitHub
parent 5ba2959eb4
commit ec16159497
120 changed files with 3061 additions and 2164 deletions
@@ -1,56 +1,53 @@
"use server";
import { getServerSession } from "next-auth";
import { z } from "zod";
import { sendInviteMemberEmail } from "@formbricks/email";
import { authOptions } from "@formbricks/lib/authOptions";
import { authenticatedActionClient } from "@formbricks/lib/actionClient";
import { checkAuthorization } from "@formbricks/lib/actionClient/utils";
import { INVITE_DISABLED } from "@formbricks/lib/constants";
import { inviteUser } from "@formbricks/lib/invite/service";
import { verifyUserRoleAccess } from "@formbricks/lib/organization/auth";
import { getOrganizationsByUserId } from "@formbricks/lib/organization/service";
import { getUser } from "@formbricks/lib/user/service";
import { ZId } from "@formbricks/types/environment";
import { AuthenticationError } from "@formbricks/types/errors";
export const inviteOrganizationMemberAction = async (email: string, organizationId: string) => {
const session = await getServerSession(authOptions);
const ZInviteOrganizationMemberAction = z.object({
email: z.string(),
organizationId: ZId,
});
if (!session) {
throw new AuthenticationError("Not authenticated");
}
export const inviteOrganizationMemberAction = authenticatedActionClient
.schema(ZInviteOrganizationMemberAction)
.action(async ({ ctx, parsedInput }) => {
if (INVITE_DISABLED) {
throw new AuthenticationError("Invite disabled");
}
const user = await getUser(session.user.id);
if (!user) {
throw new Error("User not found");
}
await checkAuthorization({
userId: ctx.user.id,
organizationId: parsedInput.organizationId,
rules: ["membership", "create"],
});
const organizations = await getOrganizationsByUserId(session.user.id);
const organizations = await getOrganizationsByUserId(ctx.user.id);
if (INVITE_DISABLED) {
throw new AuthenticationError("Invite disabled");
}
const invite = await inviteUser({
organizationId: organizations[0].id,
invitee: {
email: parsedInput.email,
name: "",
role: "admin",
},
});
const { hasCreateOrUpdateMembersAccess } = await verifyUserRoleAccess(organizationId, session.user.id);
if (!hasCreateOrUpdateMembersAccess) {
throw new AuthenticationError("Not authorized");
}
if (invite) {
await sendInviteMemberEmail(
invite.id,
parsedInput.email,
ctx.user.name ?? "",
"",
false // is onboarding invite
);
}
const invite = await inviteUser({
organizationId: organizations[0].id,
invitee: {
email,
name: "",
role: "admin",
},
return invite;
});
if (invite) {
await sendInviteMemberEmail(
invite.id,
email,
user.name ?? "",
"",
false // is onboarding invite
);
}
return invite;
};
@@ -38,7 +38,7 @@ export const InviteMembers = ({ IS_SMTP_CONFIGURED, organizationId }: InviteMemb
for (const email of emails) {
try {
if (!email) continue;
await inviteOrganizationMemberAction(email, organizationId);
await inviteOrganizationMemberAction({ email, organizationId });
if (IS_SMTP_CONFIGURED) {
toast.success(`Invitation sent to ${email}!`);
}
@@ -1,33 +1,35 @@
"use server";
import { Organization } from "@prisma/client";
import { getServerSession } from "next-auth";
import { z } from "zod";
import { getIsMultiOrgEnabled } from "@formbricks/ee/lib/service";
import { authOptions } from "@formbricks/lib/authOptions";
import { authenticatedActionClient } from "@formbricks/lib/actionClient";
import { gethasNoOrganizations } from "@formbricks/lib/instance/service";
import { createMembership } from "@formbricks/lib/membership/service";
import { createOrganization } from "@formbricks/lib/organization/service";
import { AuthorizationError, OperationNotAllowedError } from "@formbricks/types/errors";
import { OperationNotAllowedError } from "@formbricks/types/errors";
export const createOrganizationAction = async (organizationName: string): Promise<Organization> => {
const session = await getServerSession(authOptions);
if (!session) throw new AuthorizationError("Not authorized");
const ZCreateOrganizationAction = z.object({
organizationName: z.string(),
});
const hasNoOrganizations = await gethasNoOrganizations();
const isMultiOrgEnabled = await getIsMultiOrgEnabled();
export const createOrganizationAction = authenticatedActionClient
.schema(ZCreateOrganizationAction)
.action(async ({ ctx, parsedInput }) => {
const hasNoOrganizations = await gethasNoOrganizations();
const isMultiOrgEnabled = await getIsMultiOrgEnabled();
if (!hasNoOrganizations && !isMultiOrgEnabled) {
throw new OperationNotAllowedError("This action can only be performed on a fresh instance.");
}
if (!hasNoOrganizations && !isMultiOrgEnabled) {
throw new OperationNotAllowedError("This action can only be performed on a fresh instance.");
}
const newOrganization = await createOrganization({
name: organizationName,
const newOrganization = await createOrganization({
name: parsedInput.organizationName,
});
await createMembership(newOrganization.id, ctx.user.id, {
role: "owner",
accepted: true,
});
return newOrganization;
});
await createMembership(newOrganization.id, session.user.id, {
role: "owner",
accepted: true,
});
return newOrganization;
};
@@ -33,8 +33,10 @@ export const CreateOrganization = () => {
try {
setIsSubmitting(true);
const organizationName = data.name.trim();
const organization = await createOrganizationAction(organizationName);
router.push(`/setup/organization/${organization.id}/invite`);
const createOrganizationResponse = await createOrganizationAction({ organizationName });
if (createOrganizationResponse?.data) {
router.push(`/setup/organization/${createOrganizationResponse.data.id}/invite`);
}
} catch (error) {
toast.error("Some error occurred while creating organization");
setIsSubmitting(false);