@@ -33,8 +33,13 @@ import {
3333} from "../auth/constants" ;
3434
3535export interface BillingAccountsAuthUser {
36+ id ?: number | string ;
3637 role ?: string ;
3738 roles ?: string [ ] | string ;
39+ sub ?: number | string ;
40+ tcUserId ?: number | string ;
41+ user_id ?: number | string ;
42+ userID ?: number | string ;
3843 userId ?: number | string ;
3944}
4045
@@ -112,24 +117,33 @@ function getNormalizedAuthUserRoles(
112117/**
113118 * Resolves the caller user id as a trimmed string when present.
114119 *
120+ * Topcoder JWT middleware has used a few decoded claim names across services,
121+ * so this accepts the canonical `userId` first and then falls back to the other
122+ * common user-id claim spellings.
123+ *
115124 * @param authUser Authenticated caller context from `req.authUser`.
116125 * @returns Normalized user id or `undefined` when missing.
117126 */
118127function getNormalizedAuthUserId (
119128 authUser ?: BillingAccountsAuthUser ,
120129) : string | undefined {
121- if (
122- typeof authUser ?. userId === "number" &&
123- Number . isFinite ( authUser . userId )
124- ) {
125- return String ( authUser . userId ) ;
130+ const candidateUserId =
131+ authUser ?. userId ??
132+ authUser ?. user_id ??
133+ authUser ?. userID ??
134+ authUser ?. tcUserId ??
135+ authUser ?. id ??
136+ authUser ?. sub ;
137+
138+ if ( typeof candidateUserId === "number" && Number . isFinite ( candidateUserId ) ) {
139+ return String ( candidateUserId ) ;
126140 }
127141
128- if ( typeof authUser ?. userId !== "string" ) {
142+ if ( typeof candidateUserId !== "string" ) {
129143 return undefined ;
130144 }
131145
132- const normalizedUserId = authUser . userId . trim ( ) ;
146+ const normalizedUserId = candidateUserId . trim ( ) ;
133147
134148 return normalizedUserId || undefined ;
135149}
0 commit comments