@carecard/jwt-read 3.1.27 → 3.1.29

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.
@@ -106,6 +106,11 @@ depend on those folders being present.
106
106
  - Request attachment behavior for authenticated JWT objects and visitor tokens.
107
107
  - Request attachment behavior for compact scoped authorization-context JWTs
108
108
  from `X-Authorization-Context` as `req.userAuthorization`.
109
+ - Shared header defaults for scoped authorization context:
110
+ `DEFAULT_USER_AUTHORIZATION_HEADER_NAME` and
111
+ `DEFAULT_USER_AUTHORIZATION_MAX_TOKEN_LENGTH`. Token issuers and consuming
112
+ services should import these constants instead of duplicating the header name
113
+ or 2048-character limit.
109
114
  - Server-auth request attachment behavior that normalizes introspected claims
110
115
  into `req.jwt.payload` with `authMode: "server-auth"` and
111
116
  `auth_mode: "server-auth"`.
package/index.d.ts CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  import { NextFunction, Request, Response } from 'express';
6
6
 
7
+ export const DEFAULT_USER_AUTHORIZATION_HEADER_NAME: 'X-Authorization-Context';
8
+ export const DEFAULT_USER_AUTHORIZATION_MAX_TOKEN_LENGTH: 2048;
9
+
7
10
  /**
8
11
  * Represents the standard JWT header structure.
9
12
  */
@@ -281,11 +284,16 @@ export interface JwtContext {
281
284
  user_id: string | undefined;
282
285
  /** The role of the user. Only set to 'super_admin' when roles contains 'ad'. */
283
286
  role?: string;
287
+ /** Decoded scoped authorization claims from X-Authorization-Context when verified and attached. */
288
+ authorizationContext?: UserAuthorizationPayload;
289
+ /** The verified scoped authorization object attached to the request. */
290
+ userAuthorization?: UserAuthorizationRequestObject;
284
291
  }
285
292
 
286
293
  /**
287
294
  * Returns the context derived from the JWT in req.jwt.
288
295
  * Always returns user_id. If the roles array contains 'ad', also returns role: 'super_admin'.
296
+ * If req.userAuthorization is present, also returns authorizationContext and userAuthorization.
289
297
  */
290
298
  export function jwtGetContext(req: any): JwtContext;
291
299
 
package/index.js CHANGED
@@ -2,6 +2,8 @@ const jwtLib = require('./lib/jwtLib');
2
2
  const jwtRoles = require('./lib/jwtRoles');
3
3
 
4
4
  module.exports = {
5
+ DEFAULT_USER_AUTHORIZATION_HEADER_NAME: jwtLib.DEFAULT_USER_AUTHORIZATION_HEADER_NAME,
6
+ DEFAULT_USER_AUTHORIZATION_MAX_TOKEN_LENGTH: jwtLib.DEFAULT_USER_AUTHORIZATION_MAX_TOKEN_LENGTH,
5
7
  jwtVerify: jwtLib.verifyJwt,
6
8
  jwtVerifyWebToken: jwtLib.verifyWebToken,
7
9
  jwtVerifyNoThrow: jwtLib.verifyJwtNoThrow,
package/lib/jwtLib.js CHANGED
@@ -752,6 +752,8 @@ function _extractWebTokenNoThrow(jwtRaw) {
752
752
  }
753
753
 
754
754
  module.exports = {
755
+ DEFAULT_USER_AUTHORIZATION_HEADER_NAME,
756
+ DEFAULT_USER_AUTHORIZATION_MAX_TOKEN_LENGTH,
755
757
  _validateJwt,
756
758
  _validateJwtNoThrow,
757
759
  _isJwtSignatureValid,
package/lib/jwtRoles.js CHANGED
@@ -25,15 +25,27 @@ function getCodeFromNameOfRole(roleName) {
25
25
  function getContext(req) {
26
26
  const userId = jwtClientId(req);
27
27
  const roles = req.jwt?.payload?.roles;
28
+ const userAuthorization = getUserAuthorization(req);
29
+ const context = {
30
+ user_id: userId,
31
+ };
28
32
 
29
33
  if (Array.isArray(roles) && roles.includes('ad')) {
30
- return {
31
- user_id: userId,
32
- role: 'super_admin',
33
- };
34
+ context.role = 'super_admin';
34
35
  }
35
36
 
36
- return {
37
- user_id: userId,
38
- };
37
+ if (userAuthorization) {
38
+ context.authorizationContext = userAuthorization.payload;
39
+ context.userAuthorization = userAuthorization;
40
+ }
41
+
42
+ return context;
43
+ }
44
+
45
+ function getUserAuthorization(req) {
46
+ const userAuthorization = req?.userAuthorization;
47
+ if (!userAuthorization || typeof userAuthorization !== 'object') return null;
48
+ if (!userAuthorization.payload || typeof userAuthorization.payload !== 'object') return null;
49
+
50
+ return userAuthorization;
39
51
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carecard/jwt-read",
3
- "version": "3.1.27",
3
+ "version": "3.1.29",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/CareCard-ca/pkg-jwt-read.git"
package/readme.md CHANGED
@@ -141,6 +141,9 @@ database context and role checks.
141
141
  Use `jwtVerifyUserAuthorization` when a route needs to verify only the compact
142
142
  authorization-context token carried in `X-Authorization-Context`. The token is
143
143
  read as a raw JWT header value, not as `Bearer <token>`.
144
+ The exported `DEFAULT_USER_AUTHORIZATION_MAX_TOKEN_LENGTH` is `2048`; token
145
+ issuers and consumers should use that shared constant instead of duplicating a
146
+ local limit.
144
147
 
145
148
  ```javascript
146
149
  const { jwtVerifyUserAuthorization } = require('@carecard/jwt-read');
@@ -174,6 +177,12 @@ leaves `req.userAuthorization` as `null`. If the header is present but invalid,
174
177
  throwing middleware fails closed. No-throw middleware clears
175
178
  `req.userAuthorization` and continues.
176
179
 
180
+ `jwtGetContext(req)` preserves the normal database caller shape of `user_id`
181
+ and optional `role`. When a verified `req.userAuthorization.payload` is present,
182
+ it also returns `authorizationContext` with those compact claims and the original
183
+ `userAuthorization` object so service models can set `app.authz_context` for
184
+ RLS without rebuilding the full authorization graph.
185
+
177
186
  ## Testing
178
187
 
179
188
  Run tests using: