Skip to content

Conversation

@sujitaw
Copy link
Contributor

@sujitaw sujitaw commented Oct 10, 2025

What

  • made changes in jwt stratergy to handle refresh token based auth.
  • modified refresh token API to store newly generated access token and refresh token.
  • added session deletion logic on expiration of refresh token.

Summary by CodeRabbit

  • New Features

    • Added session detail retrieval for enhanced user session management.
    • Introduced refresh token expiration tracking.
  • Bug Fixes

    • Fixed typo in user session error message.
    • Added error message for expired refresh tokens.
  • Improvements

    • Enhanced token validation during authentication flow.
    • Refined session token update mechanism for better consistency.

@sujitaw sujitaw self-assigned this Oct 10, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 10, 2025

Walkthrough

The changes refactor session and token management across the API gateway and user services. They introduce new token data structures, modify JWT strategy to remove runtime token expiration checks, add session token update methods to the repository, and restructure the refresh token flow to use refresh tokens as the expiration source.

Changes

Cohort / File(s) Summary
API Gateway Session & JWT Updates
apps/api-gateway/common/interface.ts, apps/api-gateway/src/authz/jwt.strategy.ts
Added public ISession interface with optional fields including clientInfo. Removed runtime token expiration handling logic from JWT strategy's secret key resolution; decoded token validation retained.
User Application Token & Session Interfaces
apps/user/interfaces/user.interface.ts
Introduced new ITokenData interface with fields for sessionToken (string), expires (number), refreshToken (string), and expiresAt (Date).
User Repository Session Methods
apps/user/repositories/user.repository.ts
Added fetchUserSessionDetails() to retrieve all session details for a user. Added updateSessionToken() to update session with token data. Enhanced error handling for session deletion operations with specific Prisma error code P2025 checks.
User Service Token & Refresh Flows
apps/user/src/user.service.ts
Modified login() to decode refresh_token instead of access_token for expiration data. Refactored refreshTokenDetails() from nested error handling to linear flow: decode refresh token, validate expiry, request new access token, update session via new repository method.
Common Library Token & Error Messages
libs/common/src/interfaces/user.interface.ts, libs/common/src/response-messages/index.ts
Added optional refresh_expires_in?: number to ISignInUser. Fixed typo: userSeesionNotFound → userSessionNotFound. Added new error key refreshTokenExpired.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant UserService
    participant UserRepository
    participant AuthService
    participant TokenProvider

    Client->>UserService: refreshTokenDetails(refreshToken)
    
    rect rgb(230, 245, 255)
    Note over UserService: Validate & Decode Phase
    UserService->>UserService: decode(refreshToken)
    UserService->>UserService: validate exp & sid
    alt Token Expired
        UserService->>UserRepository: deleteSession(sid)
        UserService-->>Client: ❌ Unauthorized (expired)
    end
    end
    
    rect rgb(240, 250, 230)
    Note over UserService: Token Generation & Session Update Phase
    UserService->>AuthService: requestNewAccessToken()
    AuthService-->>UserService: newAccessToken
    UserService->>UserRepository: getSession(sid)
    UserRepository-->>UserService: existingSession
    UserService->>UserService: decode(newAccessToken)
    UserService->>UserService: derive expiresAt
    UserService->>UserRepository: updateSessionToken(sid, tokenData)
    UserRepository-->>UserService: ✓ updatedSession
    end
    
    UserService-->>Client: ✓ tokenResponse
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Extra attention areas:
    • apps/user/src/user.service.ts: The refactored refreshTokenDetails() flow replaces nested error handling with linear sequence; verify the error propagation paths (NotFound, Unauthorized, InternalServerError) align with RpcException wrapping behavior and upstream error handling expectations.
    • apps/user/repositories/user.repository.ts: New updateSessionToken() method's Prisma update logic and error handling for session mutations; ensure P2025 error code checks are comprehensive and consistent.
    • Cross-service token source alignment: Verify that the switch from access_token to refresh_token for deriving expiration in login() and refreshTokenDetails() is intentional and does not break downstream token validation logic.

Possibly related PRs

Suggested reviewers

  • tipusinghaw
  • shitrerohit
  • RinkalBhojani

Poem

🐰 A rabbit's ode to token streams,
Refresh flows refined, not just dreams!
Sessions stored, no hasty expire,
Auth paths cleaner, we climb higher.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "fix/session management using refresh token" is directly aligned with the primary changes in the changeset. The modifications across multiple files demonstrate a comprehensive refactoring of session management and JWT authentication to prioritize refresh token handling: the JWT strategy was updated to remove access token expiration checks, the user service was refactored to decode and validate refresh tokens instead of access tokens, new session token data structures were introduced (ITokenData interface), and repository methods were enhanced to update session tokens. The title accurately captures the main intent of these changes and is specific enough to convey that this involves session management improvements centered on refresh token implementation, without being overly vague or generic.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/jwt_token_management

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d838b47 and c9e50e2.

