diff --git a/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts b/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts index e02e617577..c23d85ca08 100644 --- a/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts +++ b/apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts @@ -5,7 +5,7 @@ import { GetBookingOutput_2024_04_15 } from "@/ee/bookings/2024-04-15/outputs/ge import { GetBookingsOutput_2024_04_15 } from "@/ee/bookings/2024-04-15/outputs/get-bookings.output"; import { MarkNoShowOutput_2024_04_15 } from "@/ee/bookings/2024-04-15/outputs/mark-no-show.output"; import { PlatformBookingsService } from "@/ee/bookings/shared/platform-bookings.service"; -import { hashAPIKey, isApiKey, stripApiKey } from "@/lib/api-key"; +import { sha256Hash, isApiKey, stripApiKey } from "@/lib/api-key"; import { VERSION_2024_04_15, VERSION_2024_06_11, VERSION_2024_06_14 } from "@/lib/api-versions"; import { ApiKeysRepository } from "@/modules/api-keys/api-keys-repository"; import { GetUser } from "@/modules/auth/decorators/get-user/get-user.decorator"; @@ -386,7 +386,7 @@ export class BookingsController_2024_04_15 { if (bearerToken) { if (isApiKey(bearerToken, this.config.get("api.apiKeyPrefix") ?? "cal_")) { const strippedApiKey = stripApiKey(bearerToken, this.config.get("api.keyPrefix")); - const apiKeyHash = hashAPIKey(strippedApiKey); + const apiKeyHash = sha256Hash(strippedApiKey); const keyData = await this.apiKeyRepository.getApiKeyFromHash(apiKeyHash); return keyData?.userId; } else { diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts index ed430045b3..04f67dc900 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts @@ -11,7 +11,7 @@ import { PlatformBookingsService } from "@/ee/bookings/shared/platform-bookings. import { EventTypesRepository_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/event-types.repository"; import { OutputEventTypesService_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/services/output-event-types.service"; import { apiToInternalintegrationsMapping } from "@/ee/event-types/event-types_2024_06_14/transformers"; -import { hashAPIKey, isApiKey, stripApiKey } from "@/lib/api-key"; +import { sha256Hash, isApiKey, stripApiKey } from "@/lib/api-key"; import { defaultBookingResponses } from "@/lib/safe-parse/default-responses-booking"; import { safeParse } from "@/lib/safe-parse/safe-parse"; import { ApiKeysRepository } from "@/modules/api-keys/api-keys-repository"; @@ -675,7 +675,7 @@ export class InputBookingsService_2024_08_13 { if (bearerToken) { if (isApiKey(bearerToken, this.config.get("api.apiKeyPrefix") ?? "cal_")) { const strippedApiKey = stripApiKey(bearerToken, this.config.get("api.keyPrefix")); - const apiKeyHash = hashAPIKey(strippedApiKey); + const apiKeyHash = sha256Hash(strippedApiKey); const keyData = await this.apiKeyRepository.getApiKeyFromHash(apiKeyHash); return keyData?.userId; } else { diff --git a/apps/api/v2/src/lib/api-key/index.ts b/apps/api/v2/src/lib/api-key/index.ts index ad7ec0d2a9..b580c5c29d 100644 --- a/apps/api/v2/src/lib/api-key/index.ts +++ b/apps/api/v2/src/lib/api-key/index.ts @@ -1,6 +1,6 @@ import { createHash } from "crypto"; -export const hashAPIKey = (apiKey: string): string => createHash("sha256").update(apiKey).digest("hex"); +export const sha256Hash = (token: string): string => createHash("sha256").update(token).digest("hex"); export const isApiKey = (authString: string, prefix: string): boolean => authString?.startsWith(prefix ?? "cal_"); diff --git a/apps/api/v2/src/lib/throttler-guard.ts b/apps/api/v2/src/lib/throttler-guard.ts index 042ec9ceef..e19b599cc2 100644 --- a/apps/api/v2/src/lib/throttler-guard.ts +++ b/apps/api/v2/src/lib/throttler-guard.ts @@ -1,5 +1,5 @@ import { getEnv } from "@/env"; -import { hashAPIKey, isApiKey, stripApiKey } from "@/lib/api-key"; +import { sha256Hash, isApiKey, stripApiKey } from "@/lib/api-key"; import { Throttle } from "@/lib/endpoint-throttler-decorator"; import { PrismaReadService } from "@/modules/prisma/prisma-read.service"; import { ThrottlerStorageRedisService } from "@nest-lab/throttler-storage-redis"; @@ -10,7 +10,6 @@ import { ThrottlerException, ThrottlerRequest, ThrottlerModuleOptions, - seconds, } from "@nestjs/throttler"; import { Request, Response } from "express"; import { z } from "zod"; @@ -218,18 +217,18 @@ export class CustomThrottlerGuard extends ThrottlerGuard { if (authorizationHeader) { const apiKeyPrefix = getEnv("API_KEY_PREFIX", "cal_"); return isApiKey(authorizationHeader, apiKeyPrefix) - ? `api_key_${hashAPIKey(stripApiKey(authorizationHeader, apiKeyPrefix))}` - : `access_token_${authorizationHeader}`; + ? `api_key_${sha256Hash(stripApiKey(authorizationHeader, apiKeyPrefix))}` + : `access_token_${sha256Hash(authorizationHeader)}`; } const oauthClientId = request.get(X_CAL_CLIENT_ID); if (oauthClientId) { - return `oauth_client_${oauthClientId}`; + return `oauth_client_${sha256Hash(oauthClientId)}`; } if (IP) { - return `ip_${IP}`; + return `ip_${sha256Hash(IP.toString())}`; } this.logger.verbose(`no tracker found: ${request.url}`); diff --git a/apps/api/v2/src/modules/api-keys/services/api-keys.service.ts b/apps/api/v2/src/modules/api-keys/services/api-keys.service.ts index 79f3a3bb3f..45547d868a 100644 --- a/apps/api/v2/src/modules/api-keys/services/api-keys.service.ts +++ b/apps/api/v2/src/modules/api-keys/services/api-keys.service.ts @@ -1,4 +1,4 @@ -import { hashAPIKey, stripApiKey } from "@/lib/api-key"; +import { sha256Hash, stripApiKey } from "@/lib/api-key"; import { AuthMethods } from "@/lib/enums/auth-methods"; import { ApiKeysRepository } from "@/modules/api-keys/api-keys-repository"; import { CreateApiKeyInput } from "@/modules/api-keys/inputs/create-api-key.input"; @@ -61,7 +61,7 @@ export class ApiKeysService { async refreshApiKey(authUserId: number, apiKey: string, refreshApiKeyInput: RefreshApiKeyInput) { const strippedApiKey = stripApiKey(apiKey, this.config.get("api.keyPrefix")); - const apiKeyHash = hashAPIKey(strippedApiKey); + const apiKeyHash = sha256Hash(strippedApiKey); const apiKeyInDb = await this.apiKeysRepository.getApiKeyFromHash(apiKeyHash); if (!apiKeyInDb) { throw new UnauthorizedException("ApiKeysService - provided api key is not valid."); diff --git a/apps/api/v2/src/modules/auth/strategies/api-auth/api-auth.strategy.ts b/apps/api/v2/src/modules/auth/strategies/api-auth/api-auth.strategy.ts index c04c5d8238..b1688e69b9 100644 --- a/apps/api/v2/src/modules/auth/strategies/api-auth/api-auth.strategy.ts +++ b/apps/api/v2/src/modules/auth/strategies/api-auth/api-auth.strategy.ts @@ -1,4 +1,4 @@ -import { hashAPIKey, isApiKey, stripApiKey } from "@/lib/api-key"; +import { sha256Hash, isApiKey, stripApiKey } from "@/lib/api-key"; import { AuthMethods } from "@/lib/enums/auth-methods"; import { isOriginAllowed } from "@/lib/is-origin-allowed/is-origin-allowed"; import { BaseStrategy } from "@/lib/passport/strategies/types"; @@ -226,7 +226,7 @@ export class ApiAuthStrategy extends PassportStrategy(BaseStrategy, "api-auth") ); } const strippedApiKey = stripApiKey(apiKey, this.config.get("api.keyPrefix")); - const apiKeyHash = hashAPIKey(strippedApiKey); + const apiKeyHash = sha256Hash(strippedApiKey); const keyData = await this.apiKeyRepository.getApiKeyFromHash(apiKeyHash); if (!keyData) { throw new UnauthorizedException("ApiAuthStrategy - api key - Your api key is not valid"); diff --git a/apps/api/v2/src/modules/organizations/organizations/organizations-organizations.controller.e2e-spec.ts b/apps/api/v2/src/modules/organizations/organizations/organizations-organizations.controller.e2e-spec.ts index 3dcbb33ce0..d949e3ea92 100644 --- a/apps/api/v2/src/modules/organizations/organizations/organizations-organizations.controller.e2e-spec.ts +++ b/apps/api/v2/src/modules/organizations/organizations/organizations-organizations.controller.e2e-spec.ts @@ -1,7 +1,7 @@ import { bootstrap } from "@/app"; import { AppModule } from "@/app.module"; import { getEnv } from "@/env"; -import { hashAPIKey, stripApiKey } from "@/lib/api-key"; +import { sha256Hash, stripApiKey } from "@/lib/api-key"; import { RefreshApiKeyOutput } from "@/modules/api-keys/outputs/refresh-api-key.output"; import { CreateOAuthClientResponseDto } from "@/modules/oauth-clients/controllers/oauth-clients/responses/CreateOAuthClientResponse.dto"; import { GetOAuthClientResponseDto } from "@/modules/oauth-clients/controllers/oauth-clients/responses/GetOAuthClientResponse.dto"; @@ -283,7 +283,7 @@ describe("Organizations Organizations Endpoints", () => { expect(managedOrgApiKeys?.length).toEqual(1); expect(managedOrgApiKeys?.[0]?.id).toBeDefined(); const apiKeyPrefix = getEnv("API_KEY_PREFIX", "cal_"); - const hashedApiKey = `${hashAPIKey(stripApiKey(managedOrg?.apiKey, apiKeyPrefix))}`; + const hashedApiKey = `${sha256Hash(stripApiKey(managedOrg?.apiKey, apiKeyPrefix))}`; expect(managedOrgApiKeys?.[0]?.hashedKey).toEqual(hashedApiKey); const expectedExpiresAt = DateTime.fromJSDate(newDate).setZone("utc").plus({ days: 30 }).toJSDate(); expect(managedOrgApiKeys?.[0]?.expiresAt).toEqual(expectedExpiresAt); @@ -484,7 +484,7 @@ describe("Organizations Organizations Endpoints", () => { expect(managedOrgApiKeys?.length).toEqual(1); expect(managedOrgApiKeys?.[0]?.id).toBeDefined(); const apiKeyPrefix = getEnv("API_KEY_PREFIX", "cal_"); - const hashedApiKey = `${hashAPIKey(stripApiKey(newApiKey, apiKeyPrefix))}`; + const hashedApiKey = `${sha256Hash(stripApiKey(newApiKey, apiKeyPrefix))}`; expect(managedOrgApiKeys?.[0]?.hashedKey).toEqual(hashedApiKey); const expectedExpiresAt = DateTime.fromJSDate(newDate).setZone("utc").plus({ days: 60 }).toJSDate(); expect(managedOrgApiKeys?.[0]?.expiresAt).toEqual(expectedExpiresAt);