2
0
Files
cal/calcom/packages/trpc/server/routers/viewer/organizations/adminUpdate.handler.ts
2024-08-09 00:39:27 +02:00

117 lines
3.4 KiB
TypeScript

import type { Prisma } from "@prisma/client";
import { renameDomain } from "@calcom/lib/domainManager/organization";
import { getMetadataHelpers } from "@calcom/lib/getMetadataHelpers";
import { HttpError } from "@calcom/lib/http-error";
import { prisma } from "@calcom/prisma";
import { teamMetadataSchema } from "@calcom/prisma/zod-utils";
import type { TrpcSessionUser } from "../../../trpc";
import type { TAdminUpdate } from "./adminUpdate.schema";
type AdminUpdateOptions = {
ctx: {
user: NonNullable<TrpcSessionUser>;
};
input: TAdminUpdate;
};
export const adminUpdateHandler = async ({ input }: AdminUpdateOptions) => {
const { id, organizationSettings, ...restInput } = input;
const existingOrg = await prisma.team.findUnique({
where: {
id: id,
},
include: {
organizationSettings: true,
},
});
if (!existingOrg) {
throw new HttpError({
message: "Organization not found",
statusCode: 404,
});
}
const { mergeMetadata } = getMetadataHelpers(teamMetadataSchema.unwrap(), existingOrg.metadata);
const data: Prisma.TeamUpdateArgs["data"] = restInput;
if (restInput.slug) {
await throwIfSlugConflicts({ id, slug: restInput.slug });
const isSlugChanged = restInput.slug !== existingOrg.slug;
if (isSlugChanged) {
// If slug is changed, we need to rename the domain first
// If renaming fails, we don't want to update the new slug in DB
await renameDomain(existingOrg.slug, restInput.slug);
}
data.slug = input.slug;
data.metadata = mergeMetadata({
// If we save slug, we don't need the requestedSlug anymore
requestedSlug: undefined,
});
}
const updatedOrganization = await prisma.$transaction(async (tx) => {
const updatedOrganization = await tx.team.update({
where: { id },
data,
});
if (organizationSettings || existingOrg.organizationSettings) {
await tx.organizationSettings.update({
where: {
organizationId: updatedOrganization.id,
},
data: {
isOrganizationConfigured:
organizationSettings?.isOrganizationConfigured ||
existingOrg.organizationSettings?.isOrganizationConfigured,
isOrganizationVerified:
organizationSettings?.isOrganizationVerified ||
existingOrg.organizationSettings?.isOrganizationVerified,
isAdminReviewed: organizationSettings?.isAdminReviewed,
orgAutoAcceptEmail:
organizationSettings?.orgAutoAcceptEmail || existingOrg.organizationSettings?.orgAutoAcceptEmail,
},
});
}
return updatedOrganization;
});
return updatedOrganization;
};
export default adminUpdateHandler;
async function throwIfSlugConflicts({ id, slug }: { id: number; slug: string }) {
const organizationsWithSameSlug = await prisma.team.findMany({
where: {
slug: slug,
parentId: null,
},
});
if (organizationsWithSameSlug.length > 1) {
throw new HttpError({
message: "There can only be one organization with a given slug",
statusCode: 400,
});
}
const foundOrg = organizationsWithSameSlug[0];
if (!foundOrg) {
// No org with same slug found - So, no conflict.
return;
}
// If foundOrg isn't same as the org being edited
if (foundOrg.id !== id) {
throw new HttpError({
message: "Organization or a Team with same slug already exists",
statusCode: 400,
});
}
}