📒 Files selected for processing (3)
  • apps/user/interfaces/user.interface.ts (1 hunks)
  • apps/user/src/user.service.ts (3 hunks)
  • libs/common/src/response-messages/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/user/interfaces/user.interface.ts
  • libs/common/src/response-messages/index.ts
🧰 Additional context used
🧬 Code graph analysis (1)
apps/user/src/user.service.ts (4)
libs/common/src/response-messages/index.ts (1)
  • ResponseMessages (1-522)
apps/api-gateway/src/authz/authz.controller.ts (2)
  • refreshToken (328-337)
  • sessionDetails (223-241)
apps/api-gateway/src/authz/authz.service.ts (1)
  • refreshToken (80-82)
apps/api-gateway/src/authz/jwt-payload.interface.ts (1)
  • JwtPayload (1-13)
🔇 Additional comments (1)
apps/user/src/user.service.ts (1)

469-473: LGTM: Proper token validation before use.

The refresh token is correctly decoded and validated before accessing its properties. The checks ensure the token is an object with required exp and sid fields, preventing runtime crashes from malformed tokens.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
libs/client-registration/src/client-registration.service.ts (1)

178-181: Stop logging tokens, secrets, and sensitive payloads.

Logs at these sites include client_secret, access/refresh tokens, or whole payloads/responses. This is a security and compliance risk.

  • Remove or mask sensitive fields (client_secret, access_token, refresh_token).
  • Prefer structured logs with redaction.

Example masking pattern:

this.logger.debug('Token response received', {
  endpoint: 'SAT',
  has_access_token: !!tokenResponse?.access_token,
  // do not log token values
});

Also applies to: 345-347, 695-696

apps/user/src/user.service.ts (1)

484-496: Guard decode of refresh_token to avoid NPE and fallback on refresh_expires_in

jwt.decode can return null/string; exp may be missing. Add a safe fallback.

Apply this diff:

-      const decodedToken: any = jwt.decode(tokenDetails?.refresh_token);
-      const expiresAt = new Date(decodedToken.exp * 1000);
+      const decodedRefresh = jwt.decode(tokenDetails?.refresh_token) as jwt.JwtPayload | null;
+      const expiresAt =
+        decodedRefresh?.exp
+          ? new Date(decodedRefresh.exp * 1000)
+          : new Date(Date.now() + (tokenDetails?.refresh_expires_in ?? 0) * 1000);
🧹 Nitpick comments (8)
libs/client-registration/src/client-registration.service.ts (1)

21-23: DTO naming consistency (optional).

accessTokenPayloadDto and userTokenPayloadDto are constructed via new but use lowerCamelCase. Nest/TS conventions prefer PascalCase for classes/DTOs (e.g., AccessTokenPayloadDto).

If feasible, rename classes/files to PascalCase to align with codebase conventions.

libs/common/src/interfaces/user.interface.ts (1)

9-9: Clarify units for refresh_expires_in.

Is this seconds (Keycloak default) or milliseconds? Ensure it matches expires_in units and document to avoid misuse.

Add a brief JSDoc comment indicating the unit.

apps/user/interfaces/user.interface.ts (1)

305-310: Disambiguate expiry fields in ITokenData.

Having both expires: number and expiresAt: Date is redundant and can drift. Define one source of truth or clearly document:

  • expires: seconds since epoch?
  • expiresAt: absolute Date?

Consider keeping only expiresAt (Date) or renaming expires → expiresInSeconds with clear units.

apps/api-gateway/common/interface.ts (2)

1-2: Avoid Prisma type leakage in gateway.

Importing Prisma just for JsonValue couples the gateway to ORM internals.

Use a local JsonValue type (see apps/api-gateway/src/issuance/utils/helper.ts) or a shared union in a common lib.


16-28: DRY: ISession duplication across services.

This ISession mirrors apps/user/interfaces/user.interface.ts. Duplicated contracts will drift.

Extract ISession into a shared lib (e.g., @credebl/common/interfaces) and import from there. Also replace Prisma.JsonValue with a shared JsonValue.

apps/user/src/user.controller.ts (1)

98-101: LGTM; add DTO validation for payload.

Handler is fine. Consider a DTO with class-validator to enforce refreshToken presence/type.

