diff --git a/apps/api/v2/package.json b/apps/api/v2/package.json index 6b58fb0034..c460d1c22a 100644 --- a/apps/api/v2/package.json +++ b/apps/api/v2/package.json @@ -12,11 +12,11 @@ "dev": "yarn workspace @calcom/platform-constants build:watch & yarn workspace @calcom/platform-utils build:watch & yarn workspace @calcom/platform-types build:watch & nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", - "test": "jest", + "test": "yarn workspace @calcom/platform-constants build && yarn workspace @calcom/platform-utils build && yarn workspace @calcom/platform-types build && jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./jest-e2e.json", + "test:e2e": "yarn workspace @calcom/platform-constants build && yarn workspace @calcom/platform-utils build && yarn workspace @calcom/platform-types build && jest --config ./jest-e2e.json", "prisma": "yarn workspace @calcom/prisma prisma", "generate-schemas": "yarn prisma generate && yarn prisma format" }, diff --git a/apps/api/v2/src/modules/auth/guards/access-token/token-expired.exception.ts b/apps/api/v2/src/modules/auth/guards/access-token/token-expired.exception.ts new file mode 100644 index 0000000000..1e3f4eea83 --- /dev/null +++ b/apps/api/v2/src/modules/auth/guards/access-token/token-expired.exception.ts @@ -0,0 +1,9 @@ +import { HttpException } from "@nestjs/common"; + +import { ACCESS_TOKEN_EXPIRED, HTTP_CODE_TOKEN_EXPIRED } from "@calcom/platform-constants"; + +export class TokenExpiredException extends HttpException { + constructor() { + super(ACCESS_TOKEN_EXPIRED, HTTP_CODE_TOKEN_EXPIRED); + } +} diff --git a/apps/api/v2/src/modules/auth/strategies/access-token/access-token.strategy.ts b/apps/api/v2/src/modules/auth/strategies/access-token/access-token.strategy.ts index 5f95bc3da5..fcec8ff50f 100644 --- a/apps/api/v2/src/modules/auth/strategies/access-token/access-token.strategy.ts +++ b/apps/api/v2/src/modules/auth/strategies/access-token/access-token.strategy.ts @@ -5,6 +5,8 @@ import { Injectable, UnauthorizedException } from "@nestjs/common"; import { PassportStrategy } from "@nestjs/passport"; import type { Request } from "express"; +import { INVALID_ACCESS_TOKEN } from "@calcom/platform-constants"; + class BaseStrategy { success!: (user: unknown) => void; error!: (error: Error) => void; @@ -25,25 +27,21 @@ export class AccessTokenStrategy extends PassportStrategy(BaseStrategy, "access- const accessToken = request.get("Authorization")?.replace("Bearer ", ""); if (!accessToken) { - throw new UnauthorizedException("Access token is missing or invalid."); + throw new UnauthorizedException(INVALID_ACCESS_TOKEN); } - const valid = this.oauthFlowService.validateAccessToken(accessToken); - - if (!valid) { - throw new UnauthorizedException("Access token is missing or invalid."); - } + this.oauthFlowService.validateAccessToken(accessToken); const ownerId = await this.tokensRepository.getAccessTokenOwnerId(accessToken); if (!ownerId) { - throw new UnauthorizedException("Invalid access token"); + throw new UnauthorizedException(INVALID_ACCESS_TOKEN); } const user = await this.userRepository.findById(ownerId); if (!user) { - throw new UnauthorizedException("User associated with the access token not found."); + throw new UnauthorizedException(INVALID_ACCESS_TOKEN); } return this.success(user); diff --git a/apps/api/v2/src/modules/oauth-clients/services/oauth-flow.service.ts b/apps/api/v2/src/modules/oauth-clients/services/oauth-flow.service.ts index 0011b5960b..2dd742cc23 100644 --- a/apps/api/v2/src/modules/oauth-clients/services/oauth-flow.service.ts +++ b/apps/api/v2/src/modules/oauth-clients/services/oauth-flow.service.ts @@ -1,7 +1,10 @@ +import { TokenExpiredException } from "@/modules/auth/guards/access-token/token-expired.exception"; import { OAuthClientRepository } from "@/modules/oauth-clients/oauth-client.repository"; import { TokensRepository } from "@/modules/tokens/tokens.repository"; import { BadRequestException, Injectable, Logger, UnauthorizedException } from "@nestjs/common"; +import { INVALID_ACCESS_TOKEN } from "@calcom/platform-constants"; + @Injectable() export class OAuthFlowService { private logger = new Logger("OAuthFlowService"); @@ -29,11 +32,11 @@ export class OAuthFlowService { const tokenExpiresAt = await this.tokensRepository.getAccessTokenExpiryDate(secret); if (!tokenExpiresAt) { - throw new UnauthorizedException("Access token is invalid or not found"); + throw new UnauthorizedException(INVALID_ACCESS_TOKEN); } if (new Date() > tokenExpiresAt) { - throw new BadRequestException("Token is expired"); + throw new TokenExpiredException(); } return true; diff --git a/packages/platform/constants/api.ts b/packages/platform/constants/api.ts index fd01b1dab5..aa7ab64c89 100644 --- a/packages/platform/constants/api.ts +++ b/packages/platform/constants/api.ts @@ -7,6 +7,8 @@ export const FORBIDDEN = "FORBIDDEN"; export const NOT_FOUND = "NOT_FOUND"; export const METHOD_NOT_ALLOWED = "METHOD_NOT_ALLOWED"; export const UNPROCESSABLE_ENTITY = "UNPROCESSABLE_ENTITY"; +export const ACCESS_TOKEN_EXPIRED = "ACCESS_TOKEN_IS_EXPIRED"; +export const INVALID_ACCESS_TOKEN = "Invalid Access Token."; // Server Errors (5xx) export const INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR"; @@ -35,3 +37,6 @@ export const API_ERROR_CODES = [ // Request headers export const X_CAL_SECRET_KEY = "x-cal-secret-key"; + +// HTTP status codes +export const HTTP_CODE_TOKEN_EXPIRED = 498;