Files
calendar/packages/trpc/server/routers/viewer/delegationCredential/toggleEnabled.handler.ts
T
Benny JooandGitHub bb68cd73ef refactor: circular deps between app store and lib [6] (#23971)
* move delegation credential repository to features

* mv credential repository to features

* update imports

* mv

* fix

* fix

* fix

* fix

* fix

* update imports

* update imports

* update eslint rule

* fix

* fix

* mv getConnectedDestinationCalendars

* fix import errors

* mv getCalendarsEvents

* remove getUsersCredentials

* wip

* revert eslint rule change for now

* fix type checks

* fix

* format

* cleanup

* fix

* fix

* fix

* fix

* fix tests

* migrate getUserAvailability

* migrate

* fix tests

* fix type checks

* fix

* fix

* migrate crmManager

* update imports

* migrate raqbUtils to appstore

* migrate getLuckyUser to features

* migrate findTeamMembersMatchingAttributeLogic to appstore

* update imports

* fix

* fix

* fix test

* fix unit tests

* fix

* fix

* add eslint config
2025-10-09 14:02:12 +00:00

152 lines
4.7 KiB
TypeScript

import type { z } from "zod";
import { sendDelegationCredentialDisabledEmail } from "@calcom/emails/email-manager";
import { checkIfSuccessfullyConfiguredInWorkspace } from "@calcom/app-store/delegationCredential";
import logger from "@calcom/lib/logger";
import { getTranslation } from "@calcom/lib/server/i18n";
import { DelegationCredentialRepository } from "@calcom/lib/server/repository/delegationCredential";
import type { ServiceAccountKey } from "@calcom/lib/server/repository/delegationCredential";
import { getAffectedMembersForDisable } from "./getAffectedMembersForDisable.handler";
import type { DelegationCredentialToggleEnabledSchema } from "./schema";
import { ensureNoServiceAccountKey } from "./utils";
const log = logger.getSubLogger({ prefix: ["viewer", "delegationCredential", "toggleEnabled"] });
type LoggedInUser = {
id: number;
email: string;
locale: string;
emailVerified: Date | null;
organizationId: number | null;
};
export default async function toggleEnabledHandler({
ctx,
input,
}: {
ctx: {
user: LoggedInUser;
};
input: z.infer<typeof DelegationCredentialToggleEnabledSchema>;
}) {
const { user: loggedInUser } = ctx;
const t = await getTranslation(ctx.user.locale ?? "en", "common");
if (!loggedInUser.emailVerified) {
throw new Error(t("verify_your_email"));
}
return toggleDelegationCredentialEnabled(loggedInUser, input);
}
export async function toggleDelegationCredentialEnabled(
loggedInUser: Omit<LoggedInUser, "locale" | "emailVerified">,
input: z.infer<typeof DelegationCredentialToggleEnabledSchema>
) {
// Fetch the current credential to check the current enabled state
const currentDelegationCredential = await DelegationCredentialRepository.findById({
id: input.id,
});
if (!currentDelegationCredential) {
throw new Error("Delegation credential not found");
}
const shouldBeEnabled = input.enabled;
if (shouldBeEnabled === currentDelegationCredential.enabled) {
// Already enabled or disabled, so no need to do anything
return currentDelegationCredential;
}
if (shouldBeEnabled) {
await assertWorkspaceConfigured({
delegationCredentialId: input.id,
user: loggedInUser,
});
}
if (!shouldBeEnabled) {
const affectedMemberships = await getAffectedMembersForDisable({ delegationCredentialId: input.id });
const slug = currentDelegationCredential.workspacePlatform?.slug;
if (!slug) {
log.error(`Delegation credential ${input.id} has no workspace platform slug`);
}
let calendarAppName;
let conferencingAppName;
if (slug === "google") {
calendarAppName = "Google Calendar";
conferencingAppName = "Google Meet";
} else if (slug === "office365") {
calendarAppName = "Microsoft 365";
conferencingAppName = "Microsoft Teams";
} else {
throw new Error(`Unsupported workspace platform slug: ${slug}`);
}
for (const membership of affectedMemberships) {
if (membership.email) {
await sendDelegationCredentialDisabledEmail({
recipientEmail: membership.email,
recipientName: membership.name || undefined,
calendarAppName,
conferencingAppName,
});
}
}
}
const updatedDelegationCredential = await DelegationCredentialRepository.updateById({
id: input.id,
data: {
enabled: shouldBeEnabled,
// Don't touch lastEnabledAt if we are disabling
lastEnabledAt: shouldBeEnabled ? new Date() : undefined,
// Don't touch lastDisabledAt if we are enabling
lastDisabledAt: shouldBeEnabled ? undefined : new Date(),
},
});
return ensureNoServiceAccountKey(updatedDelegationCredential);
}
const assertWorkspaceConfigured = async ({
delegationCredentialId,
user,
}: {
delegationCredentialId: string;
user: { id: number; email: string; organizationId: number | null };
}) => {
const delegationCredential = await DelegationCredentialRepository.findByIdIncludeSensitiveServiceAccountKey(
{
id: delegationCredentialId,
}
);
if (!delegationCredential) {
throw new Error("Domain wide delegation not found");
}
if (!hasServiceAccountKey(delegationCredential)) {
throw new Error("Domain wide delegation doesn't have service account key");
}
const isSuccessfullyConfigured = await checkIfSuccessfullyConfiguredInWorkspace({
delegationCredential,
user,
});
if (!isSuccessfullyConfigured) {
throw new Error("Workspace not successfully configured");
}
};
function hasServiceAccountKey<T extends { serviceAccountKey: ServiceAccountKey | null }>(
delegationCredential: T
): delegationCredential is T & { serviceAccountKey: ServiceAccountKey } {
return delegationCredential.serviceAccountKey !== null;
}