Example:

export class GenerateAccessTokenUsingRefreshTokenDto {
  @IsString()
  refreshToken: string;
}

Then type payload accordingly.

apps/user/repositories/user.repository.ts (2)

732-745: Minimize exposure: select only needed fields for session cleanup

This method returns full session records “without any restriction,” including tokens. Prefer selecting only fields required by callers to reduce accidental leakage.

Apply this diff:

-  async fetchUserSessionDetails(userId: string): Promise<ISession[]> {
+  async fetchUserSessionDetails(userId: string): Promise<ISession[]> {
     try {
-      const userSessionCount = await this.prisma.session.findMany({
-        where: {
-          userId
-        }
-      });
-      return userSessionCount;
+      const sessions = await this.prisma.session.findMany({
+        where: { userId },
+        select: { id: true, refreshToken: true, expiresAt: true }
+      });
+      return sessions as unknown as ISession[];
     } catch (error) {
       this.logger.error(`Error in getting user session details: ${error.message} `);
       throw error;
     }
   }

1005-1011: Good P2025 handling; align other methods for consistency

Catching Prisma P2025 and mapping to NotFound is good. Mirror this pattern in deleteSessionBySessionId for consistent behavior across repository methods.

Suggested change outside this range (deleteSessionBySessionId):

} catch (error) {
  if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2025') {
    throw new RpcException(new NotFoundException(`Session not found for userId: ${userId}`));
  }
  this.logger.error(`Error in Deleting Session: ${error.message}`);
  throw error;
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 69b8f27 and fbc34ff.

📒 Files selected for processing (10)
  • apps/api-gateway/common/interface.ts (2 hunks)
  • apps/api-gateway/src/authz/jwt.strategy.ts (0 hunks)
  • apps/api-gateway/src/user/user.service.ts (2 hunks)
  • apps/user/interfaces/user.interface.ts (1 hunks)
  • apps/user/repositories/user.repository.ts (4 hunks)
  • apps/user/src/user.controller.ts (1 hunks)
  • apps/user/src/user.service.ts (3 hunks)
  • libs/client-registration/src/client-registration.service.ts (1 hunks)
  • libs/common/src/interfaces/user.interface.ts (1 hunks)
  • libs/common/src/response-messages/index.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/api-gateway/src/authz/jwt.strategy.ts
🧰 Additional context used
🧬 Code graph analysis (5)
apps/api-gateway/src/user/user.service.ts (3)
apps/api-gateway/src/authz/authz.controller.ts (1)
  • refreshToken (328-337)
apps/api-gateway/src/authz/authz.service.ts (1)
  • refreshToken (80-82)
libs/common/src/interfaces/user.interface.ts (1)
  • ISignInUser (1-10)
apps/user/src/user.controller.ts (1)
libs/common/src/interfaces/user.interface.ts (1)
  • ISignInUser (1-10)
apps/api-gateway/common/interface.ts (2)
apps/user/interfaces/user.interface.ts (1)
  • ISession (185-197)
apps/api-gateway/src/issuance/utils/helper.ts (1)
  • JsonValue (5-5)
apps/user/src/user.service.ts (5)
apps/api-gateway/src/authz/authz.controller.ts (2)
  • refreshToken (328-337)
  • sessionDetails (223-241)
apps/api-gateway/src/authz/authz.service.ts (1)
  • refreshToken (80-82)
apps/api-gateway/src/authz/jwt-payload.interface.ts (1)
  • JwtPayload (1-13)
libs/common/src/response-messages/index.ts (1)
  • ResponseMessages (1-519)
libs/common/src/interfaces/user.interface.ts (1)
  • ISignInUser (1-10)
apps/user/repositories/user.repository.ts (3)
apps/api-gateway/common/interface.ts (1)
  • ISession (16-28)
apps/user/interfaces/user.interface.ts (2)
  • ISession (185-197)
  • ITokenData (305-310)
libs/logger/src/logger.service.ts (1)
  • error (51-54)
🔇 Additional comments (3)
apps/api-gateway/common/interface.ts (1)

11-14: OK: ExceptionResponse typing tightened.

apps/api-gateway/src/user/user.service.ts (2)

10-10: Import update looks good.


77-81: LGTM; confirm subject naming across services.

Method correctly proxies to user service. Double-check we need both flows:

  • refresh-token-details (existing)
  • generate-accessToken-using-refresh-token (new)

If both remain, document their distinct purposes to avoid caller confusion.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
libs/common/src/response-messages/index.ts (1)

76-76: Typo fix already flagged in previous review.

