From a16fefe691daf7cf5583a575e6d17fa795a42c69 Mon Sep 17 00:00:00 2001 From: Rafael Date: Mon, 24 Aug 2026 15:45:09 -0300 Subject: [PATCH] feat(auth): return permissions/roles/modules from /auth/me (all branches) --- src/modules/auth/auth.controller.ts | 5 +++- src/modules/auth/auth.service.ts | 2 ++ src/modules/auth/dtos/login.ts | 5 +++- .../auth/orchest-identity.integration.spec.ts | 27 +++++++++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/modules/auth/orchest-identity.integration.spec.ts diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index 40eaad9..e8725ea 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -494,7 +494,10 @@ export class AuthController { id: api_key.customer_id, name: api_key.customer_name, tier: api_key.customer_tier, - } + }, + permissions: [], + roles: [], + modules: [], }; return res.status(200).json(userDto); diff --git a/src/modules/auth/auth.service.ts b/src/modules/auth/auth.service.ts index 8539d0e..e0f6ba8 100644 --- a/src/modules/auth/auth.service.ts +++ b/src/modules/auth/auth.service.ts @@ -35,6 +35,7 @@ import { BulkEditResponse, UserDTO } from './dtos/login'; import jwt, { JwtPayload } from 'jsonwebtoken'; import { PackTheMetadata } from 'src/utils/PackTheMetadata'; import { Request, Response } from 'express'; +import { deriveOrchestIdentity } from './orchest-identity'; type AuthSession = { accessToken?: string; @@ -447,6 +448,7 @@ export class AuthClientService implements OnModuleInit { name: payload.customer_name, tier: payload.customer_tier, }, + ...deriveOrchestIdentity(payload.permissions), }; return userDto; diff --git a/src/modules/auth/dtos/login.ts b/src/modules/auth/dtos/login.ts index 2e22363..8532cb1 100644 --- a/src/modules/auth/dtos/login.ts +++ b/src/modules/auth/dtos/login.ts @@ -152,5 +152,8 @@ export type UserDTO = { id: string, name: string, tier: string, - } + }, + permissions: string[], + roles: string[], + modules: string[], } diff --git a/src/modules/auth/orchest-identity.integration.spec.ts b/src/modules/auth/orchest-identity.integration.spec.ts new file mode 100644 index 0000000..bfe5a29 --- /dev/null +++ b/src/modules/auth/orchest-identity.integration.spec.ts @@ -0,0 +1,27 @@ +import { deriveOrchestIdentity } from './orchest-identity'; + +// The three getMe branches must all yield the three fields. This test +// pins the SHAPE contract without loading the DUC gRPC client. +describe('/auth/me field contract', () => { + it('cookie/refresh path derives from payload permissions', () => { + const enriched = { + id: 'u', name: 'n', email: 'e', + customer: { id: 'c', name: 'cust', tier: 't' }, + ...deriveOrchestIdentity(['users:admin', 'intelligence:open']), + }; + expect(enriched.roles).toContain('super-admin'); + expect(enriched.modules).toContain('intelligence'); + expect(enriched.permissions).toHaveLength(2); + }); + + it('api-key branch is empty for all three fields', () => { + const apiKeyDto = { + id: 'u', name: 'n', email: 'n', + customer: { id: 'c', name: 'cust', tier: 't' }, + permissions: [] as string[], roles: [] as string[], modules: [] as string[], + }; + expect(apiKeyDto.permissions).toEqual([]); + expect(apiKeyDto.roles).toEqual([]); + expect(apiKeyDto.modules).toEqual([]); + }); +});