Files
calendar/packages/features/auth/lib/next-auth-custom-adapter.ts
T
Benny JooGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Keith Williams
6defa1cd7d refactor: replace @prisma/client/runtime imports with public API (#23087)
- Replace PrismaClientKnownRequestError and other error classes with Prisma namespace equivalents
- Remove internal DefaultArgs and InternalArgs type imports from Prisma extensions
- Ensure all error handling uses stable public API exports
- Maintain compatibility with future Prisma versions by avoiding runtime dependencies

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-08-29 03:09:52 +01:00

100 lines
4.4 KiB
TypeScript

import type { Account, IdentityProvider, User, VerificationToken } from "@prisma/client";
import { Prisma } from "@prisma/client";
import type { Awaitable } from "next-auth";
import type { PrismaClient } from "@calcom/prisma";
import { identityProviderNameMap } from "./identityProviderNameMap";
type CalComAdapter = {
createUser: (data: Prisma.UserCreateInput) => Awaitable<User>;
getUser: (id: string | number) => Awaitable<User | null>;
getUserByEmail: (email: User["email"]) => Awaitable<User | null>;
getUserByAccount: (provider_providerAccountId: {
providerAccountId: Account["providerAccountId"];
provider: User["identityProvider"];
}) => Awaitable<User | null>;
updateUser: (data: Prisma.UserUncheckedCreateInput) => Awaitable<User>;
deleteUser: (id: User["id"]) => Awaitable<User>;
createVerificationToken: (data: VerificationToken) => Awaitable<Omit<VerificationToken, "id">>;
useVerificationToken: (
identifier_token: Prisma.VerificationTokenIdentifierTokenCompoundUniqueInput
) => Awaitable<Omit<VerificationToken, "id"> | null>;
linkAccount: (data: Prisma.AccountCreateInput) => Awaitable<Account>;
unlinkAccount: (
provider_providerAccountId: Prisma.AccountProviderProviderAccountIdCompoundUniqueInput
) => Awaitable<Account>;
};
/** @return { import("next-auth/adapters").Adapter } */
export default function CalComAdapter(prismaClient: PrismaClient): CalComAdapter {
return {
createUser: (data: Prisma.UserCreateInput) => prismaClient.user.create({ data }),
getUser: (id: string | number) =>
prismaClient.user.findUnique({ where: { id: typeof id === "string" ? parseInt(id) : id } }),
getUserByEmail: (email: User["email"]) => prismaClient.user.findUnique({ where: { email } }),
async getUserByAccount(provider_providerAccountId: {
providerAccountId: Account["providerAccountId"];
provider: User["identityProvider"];
}) {
let _account;
const account = await prismaClient.account.findUnique({
where: {
provider_providerAccountId,
},
select: { user: true },
});
if (account) {
return (_account = account === null || account === void 0 ? void 0 : account.user) !== null &&
_account !== void 0
? _account
: null;
}
// NOTE: this code it's our fallback to users without Account but credentials in User Table
// We should remove this code after all googles tokens have expired
const provider = provider_providerAccountId?.provider.toUpperCase() as IdentityProvider;
if (["GOOGLE", "SAML"].indexOf(provider) < 0) {
return null;
}
const obtainProvider = identityProviderNameMap[provider].toUpperCase() as IdentityProvider;
const user = await prismaClient.user.findFirst({
where: {
identityProviderId: provider_providerAccountId?.providerAccountId,
identityProvider: obtainProvider,
},
});
return user || null;
},
updateUser: ({ id, ...data }: Prisma.UserUncheckedCreateInput) =>
prismaClient.user.update({ where: { id }, data }),
deleteUser: (id: User["id"]) => prismaClient.user.delete({ where: { id } }),
async createVerificationToken(data: VerificationToken) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id: _, ...verificationToken } = await prismaClient.verificationToken.create({
data,
});
return verificationToken;
},
async useVerificationToken(identifier_token: Prisma.VerificationTokenIdentifierTokenCompoundUniqueInput) {
try {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id: _, ...verificationToken } = await prismaClient.verificationToken.delete({
where: { identifier_token },
});
return verificationToken;
} catch (error) {
// If token already used/deleted, just return null
// https://www.prisma.io/docs/reference/api-reference/error-reference#p2025
if (error instanceof Prisma.PrismaClientKnownRequestError) {
if (error.code === "P2025") return null;
}
throw error;
}
},
linkAccount: (data: Prisma.AccountCreateInput) => prismaClient.account.create({ data }),
unlinkAccount: (provider_providerAccountId: Prisma.AccountProviderProviderAccountIdCompoundUniqueInput) =>
prismaClient.account.delete({ where: { provider_providerAccountId } }),
};
}