The typo correction from userSeesionNotFound to userSessionNotFound was already identified in a previous review comment.

apps/user/src/user.service.ts (1)

540-583: Critical: Multiple security and reliability issues in refresh token flow.

This method has several critical issues that remain from previous reviews:

  1. Line 540: Unsafe jwt.decode without validation - can crash if token is malformed
  2. Lines 548, 554: Logging PII (user details) and sensitive data (tokens, client secrets)
  3. Line 544: Session deletion not wrapped in try-catch - could mask refreshTokenExpired error
  4. Line 577: Using tokenResponse.session_state instead of sessionDetails.id for update - may fail or update wrong session
  5. Lines 569-570: Unsafe decode of new refresh token without validation

Apply this comprehensive diff to address all issues:

-      const data = jwt.decode(refreshToken) as jwt.JwtPayload;
-      const refreshTokenExp = new Date(data.exp * 1000);
+      const payload = jwt.decode(refreshToken) as jwt.JwtPayload | null;
+      if (!payload || typeof payload !== 'object' || !payload.exp || !payload.sid || !payload.sub) {
+        throw new UnauthorizedException(ResponseMessages.user.error.invalidRefreshToken);
+      }
+      const refreshTokenExp = new Date(payload.exp * 1000);
       const currentTime = new Date();
       if (refreshTokenExp < currentTime) {
-        await this.userRepository.deleteSession(data?.sid);
+        // Best-effort cleanup; ignore not-found errors
+        try {
+          await this.userRepository.deleteSession(payload.sid as string);
+        } catch (err) {
+          // Ignore deletion errors (e.g., session already deleted)
+        }
         throw new UnauthorizedException(ResponseMessages.user.error.refreshTokenExpired);
       }
-      const userByKeycloakId = await this.userRepository.getUserByKeycloakId(data?.sub);
-      this.logger.debug(`User details::;${JSON.stringify(userByKeycloakId)}`);
+      const userByKeycloakId = await this.userRepository.getUserByKeycloakId(payload.sub as string);
       const tokenResponse = await this.clientRegistrationService.getAccessToken(
         refreshToken,
         userByKeycloakId?.['clientId'],
         userByKeycloakId?.['clientSecret']
       );
-      this.logger.debug(`tokenResponse::::${JSON.stringify(tokenResponse)}`);
       // Fetch the details from account table based on userid and refresh token
       const userAccountDetails = await this.userRepository.checkAccountDetails(userByKeycloakId?.['id']);
       // Update the account details with latest access token, refresh token and exp date
       if (!userAccountDetails) {
         throw new NotFoundException(ResponseMessages.user.error.userAccountNotFound);
       }
       // Fetch session details
-
-      const sessionDetails = await this.userRepository.getSession(data.sid);
+      const sessionDetails = await this.userRepository.getSession(payload.sid as string);
       if (!sessionDetails) {
-        throw new NotFoundException(ResponseMessages.user.error.userSessionNotFound);
+        throw new NotFoundException(ResponseMessages.user.error.userSessionNotFound);
       }
-
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      const decodedToken: any = jwt.decode(tokenResponse?.refresh_token);
-      const expiresAt = new Date(decodedToken.exp * 1000);
+      const decodedRefresh = jwt.decode(tokenResponse?.refresh_token) as jwt.JwtPayload | null;
+      const expiresAt =
+        decodedRefresh?.exp
+          ? new Date(decodedRefresh.exp * 1000)
+          : new Date(Date.now() + (tokenResponse?.refresh_expires_in ?? 0) * 1000);
       const sessionData = {
         sessionToken: tokenResponse.access_token,
         expires: tokenResponse.expires_in,
         refreshToken: tokenResponse.refresh_token,
         expiresAt
       };
-      const addSessionDetails = await this.userRepository.updateSessionToken(tokenResponse.session_state, sessionData);
+      const addSessionDetails = await this.userRepository.updateSessionToken(sessionDetails.id, sessionData);
       if (!addSessionDetails) {
         throw new InternalServerErrorException(ResponseMessages.user.error.errorInSessionCreation);
       }
 
       return tokenResponse;

Based on past review comments.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbc34ff and 71b3285.

📒 Files selected for processing (3)
  • apps/user/repositories/user.repository.ts (4 hunks)
  • apps/user/src/user.service.ts (3 hunks)
  • libs/common/src/response-messages/index.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/user/repositories/user.repository.ts
🧰 Additional context used
🧬 Code graph analysis (1)
apps/user/src/user.service.ts (3)
apps/api-gateway/src/authz/authz.controller.ts (1)
  • refreshToken (328-337)
