diff --git a/apps/api/v1/lib/helpers/verifyApiKey.ts b/apps/api/v1/lib/helpers/verifyApiKey.ts index fca0077ebb..f9832b6f9c 100644 --- a/apps/api/v1/lib/helpers/verifyApiKey.ts +++ b/apps/api/v1/lib/helpers/verifyApiKey.ts @@ -1,6 +1,6 @@ import type { NextMiddleware } from "next-api-middleware"; -import LicenseKeyService from "@calcom/ee/common/server/LicenseKeyService"; +import { LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService"; import { hashAPIKey } from "@calcom/features/ee/api-keys/lib/apiKeys"; import { IS_PRODUCTION } from "@calcom/lib/constants"; import prisma from "@calcom/prisma"; @@ -18,7 +18,7 @@ export const dateNotInPast = function (date: Date) { // This verifies the apiKey and sets the user if it is valid. export const verifyApiKey: NextMiddleware = async (req, res, next) => { - const licenseKeyService = await LicenseKeyService.create(); + const licenseKeyService = await LicenseKeySingleton.getInstance(); const hasValidLicense = await licenseKeyService.checkLicense(); if (!hasValidLicense && IS_PRODUCTION) { diff --git a/packages/features/auth/lib/getServerSession.ts b/packages/features/auth/lib/getServerSession.ts index f87cfd83cb..36bf09d49d 100644 --- a/packages/features/auth/lib/getServerSession.ts +++ b/packages/features/auth/lib/getServerSession.ts @@ -3,7 +3,7 @@ import type { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from import type { AuthOptions, Session } from "next-auth"; import { getToken } from "next-auth/jwt"; -import LicenseKeyService from "@calcom/ee/common/server/LicenseKeyService"; +import { LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService"; import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; @@ -65,7 +65,7 @@ export async function getServerSession(options: { return null; } - const licenseKeyService = await LicenseKeyService.create(); + const licenseKeyService = await LicenseKeySingleton.getInstance(); const hasValidLicense = await licenseKeyService.checkLicense(); let upId = token.upId; diff --git a/packages/features/auth/lib/next-auth-options.ts b/packages/features/auth/lib/next-auth-options.ts index a16f84d804..dff904dc27 100644 --- a/packages/features/auth/lib/next-auth-options.ts +++ b/packages/features/auth/lib/next-auth-options.ts @@ -7,7 +7,7 @@ import CredentialsProvider from "next-auth/providers/credentials"; import EmailProvider from "next-auth/providers/email"; import GoogleProvider from "next-auth/providers/google"; -import LicenseKeyService from "@calcom/ee/common/server/LicenseKeyService"; +import { LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService"; import createUsersAndConnectToOrg from "@calcom/features/ee/dsync/lib/users/createUsersAndConnectToOrg"; import ImpersonationProvider from "@calcom/features/ee/impersonation/lib/ImpersonationProvider"; import { getOrgFullOrigin, subdomainSuffix } from "@calcom/features/ee/organizations/lib/orgDomains"; @@ -619,7 +619,7 @@ export const AUTH_OPTIONS: AuthOptions = { }, async session({ session, token, user }) { log.debug("callbacks:session - Session callback called", safeStringify({ session, token, user })); - const licenseKeyService = await LicenseKeyService.create(); + const licenseKeyService = await LicenseKeySingleton.getInstance(); const hasValidLicense = await licenseKeyService.checkLicense(); const profileId = token.profileId; diff --git a/packages/features/ee/common/server/LicenseKeyService.ts b/packages/features/ee/common/server/LicenseKeyService.ts index 1f5b215b3b..f15fa8d0cf 100644 --- a/packages/features/ee/common/server/LicenseKeyService.ts +++ b/packages/features/ee/common/server/LicenseKeyService.ts @@ -113,4 +113,22 @@ export class NoopLicenseKeyService implements ILicenseKeyService { } } +export class LicenseKeySingleton { + private static instance: ILicenseKeyService | null = null; + + // eslint-disable-next-line @typescript-eslint/no-empty-function -- Private constructor to prevent direct instantiation + private constructor() {} + + public static async getInstance(): Promise { + if (!LicenseKeySingleton.instance) { + const licenseKey = await getDeploymentKey(prisma); + const useNoop = !licenseKey || process.env.NEXT_PUBLIC_IS_E2E === "1"; + LicenseKeySingleton.instance = !useNoop + ? await LicenseKeyService.create() + : new NoopLicenseKeyService(); + } + return LicenseKeySingleton.instance; + } +} + export default LicenseKeyService; diff --git a/packages/prisma/extensions/usage-tracking.ts b/packages/prisma/extensions/usage-tracking.ts index 4d5ad9fc53..f4b507d6a0 100644 --- a/packages/prisma/extensions/usage-tracking.ts +++ b/packages/prisma/extensions/usage-tracking.ts @@ -1,11 +1,11 @@ import { Prisma } from "@prisma/client"; import { waitUntil } from "@vercel/functions"; -import LicenseKeyService, { UsageEvent } from "@calcom/ee/common/server/LicenseKeyService"; +import { UsageEvent, LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService"; async function incrementUsage(event?: UsageEvent) { try { - const licenseKeyService = await LicenseKeyService.create(); + const licenseKeyService = await LicenseKeySingleton.getInstance(); await licenseKeyService.incrementUsage(event); } catch (e) { console.log(e);