@dismissible/nestjs-jwt-auth-hook 1.0.3-alpha.cdc64a4.0 → 2.0.2-alpha.72996f5.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.
- package/README.md +11 -1
- package/package.json +5 -5
- package/src/jwt-auth-hook.config.d.ts +34 -4
- package/src/jwt-auth-hook.config.js +35 -5
- package/src/jwt-auth-hook.config.js.map +1 -1
- package/src/jwt-auth-hook.module.js +4 -4
- package/src/jwt-auth-hook.module.js.map +1 -1
- package/src/jwt-auth.hook.d.ts +4 -0
- package/src/jwt-auth.hook.js +24 -6
- package/src/jwt-auth.hook.js.map +1 -1
- package/src/jwt-auth.service.js +7 -4
- package/src/jwt-auth.service.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<a href="https://dismissible.io" target="_blank"><img src="
|
|
2
|
+
<a href="https://dismissible.io" target="_blank"><img src="https://raw.githubusercontent.com/DismissibleIo/dismissible-api/main/docs/images/dismissible_logo.png" width="120" alt="Dismissible" /></a>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">Never Show The Same Thing Twice!</p>
|
|
@@ -96,9 +96,15 @@ export class AppModule {}
|
|
|
96
96
|
| `jwksCacheDuration` | `number` | No | `600000` | JWKS cache duration in milliseconds (10 minutes) |
|
|
97
97
|
| `requestTimeout` | `number` | No | `30000` | Request timeout in milliseconds (30 seconds) |
|
|
98
98
|
| `priority` | `number` | No | `-100` | Hook priority (lower numbers run first) |
|
|
99
|
+
| `matchUserId` | `boolean` | No | `true` | Enable user ID matching against JWT claim |
|
|
100
|
+
| `userIdClaim` | `string` | No | `'sub'` | The JWT claim key to use for user ID matching |
|
|
101
|
+
| `userIdMatchType` | `string` | No | `'exact'` | Match method: `exact`, `substring`, or `regex` |
|
|
102
|
+
| `userIdMatchRegex` | `string` | No\*\* | - | Regex pattern for user ID matching (required when type is `regex`) |
|
|
99
103
|
|
|
100
104
|
\* `wellKnownUrl` is only required when `enabled` is `true`.
|
|
101
105
|
|
|
106
|
+
\*\* `userIdMatchRegex` is required when `userIdMatchType` is `regex`.
|
|
107
|
+
|
|
102
108
|
## Environment Variables
|
|
103
109
|
|
|
104
110
|
When using the Dismissible API Docker image or the standalone API, these environment variables configure JWT authentication:
|
|
@@ -113,6 +119,10 @@ When using the Dismissible API Docker image or the standalone API, these environ
|
|
|
113
119
|
| `DISMISSIBLE_JWT_AUTH_JWKS_CACHE_DURATION` | JWKS cache duration in ms | `600000` |
|
|
114
120
|
| `DISMISSIBLE_JWT_AUTH_REQUEST_TIMEOUT` | Request timeout in ms | `30000` |
|
|
115
121
|
| `DISMISSIBLE_JWT_AUTH_PRIORITY` | Hook priority (lower runs first) | `-100` |
|
|
122
|
+
| `DISMISSIBLE_JWT_AUTH_MATCH_USER_ID` | Enable user ID matching | `true` |
|
|
123
|
+
| `DISMISSIBLE_JWT_AUTH_USER_ID_CLAIM` | JWT claim key for user ID matching | `sub` |
|
|
124
|
+
| `DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_TYPE` | User ID match method | `exact` |
|
|
125
|
+
| `DISMISSIBLE_JWT_AUTH_USER_ID_MATCH_REGEX` | Regex pattern for user ID matching | `""` |
|
|
116
126
|
|
|
117
127
|
### Example: Disabling JWT Auth for Development
|
|
118
128
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dismissible/nestjs-jwt-auth-hook",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.2-alpha.72996f5.0",
|
|
4
4
|
"description": "JWT authentication hook for Dismissible applications using OIDC well-known discovery",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"types": "./src/index.d.ts",
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@nestjs/axios": "4.0.1",
|
|
21
|
-
"@dismissible/nestjs-hooks": "
|
|
22
|
-
"@dismissible/nestjs-request": "
|
|
23
|
-
"@dismissible/nestjs-logger": "
|
|
24
|
-
"@dismissible/nestjs-validation": "
|
|
21
|
+
"@dismissible/nestjs-hooks": "2.0.2-alpha.72996f5.0",
|
|
22
|
+
"@dismissible/nestjs-request": "2.0.2-alpha.72996f5.0",
|
|
23
|
+
"@dismissible/nestjs-logger": "2.0.2-alpha.72996f5.0",
|
|
24
|
+
"@dismissible/nestjs-validation": "2.0.2-alpha.72996f5.0",
|
|
25
25
|
"jwks-rsa": "3.2.0",
|
|
26
26
|
"jsonwebtoken": "9.0.3"
|
|
27
27
|
},
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Injection token for JWT auth hook configuration.
|
|
3
3
|
*/
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const DISMISSIBLE_JWT_AUTH_HOOK_CONFIG: unique symbol;
|
|
5
|
+
/**
|
|
6
|
+
* User ID match type for comparing JWT claim against request userId.
|
|
7
|
+
*/
|
|
8
|
+
export declare enum UserIdMatchType {
|
|
9
|
+
/** Exact string match (default) */
|
|
10
|
+
EXACT = "exact",
|
|
11
|
+
/** Substring match - either value contains the other */
|
|
12
|
+
SUBSTRING = "substring",
|
|
13
|
+
/** Regex match - tokenUserId is tested against a regex pattern */
|
|
14
|
+
REGEX = "regex"
|
|
15
|
+
}
|
|
5
16
|
/**
|
|
6
17
|
* Configuration options for JWT authentication hook.
|
|
7
18
|
*/
|
|
@@ -14,9 +25,11 @@ export declare class JwtAuthHookConfig {
|
|
|
14
25
|
readonly wellKnownUrl: string;
|
|
15
26
|
/**
|
|
16
27
|
* Optional: Expected issuer claim (iss) to validate.
|
|
28
|
+
* Can be a comma-separated string or array of issuers.
|
|
17
29
|
* If not provided, issuer validation is skipped.
|
|
30
|
+
* The token's issuer must match at least one of the provided issuers.
|
|
18
31
|
*/
|
|
19
|
-
readonly issuer?: string;
|
|
32
|
+
readonly issuer?: string[];
|
|
20
33
|
/**
|
|
21
34
|
* Optional: Expected audience claim (aud) to validate.
|
|
22
35
|
* If not provided, audience validation is skipped.
|
|
@@ -24,6 +37,7 @@ export declare class JwtAuthHookConfig {
|
|
|
24
37
|
readonly audience?: string;
|
|
25
38
|
/**
|
|
26
39
|
* Optional: Allowed algorithms for JWT verification.
|
|
40
|
+
* Can be a comma-separated string or array of algorithms.
|
|
27
41
|
* Defaults to ['RS256'].
|
|
28
42
|
*/
|
|
29
43
|
readonly algorithms?: string[];
|
|
@@ -43,8 +57,24 @@ export declare class JwtAuthHookConfig {
|
|
|
43
57
|
*/
|
|
44
58
|
readonly priority?: number;
|
|
45
59
|
/**
|
|
46
|
-
* Optional:
|
|
60
|
+
* Optional: Match the userId parameter against the JWT claim set in userIdClaim.
|
|
47
61
|
* Defaults to true for security. Set to false for service-to-service scenarios.
|
|
48
62
|
*/
|
|
49
|
-
readonly
|
|
63
|
+
readonly matchUserId?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Optional: The JWT claim key to use for user ID matching.
|
|
66
|
+
* Defaults to 'sub' (the standard JWT subject claim).
|
|
67
|
+
*/
|
|
68
|
+
readonly userIdClaim?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Optional: The type of matching to use for user ID comparison.
|
|
71
|
+
* Defaults to 'exact' for strict equality matching.
|
|
72
|
+
*/
|
|
73
|
+
readonly userIdMatchType?: UserIdMatchType;
|
|
74
|
+
/**
|
|
75
|
+
* Optional: Regex pattern for user ID matching.
|
|
76
|
+
* Required when userIdMatchType is 'regex'.
|
|
77
|
+
* The pattern is tested against the tokenUserId from the JWT claim.
|
|
78
|
+
*/
|
|
79
|
+
readonly userIdMatchRegex?: string;
|
|
50
80
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.JwtAuthHookConfig = exports.
|
|
3
|
+
exports.JwtAuthHookConfig = exports.UserIdMatchType = exports.DISMISSIBLE_JWT_AUTH_HOOK_CONFIG = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const class_validator_1 = require("class-validator");
|
|
6
6
|
const class_transformer_1 = require("class-transformer");
|
|
@@ -8,7 +8,19 @@ const nestjs_validation_1 = require("@dismissible/nestjs-validation");
|
|
|
8
8
|
/**
|
|
9
9
|
* Injection token for JWT auth hook configuration.
|
|
10
10
|
*/
|
|
11
|
-
exports.
|
|
11
|
+
exports.DISMISSIBLE_JWT_AUTH_HOOK_CONFIG = Symbol('DISMISSIBLE_JWT_AUTH_HOOK_CONFIG');
|
|
12
|
+
/**
|
|
13
|
+
* User ID match type for comparing JWT claim against request userId.
|
|
14
|
+
*/
|
|
15
|
+
var UserIdMatchType;
|
|
16
|
+
(function (UserIdMatchType) {
|
|
17
|
+
/** Exact string match (default) */
|
|
18
|
+
UserIdMatchType["EXACT"] = "exact";
|
|
19
|
+
/** Substring match - either value contains the other */
|
|
20
|
+
UserIdMatchType["SUBSTRING"] = "substring";
|
|
21
|
+
/** Regex match - tokenUserId is tested against a regex pattern */
|
|
22
|
+
UserIdMatchType["REGEX"] = "regex";
|
|
23
|
+
})(UserIdMatchType || (exports.UserIdMatchType = UserIdMatchType = {}));
|
|
12
24
|
/**
|
|
13
25
|
* Configuration options for JWT authentication hook.
|
|
14
26
|
*/
|
|
@@ -27,8 +39,10 @@ tslib_1.__decorate([
|
|
|
27
39
|
], JwtAuthHookConfig.prototype, "wellKnownUrl", void 0);
|
|
28
40
|
tslib_1.__decorate([
|
|
29
41
|
(0, class_validator_1.IsOptional)(),
|
|
30
|
-
(0, class_validator_1.
|
|
31
|
-
|
|
42
|
+
(0, class_validator_1.IsArray)(),
|
|
43
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
44
|
+
(0, nestjs_validation_1.TransformCommaSeparated)(),
|
|
45
|
+
tslib_1.__metadata("design:type", Array)
|
|
32
46
|
], JwtAuthHookConfig.prototype, "issuer", void 0);
|
|
33
47
|
tslib_1.__decorate([
|
|
34
48
|
(0, class_validator_1.IsOptional)(),
|
|
@@ -39,6 +53,7 @@ tslib_1.__decorate([
|
|
|
39
53
|
(0, class_validator_1.IsOptional)(),
|
|
40
54
|
(0, class_validator_1.IsArray)(),
|
|
41
55
|
(0, class_validator_1.IsString)({ each: true }),
|
|
56
|
+
(0, nestjs_validation_1.TransformCommaSeparated)(),
|
|
42
57
|
tslib_1.__metadata("design:type", Array)
|
|
43
58
|
], JwtAuthHookConfig.prototype, "algorithms", void 0);
|
|
44
59
|
tslib_1.__decorate([
|
|
@@ -65,5 +80,20 @@ tslib_1.__decorate([
|
|
|
65
80
|
(0, nestjs_validation_1.TransformBoolean)(true) // Default to true if not provided
|
|
66
81
|
,
|
|
67
82
|
tslib_1.__metadata("design:type", Boolean)
|
|
68
|
-
], JwtAuthHookConfig.prototype, "
|
|
83
|
+
], JwtAuthHookConfig.prototype, "matchUserId", void 0);
|
|
84
|
+
tslib_1.__decorate([
|
|
85
|
+
(0, class_validator_1.IsOptional)(),
|
|
86
|
+
(0, class_validator_1.IsString)(),
|
|
87
|
+
tslib_1.__metadata("design:type", String)
|
|
88
|
+
], JwtAuthHookConfig.prototype, "userIdClaim", void 0);
|
|
89
|
+
tslib_1.__decorate([
|
|
90
|
+
(0, class_validator_1.IsOptional)(),
|
|
91
|
+
(0, class_validator_1.IsEnum)(UserIdMatchType),
|
|
92
|
+
tslib_1.__metadata("design:type", String)
|
|
93
|
+
], JwtAuthHookConfig.prototype, "userIdMatchType", void 0);
|
|
94
|
+
tslib_1.__decorate([
|
|
95
|
+
(0, class_validator_1.ValidateIf)((o) => o.userIdMatchType === UserIdMatchType.REGEX),
|
|
96
|
+
(0, class_validator_1.IsString)(),
|
|
97
|
+
tslib_1.__metadata("design:type", String)
|
|
98
|
+
], JwtAuthHookConfig.prototype, "userIdMatchRegex", void 0);
|
|
69
99
|
//# sourceMappingURL=jwt-auth-hook.config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-auth-hook.config.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth-hook.config.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"jwt-auth-hook.config.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth-hook.config.ts"],"names":[],"mappings":";;;;AAAA,qDASyB;AACzB,yDAAyC;AACzC,sEAA2F;AAE3F;;GAEG;AACU,QAAA,gCAAgC,GAAG,MAAM,CAAC,kCAAkC,CAAC,CAAC;AAE3F;;GAEG;AACH,IAAY,eAOX;AAPD,WAAY,eAAe;IACzB,mCAAmC;IACnC,kCAAe,CAAA;IACf,wDAAwD;IACxD,0CAAuB,CAAA;IACvB,kEAAkE;IAClE,kCAAe,CAAA;AACjB,CAAC,EAPW,eAAe,+BAAf,eAAe,QAO1B;AAED;;GAEG;AACH,MAAa,iBAAiB;CAwG7B;AAxGD,8CAwGC;AArGiB;IAFf,IAAA,2BAAS,GAAE;IACX,IAAA,oCAAgB,GAAE;;kDACe;AAQlB;IAFf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC;IACrC,IAAA,uBAAK,GAAE;;uDAC8B;AAYtB;IAJf,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,2CAAuB,GAAE;;iDACQ;AAQlB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;mDACuB;AAWlB;IAJf,IAAA,4BAAU,GAAE;IACZ,IAAA,yBAAO,GAAE;IACT,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,2CAAuB,GAAE;;qDACY;AAStB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;4DACwB;AAS3B;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;yDACqB;AASxB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,wBAAI,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;;mDACe;AASlB;IAHf,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,GAAE;IACX,IAAA,oCAAgB,EAAC,IAAI,CAAC,CAAC,kCAAkC;;;sDACpB;AAQtB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;;sDAC0B;AAQrB;IAFf,IAAA,4BAAU,GAAE;IACZ,IAAA,wBAAM,EAAC,eAAe,CAAC;;0DAC0B;AASlC;IAFf,IAAA,4BAAU,EAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,KAAK,eAAe,CAAC,KAAK,CAAC;IAC9D,IAAA,0BAAQ,GAAE;;2DAC+B"}
|
|
@@ -39,13 +39,13 @@ let JwtAuthHookModule = JwtAuthHookModule_1 = class JwtAuthHookModule {
|
|
|
39
39
|
imports: [axios_1.HttpModule],
|
|
40
40
|
providers: [
|
|
41
41
|
{
|
|
42
|
-
provide: jwt_auth_hook_config_1.
|
|
42
|
+
provide: jwt_auth_hook_config_1.DISMISSIBLE_JWT_AUTH_HOOK_CONFIG,
|
|
43
43
|
useValue: config,
|
|
44
44
|
},
|
|
45
45
|
jwt_auth_service_1.JwtAuthService,
|
|
46
46
|
jwt_auth_hook_1.JwtAuthHook,
|
|
47
47
|
],
|
|
48
|
-
exports: [jwt_auth_hook_1.JwtAuthHook, jwt_auth_service_1.JwtAuthService, jwt_auth_hook_config_1.
|
|
48
|
+
exports: [jwt_auth_hook_1.JwtAuthHook, jwt_auth_service_1.JwtAuthService, jwt_auth_hook_config_1.DISMISSIBLE_JWT_AUTH_HOOK_CONFIG],
|
|
49
49
|
global: true,
|
|
50
50
|
};
|
|
51
51
|
}
|
|
@@ -59,14 +59,14 @@ let JwtAuthHookModule = JwtAuthHookModule_1 = class JwtAuthHookModule {
|
|
|
59
59
|
imports: [axios_1.HttpModule],
|
|
60
60
|
providers: [
|
|
61
61
|
{
|
|
62
|
-
provide: jwt_auth_hook_config_1.
|
|
62
|
+
provide: jwt_auth_hook_config_1.DISMISSIBLE_JWT_AUTH_HOOK_CONFIG,
|
|
63
63
|
useFactory: options.useFactory,
|
|
64
64
|
inject: options.inject ?? [],
|
|
65
65
|
},
|
|
66
66
|
jwt_auth_service_1.JwtAuthService,
|
|
67
67
|
jwt_auth_hook_1.JwtAuthHook,
|
|
68
68
|
],
|
|
69
|
-
exports: [jwt_auth_hook_1.JwtAuthHook, jwt_auth_service_1.JwtAuthService, jwt_auth_hook_config_1.
|
|
69
|
+
exports: [jwt_auth_hook_1.JwtAuthHook, jwt_auth_service_1.JwtAuthService, jwt_auth_hook_config_1.DISMISSIBLE_JWT_AUTH_HOOK_CONFIG],
|
|
70
70
|
global: true,
|
|
71
71
|
};
|
|
72
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-auth-hook.module.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth-hook.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAAuE;AACvE,yCAA2C;AAC3C,mDAA8C;AAC9C,yDAAoD;AACpD,
|
|
1
|
+
{"version":3,"file":"jwt-auth-hook.module.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth-hook.module.ts"],"names":[],"mappings":";;;;;AAAA,2CAAuE;AACvE,yCAA2C;AAC3C,mDAA8C;AAC9C,yDAAoD;AACpD,iEAA6F;AAU7F;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEI,IAAM,iBAAiB,yBAAvB,MAAM,iBAAiB;IAC5B,MAAM,CAAC,OAAO,CAAC,MAAyB;QACtC,OAAO;YACL,MAAM,EAAE,mBAAiB;YACzB,OAAO,EAAE,CAAC,kBAAU,CAAC;YACrB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,uDAAgC;oBACzC,QAAQ,EAAE,MAAM;iBACjB;gBACD,iCAAc;gBACd,2BAAW;aACZ;YACD,OAAO,EAAE,CAAC,2BAAW,EAAE,iCAAc,EAAE,uDAAgC,CAAC;YACxE,MAAM,EAAE,IAAI;SACb,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,OAAuC;QACzD,OAAO;YACL,MAAM,EAAE,mBAAiB;YACzB,OAAO,EAAE,CAAC,kBAAU,CAAC;YACrB,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,uDAAgC;oBACzC,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;iBAC7B;gBACD,iCAAc;gBACd,2BAAW;aACZ;YACD,OAAO,EAAE,CAAC,2BAAW,EAAE,iCAAc,EAAE,uDAAgC,CAAC;YACxE,MAAM,EAAE,IAAI;SACb,CAAC;IACJ,CAAC;CACF,CAAA;AAvCY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,iBAAiB,CAuC7B"}
|
package/src/jwt-auth.hook.d.ts
CHANGED
|
@@ -18,4 +18,8 @@ export declare class JwtAuthHook implements IDismissibleLifecycleHook {
|
|
|
18
18
|
* Runs before any dismissible operation.
|
|
19
19
|
*/
|
|
20
20
|
onBeforeRequest(itemId: string, userId: string, context?: IRequestContext): Promise<IHookResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Matches the token user ID against the request user ID based on the configured match type.
|
|
23
|
+
*/
|
|
24
|
+
private matchUserIdValue;
|
|
21
25
|
}
|
package/src/jwt-auth.hook.js
CHANGED
|
@@ -45,14 +45,16 @@ let JwtAuthHook = class JwtAuthHook {
|
|
|
45
45
|
});
|
|
46
46
|
throw new common_1.UnauthorizedException(result.error);
|
|
47
47
|
}
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
const matchUserId = this.config.matchUserId ?? true;
|
|
49
|
+
const userIdClaim = this.config.userIdClaim ?? 'sub';
|
|
50
|
+
const tokenUserId = result.payload?.[userIdClaim];
|
|
51
|
+
if (matchUserId && tokenUserId) {
|
|
52
|
+
if (!this.matchUserIdValue(tokenUserId, userId)) {
|
|
51
53
|
this.logger.debug('JWT auth hook: User ID mismatch', {
|
|
52
54
|
itemId,
|
|
53
55
|
userId,
|
|
54
56
|
requestId: context?.requestId,
|
|
55
|
-
tokenSubject:
|
|
57
|
+
tokenSubject: tokenUserId,
|
|
56
58
|
});
|
|
57
59
|
throw new common_1.ForbiddenException('User ID in request does not match authenticated user');
|
|
58
60
|
}
|
|
@@ -61,17 +63,33 @@ let JwtAuthHook = class JwtAuthHook {
|
|
|
61
63
|
itemId,
|
|
62
64
|
userId,
|
|
63
65
|
requestId: context?.requestId,
|
|
64
|
-
subject:
|
|
66
|
+
subject: tokenUserId,
|
|
65
67
|
});
|
|
66
68
|
return {
|
|
67
69
|
proceed: true,
|
|
68
70
|
};
|
|
69
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Matches the token user ID against the request user ID based on the configured match type.
|
|
74
|
+
*/
|
|
75
|
+
matchUserIdValue(tokenUserId, userId) {
|
|
76
|
+
const matchType = this.config.userIdMatchType ?? jwt_auth_hook_config_1.UserIdMatchType.EXACT;
|
|
77
|
+
switch (matchType) {
|
|
78
|
+
case jwt_auth_hook_config_1.UserIdMatchType.EXACT:
|
|
79
|
+
return tokenUserId === userId;
|
|
80
|
+
case jwt_auth_hook_config_1.UserIdMatchType.SUBSTRING:
|
|
81
|
+
return tokenUserId.includes(userId) || userId.includes(tokenUserId);
|
|
82
|
+
case jwt_auth_hook_config_1.UserIdMatchType.REGEX: {
|
|
83
|
+
const regex = new RegExp(this.config.userIdMatchRegex);
|
|
84
|
+
return regex.test(tokenUserId);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
70
88
|
};
|
|
71
89
|
exports.JwtAuthHook = JwtAuthHook;
|
|
72
90
|
exports.JwtAuthHook = JwtAuthHook = tslib_1.__decorate([
|
|
73
91
|
(0, common_1.Injectable)(),
|
|
74
|
-
tslib_1.__param(1, (0, common_1.Inject)(jwt_auth_hook_config_1.
|
|
92
|
+
tslib_1.__param(1, (0, common_1.Inject)(jwt_auth_hook_config_1.DISMISSIBLE_JWT_AUTH_HOOK_CONFIG)),
|
|
75
93
|
tslib_1.__param(2, (0, common_1.Inject)(nestjs_logger_1.DISMISSIBLE_LOGGER)),
|
|
76
94
|
tslib_1.__metadata("design:paramtypes", [jwt_auth_service_1.JwtAuthService,
|
|
77
95
|
jwt_auth_hook_config_1.JwtAuthHookConfig, Object])
|
package/src/jwt-auth.hook.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-auth.hook.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth.hook.ts"],"names":[],"mappings":";;;;AAAA,2CAA+F;AAG/F,8DAAoF;AACpF,yDAAoD;AACpD,
|
|
1
|
+
{"version":3,"file":"jwt-auth.hook.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth.hook.ts"],"names":[],"mappings":"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"}
|
package/src/jwt-auth.service.js
CHANGED
|
@@ -47,7 +47,7 @@ let JwtAuthService = class JwtAuthService {
|
|
|
47
47
|
cacheMaxAge: this.config.jwksCacheDuration ?? 600000,
|
|
48
48
|
timeout: this.config.requestTimeout ?? 30000,
|
|
49
49
|
});
|
|
50
|
-
this.logger.
|
|
50
|
+
this.logger.log('JWKS client initialized successfully', {
|
|
51
51
|
jwksUri: this.jwksUri,
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -108,8 +108,11 @@ let JwtAuthService = class JwtAuthService {
|
|
|
108
108
|
const verifyOptions = {
|
|
109
109
|
algorithms: this.config.algorithms ?? ['RS256'],
|
|
110
110
|
};
|
|
111
|
-
if (this.config.issuer) {
|
|
112
|
-
verifyOptions.issuer =
|
|
111
|
+
if (this.config.issuer && this.config.issuer.length > 0) {
|
|
112
|
+
verifyOptions.issuer =
|
|
113
|
+
this.config.issuer.length === 1
|
|
114
|
+
? this.config.issuer[0]
|
|
115
|
+
: this.config.issuer;
|
|
113
116
|
}
|
|
114
117
|
if (this.config.audience) {
|
|
115
118
|
verifyOptions.audience = this.config.audience;
|
|
@@ -135,7 +138,7 @@ let JwtAuthService = class JwtAuthService {
|
|
|
135
138
|
exports.JwtAuthService = JwtAuthService;
|
|
136
139
|
exports.JwtAuthService = JwtAuthService = tslib_1.__decorate([
|
|
137
140
|
(0, common_1.Injectable)(),
|
|
138
|
-
tslib_1.__param(1, (0, common_1.Inject)(jwt_auth_hook_config_1.
|
|
141
|
+
tslib_1.__param(1, (0, common_1.Inject)(jwt_auth_hook_config_1.DISMISSIBLE_JWT_AUTH_HOOK_CONFIG)),
|
|
139
142
|
tslib_1.__param(2, (0, common_1.Inject)(nestjs_logger_1.DISMISSIBLE_LOGGER)),
|
|
140
143
|
tslib_1.__metadata("design:paramtypes", [axios_1.HttpService,
|
|
141
144
|
jwt_auth_hook_config_1.JwtAuthHookConfig, Object])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-auth.service.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth.service.ts"],"names":[],"mappings":";;;;AAAA,2CAAkE;AAClE,yCAA4C;AAC5C,uCAAkD;AAClD,0DAAoC;AACpC,+BAAsC;AACtC,
|
|
1
|
+
{"version":3,"file":"jwt-auth.service.js","sourceRoot":"","sources":["../../../../libs/jwt-auth-hook/src/jwt-auth.service.ts"],"names":[],"mappings":"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"}
|