apps/api-gateway/src/authz/authz.service.ts (1)
  • refreshToken (80-82)
apps/api-gateway/src/authz/jwt-payload.interface.ts (1)
  • JwtPayload (1-13)
🔇 Additional comments (2)
libs/common/src/response-messages/index.ts (1)

77-77: LGTM — refreshTokenExpired is referenced in apps/user/src/user.service.ts:545.

apps/user/src/user.service.ts (1)

455-455: deleteInactiveSessions correctly uses stored expiresAt
The repository implementation deletes sessions where expiresAt < new Date(), so it relies on the stored expiry timestamp rather than decoding tokens.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
apps/user/src/user.service.ts (4)

542-548: Critical: Validate decoded refresh token before accessing claims.

The code directly accesses data.exp and data.sid without validating that jwt.decode returned a valid payload. If the token is malformed, this will crash.

Apply this diff to add validation:

-      const data = jwt.decode(refreshToken) as jwt.JwtPayload;
-      const refreshTokenExp = new Date(data.exp * 1000);
+      const payload = jwt.decode(refreshToken) as jwt.JwtPayload | null;
+      if (!payload || typeof payload !== 'object' || !payload.exp || !payload.sid || !payload.sub) {
+        throw new UnauthorizedException(ResponseMessages.user.error.invalidRefreshToken);
+      }
+      const refreshTokenExp = new Date(payload.exp * 1000);
       const currentTime = new Date();
       if (refreshTokenExp < currentTime) {
-        await this.userRepository.deleteSession(data?.sid);
+        try {
+          await this.userRepository.deleteSession(payload.sid as string);
+        } catch (_) {
+          // Best-effort cleanup; ignore not-found errors
+        }
         throw new UnauthorizedException(ResponseMessages.user.error.refreshTokenExpired);
       }
-      const userByKeycloakId = await this.userRepository.getUserByKeycloakId(data?.sub);
+      const userByKeycloakId = await this.userRepository.getUserByKeycloakId(payload.sub as string);

550-550: Remove PII from logs.

Logging the full user object exposes personally identifiable information (PII). Remove this debug log.

Apply this diff:

-      this.logger.debug(`User details::;${JSON.stringify(userByKeycloakId)}`);

556-556: Remove sensitive token data from logs.

Logging tokenResponse exposes access tokens, refresh tokens, and client secrets. Remove this debug log.

Apply this diff:

-      this.logger.debug(`tokenResponse::::${JSON.stringify(tokenResponse)}`);

570-579: Critical: Validate decoded refresh token and use correct session ID.

Two issues here:

  1. The decoded token is typed as any and accessed without validation.
  2. Line 579 uses tokenResponse.session_state instead of sessionDetails.id to update the session.

Apply this diff:

-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      const decodedToken: any = jwt.decode(tokenResponse?.refresh_token);
-      const expiresAt = new Date(decodedToken.exp * 1000);
+      const decodedRefresh = jwt.decode(tokenResponse?.refresh_token) as jwt.JwtPayload | null;
+      const expiresAt =
+        decodedRefresh?.exp
+          ? new Date(decodedRefresh.exp * 1000)
+          : new Date(Date.now() + (tokenResponse?.refresh_expires_in ?? 0) * 1000);
       const sessionData = {
         sessionToken: tokenResponse.access_token,
         expires: tokenResponse.expires_in,
         refreshToken: tokenResponse.refresh_token,
         expiresAt
       };
-      const addSessionDetails = await this.userRepository.updateSessionToken(tokenResponse.session_state, sessionData);
+      const addSessionDetails = await this.userRepository.updateSessionToken(sessionDetails.id, sessionData);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71b3285 and a1bb7cb.

📒 Files selected for processing (1)
  • apps/user/src/user.service.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/user/src/user.service.ts (4)
libs/common/src/response-messages/index.ts (1)
  • ResponseMessages (1-519)
apps/api-gateway/src/authz/authz.controller.ts (1)
  • refreshToken (328-337)
apps/api-gateway/src/authz/authz.service.ts (1)
  • refreshToken (80-82)
apps/api-gateway/src/authz/jwt-payload.interface.ts (1)
  • JwtPayload (1-13)
🔇 Additional comments (1)
apps/user/src/user.service.ts (1)

565-568: Use consistent error message key.

The error message key userSessionNotFound should match the response messages definition. Based on the relevant code snippets, the key is userSessionNotFound (not userSeesionNotFound).

@sonarqubecloud
Copy link

@sujitaw sujitaw merged commit 76c00cf into main Nov 5, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants