From e1007e7e753a3b1e23b315bcff8f0800062ae702 Mon Sep 17 00:00:00 2001 From: YuryShkoda Date: Wed, 15 Jul 2026 10:56:28 +0300 Subject: [PATCH] fix(api): return uid consistently from login and session endpoints POST /SASLogon/login and GET /SASjsApi/session still returned the old `id` field, while the rest of the ID->UID migration (#363) standardized on `uid`. Not functionally broken - Mongoose provides a built-in `id` virtual by default (_id.toHexString()) that happened to resolve to the same value as the new `uid` virtual - but it's an inconsistent public API surface, and relying on that coincidence wasn't the intent of the migration. Neither of these files was touched by any of issue-361's own commits, so this predates the merge rather than being caused by it. - web.ts: login response and session storage now source from user.uid explicitly - session.ts: SessionResponse dropped its Omit + id override in favor of just extending UserResponse - verifyTokenInDB.ts: token-refresh path, same fix - login.tsx / appContext.tsx: updated to read the corrected field Verified with a real end-to-end request (genuine app boot, real MongoDB, real CSRF handshake) - not just type-checking - to confirm the actual HTTP response bodies carry uid, not id. --- api/src/controllers/session.ts | 7 +++---- api/src/controllers/web.ts | 4 ++-- api/src/routes/api/spec/web.spec.ts | 2 +- api/src/utils/verifyTokenInDB.ts | 2 +- web/src/components/login.tsx | 2 +- web/src/context/appContext.tsx | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/api/src/controllers/session.ts b/api/src/controllers/session.ts index 0337355..e2aae8a 100644 --- a/api/src/controllers/session.ts +++ b/api/src/controllers/session.ts @@ -4,8 +4,7 @@ import { UserResponse } from './user' import { getSessionController } from './internal' import { SessionState } from '../types' -interface SessionResponse extends Omit { - id: string +interface SessionResponse extends UserResponse { needsToUpdatePassword?: boolean } @@ -18,7 +17,7 @@ export class SessionController { * */ @Example({ - id: 'userIdString', + uid: 'userIdString', username: 'johnusername', displayName: 'John', isAdmin: false, @@ -45,7 +44,7 @@ export class SessionController { } const session = (req: express.Request) => ({ - id: req.user!.userId, + uid: req.user!.userId, username: req.user!.username, displayName: req.user!.displayName, isAdmin: req.user!.isAdmin, diff --git a/api/src/controllers/web.ts b/api/src/controllers/web.ts index e0a4d4d..a47a411 100644 --- a/api/src/controllers/web.ts +++ b/api/src/controllers/web.ts @@ -121,7 +121,7 @@ const login = async ( req.session.loggedIn = true req.session.user = { - userId: user.id, + userId: user.uid, clientId: 'web_app', username: user.username, displayName: user.displayName, @@ -134,7 +134,7 @@ const login = async ( return { loggedIn: true, user: { - id: user.id, + uid: user.uid, username: user.username, displayName: user.displayName, isAdmin: user.isAdmin, diff --git a/api/src/routes/api/spec/web.spec.ts b/api/src/routes/api/spec/web.spec.ts index 9d7a6e2..d4dac5d 100644 --- a/api/src/routes/api/spec/web.spec.ts +++ b/api/src/routes/api/spec/web.spec.ts @@ -145,7 +145,7 @@ describe('web', () => { expect(res.body.loggedIn).toBeTruthy() expect(res.body.user).toEqual({ - id: expect.any(String), + uid: expect.any(String), username: user.username, displayName: user.displayName, isAdmin: user.isAdmin, diff --git a/api/src/utils/verifyTokenInDB.ts b/api/src/utils/verifyTokenInDB.ts index d612db9..8ead93f 100644 --- a/api/src/utils/verifyTokenInDB.ts +++ b/api/src/utils/verifyTokenInDB.ts @@ -36,7 +36,7 @@ export const verifyTokenInDB = async ( return currentTokenObj?.[tokenType] === token ? { - userId: dbUser.id, + userId: dbUser.uid, clientId, username: dbUser.username, displayName: dbUser.displayName, diff --git a/web/src/components/login.tsx b/web/src/components/login.tsx index 0b40419..f9369b2 100644 --- a/web/src/components/login.tsx +++ b/web/src/components/login.tsx @@ -40,7 +40,7 @@ const Login = () => { }) if (loggedIn) { - appContext.setUserId?.(user.id) + appContext.setUserId?.(user.uid) appContext.setUsername?.(user.username) appContext.setDisplayName?.(user.displayName) appContext.setIsAdmin?.(user.isAdmin) diff --git a/web/src/context/appContext.tsx b/web/src/context/appContext.tsx index cf556a8..ac59544 100644 --- a/web/src/context/appContext.tsx +++ b/web/src/context/appContext.tsx @@ -72,7 +72,7 @@ const AppContextProvider = (props: { children: ReactNode }) => { .then((res) => res.data) .then((data: any) => { setCheckingSession(false) - setUserId(data.id) + setUserId(data.uid) setUsername(data.username) setDisplayName(data.displayName) setIsAdmin(data.isAdmin)