@quanticjs/auth-web-bff 5.8.0 → 5.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,15 +19,20 @@ const uuid_1 = require("uuid");
19
19
  const crypto_1 = require("crypto");
20
20
  const core_1 = require("@quanticjs/core");
21
21
  const interfaces_1 = require("./interfaces");
22
- function extractRealmRoles(accessToken) {
22
+ function extractTokenClaims(accessToken, clientId) {
23
23
  try {
24
24
  const payload = JSON.parse(Buffer.from(accessToken.split('.')[1], 'base64url').toString());
25
- return Array.isArray(payload.realm_access?.roles)
26
- ? payload.realm_access.roles
27
- : [];
25
+ return {
26
+ realmRoles: Array.isArray(payload.realm_access?.roles)
27
+ ? payload.realm_access.roles
28
+ : [],
29
+ clientRoles: Array.isArray(payload.resource_access?.[clientId]?.roles)
30
+ ? payload.resource_access[clientId].roles
31
+ : [],
32
+ };
28
33
  }
29
34
  catch {
30
- return [];
35
+ return { realmRoles: [], clientRoles: [] };
31
36
  }
32
37
  }
33
38
  let BffService = class BffService {
@@ -78,6 +83,11 @@ let BffService = class BffService {
78
83
  const tokenSet = await this.client.callback(this.getCallbackUrl(), { code, state, iss: this.client.issuer.metadata.issuer }, { code_verifier: codeVerifier, state });
79
84
  const claims = tokenSet.claims();
80
85
  const sessionId = (0, uuid_1.v4)();
86
+ const { realmRoles, clientRoles } = extractTokenClaims(tokenSet.access_token, this.options.keycloak.clientId);
87
+ let permissions = clientRoles;
88
+ if (this.options.permissionResolver) {
89
+ permissions = await this.options.permissionResolver(realmRoles, clientRoles);
90
+ }
81
91
  const sessionData = {
82
92
  accessToken: tokenSet.access_token,
83
93
  refreshToken: tokenSet.refresh_token,
@@ -86,7 +96,8 @@ let BffService = class BffService {
86
96
  id: claims.sub,
87
97
  email: claims.email ?? '',
88
98
  displayName: claims.name ?? claims.preferred_username ?? '',
89
- roles: extractRealmRoles(tokenSet.access_token),
99
+ roles: realmRoles,
100
+ permissions,
90
101
  username: claims.preferred_username,
91
102
  };
92
103
  await this.saveSession(sessionId, sessionData);
@@ -123,13 +134,19 @@ let BffService = class BffService {
123
134
  return null;
124
135
  try {
125
136
  const tokenSet = await this.client.refresh(sess.refreshToken);
137
+ const { realmRoles, clientRoles } = extractTokenClaims(tokenSet.access_token, this.options.keycloak.clientId);
138
+ let permissions = clientRoles;
139
+ if (this.options.permissionResolver) {
140
+ permissions = await this.options.permissionResolver(realmRoles, clientRoles);
141
+ }
126
142
  const updated = {
127
143
  ...sess,
128
144
  accessToken: tokenSet.access_token,
129
145
  refreshToken: tokenSet.refresh_token ?? sess.refreshToken,
130
146
  idToken: tokenSet.id_token ?? sess.idToken,
131
147
  expiresAt: tokenSet.expires_at ?? Math.floor(Date.now() / 1000) + 300,
132
- roles: extractRealmRoles(tokenSet.access_token),
148
+ roles: realmRoles,
149
+ permissions,
133
150
  };
134
151
  await this.saveSession(sessionId, updated);
135
152
  return updated.accessToken;
@@ -186,6 +203,7 @@ let BffService = class BffService {
186
203
  email: session.email,
187
204
  displayName: session.displayName,
188
205
  roles: session.roles,
206
+ permissions: session.permissions,
189
207
  username: session.username,
190
208
  };
191
209
  }
@@ -16,6 +16,7 @@ export interface BffModuleOptions {
16
16
  };
17
17
  publicUrl: string;
18
18
  callbackPath?: string;
19
+ permissionResolver?: (realmRoles: string[], clientRoles: string[]) => string[] | Promise<string[]>;
19
20
  }
20
21
  export interface SessionData {
21
22
  accessToken: string;
@@ -26,6 +27,7 @@ export interface SessionData {
26
27
  email: string;
27
28
  displayName: string;
28
29
  roles: string[];
30
+ permissions: string[];
29
31
  username?: string;
30
32
  }
31
33
  export declare const BFF_OPTIONS: unique symbol;
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@quanticjs/auth-web-bff",
3
- "version": "5.8.0",
3
+ "version": "5.10.0",
4
4
  "description": "BFF authentication module — Keycloak OIDC, Redis sessions, httpOnly cookies",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc -p tsconfig.json",
9
+ "test": "jest --passWithNoTests",
9
10
  "clean": "rm -rf dist"
10
11
  },
11
12
  "dependencies": {
12
- "@quanticjs/core": "^5.8.0"
13
+ "@quanticjs/core": "^5.10.0"
13
14
  },
14
15
  "peerDependencies": {
15
16
  "@nestjs/common": "^10.0.0 || ^11.0.0",