Files
calendar/packages/trpc/server/routers/viewer/domainWideDelegation/utils.ts
T
2024-12-09 08:27:16 +05:30

107 lines
3.1 KiB
TypeScript

import { z } from "zod";
import logger from "@calcom/lib/logger";
import { safeStringify } from "@calcom/lib/safeStringify";
import { DomainWideDelegationRepository } from "@calcom/lib/server/repository/domainWideDelegation";
import type { Prisma } from "@calcom/prisma/client";
import { TRPCError } from "@trpc/server";
const log = logger.getSubLogger({ prefix: ["domainWideDelegation/utils"] });
export class InvalidServiceAccountKeyError extends Error {
constructor(message: string) {
super(message);
this.name = "InvalidServiceAccountKeyError";
}
}
export async function ensureDomainWideDelegationNotAlreadyConfigured({
domain,
currentOrganizationId,
dwdBeingUpdatedId,
}: {
domain: string;
currentOrganizationId: number;
dwdBeingUpdatedId: string | null;
}) {
const allDelegationsForDomain = await DomainWideDelegationRepository.findAllByDomain({
domain,
});
const conflictingDelegationInCurrentOrg = allDelegationsForDomain.find(
(delegation) => delegation.organizationId === currentOrganizationId && delegation.id !== dwdBeingUpdatedId
);
if (conflictingDelegationInCurrentOrg) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Your organization already has domain-wide delegation for ${conflictingDelegationInCurrentOrg.domain}`,
});
}
const differentOrgEnabledDelegations = allDelegationsForDomain.filter(
(delegation) => delegation.organizationId !== currentOrganizationId && delegation.enabled
);
if (differentOrgEnabledDelegations.length > 0) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Domain ${domain} already has domain-wide delegation enabled in another organization`,
});
}
}
export function parseServiceAccountKey(serviceAccountKey: Prisma.JsonValue) {
if (!serviceAccountKey) {
return null;
}
const schema = z.object({
client_id: z.string(),
private_key: z.string(),
client_email: z.string(),
});
const parsedServiceAccountKey = schema.safeParse(serviceAccountKey);
if (!parsedServiceAccountKey.success) {
console.error("Invalid service account key", parsedServiceAccountKey.error);
throw new InvalidServiceAccountKeyError(
"Service account key must contain private_key, client_email and client_id"
);
}
return parsedServiceAccountKey.data;
}
export const handleDomainWideDelegationError = (error: unknown) => {
if (error instanceof InvalidServiceAccountKeyError) {
throw new TRPCError({
code: "BAD_REQUEST",
message: error.message,
});
}
if (error instanceof TRPCError) {
throw error;
}
log.error("Error handling domain-wide delegation:", safeStringify(error));
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "An error occurred while handling domain-wide delegation settings.",
});
};
export const ensureNoServiceAccountKey = <T extends { id: string; serviceAccountKey?: unknown } | null>(
domainWideDelegation: T
) => {
if (!domainWideDelegation) {
return null;
}
const { serviceAccountKey: _1, ...rest } = domainWideDelegation;
return {
...rest,
serviceAccountKey: undefined,
};
};