refactor(auth): /auth/me returns raw permission seqids

Return payload.permissions verbatim (numeric seqids) instead of
translating them to claim strings. Consumers own the seqid->meaning
mapping. Drops permission-claims.ts entirely; UserDTO.permissions is
now number[].

Co-Authored-By: WOZCODE <contact@withwoz.com>
This commit is contained in:
Rafael
2026-08-24 16:56:23 -03:00
co-authored by WOZCODE
parent cd21fd0b7b
commit cac36f2c60
4 changed files with 4 additions and 62 deletions
+3 -2
View File
@@ -35,7 +35,6 @@ import { BulkEditResponse, UserDTO } from './dtos/login';
import jwt, { JwtPayload } from 'jsonwebtoken';
import { PackTheMetadata } from 'src/utils/PackTheMetadata';
import { Request, Response } from 'express';
import { translateSeqidsToClaims } from './permission-claims';
type AuthSession = {
accessToken?: string;
@@ -448,7 +447,9 @@ export class AuthClientService implements OnModuleInit {
name: payload.customer_name,
tier: payload.customer_tier,
},
permissions: translateSeqidsToClaims(payload.permissions),
// Raw permission seqids from the JWT. Consumers own the seqid->meaning
// mapping (e.g. Orchest's auth-server); Maestro reports them as-is.
permissions: payload.permissions ?? [],
};
return userDto;
+1 -1
View File
@@ -153,5 +153,5 @@ export type UserDTO = {
name: string,
tier: string,
},
permissions: string[],
permissions: number[],
}
@@ -1,30 +0,0 @@
import { translateSeqidsToClaims } from './permission-claims';
// The JWT permissions claim carries numeric seqids at runtime
// (34 = users:admin, 31 = intelligence:open, 43 = process:open), so
// fixtures here use numeric seqid arrays.
describe('translateSeqidsToClaims', () => {
it('translates a single seqid to its claim string', () => {
expect(translateSeqidsToClaims([31])).toEqual(['intelligence:open']);
});
it('translates multiple seqids, preserving order', () => {
expect(translateSeqidsToClaims([34, 31, 43])).toEqual([
'users:admin',
'intelligence:open',
'process:open',
]);
});
it('drops unknown seqids not present in the catalog', () => {
expect(translateSeqidsToClaims([34, 999999])).toEqual(['users:admin']);
});
it('returns an empty array for undefined permissions', () => {
expect(translateSeqidsToClaims(undefined)).toEqual([]);
});
it('returns an empty array for empty permissions', () => {
expect(translateSeqidsToClaims([])).toEqual([]);
});
});
-29
View File
@@ -1,29 +0,0 @@
import { PERMISSIONS_GROUPS } from 'src/authentication/permissions.enum';
// The JWT `permissions` claim is an array of numeric seqids (not claim
// strings) — see src/authentication/authentication.guard.ts and
// src/decorators/authentication.decorator.ts. This module translates those
// seqids into their human-readable claim strings so /auth/me can expose a
// self-describing `permissions` array; consumers derive whatever meaning
// they need (roles, module access, groups) from the claim vocabulary.
//
// Full seqid -> claim catalog, built once from every group/permission in
// PERMISSIONS_GROUPS. Generic: no consumer-specific knowledge lives here.
const SEQID_TO_CLAIM: Record<number, string> = Object.values(
PERMISSIONS_GROUPS,
).reduce((catalog, group) => {
for (const permission of Object.values(group.permissions)) {
catalog[permission.seqid] = permission.claim;
}
return catalog;
}, {} as Record<number, string>);
// Translate the JWT's numeric permission seqids into claim strings.
// Unknown seqids (not present in the catalog) are dropped.
export function translateSeqidsToClaims(
permissions: number[] | undefined,
): string[] {
return (permissions ?? [])
.filter((seqid) => seqid in SEQID_TO_CLAIM)
.map((seqid) => SEQID_TO_CLAIM[seqid]);
}