@dereekb/firebase-server 13.27.1 → 13.28.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/mailgun/package.json +9 -9
- package/mcp/package.json +11 -11
- package/model/package.json +9 -9
- package/oidc/index.cjs.js +168 -57
- package/oidc/index.esm.js +168 -58
- package/oidc/package.json +10 -10
- package/oidc/src/lib/middleware/oauth-cors.module.d.ts +41 -8
- package/oidc/src/lib/oidc.config.d.ts +47 -0
- package/oidc/src/lib/oidc.module.d.ts +1 -1
- package/package.json +10 -10
- package/test/package.json +11 -11
- package/twilio/package.json +8 -8
- package/zoho/package.json +9 -9
package/mailgun/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/mailgun",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.28.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/firebase": "13.
|
|
7
|
-
"@dereekb/firebase-server": "13.
|
|
8
|
-
"@dereekb/date": "13.
|
|
9
|
-
"@dereekb/nestjs": "13.
|
|
10
|
-
"@dereekb/model": "13.
|
|
11
|
-
"@dereekb/rxjs": "13.
|
|
12
|
-
"@dereekb/util": "13.
|
|
5
|
+
"@dereekb/analytics": "13.28.0",
|
|
6
|
+
"@dereekb/firebase": "13.28.0",
|
|
7
|
+
"@dereekb/firebase-server": "13.28.0",
|
|
8
|
+
"@dereekb/date": "13.28.0",
|
|
9
|
+
"@dereekb/nestjs": "13.28.0",
|
|
10
|
+
"@dereekb/model": "13.28.0",
|
|
11
|
+
"@dereekb/rxjs": "13.28.0",
|
|
12
|
+
"@dereekb/util": "13.28.0"
|
|
13
13
|
},
|
|
14
14
|
"exports": {
|
|
15
15
|
"./package.json": "./package.json",
|
package/mcp/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/mcp",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.28.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server": "13.
|
|
9
|
-
"@dereekb/firebase-server/oidc": "13.
|
|
10
|
-
"@dereekb/model": "13.
|
|
11
|
-
"@dereekb/nestjs": "13.
|
|
12
|
-
"@dereekb/rxjs": "13.
|
|
13
|
-
"@dereekb/util": "13.
|
|
14
|
-
"@dereekb/zoho": "13.
|
|
5
|
+
"@dereekb/analytics": "13.28.0",
|
|
6
|
+
"@dereekb/date": "13.28.0",
|
|
7
|
+
"@dereekb/firebase": "13.28.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.28.0",
|
|
9
|
+
"@dereekb/firebase-server/oidc": "13.28.0",
|
|
10
|
+
"@dereekb/model": "13.28.0",
|
|
11
|
+
"@dereekb/nestjs": "13.28.0",
|
|
12
|
+
"@dereekb/rxjs": "13.28.0",
|
|
13
|
+
"@dereekb/util": "13.28.0",
|
|
14
|
+
"@dereekb/zoho": "13.28.0",
|
|
15
15
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
16
16
|
"@nestjs/common": "^11.1.19",
|
|
17
17
|
"@nestjs/core": "^11.1.19",
|
package/model/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/model",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.28.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server": "13.
|
|
9
|
-
"@dereekb/model": "13.
|
|
10
|
-
"@dereekb/nestjs": "13.
|
|
11
|
-
"@dereekb/rxjs": "13.
|
|
12
|
-
"@dereekb/util": "13.
|
|
5
|
+
"@dereekb/analytics": "13.28.0",
|
|
6
|
+
"@dereekb/date": "13.28.0",
|
|
7
|
+
"@dereekb/firebase": "13.28.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.28.0",
|
|
9
|
+
"@dereekb/model": "13.28.0",
|
|
10
|
+
"@dereekb/nestjs": "13.28.0",
|
|
11
|
+
"@dereekb/rxjs": "13.28.0",
|
|
12
|
+
"@dereekb/util": "13.28.0",
|
|
13
13
|
"@nestjs/common": "^11.1.19",
|
|
14
14
|
"@nestjs/config": "^4.0.4",
|
|
15
15
|
"archiver": "^7.0.1",
|
package/oidc/index.cjs.js
CHANGED
|
@@ -344,6 +344,14 @@ function _define_property$g(obj, key, value) {
|
|
|
344
344
|
*
|
|
345
345
|
* Defaults to `false`.
|
|
346
346
|
*/ _define_property$g(this, "trustProxyInNonProduction", void 0);
|
|
347
|
+
/**
|
|
348
|
+
* Unified CORS configuration for the cross-origin browser OIDC endpoints
|
|
349
|
+
* (discovery GET, token POST). When unset, the Express CORS layer preserves the
|
|
350
|
+
* pre-existing behavior: `Access-Control-Allow-Origin: <appUrl>` on every
|
|
351
|
+
* response, which pre-empts oidc-provider's own CORS handling.
|
|
352
|
+
*
|
|
353
|
+
* @see OidcCorsConfig
|
|
354
|
+
*/ _define_property$g(this, "cors", void 0);
|
|
347
355
|
}
|
|
348
356
|
_create_class$e(OidcModuleConfig, null, [
|
|
349
357
|
{
|
|
@@ -3225,13 +3233,13 @@ var GRANTABLE_MODELS = new Set(GRANTABLE_MODEL_NAMES);
|
|
|
3225
3233
|
return FirestoreAdapter;
|
|
3226
3234
|
}
|
|
3227
3235
|
|
|
3228
|
-
function _array_like_to_array$
|
|
3236
|
+
function _array_like_to_array$6(arr, len) {
|
|
3229
3237
|
if (len == null || len > arr.length) len = arr.length;
|
|
3230
3238
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
3231
3239
|
return arr2;
|
|
3232
3240
|
}
|
|
3233
|
-
function _array_without_holes$
|
|
3234
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
3241
|
+
function _array_without_holes$6(arr) {
|
|
3242
|
+
if (Array.isArray(arr)) return _array_like_to_array$6(arr);
|
|
3235
3243
|
}
|
|
3236
3244
|
function _class_call_check$a(instance, Constructor) {
|
|
3237
3245
|
if (!(instance instanceof Constructor)) {
|
|
@@ -3264,22 +3272,22 @@ function _define_property$a(obj, key, value) {
|
|
|
3264
3272
|
}
|
|
3265
3273
|
return obj;
|
|
3266
3274
|
}
|
|
3267
|
-
function _iterable_to_array$
|
|
3275
|
+
function _iterable_to_array$6(iter) {
|
|
3268
3276
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
3269
3277
|
}
|
|
3270
|
-
function _non_iterable_spread$
|
|
3278
|
+
function _non_iterable_spread$6() {
|
|
3271
3279
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3272
3280
|
}
|
|
3273
|
-
function _to_consumable_array$
|
|
3274
|
-
return _array_without_holes$
|
|
3281
|
+
function _to_consumable_array$6(arr) {
|
|
3282
|
+
return _array_without_holes$6(arr) || _iterable_to_array$6(arr) || _unsupported_iterable_to_array$6(arr) || _non_iterable_spread$6();
|
|
3275
3283
|
}
|
|
3276
|
-
function _unsupported_iterable_to_array$
|
|
3284
|
+
function _unsupported_iterable_to_array$6(o, minLen) {
|
|
3277
3285
|
if (!o) return;
|
|
3278
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
3286
|
+
if (typeof o === "string") return _array_like_to_array$6(o, minLen);
|
|
3279
3287
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
3280
3288
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
3281
3289
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
3282
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
3290
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$6(o, minLen);
|
|
3283
3291
|
}
|
|
3284
3292
|
// MARK: Encrypted Fields
|
|
3285
3293
|
/**
|
|
@@ -3307,7 +3315,7 @@ function _unsupported_iterable_to_array$5(o, minLen) {
|
|
|
3307
3315
|
this.provider = nestjs.createAesStringEncryptionProvider(config.jwksKeyConverterConfig.encryptionSecret);
|
|
3308
3316
|
this.adapterPayloadEncryptor = util.selectiveFieldEncryptor({
|
|
3309
3317
|
provider: this.provider,
|
|
3310
|
-
fields: _to_consumable_array$
|
|
3318
|
+
fields: _to_consumable_array$6(OIDC_ENCRYPTED_PAYLOAD_FIELDS)
|
|
3311
3319
|
});
|
|
3312
3320
|
}
|
|
3313
3321
|
_create_class$8(OidcEncryptionService, [
|
|
@@ -3343,13 +3351,13 @@ exports.OidcEncryptionService = __decorate([
|
|
|
3343
3351
|
__param(0, common.Inject(OidcModuleConfig))
|
|
3344
3352
|
], exports.OidcEncryptionService);
|
|
3345
3353
|
|
|
3346
|
-
function _array_like_to_array$
|
|
3354
|
+
function _array_like_to_array$5(arr, len) {
|
|
3347
3355
|
if (len == null || len > arr.length) len = arr.length;
|
|
3348
3356
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
3349
3357
|
return arr2;
|
|
3350
3358
|
}
|
|
3351
|
-
function _array_without_holes$
|
|
3352
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
3359
|
+
function _array_without_holes$5(arr) {
|
|
3360
|
+
if (Array.isArray(arr)) return _array_like_to_array$5(arr);
|
|
3353
3361
|
}
|
|
3354
3362
|
function _class_call_check$9(instance, Constructor) {
|
|
3355
3363
|
if (!(instance instanceof Constructor)) {
|
|
@@ -3382,22 +3390,22 @@ function _define_property$9(obj, key, value) {
|
|
|
3382
3390
|
}
|
|
3383
3391
|
return obj;
|
|
3384
3392
|
}
|
|
3385
|
-
function _iterable_to_array$
|
|
3393
|
+
function _iterable_to_array$5(iter) {
|
|
3386
3394
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
3387
3395
|
}
|
|
3388
|
-
function _non_iterable_spread$
|
|
3396
|
+
function _non_iterable_spread$5() {
|
|
3389
3397
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3390
3398
|
}
|
|
3391
|
-
function _to_consumable_array$
|
|
3392
|
-
return _array_without_holes$
|
|
3399
|
+
function _to_consumable_array$5(arr) {
|
|
3400
|
+
return _array_without_holes$5(arr) || _iterable_to_array$5(arr) || _unsupported_iterable_to_array$5(arr) || _non_iterable_spread$5();
|
|
3393
3401
|
}
|
|
3394
|
-
function _unsupported_iterable_to_array$
|
|
3402
|
+
function _unsupported_iterable_to_array$5(o, minLen) {
|
|
3395
3403
|
if (!o) return;
|
|
3396
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
3404
|
+
if (typeof o === "string") return _array_like_to_array$5(o, minLen);
|
|
3397
3405
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
3398
3406
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
3399
3407
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
3400
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
3408
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$5(o, minLen);
|
|
3401
3409
|
}
|
|
3402
3410
|
// MARK: Routes
|
|
3403
3411
|
/**
|
|
@@ -3474,7 +3482,7 @@ var DEFAULT_OIDC_CODE_CHALLENGE_METHODS = [
|
|
|
3474
3482
|
this.providerConfig = accountService.providerConfig;
|
|
3475
3483
|
this.scopesSupported = Object.keys(this.providerConfig.claims);
|
|
3476
3484
|
this.claimsSupported = Array.from(new Set(Object.values(this.providerConfig.claims).flat()));
|
|
3477
|
-
this.tokenEndpointAuthMethodsSupported = (_this_config_tokenEndpointAuthMethods = this.config.tokenEndpointAuthMethods) !== null && _this_config_tokenEndpointAuthMethods !== void 0 ? _this_config_tokenEndpointAuthMethods : _to_consumable_array$
|
|
3485
|
+
this.tokenEndpointAuthMethodsSupported = (_this_config_tokenEndpointAuthMethods = this.config.tokenEndpointAuthMethods) !== null && _this_config_tokenEndpointAuthMethods !== void 0 ? _this_config_tokenEndpointAuthMethods : _to_consumable_array$5(DEFAULT_OIDC_TOKEN_ENDPOINT_AUTH_METHODS);
|
|
3478
3486
|
var appUrl = envService.appUrl;
|
|
3479
3487
|
this.appLoginUrl = util.websiteUrlFromPaths(appUrl, [
|
|
3480
3488
|
this.config.appOAuthInteractionPath,
|
|
@@ -3507,16 +3515,16 @@ var DEFAULT_OIDC_CODE_CHALLENGE_METHODS = [
|
|
|
3507
3515
|
jwks_uri: jwksUri !== null && jwksUri !== void 0 ? jwksUri : "".concat(issuer).concat(routes.jwks),
|
|
3508
3516
|
registration_endpoint: this.oidcRegistrationRouteEnabled ? "".concat(issuer).concat(routes.registration) : undefined,
|
|
3509
3517
|
scopes_supported: this.scopesSupported,
|
|
3510
|
-
response_types_supported: _to_consumable_array$
|
|
3518
|
+
response_types_supported: _to_consumable_array$5(providerConfig.responseTypes),
|
|
3511
3519
|
response_modes_supported: [
|
|
3512
3520
|
'query'
|
|
3513
3521
|
],
|
|
3514
|
-
grant_types_supported: _to_consumable_array$
|
|
3515
|
-
subject_types_supported: _to_consumable_array$
|
|
3516
|
-
id_token_signing_alg_values_supported: _to_consumable_array$
|
|
3517
|
-
token_endpoint_auth_methods_supported: _to_consumable_array$
|
|
3522
|
+
grant_types_supported: _to_consumable_array$5(providerConfig.grantTypes),
|
|
3523
|
+
subject_types_supported: _to_consumable_array$5(DEFAULT_OIDC_SUBJECT_TYPES),
|
|
3524
|
+
id_token_signing_alg_values_supported: _to_consumable_array$5(DEFAULT_OIDC_ID_TOKEN_SIGNING_ALG_VALUES),
|
|
3525
|
+
token_endpoint_auth_methods_supported: _to_consumable_array$5(this.tokenEndpointAuthMethodsSupported),
|
|
3518
3526
|
claims_supported: this.claimsSupported,
|
|
3519
|
-
code_challenge_methods_supported: _to_consumable_array$
|
|
3527
|
+
code_challenge_methods_supported: _to_consumable_array$5(DEFAULT_OIDC_CODE_CHALLENGE_METHODS)
|
|
3520
3528
|
};
|
|
3521
3529
|
}
|
|
3522
3530
|
}
|
|
@@ -3530,13 +3538,13 @@ exports.OidcProviderConfigService = __decorate([
|
|
|
3530
3538
|
__param(2, common.Inject(firebaseServer.FirebaseServerEnvService))
|
|
3531
3539
|
], exports.OidcProviderConfigService);
|
|
3532
3540
|
|
|
3533
|
-
function _array_like_to_array$
|
|
3541
|
+
function _array_like_to_array$4(arr, len) {
|
|
3534
3542
|
if (len == null || len > arr.length) len = arr.length;
|
|
3535
3543
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
3536
3544
|
return arr2;
|
|
3537
3545
|
}
|
|
3538
|
-
function _array_without_holes$
|
|
3539
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
3546
|
+
function _array_without_holes$4(arr) {
|
|
3547
|
+
if (Array.isArray(arr)) return _array_like_to_array$4(arr);
|
|
3540
3548
|
}
|
|
3541
3549
|
function asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, key, arg) {
|
|
3542
3550
|
try {
|
|
@@ -3598,10 +3606,10 @@ function _define_property$8(obj, key, value) {
|
|
|
3598
3606
|
}
|
|
3599
3607
|
return obj;
|
|
3600
3608
|
}
|
|
3601
|
-
function _iterable_to_array$
|
|
3609
|
+
function _iterable_to_array$4(iter) {
|
|
3602
3610
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
3603
3611
|
}
|
|
3604
|
-
function _non_iterable_spread$
|
|
3612
|
+
function _non_iterable_spread$4() {
|
|
3605
3613
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3606
3614
|
}
|
|
3607
3615
|
function _object_spread$3(target) {
|
|
@@ -3674,16 +3682,16 @@ function _object_without_properties_loose(source, excluded) {
|
|
|
3674
3682
|
}
|
|
3675
3683
|
return target;
|
|
3676
3684
|
}
|
|
3677
|
-
function _to_consumable_array$
|
|
3678
|
-
return _array_without_holes$
|
|
3685
|
+
function _to_consumable_array$4(arr) {
|
|
3686
|
+
return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$4(arr) || _non_iterable_spread$4();
|
|
3679
3687
|
}
|
|
3680
|
-
function _unsupported_iterable_to_array$
|
|
3688
|
+
function _unsupported_iterable_to_array$4(o, minLen) {
|
|
3681
3689
|
if (!o) return;
|
|
3682
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
3690
|
+
if (typeof o === "string") return _array_like_to_array$4(o, minLen);
|
|
3683
3691
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
3684
3692
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
3685
3693
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
3686
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
3694
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$4(o, minLen);
|
|
3687
3695
|
}
|
|
3688
3696
|
function _ts_generator$5(thisArg, body) {
|
|
3689
3697
|
var f, y, t, _ = {
|
|
@@ -4060,6 +4068,7 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4060
4068
|
value: function buildProviderConfiguration(cookieKeys) {
|
|
4061
4069
|
var _this = this;
|
|
4062
4070
|
var _config_maxRequestedLoginDuration, _config_minRequestedLoginDuration;
|
|
4071
|
+
var _config_cors;
|
|
4063
4072
|
var config = this.config;
|
|
4064
4073
|
var providerConfig = this.providerConfigService.providerConfig;
|
|
4065
4074
|
var serverMaxSeconds = (_config_maxRequestedLoginDuration = config.maxRequestedLoginDuration) !== null && _config_maxRequestedLoginDuration !== void 0 ? _config_maxRequestedLoginDuration : DEFAULT_MAX_REQUESTED_LOGIN_DURATION_SECONDS;
|
|
@@ -4077,7 +4086,7 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4077
4086
|
return _object_spread_props(_object_spread$3({
|
|
4078
4087
|
routes: _object_spread$3({}, this.providerConfigService.routes),
|
|
4079
4088
|
claims: _object_spread$3({}, providerConfig.claims),
|
|
4080
|
-
responseTypes: _to_consumable_array$
|
|
4089
|
+
responseTypes: _to_consumable_array$4(providerConfig.responseTypes),
|
|
4081
4090
|
pkce: {
|
|
4082
4091
|
required: function required() {
|
|
4083
4092
|
return true;
|
|
@@ -4233,6 +4242,19 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4233
4242
|
}
|
|
4234
4243
|
}, config.renderError ? {
|
|
4235
4244
|
renderError: config.renderError
|
|
4245
|
+
} : {}, ((_config_cors = config.cors) === null || _config_cors === void 0 ? void 0 : _config_cors.clientBased) ? {
|
|
4246
|
+
clientBasedCORS: function clientBasedCORS(_ctx, origin, client) {
|
|
4247
|
+
var _client_redirectUris;
|
|
4248
|
+
return ((_client_redirectUris = client.redirectUris) !== null && _client_redirectUris !== void 0 ? _client_redirectUris : []).some(function(uri) {
|
|
4249
|
+
var matches = false;
|
|
4250
|
+
try {
|
|
4251
|
+
matches = new URL(uri).origin === origin;
|
|
4252
|
+
} catch (unused) {
|
|
4253
|
+
// malformed persisted redirect_uri — treat as non-matching
|
|
4254
|
+
}
|
|
4255
|
+
return matches;
|
|
4256
|
+
});
|
|
4257
|
+
}
|
|
4236
4258
|
} : {}), {
|
|
4237
4259
|
// Setting `rotateRefreshToken` disables oidc-provider's built-in default, so we both honor the
|
|
4238
4260
|
// dbx-components `nonRotatingScopes` extension (service tokens never rotate, keeping a stable
|
|
@@ -4862,9 +4884,69 @@ exports.OidcAuthBearerTokenMiddleware = __decorate([
|
|
|
4862
4884
|
__param(1, common.Inject(OidcAuthMiddlewareConfig))
|
|
4863
4885
|
], exports.OidcAuthBearerTokenMiddleware);
|
|
4864
4886
|
|
|
4887
|
+
function _array_like_to_array$3(arr, len) {
|
|
4888
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
4889
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4890
|
+
return arr2;
|
|
4891
|
+
}
|
|
4892
|
+
function _array_without_holes$3(arr) {
|
|
4893
|
+
if (Array.isArray(arr)) return _array_like_to_array$3(arr);
|
|
4894
|
+
}
|
|
4895
|
+
function _iterable_to_array$3(iter) {
|
|
4896
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
4897
|
+
}
|
|
4898
|
+
function _non_iterable_spread$3() {
|
|
4899
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
4900
|
+
}
|
|
4901
|
+
function _to_consumable_array$3(arr) {
|
|
4902
|
+
return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
|
|
4903
|
+
}
|
|
4904
|
+
function _unsupported_iterable_to_array$3(o, minLen) {
|
|
4905
|
+
if (!o) return;
|
|
4906
|
+
if (typeof o === "string") return _array_like_to_array$3(o, minLen);
|
|
4907
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
4908
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
4909
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
4910
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$3(o, minLen);
|
|
4911
|
+
}
|
|
4912
|
+
/**
|
|
4913
|
+
* Builds the `cors`-package origin delegate implementing the composed OIDC CORS policy.
|
|
4914
|
+
*
|
|
4915
|
+
* - An allowlisted origin (`appUrl` or any {@link OidcCorsConfig.allowOrigins} entry) is
|
|
4916
|
+
* reflected exactly, which pre-empts oidc-provider's own CORS handling.
|
|
4917
|
+
* - Otherwise, when {@link OidcCorsConfig.clientBased} is enabled, the header is OMITTED so
|
|
4918
|
+
* oidc-provider runs its `clientBasedCORS` check on client routes (`/token`) and its builtin
|
|
4919
|
+
* reflect on client-less routes (discovery/JWKS).
|
|
4920
|
+
* - Otherwise (client-based off), `appUrl` is returned unconditionally so oidc-provider stays
|
|
4921
|
+
* pre-empted and there is never a reflect-any.
|
|
4922
|
+
*
|
|
4923
|
+
* Exported for unit testing without a running Nest application.
|
|
4924
|
+
*
|
|
4925
|
+
* @param appUrl - The authoritative frontend origin (always allowed).
|
|
4926
|
+
* @param cors - The unified CORS configuration.
|
|
4927
|
+
* @returns A `cors`-package origin delegate.
|
|
4928
|
+
*/ function oidcCorsOriginDelegate(appUrl, cors) {
|
|
4929
|
+
var _cors_allowOrigins;
|
|
4930
|
+
var clientBased = cors.clientBased === true;
|
|
4931
|
+
var allowlist = new Set([
|
|
4932
|
+
appUrl
|
|
4933
|
+
].concat(_to_consumable_array$3((_cors_allowOrigins = cors.allowOrigins) !== null && _cors_allowOrigins !== void 0 ? _cors_allowOrigins : [])));
|
|
4934
|
+
return function(requestOrigin, callback) {
|
|
4935
|
+
var resolved;
|
|
4936
|
+
if (requestOrigin && allowlist.has(requestOrigin)) {
|
|
4937
|
+
resolved = requestOrigin; // reflect the exact allowlisted origin; pre-empts oidc-provider
|
|
4938
|
+
} else if (clientBased) {
|
|
4939
|
+
resolved = false; // OMIT ACAO → oidc-provider runs clientBasedCORS (token) / builtin reflect (discovery)
|
|
4940
|
+
} else {
|
|
4941
|
+
resolved = appUrl; // legacy fallback: ACAO=appUrl always; no reflect-any
|
|
4942
|
+
}
|
|
4943
|
+
callback(null, resolved);
|
|
4944
|
+
};
|
|
4945
|
+
}
|
|
4865
4946
|
// MARK: Express-Level Helper
|
|
4866
4947
|
/**
|
|
4867
|
-
* Enables CORS on the NestJS app for OIDC cross-origin requests originating from the frontend
|
|
4948
|
+
* Enables CORS on the NestJS app for OIDC cross-origin requests originating from the frontend
|
|
4949
|
+
* and any additional relying-party origins.
|
|
4868
4950
|
*
|
|
4869
4951
|
* When the OIDC issuer lives on a different origin than the frontend app (e.g. the frontend is
|
|
4870
4952
|
* `https://app.example.com` and the OIDC server is at `https://api.example.com`), the frontend's
|
|
@@ -4872,16 +4954,22 @@ exports.OidcAuthBearerTokenMiddleware = __decorate([
|
|
|
4872
4954
|
* and `/interaction/{uid}/consent`. Because the POST body is `application/json`, the browser
|
|
4873
4955
|
* sends a CORS preflight. Without an `Access-Control-Allow-Origin` reply the preflight fails,
|
|
4874
4956
|
* the POST never reaches the server, and the OAuth flow stalls before `finishInteractionByUid`
|
|
4875
|
-
* can run.
|
|
4957
|
+
* can run. Browser-based OIDC relying parties (public PKCE clients) likewise need CORS on the
|
|
4958
|
+
* discovery GET and the token POST.
|
|
4959
|
+
*
|
|
4960
|
+
* `appUrl` (from `FirebaseServerEnvService.appUrl`) is always allowed. Additional behavior is
|
|
4961
|
+
* driven by the optional {@link OidcModuleConfig.cors} configuration:
|
|
4962
|
+
* - {@link OidcCorsConfig.allowOrigins} adds an explicit allowlist of relying-party origins.
|
|
4963
|
+
* - {@link OidcCorsConfig.clientBased} defers non-allowlisted origins to oidc-provider's
|
|
4964
|
+
* `clientBasedCORS`, which trusts each requesting client's registered `redirect_uris`.
|
|
4876
4965
|
*
|
|
4877
|
-
*
|
|
4878
|
-
*
|
|
4879
|
-
*
|
|
4880
|
-
* actually same-origin and CORS is a no-op.
|
|
4966
|
+
* When `cors` is unset, this preserves the legacy single-origin behavior exactly:
|
|
4967
|
+
* `Access-Control-Allow-Origin: <appUrl>` on every response, which pre-empts oidc-provider's
|
|
4968
|
+
* own CORS handling.
|
|
4881
4969
|
*
|
|
4882
4970
|
* Credentials are intentionally NOT enabled (`Access-Control-Allow-Credentials` stays off). The
|
|
4883
|
-
* `/interaction/{uid}/*` POSTs
|
|
4884
|
-
* we keep the CORS surface minimal.
|
|
4971
|
+
* `/interaction/{uid}/*` POSTs and the token exchange carry their bearer material in the request
|
|
4972
|
+
* body, not in cookies, so we keep the CORS surface minimal.
|
|
4885
4973
|
*
|
|
4886
4974
|
* @param nestApp - The NestJS application to configure.
|
|
4887
4975
|
*
|
|
@@ -4897,18 +4985,40 @@ exports.OidcAuthBearerTokenMiddleware = __decorate([
|
|
|
4897
4985
|
* ```
|
|
4898
4986
|
*/ function applyOidcCorsMiddleware(nestApp) {
|
|
4899
4987
|
var envService = nestApp.get(firebaseServer.FirebaseServerEnvService);
|
|
4900
|
-
var
|
|
4901
|
-
if (!
|
|
4988
|
+
var appUrl = envService.appUrl;
|
|
4989
|
+
if (!appUrl) {
|
|
4902
4990
|
return;
|
|
4903
4991
|
}
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
})
|
|
4992
|
+
// OidcModuleConfig may be absent (module not registered / out of the resolution scope).
|
|
4993
|
+
var cors;
|
|
4994
|
+
try {
|
|
4995
|
+
var _nestApp_get;
|
|
4996
|
+
cors = (_nestApp_get = nestApp.get(OidcModuleConfig, {
|
|
4997
|
+
strict: false
|
|
4998
|
+
})) === null || _nestApp_get === void 0 ? void 0 : _nestApp_get.cors;
|
|
4999
|
+
} catch (unused) {
|
|
5000
|
+
cors = undefined;
|
|
5001
|
+
}
|
|
5002
|
+
if (cors) {
|
|
5003
|
+
nestApp.enableCors({
|
|
5004
|
+
origin: oidcCorsOriginDelegate(appUrl, cors),
|
|
5005
|
+
methods: [
|
|
5006
|
+
'GET',
|
|
5007
|
+
'POST',
|
|
5008
|
+
'OPTIONS'
|
|
5009
|
+
]
|
|
5010
|
+
});
|
|
5011
|
+
} else {
|
|
5012
|
+
// No cors config → byte-identical to the legacy behavior: ACAO=appUrl unconditionally.
|
|
5013
|
+
nestApp.enableCors({
|
|
5014
|
+
origin: appUrl,
|
|
5015
|
+
methods: [
|
|
5016
|
+
'GET',
|
|
5017
|
+
'POST',
|
|
5018
|
+
'OPTIONS'
|
|
5019
|
+
]
|
|
5020
|
+
});
|
|
5021
|
+
}
|
|
4912
5022
|
}
|
|
4913
5023
|
|
|
4914
5024
|
/**
|
|
@@ -7635,6 +7745,7 @@ exports.jwksKeysWithStatusQuery = jwksKeysWithStatusQuery;
|
|
|
7635
7745
|
exports.nonRetiredJwksKeysQuery = nonRetiredJwksKeysQuery;
|
|
7636
7746
|
exports.noopOidcAnalyticsService = noopOidcAnalyticsService;
|
|
7637
7747
|
exports.oidcCallModelScopePreAssert = oidcCallModelScopePreAssert;
|
|
7748
|
+
exports.oidcCorsOriginDelegate = oidcCorsOriginDelegate;
|
|
7638
7749
|
exports.oidcFirestoreCollectionsFactory = oidcFirestoreCollectionsFactory;
|
|
7639
7750
|
exports.oidcModelServerActions = oidcModelServerActions;
|
|
7640
7751
|
exports.oidcModelServerActionsFactory = oidcModelServerActionsFactory;
|
package/oidc/index.esm.js
CHANGED
|
@@ -342,6 +342,14 @@ function _define_property$g(obj, key, value) {
|
|
|
342
342
|
*
|
|
343
343
|
* Defaults to `false`.
|
|
344
344
|
*/ _define_property$g(this, "trustProxyInNonProduction", void 0);
|
|
345
|
+
/**
|
|
346
|
+
* Unified CORS configuration for the cross-origin browser OIDC endpoints
|
|
347
|
+
* (discovery GET, token POST). When unset, the Express CORS layer preserves the
|
|
348
|
+
* pre-existing behavior: `Access-Control-Allow-Origin: <appUrl>` on every
|
|
349
|
+
* response, which pre-empts oidc-provider's own CORS handling.
|
|
350
|
+
*
|
|
351
|
+
* @see OidcCorsConfig
|
|
352
|
+
*/ _define_property$g(this, "cors", void 0);
|
|
345
353
|
}
|
|
346
354
|
_create_class$e(OidcModuleConfig, null, [
|
|
347
355
|
{
|
|
@@ -3223,13 +3231,13 @@ var GRANTABLE_MODELS = new Set(GRANTABLE_MODEL_NAMES);
|
|
|
3223
3231
|
return FirestoreAdapter;
|
|
3224
3232
|
}
|
|
3225
3233
|
|
|
3226
|
-
function _array_like_to_array$
|
|
3234
|
+
function _array_like_to_array$6(arr, len) {
|
|
3227
3235
|
if (len == null || len > arr.length) len = arr.length;
|
|
3228
3236
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
3229
3237
|
return arr2;
|
|
3230
3238
|
}
|
|
3231
|
-
function _array_without_holes$
|
|
3232
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
3239
|
+
function _array_without_holes$6(arr) {
|
|
3240
|
+
if (Array.isArray(arr)) return _array_like_to_array$6(arr);
|
|
3233
3241
|
}
|
|
3234
3242
|
function _class_call_check$a(instance, Constructor) {
|
|
3235
3243
|
if (!(instance instanceof Constructor)) {
|
|
@@ -3262,22 +3270,22 @@ function _define_property$a(obj, key, value) {
|
|
|
3262
3270
|
}
|
|
3263
3271
|
return obj;
|
|
3264
3272
|
}
|
|
3265
|
-
function _iterable_to_array$
|
|
3273
|
+
function _iterable_to_array$6(iter) {
|
|
3266
3274
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
3267
3275
|
}
|
|
3268
|
-
function _non_iterable_spread$
|
|
3276
|
+
function _non_iterable_spread$6() {
|
|
3269
3277
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3270
3278
|
}
|
|
3271
|
-
function _to_consumable_array$
|
|
3272
|
-
return _array_without_holes$
|
|
3279
|
+
function _to_consumable_array$6(arr) {
|
|
3280
|
+
return _array_without_holes$6(arr) || _iterable_to_array$6(arr) || _unsupported_iterable_to_array$6(arr) || _non_iterable_spread$6();
|
|
3273
3281
|
}
|
|
3274
|
-
function _unsupported_iterable_to_array$
|
|
3282
|
+
function _unsupported_iterable_to_array$6(o, minLen) {
|
|
3275
3283
|
if (!o) return;
|
|
3276
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
3284
|
+
if (typeof o === "string") return _array_like_to_array$6(o, minLen);
|
|
3277
3285
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
3278
3286
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
3279
3287
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
3280
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
3288
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$6(o, minLen);
|
|
3281
3289
|
}
|
|
3282
3290
|
// MARK: Encrypted Fields
|
|
3283
3291
|
/**
|
|
@@ -3305,7 +3313,7 @@ function _unsupported_iterable_to_array$5(o, minLen) {
|
|
|
3305
3313
|
this.provider = createAesStringEncryptionProvider(config.jwksKeyConverterConfig.encryptionSecret);
|
|
3306
3314
|
this.adapterPayloadEncryptor = selectiveFieldEncryptor({
|
|
3307
3315
|
provider: this.provider,
|
|
3308
|
-
fields: _to_consumable_array$
|
|
3316
|
+
fields: _to_consumable_array$6(OIDC_ENCRYPTED_PAYLOAD_FIELDS)
|
|
3309
3317
|
});
|
|
3310
3318
|
}
|
|
3311
3319
|
_create_class$8(OidcEncryptionService, [
|
|
@@ -3341,13 +3349,13 @@ OidcEncryptionService = __decorate([
|
|
|
3341
3349
|
__param(0, Inject(OidcModuleConfig))
|
|
3342
3350
|
], OidcEncryptionService);
|
|
3343
3351
|
|
|
3344
|
-
function _array_like_to_array$
|
|
3352
|
+
function _array_like_to_array$5(arr, len) {
|
|
3345
3353
|
if (len == null || len > arr.length) len = arr.length;
|
|
3346
3354
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
3347
3355
|
return arr2;
|
|
3348
3356
|
}
|
|
3349
|
-
function _array_without_holes$
|
|
3350
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
3357
|
+
function _array_without_holes$5(arr) {
|
|
3358
|
+
if (Array.isArray(arr)) return _array_like_to_array$5(arr);
|
|
3351
3359
|
}
|
|
3352
3360
|
function _class_call_check$9(instance, Constructor) {
|
|
3353
3361
|
if (!(instance instanceof Constructor)) {
|
|
@@ -3380,22 +3388,22 @@ function _define_property$9(obj, key, value) {
|
|
|
3380
3388
|
}
|
|
3381
3389
|
return obj;
|
|
3382
3390
|
}
|
|
3383
|
-
function _iterable_to_array$
|
|
3391
|
+
function _iterable_to_array$5(iter) {
|
|
3384
3392
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
3385
3393
|
}
|
|
3386
|
-
function _non_iterable_spread$
|
|
3394
|
+
function _non_iterable_spread$5() {
|
|
3387
3395
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3388
3396
|
}
|
|
3389
|
-
function _to_consumable_array$
|
|
3390
|
-
return _array_without_holes$
|
|
3397
|
+
function _to_consumable_array$5(arr) {
|
|
3398
|
+
return _array_without_holes$5(arr) || _iterable_to_array$5(arr) || _unsupported_iterable_to_array$5(arr) || _non_iterable_spread$5();
|
|
3391
3399
|
}
|
|
3392
|
-
function _unsupported_iterable_to_array$
|
|
3400
|
+
function _unsupported_iterable_to_array$5(o, minLen) {
|
|
3393
3401
|
if (!o) return;
|
|
3394
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
3402
|
+
if (typeof o === "string") return _array_like_to_array$5(o, minLen);
|
|
3395
3403
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
3396
3404
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
3397
3405
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
3398
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
3406
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$5(o, minLen);
|
|
3399
3407
|
}
|
|
3400
3408
|
// MARK: Routes
|
|
3401
3409
|
/**
|
|
@@ -3472,7 +3480,7 @@ var DEFAULT_OIDC_CODE_CHALLENGE_METHODS = [
|
|
|
3472
3480
|
this.providerConfig = accountService.providerConfig;
|
|
3473
3481
|
this.scopesSupported = Object.keys(this.providerConfig.claims);
|
|
3474
3482
|
this.claimsSupported = Array.from(new Set(Object.values(this.providerConfig.claims).flat()));
|
|
3475
|
-
this.tokenEndpointAuthMethodsSupported = (_this_config_tokenEndpointAuthMethods = this.config.tokenEndpointAuthMethods) !== null && _this_config_tokenEndpointAuthMethods !== void 0 ? _this_config_tokenEndpointAuthMethods : _to_consumable_array$
|
|
3483
|
+
this.tokenEndpointAuthMethodsSupported = (_this_config_tokenEndpointAuthMethods = this.config.tokenEndpointAuthMethods) !== null && _this_config_tokenEndpointAuthMethods !== void 0 ? _this_config_tokenEndpointAuthMethods : _to_consumable_array$5(DEFAULT_OIDC_TOKEN_ENDPOINT_AUTH_METHODS);
|
|
3476
3484
|
var appUrl = envService.appUrl;
|
|
3477
3485
|
this.appLoginUrl = websiteUrlFromPaths(appUrl, [
|
|
3478
3486
|
this.config.appOAuthInteractionPath,
|
|
@@ -3505,16 +3513,16 @@ var DEFAULT_OIDC_CODE_CHALLENGE_METHODS = [
|
|
|
3505
3513
|
jwks_uri: jwksUri !== null && jwksUri !== void 0 ? jwksUri : "".concat(issuer).concat(routes.jwks),
|
|
3506
3514
|
registration_endpoint: this.oidcRegistrationRouteEnabled ? "".concat(issuer).concat(routes.registration) : undefined,
|
|
3507
3515
|
scopes_supported: this.scopesSupported,
|
|
3508
|
-
response_types_supported: _to_consumable_array$
|
|
3516
|
+
response_types_supported: _to_consumable_array$5(providerConfig.responseTypes),
|
|
3509
3517
|
response_modes_supported: [
|
|
3510
3518
|
'query'
|
|
3511
3519
|
],
|
|
3512
|
-
grant_types_supported: _to_consumable_array$
|
|
3513
|
-
subject_types_supported: _to_consumable_array$
|
|
3514
|
-
id_token_signing_alg_values_supported: _to_consumable_array$
|
|
3515
|
-
token_endpoint_auth_methods_supported: _to_consumable_array$
|
|
3520
|
+
grant_types_supported: _to_consumable_array$5(providerConfig.grantTypes),
|
|
3521
|
+
subject_types_supported: _to_consumable_array$5(DEFAULT_OIDC_SUBJECT_TYPES),
|
|
3522
|
+
id_token_signing_alg_values_supported: _to_consumable_array$5(DEFAULT_OIDC_ID_TOKEN_SIGNING_ALG_VALUES),
|
|
3523
|
+
token_endpoint_auth_methods_supported: _to_consumable_array$5(this.tokenEndpointAuthMethodsSupported),
|
|
3516
3524
|
claims_supported: this.claimsSupported,
|
|
3517
|
-
code_challenge_methods_supported: _to_consumable_array$
|
|
3525
|
+
code_challenge_methods_supported: _to_consumable_array$5(DEFAULT_OIDC_CODE_CHALLENGE_METHODS)
|
|
3518
3526
|
};
|
|
3519
3527
|
}
|
|
3520
3528
|
}
|
|
@@ -3528,13 +3536,13 @@ OidcProviderConfigService = __decorate([
|
|
|
3528
3536
|
__param(2, Inject(FirebaseServerEnvService))
|
|
3529
3537
|
], OidcProviderConfigService);
|
|
3530
3538
|
|
|
3531
|
-
function _array_like_to_array$
|
|
3539
|
+
function _array_like_to_array$4(arr, len) {
|
|
3532
3540
|
if (len == null || len > arr.length) len = arr.length;
|
|
3533
3541
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
3534
3542
|
return arr2;
|
|
3535
3543
|
}
|
|
3536
|
-
function _array_without_holes$
|
|
3537
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
3544
|
+
function _array_without_holes$4(arr) {
|
|
3545
|
+
if (Array.isArray(arr)) return _array_like_to_array$4(arr);
|
|
3538
3546
|
}
|
|
3539
3547
|
function asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, key, arg) {
|
|
3540
3548
|
try {
|
|
@@ -3596,10 +3604,10 @@ function _define_property$8(obj, key, value) {
|
|
|
3596
3604
|
}
|
|
3597
3605
|
return obj;
|
|
3598
3606
|
}
|
|
3599
|
-
function _iterable_to_array$
|
|
3607
|
+
function _iterable_to_array$4(iter) {
|
|
3600
3608
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
3601
3609
|
}
|
|
3602
|
-
function _non_iterable_spread$
|
|
3610
|
+
function _non_iterable_spread$4() {
|
|
3603
3611
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3604
3612
|
}
|
|
3605
3613
|
function _object_spread$3(target) {
|
|
@@ -3672,16 +3680,16 @@ function _object_without_properties_loose(source, excluded) {
|
|
|
3672
3680
|
}
|
|
3673
3681
|
return target;
|
|
3674
3682
|
}
|
|
3675
|
-
function _to_consumable_array$
|
|
3676
|
-
return _array_without_holes$
|
|
3683
|
+
function _to_consumable_array$4(arr) {
|
|
3684
|
+
return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$4(arr) || _non_iterable_spread$4();
|
|
3677
3685
|
}
|
|
3678
|
-
function _unsupported_iterable_to_array$
|
|
3686
|
+
function _unsupported_iterable_to_array$4(o, minLen) {
|
|
3679
3687
|
if (!o) return;
|
|
3680
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
3688
|
+
if (typeof o === "string") return _array_like_to_array$4(o, minLen);
|
|
3681
3689
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
3682
3690
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
3683
3691
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
3684
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
3692
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$4(o, minLen);
|
|
3685
3693
|
}
|
|
3686
3694
|
function _ts_generator$5(thisArg, body) {
|
|
3687
3695
|
var f, y, t, _ = {
|
|
@@ -4058,6 +4066,7 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4058
4066
|
value: function buildProviderConfiguration(cookieKeys) {
|
|
4059
4067
|
var _this = this;
|
|
4060
4068
|
var _config_maxRequestedLoginDuration, _config_minRequestedLoginDuration;
|
|
4069
|
+
var _config_cors;
|
|
4061
4070
|
var config = this.config;
|
|
4062
4071
|
var providerConfig = this.providerConfigService.providerConfig;
|
|
4063
4072
|
var serverMaxSeconds = (_config_maxRequestedLoginDuration = config.maxRequestedLoginDuration) !== null && _config_maxRequestedLoginDuration !== void 0 ? _config_maxRequestedLoginDuration : DEFAULT_MAX_REQUESTED_LOGIN_DURATION_SECONDS;
|
|
@@ -4075,7 +4084,7 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4075
4084
|
return _object_spread_props(_object_spread$3({
|
|
4076
4085
|
routes: _object_spread$3({}, this.providerConfigService.routes),
|
|
4077
4086
|
claims: _object_spread$3({}, providerConfig.claims),
|
|
4078
|
-
responseTypes: _to_consumable_array$
|
|
4087
|
+
responseTypes: _to_consumable_array$4(providerConfig.responseTypes),
|
|
4079
4088
|
pkce: {
|
|
4080
4089
|
required: function required() {
|
|
4081
4090
|
return true;
|
|
@@ -4231,6 +4240,19 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4231
4240
|
}
|
|
4232
4241
|
}, config.renderError ? {
|
|
4233
4242
|
renderError: config.renderError
|
|
4243
|
+
} : {}, ((_config_cors = config.cors) === null || _config_cors === void 0 ? void 0 : _config_cors.clientBased) ? {
|
|
4244
|
+
clientBasedCORS: function clientBasedCORS(_ctx, origin, client) {
|
|
4245
|
+
var _client_redirectUris;
|
|
4246
|
+
return ((_client_redirectUris = client.redirectUris) !== null && _client_redirectUris !== void 0 ? _client_redirectUris : []).some(function(uri) {
|
|
4247
|
+
var matches = false;
|
|
4248
|
+
try {
|
|
4249
|
+
matches = new URL(uri).origin === origin;
|
|
4250
|
+
} catch (unused) {
|
|
4251
|
+
// malformed persisted redirect_uri — treat as non-matching
|
|
4252
|
+
}
|
|
4253
|
+
return matches;
|
|
4254
|
+
});
|
|
4255
|
+
}
|
|
4234
4256
|
} : {}), {
|
|
4235
4257
|
// Setting `rotateRefreshToken` disables oidc-provider's built-in default, so we both honor the
|
|
4236
4258
|
// dbx-components `nonRotatingScopes` extension (service tokens never rotate, keeping a stable
|
|
@@ -4860,9 +4882,69 @@ OidcAuthBearerTokenMiddleware = __decorate([
|
|
|
4860
4882
|
__param(1, Inject(OidcAuthMiddlewareConfig))
|
|
4861
4883
|
], OidcAuthBearerTokenMiddleware);
|
|
4862
4884
|
|
|
4885
|
+
function _array_like_to_array$3(arr, len) {
|
|
4886
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
4887
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4888
|
+
return arr2;
|
|
4889
|
+
}
|
|
4890
|
+
function _array_without_holes$3(arr) {
|
|
4891
|
+
if (Array.isArray(arr)) return _array_like_to_array$3(arr);
|
|
4892
|
+
}
|
|
4893
|
+
function _iterable_to_array$3(iter) {
|
|
4894
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
4895
|
+
}
|
|
4896
|
+
function _non_iterable_spread$3() {
|
|
4897
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
4898
|
+
}
|
|
4899
|
+
function _to_consumable_array$3(arr) {
|
|
4900
|
+
return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
|
|
4901
|
+
}
|
|
4902
|
+
function _unsupported_iterable_to_array$3(o, minLen) {
|
|
4903
|
+
if (!o) return;
|
|
4904
|
+
if (typeof o === "string") return _array_like_to_array$3(o, minLen);
|
|
4905
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
4906
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
4907
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
4908
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$3(o, minLen);
|
|
4909
|
+
}
|
|
4910
|
+
/**
|
|
4911
|
+
* Builds the `cors`-package origin delegate implementing the composed OIDC CORS policy.
|
|
4912
|
+
*
|
|
4913
|
+
* - An allowlisted origin (`appUrl` or any {@link OidcCorsConfig.allowOrigins} entry) is
|
|
4914
|
+
* reflected exactly, which pre-empts oidc-provider's own CORS handling.
|
|
4915
|
+
* - Otherwise, when {@link OidcCorsConfig.clientBased} is enabled, the header is OMITTED so
|
|
4916
|
+
* oidc-provider runs its `clientBasedCORS` check on client routes (`/token`) and its builtin
|
|
4917
|
+
* reflect on client-less routes (discovery/JWKS).
|
|
4918
|
+
* - Otherwise (client-based off), `appUrl` is returned unconditionally so oidc-provider stays
|
|
4919
|
+
* pre-empted and there is never a reflect-any.
|
|
4920
|
+
*
|
|
4921
|
+
* Exported for unit testing without a running Nest application.
|
|
4922
|
+
*
|
|
4923
|
+
* @param appUrl - The authoritative frontend origin (always allowed).
|
|
4924
|
+
* @param cors - The unified CORS configuration.
|
|
4925
|
+
* @returns A `cors`-package origin delegate.
|
|
4926
|
+
*/ function oidcCorsOriginDelegate(appUrl, cors) {
|
|
4927
|
+
var _cors_allowOrigins;
|
|
4928
|
+
var clientBased = cors.clientBased === true;
|
|
4929
|
+
var allowlist = new Set([
|
|
4930
|
+
appUrl
|
|
4931
|
+
].concat(_to_consumable_array$3((_cors_allowOrigins = cors.allowOrigins) !== null && _cors_allowOrigins !== void 0 ? _cors_allowOrigins : [])));
|
|
4932
|
+
return function(requestOrigin, callback) {
|
|
4933
|
+
var resolved;
|
|
4934
|
+
if (requestOrigin && allowlist.has(requestOrigin)) {
|
|
4935
|
+
resolved = requestOrigin; // reflect the exact allowlisted origin; pre-empts oidc-provider
|
|
4936
|
+
} else if (clientBased) {
|
|
4937
|
+
resolved = false; // OMIT ACAO → oidc-provider runs clientBasedCORS (token) / builtin reflect (discovery)
|
|
4938
|
+
} else {
|
|
4939
|
+
resolved = appUrl; // legacy fallback: ACAO=appUrl always; no reflect-any
|
|
4940
|
+
}
|
|
4941
|
+
callback(null, resolved);
|
|
4942
|
+
};
|
|
4943
|
+
}
|
|
4863
4944
|
// MARK: Express-Level Helper
|
|
4864
4945
|
/**
|
|
4865
|
-
* Enables CORS on the NestJS app for OIDC cross-origin requests originating from the frontend
|
|
4946
|
+
* Enables CORS on the NestJS app for OIDC cross-origin requests originating from the frontend
|
|
4947
|
+
* and any additional relying-party origins.
|
|
4866
4948
|
*
|
|
4867
4949
|
* When the OIDC issuer lives on a different origin than the frontend app (e.g. the frontend is
|
|
4868
4950
|
* `https://app.example.com` and the OIDC server is at `https://api.example.com`), the frontend's
|
|
@@ -4870,16 +4952,22 @@ OidcAuthBearerTokenMiddleware = __decorate([
|
|
|
4870
4952
|
* and `/interaction/{uid}/consent`. Because the POST body is `application/json`, the browser
|
|
4871
4953
|
* sends a CORS preflight. Without an `Access-Control-Allow-Origin` reply the preflight fails,
|
|
4872
4954
|
* the POST never reaches the server, and the OAuth flow stalls before `finishInteractionByUid`
|
|
4873
|
-
* can run.
|
|
4955
|
+
* can run. Browser-based OIDC relying parties (public PKCE clients) likewise need CORS on the
|
|
4956
|
+
* discovery GET and the token POST.
|
|
4957
|
+
*
|
|
4958
|
+
* `appUrl` (from `FirebaseServerEnvService.appUrl`) is always allowed. Additional behavior is
|
|
4959
|
+
* driven by the optional {@link OidcModuleConfig.cors} configuration:
|
|
4960
|
+
* - {@link OidcCorsConfig.allowOrigins} adds an explicit allowlist of relying-party origins.
|
|
4961
|
+
* - {@link OidcCorsConfig.clientBased} defers non-allowlisted origins to oidc-provider's
|
|
4962
|
+
* `clientBasedCORS`, which trusts each requesting client's registered `redirect_uris`.
|
|
4874
4963
|
*
|
|
4875
|
-
*
|
|
4876
|
-
*
|
|
4877
|
-
*
|
|
4878
|
-
* actually same-origin and CORS is a no-op.
|
|
4964
|
+
* When `cors` is unset, this preserves the legacy single-origin behavior exactly:
|
|
4965
|
+
* `Access-Control-Allow-Origin: <appUrl>` on every response, which pre-empts oidc-provider's
|
|
4966
|
+
* own CORS handling.
|
|
4879
4967
|
*
|
|
4880
4968
|
* Credentials are intentionally NOT enabled (`Access-Control-Allow-Credentials` stays off). The
|
|
4881
|
-
* `/interaction/{uid}/*` POSTs
|
|
4882
|
-
* we keep the CORS surface minimal.
|
|
4969
|
+
* `/interaction/{uid}/*` POSTs and the token exchange carry their bearer material in the request
|
|
4970
|
+
* body, not in cookies, so we keep the CORS surface minimal.
|
|
4883
4971
|
*
|
|
4884
4972
|
* @param nestApp - The NestJS application to configure.
|
|
4885
4973
|
*
|
|
@@ -4895,18 +4983,40 @@ OidcAuthBearerTokenMiddleware = __decorate([
|
|
|
4895
4983
|
* ```
|
|
4896
4984
|
*/ function applyOidcCorsMiddleware(nestApp) {
|
|
4897
4985
|
var envService = nestApp.get(FirebaseServerEnvService);
|
|
4898
|
-
var
|
|
4899
|
-
if (!
|
|
4986
|
+
var appUrl = envService.appUrl;
|
|
4987
|
+
if (!appUrl) {
|
|
4900
4988
|
return;
|
|
4901
4989
|
}
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
})
|
|
4990
|
+
// OidcModuleConfig may be absent (module not registered / out of the resolution scope).
|
|
4991
|
+
var cors;
|
|
4992
|
+
try {
|
|
4993
|
+
var _nestApp_get;
|
|
4994
|
+
cors = (_nestApp_get = nestApp.get(OidcModuleConfig, {
|
|
4995
|
+
strict: false
|
|
4996
|
+
})) === null || _nestApp_get === void 0 ? void 0 : _nestApp_get.cors;
|
|
4997
|
+
} catch (unused) {
|
|
4998
|
+
cors = undefined;
|
|
4999
|
+
}
|
|
5000
|
+
if (cors) {
|
|
5001
|
+
nestApp.enableCors({
|
|
5002
|
+
origin: oidcCorsOriginDelegate(appUrl, cors),
|
|
5003
|
+
methods: [
|
|
5004
|
+
'GET',
|
|
5005
|
+
'POST',
|
|
5006
|
+
'OPTIONS'
|
|
5007
|
+
]
|
|
5008
|
+
});
|
|
5009
|
+
} else {
|
|
5010
|
+
// No cors config → byte-identical to the legacy behavior: ACAO=appUrl unconditionally.
|
|
5011
|
+
nestApp.enableCors({
|
|
5012
|
+
origin: appUrl,
|
|
5013
|
+
methods: [
|
|
5014
|
+
'GET',
|
|
5015
|
+
'POST',
|
|
5016
|
+
'OPTIONS'
|
|
5017
|
+
]
|
|
5018
|
+
});
|
|
5019
|
+
}
|
|
4910
5020
|
}
|
|
4911
5021
|
|
|
4912
5022
|
/**
|
|
@@ -7571,4 +7681,4 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
7571
7681
|
return fn;
|
|
7572
7682
|
}
|
|
7573
7683
|
|
|
7574
|
-
export { DEFAULT_APP_OAUTH_CONSENT_PATH_PART, DEFAULT_APP_OAUTH_INTERACTION_PATH, DEFAULT_APP_OAUTH_LOGIN_PATH_PART, DEFAULT_MAX_ADMIN_LOGIN_DURATION_SECONDS, DEFAULT_MAX_NONADMIN_LOGIN_DURATION_SECONDS, DEFAULT_MAX_REQUESTED_LOGIN_DURATION_SECONDS, DEFAULT_MAX_SERVICE_TOKEN_LOGIN_DURATION_SECONDS, DEFAULT_MIN_REQUESTED_LOGIN_DURATION_SECONDS, DEFAULT_OIDC_ANALYTICS_EVENT_NAMES, DEFAULT_OIDC_ANALYTICS_EVENT_NAME_PREFIX, DEFAULT_OIDC_CODE_CHALLENGE_METHODS, DEFAULT_OIDC_ID_TOKEN_SIGNING_ALG_VALUES, DEFAULT_OIDC_ISSUER_PATH, DEFAULT_OIDC_ROUTES, DEFAULT_OIDC_SUBJECT_TYPES, DEFAULT_OIDC_TOKEN_ENDPOINT_AUTH_METHODS, DEFAULT_OIDC_TOKEN_LIFETIMES, DEFAULT_ROTATED_KEY_MAX_AGE, FIREBASE_SERVER_OIDC_ANALYTICS_CONFIG, FIREBASE_SERVER_OIDC_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE, FirebaseServerOidcAnalyticsService, GRANTABLE_MODEL_NAMES, JwksFirestoreCollections, JwksKeyDocument, JwksService, JwksServiceConfig, JwksServiceStorageConfig, OIDC_ANALYTICS_SERVICE, OIDC_ENCRYPTED_PAYLOAD_FIELDS, OIDC_JSON_RENDER_ERROR_FUNCTION, OIDC_JWKS_ENCRYPTION_SECRET_ENV_KEY, OidcAccountService, OidcAccountServiceDelegate, OidcAccountServiceUserContext, OidcAnalyticsService, OidcAuth, OidcAuthBearerTokenMiddleware, OidcAuthMiddlewareConfig, OidcClientService, OidcEncryptionService, OidcInteractionController, OidcInteractionService, OidcModelServerActions, OidcModuleConfig, OidcProviderConfigService, OidcProviderController, OidcServerFirestoreCollections, OidcService, OidcWellKnownController, activeJwksKeysQuery, allOidcScopesStringForProviderConfig, appOidcAnalyticsModuleMetadata, appOidcModelModuleMetadata, applyOidcAuthMiddleware, applyOidcCorsMiddleware, buildBearerChallenge, buildFirebaseServerMcpResourceServer, createAdapterFactory, createOidcClientFactory, deleteOidcClientFactory, deleteOidcTokenFactory, deriveResourceMetadataUrlFromEnv, emitOidcAnalyticsEvent, getOidcScopesFromRequest, jwksKeyCollectionReference, jwksKeyConverter, jwksKeyFirestoreCollection, jwksKeyIdentity, jwksKeysWithStatusQuery, nonRetiredJwksKeysQuery, noopOidcAnalyticsService, oidcCallModelScopePreAssert, oidcFirestoreCollectionsFactory, oidcModelServerActions, oidcModelServerActionsFactory, oidcModuleConfigFactory, oidcModuleMetadata, resolveEffectiveSubset, rotateOidcClientSecretFactory, rotatedJwksKeysQuery, updateOidcClientFactory };
|
|
7684
|
+
export { DEFAULT_APP_OAUTH_CONSENT_PATH_PART, DEFAULT_APP_OAUTH_INTERACTION_PATH, DEFAULT_APP_OAUTH_LOGIN_PATH_PART, DEFAULT_MAX_ADMIN_LOGIN_DURATION_SECONDS, DEFAULT_MAX_NONADMIN_LOGIN_DURATION_SECONDS, DEFAULT_MAX_REQUESTED_LOGIN_DURATION_SECONDS, DEFAULT_MAX_SERVICE_TOKEN_LOGIN_DURATION_SECONDS, DEFAULT_MIN_REQUESTED_LOGIN_DURATION_SECONDS, DEFAULT_OIDC_ANALYTICS_EVENT_NAMES, DEFAULT_OIDC_ANALYTICS_EVENT_NAME_PREFIX, DEFAULT_OIDC_CODE_CHALLENGE_METHODS, DEFAULT_OIDC_ID_TOKEN_SIGNING_ALG_VALUES, DEFAULT_OIDC_ISSUER_PATH, DEFAULT_OIDC_ROUTES, DEFAULT_OIDC_SUBJECT_TYPES, DEFAULT_OIDC_TOKEN_ENDPOINT_AUTH_METHODS, DEFAULT_OIDC_TOKEN_LIFETIMES, DEFAULT_ROTATED_KEY_MAX_AGE, FIREBASE_SERVER_OIDC_ANALYTICS_CONFIG, FIREBASE_SERVER_OIDC_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE, FirebaseServerOidcAnalyticsService, GRANTABLE_MODEL_NAMES, JwksFirestoreCollections, JwksKeyDocument, JwksService, JwksServiceConfig, JwksServiceStorageConfig, OIDC_ANALYTICS_SERVICE, OIDC_ENCRYPTED_PAYLOAD_FIELDS, OIDC_JSON_RENDER_ERROR_FUNCTION, OIDC_JWKS_ENCRYPTION_SECRET_ENV_KEY, OidcAccountService, OidcAccountServiceDelegate, OidcAccountServiceUserContext, OidcAnalyticsService, OidcAuth, OidcAuthBearerTokenMiddleware, OidcAuthMiddlewareConfig, OidcClientService, OidcEncryptionService, OidcInteractionController, OidcInteractionService, OidcModelServerActions, OidcModuleConfig, OidcProviderConfigService, OidcProviderController, OidcServerFirestoreCollections, OidcService, OidcWellKnownController, activeJwksKeysQuery, allOidcScopesStringForProviderConfig, appOidcAnalyticsModuleMetadata, appOidcModelModuleMetadata, applyOidcAuthMiddleware, applyOidcCorsMiddleware, buildBearerChallenge, buildFirebaseServerMcpResourceServer, createAdapterFactory, createOidcClientFactory, deleteOidcClientFactory, deleteOidcTokenFactory, deriveResourceMetadataUrlFromEnv, emitOidcAnalyticsEvent, getOidcScopesFromRequest, jwksKeyCollectionReference, jwksKeyConverter, jwksKeyFirestoreCollection, jwksKeyIdentity, jwksKeysWithStatusQuery, nonRetiredJwksKeysQuery, noopOidcAnalyticsService, oidcCallModelScopePreAssert, oidcCorsOriginDelegate, oidcFirestoreCollectionsFactory, oidcModelServerActions, oidcModelServerActionsFactory, oidcModuleConfigFactory, oidcModuleMetadata, resolveEffectiveSubset, rotateOidcClientSecretFactory, rotatedJwksKeysQuery, updateOidcClientFactory };
|
package/oidc/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/oidc",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.28.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server": "13.
|
|
9
|
-
"@dereekb/model": "13.
|
|
10
|
-
"@dereekb/nestjs": "13.
|
|
11
|
-
"@dereekb/rxjs": "13.
|
|
12
|
-
"@dereekb/util": "13.
|
|
13
|
-
"@dereekb/zoho": "13.
|
|
5
|
+
"@dereekb/analytics": "13.28.0",
|
|
6
|
+
"@dereekb/date": "13.28.0",
|
|
7
|
+
"@dereekb/firebase": "13.28.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.28.0",
|
|
9
|
+
"@dereekb/model": "13.28.0",
|
|
10
|
+
"@dereekb/nestjs": "13.28.0",
|
|
11
|
+
"@dereekb/rxjs": "13.28.0",
|
|
12
|
+
"@dereekb/util": "13.28.0",
|
|
13
|
+
"@dereekb/zoho": "13.28.0",
|
|
14
14
|
"@nestjs/common": "^11.1.19",
|
|
15
15
|
"@nestjs/config": "^4.0.4",
|
|
16
16
|
"express": "^5.2.1",
|
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
import { type INestApplication } from '@nestjs/common';
|
|
2
|
+
import { type Maybe } from '@dereekb/util';
|
|
3
|
+
import { type OidcCorsConfig } from '../oidc.config';
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
5
|
+
* Signature of the `origin` callback the `cors` package (used by NestJS
|
|
6
|
+
* `enableCors`) invokes per request. Returning a string sets that exact
|
|
7
|
+
* `Access-Control-Allow-Origin`; returning `false` omits the header entirely.
|
|
8
|
+
*/
|
|
9
|
+
export type OidcCorsOriginDelegate = (requestOrigin: Maybe<string>, callback: (err: Maybe<Error>, origin?: string | boolean) => void) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Builds the `cors`-package origin delegate implementing the composed OIDC CORS policy.
|
|
12
|
+
*
|
|
13
|
+
* - An allowlisted origin (`appUrl` or any {@link OidcCorsConfig.allowOrigins} entry) is
|
|
14
|
+
* reflected exactly, which pre-empts oidc-provider's own CORS handling.
|
|
15
|
+
* - Otherwise, when {@link OidcCorsConfig.clientBased} is enabled, the header is OMITTED so
|
|
16
|
+
* oidc-provider runs its `clientBasedCORS` check on client routes (`/token`) and its builtin
|
|
17
|
+
* reflect on client-less routes (discovery/JWKS).
|
|
18
|
+
* - Otherwise (client-based off), `appUrl` is returned unconditionally so oidc-provider stays
|
|
19
|
+
* pre-empted and there is never a reflect-any.
|
|
20
|
+
*
|
|
21
|
+
* Exported for unit testing without a running Nest application.
|
|
22
|
+
*
|
|
23
|
+
* @param appUrl - The authoritative frontend origin (always allowed).
|
|
24
|
+
* @param cors - The unified CORS configuration.
|
|
25
|
+
* @returns A `cors`-package origin delegate.
|
|
26
|
+
*/
|
|
27
|
+
export declare function oidcCorsOriginDelegate(appUrl: string, cors: OidcCorsConfig): OidcCorsOriginDelegate;
|
|
28
|
+
/**
|
|
29
|
+
* Enables CORS on the NestJS app for OIDC cross-origin requests originating from the frontend
|
|
30
|
+
* and any additional relying-party origins.
|
|
4
31
|
*
|
|
5
32
|
* When the OIDC issuer lives on a different origin than the frontend app (e.g. the frontend is
|
|
6
33
|
* `https://app.example.com` and the OIDC server is at `https://api.example.com`), the frontend's
|
|
@@ -8,16 +35,22 @@ import { type INestApplication } from '@nestjs/common';
|
|
|
8
35
|
* and `/interaction/{uid}/consent`. Because the POST body is `application/json`, the browser
|
|
9
36
|
* sends a CORS preflight. Without an `Access-Control-Allow-Origin` reply the preflight fails,
|
|
10
37
|
* the POST never reaches the server, and the OAuth flow stalls before `finishInteractionByUid`
|
|
11
|
-
* can run.
|
|
38
|
+
* can run. Browser-based OIDC relying parties (public PKCE clients) likewise need CORS on the
|
|
39
|
+
* discovery GET and the token POST.
|
|
40
|
+
*
|
|
41
|
+
* `appUrl` (from `FirebaseServerEnvService.appUrl`) is always allowed. Additional behavior is
|
|
42
|
+
* driven by the optional {@link OidcModuleConfig.cors} configuration:
|
|
43
|
+
* - {@link OidcCorsConfig.allowOrigins} adds an explicit allowlist of relying-party origins.
|
|
44
|
+
* - {@link OidcCorsConfig.clientBased} defers non-allowlisted origins to oidc-provider's
|
|
45
|
+
* `clientBasedCORS`, which trusts each requesting client's registered `redirect_uris`.
|
|
12
46
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* actually same-origin and CORS is a no-op.
|
|
47
|
+
* When `cors` is unset, this preserves the legacy single-origin behavior exactly:
|
|
48
|
+
* `Access-Control-Allow-Origin: <appUrl>` on every response, which pre-empts oidc-provider's
|
|
49
|
+
* own CORS handling.
|
|
17
50
|
*
|
|
18
51
|
* Credentials are intentionally NOT enabled (`Access-Control-Allow-Credentials` stays off). The
|
|
19
|
-
* `/interaction/{uid}/*` POSTs
|
|
20
|
-
* we keep the CORS surface minimal.
|
|
52
|
+
* `/interaction/{uid}/*` POSTs and the token exchange carry their bearer material in the request
|
|
53
|
+
* body, not in cookies, so we keep the CORS surface minimal.
|
|
21
54
|
*
|
|
22
55
|
* @param nestApp - The NestJS application to configure.
|
|
23
56
|
*
|
|
@@ -184,6 +184,44 @@ export declare const DEFAULT_MAX_SERVICE_TOKEN_LOGIN_DURATION_SECONDS: number;
|
|
|
184
184
|
* Default token lifetimes: 15 min access tokens, 30-day refresh tokens, 30-day sessions/grants, 60 s auth codes.
|
|
185
185
|
*/
|
|
186
186
|
export declare const DEFAULT_OIDC_TOKEN_LIFETIMES: OidcTokenLifetimes;
|
|
187
|
+
/**
|
|
188
|
+
* Unified CORS configuration for the cross-origin browser OIDC endpoints (the
|
|
189
|
+
* discovery GET and the token POST). Supports two independent, composable modes;
|
|
190
|
+
* both, either, or neither may be used.
|
|
191
|
+
*
|
|
192
|
+
* When the whole {@link OidcModuleConfig.cors} object is unset, the Express-level
|
|
193
|
+
* {@link applyOidcCorsMiddleware} preserves the pre-existing behavior: it emits
|
|
194
|
+
* `Access-Control-Allow-Origin: <appUrl>` unconditionally on every response, which
|
|
195
|
+
* pre-empts oidc-provider's own CORS handling.
|
|
196
|
+
*/
|
|
197
|
+
export interface OidcCorsConfig {
|
|
198
|
+
/**
|
|
199
|
+
* Explicit allowlist of additional browser origins (beyond `appUrl`, which is
|
|
200
|
+
* ALWAYS allowed) permitted to make cross-origin requests to the OIDC endpoints.
|
|
201
|
+
*
|
|
202
|
+
* Each entry must be a bare origin (scheme + host + optional port, no path or
|
|
203
|
+
* trailing slash), e.g. `'https://lms.app.example.com'`. When a request's `Origin`
|
|
204
|
+
* matches, the Express CORS layer reflects that exact origin
|
|
205
|
+
* (`Access-Control-Allow-Origin: <origin>`), pre-empting oidc-provider's own CORS.
|
|
206
|
+
*/
|
|
207
|
+
readonly allowOrigins?: readonly string[];
|
|
208
|
+
/**
|
|
209
|
+
* When `true`, enables oidc-provider's `clientBasedCORS` on client-assigned routes
|
|
210
|
+
* (notably `POST /token`). For a request whose `Origin` is NOT in the explicit
|
|
211
|
+
* {@link allowOrigins} list, the Express layer OMITS `Access-Control-Allow-Origin`
|
|
212
|
+
* so oidc-provider runs its per-client check: the request is allowed iff the `Origin`
|
|
213
|
+
* matches the origin of one of the requesting client's registered `redirect_uris`.
|
|
214
|
+
* Discovery and JWKS (no client context) fall back to oidc-provider's builtin
|
|
215
|
+
* reflect (public metadata).
|
|
216
|
+
*
|
|
217
|
+
* When `false`/unset, non-allowlisted origins receive `Access-Control-Allow-Origin:
|
|
218
|
+
* <appUrl>` from the Express layer (pre-empting oidc-provider), so there is no
|
|
219
|
+
* reflect-any.
|
|
220
|
+
*
|
|
221
|
+
* Defaults to `false`.
|
|
222
|
+
*/
|
|
223
|
+
readonly clientBased?: boolean;
|
|
224
|
+
}
|
|
187
225
|
/**
|
|
188
226
|
* Configuration for the OIDC module.
|
|
189
227
|
*
|
|
@@ -411,6 +449,15 @@ export declare abstract class OidcModuleConfig {
|
|
|
411
449
|
* Defaults to `false`.
|
|
412
450
|
*/
|
|
413
451
|
readonly trustProxyInNonProduction?: boolean;
|
|
452
|
+
/**
|
|
453
|
+
* Unified CORS configuration for the cross-origin browser OIDC endpoints
|
|
454
|
+
* (discovery GET, token POST). When unset, the Express CORS layer preserves the
|
|
455
|
+
* pre-existing behavior: `Access-Control-Allow-Origin: <appUrl>` on every
|
|
456
|
+
* response, which pre-empts oidc-provider's own CORS handling.
|
|
457
|
+
*
|
|
458
|
+
* @see OidcCorsConfig
|
|
459
|
+
*/
|
|
460
|
+
readonly cors?: OidcCorsConfig;
|
|
414
461
|
/**
|
|
415
462
|
* Validates that all required fields are present on the config.
|
|
416
463
|
*
|
|
@@ -138,7 +138,7 @@ export declare function oidcFirestoreCollectionsFactory(firestoreContext: Firest
|
|
|
138
138
|
* Subset of {@link OidcModuleConfig} that consumers may override via
|
|
139
139
|
* `oidcModuleMetadata`'s `config` or `configFactory`.
|
|
140
140
|
*/
|
|
141
|
-
export type OidcModuleMetadataOverrides = Partial<Pick<OidcModuleConfig, 'issuer' | 'suppressBodyParserWarning' | 'renderError' | 'protectedPaths' | 'appOAuthInteractionPath' | 'appOAuthLoginUrlPart' | 'appOAuthConsentUrlPart' | 'tokenEndpointAuthMethods' | 'registrationEnabled' | 'trustProxy' | 'trustProxyInNonProduction' | 'tokenLifetimes' | 'maxRequestedLoginDuration' | 'minRequestedLoginDuration' | 'defaultRequestedLoginDuration' | 'resourceServers' | 'resourceMetadataUrl' | 'configureMcpResourceServer'>>;
|
|
141
|
+
export type OidcModuleMetadataOverrides = Partial<Pick<OidcModuleConfig, 'issuer' | 'suppressBodyParserWarning' | 'renderError' | 'protectedPaths' | 'appOAuthInteractionPath' | 'appOAuthLoginUrlPart' | 'appOAuthConsentUrlPart' | 'tokenEndpointAuthMethods' | 'registrationEnabled' | 'trustProxy' | 'trustProxyInNonProduction' | 'tokenLifetimes' | 'maxRequestedLoginDuration' | 'minRequestedLoginDuration' | 'defaultRequestedLoginDuration' | 'resourceServers' | 'resourceMetadataUrl' | 'configureMcpResourceServer' | 'cors'>>;
|
|
142
142
|
export interface ProvideAppOidcModuleMetadataConfig extends Pick<ModuleMetadata, 'imports' | 'exports' | 'providers'> {
|
|
143
143
|
/**
|
|
144
144
|
* Module that exports the required dependencies for this module.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.28.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"exports": {
|
|
6
6
|
"./test": {
|
|
@@ -57,15 +57,15 @@
|
|
|
57
57
|
"types": "./src/index.d.ts",
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@cantoo/pdf-lib": "^2.6.5",
|
|
60
|
-
"@dereekb/analytics": "13.
|
|
61
|
-
"@dereekb/date": "13.
|
|
62
|
-
"@dereekb/dbx-core": "13.
|
|
63
|
-
"@dereekb/firebase": "13.
|
|
64
|
-
"@dereekb/model": "13.
|
|
65
|
-
"@dereekb/nestjs": "13.
|
|
66
|
-
"@dereekb/rxjs": "13.
|
|
67
|
-
"@dereekb/util": "13.
|
|
68
|
-
"@dereekb/zoho": "13.
|
|
60
|
+
"@dereekb/analytics": "13.28.0",
|
|
61
|
+
"@dereekb/date": "13.28.0",
|
|
62
|
+
"@dereekb/dbx-core": "13.28.0",
|
|
63
|
+
"@dereekb/firebase": "13.28.0",
|
|
64
|
+
"@dereekb/model": "13.28.0",
|
|
65
|
+
"@dereekb/nestjs": "13.28.0",
|
|
66
|
+
"@dereekb/rxjs": "13.28.0",
|
|
67
|
+
"@dereekb/util": "13.28.0",
|
|
68
|
+
"@dereekb/zoho": "13.28.0",
|
|
69
69
|
"@google-cloud/firestore": "^7.11.6",
|
|
70
70
|
"@google-cloud/storage": "^7.19.0",
|
|
71
71
|
"@modelcontextprotocol/sdk": "1.29.0",
|
package/test/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/test",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.28.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server": "13.
|
|
9
|
-
"@dereekb/firebase-server/oidc": "13.
|
|
10
|
-
"@dereekb/model": "13.
|
|
11
|
-
"@dereekb/nestjs": "13.
|
|
12
|
-
"@dereekb/rxjs": "13.
|
|
13
|
-
"@dereekb/util": "13.
|
|
5
|
+
"@dereekb/analytics": "13.28.0",
|
|
6
|
+
"@dereekb/date": "13.28.0",
|
|
7
|
+
"@dereekb/firebase": "13.28.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.28.0",
|
|
9
|
+
"@dereekb/firebase-server/oidc": "13.28.0",
|
|
10
|
+
"@dereekb/model": "13.28.0",
|
|
11
|
+
"@dereekb/nestjs": "13.28.0",
|
|
12
|
+
"@dereekb/rxjs": "13.28.0",
|
|
13
|
+
"@dereekb/util": "13.28.0",
|
|
14
14
|
"@google-cloud/firestore": "^7.11.6",
|
|
15
15
|
"@google-cloud/storage": "^7.19.0",
|
|
16
16
|
"@nestjs/common": "^11.1.19",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"supertest": "^7.2.2"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@dereekb/nestjs": "13.
|
|
26
|
+
"@dereekb/nestjs": "13.28.0"
|
|
27
27
|
},
|
|
28
28
|
"exports": {
|
|
29
29
|
"./package.json": "./package.json",
|
package/twilio/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/twilio",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.28.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/date": "13.
|
|
6
|
-
"@dereekb/firebase": "13.
|
|
7
|
-
"@dereekb/firebase-server": "13.
|
|
8
|
-
"@dereekb/model": "13.
|
|
9
|
-
"@dereekb/nestjs": "13.
|
|
10
|
-
"@dereekb/rxjs": "13.
|
|
11
|
-
"@dereekb/util": "13.
|
|
5
|
+
"@dereekb/date": "13.28.0",
|
|
6
|
+
"@dereekb/firebase": "13.28.0",
|
|
7
|
+
"@dereekb/firebase-server": "13.28.0",
|
|
8
|
+
"@dereekb/model": "13.28.0",
|
|
9
|
+
"@dereekb/nestjs": "13.28.0",
|
|
10
|
+
"@dereekb/rxjs": "13.28.0",
|
|
11
|
+
"@dereekb/util": "13.28.0"
|
|
12
12
|
},
|
|
13
13
|
"exports": {
|
|
14
14
|
"./package.json": "./package.json",
|
package/zoho/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/zoho",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.28.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/model": "13.
|
|
8
|
-
"@dereekb/nestjs": "13.
|
|
9
|
-
"@dereekb/rxjs": "13.
|
|
10
|
-
"@dereekb/firebase": "13.
|
|
11
|
-
"@dereekb/util": "13.
|
|
12
|
-
"@dereekb/zoho": "13.
|
|
5
|
+
"@dereekb/analytics": "13.28.0",
|
|
6
|
+
"@dereekb/date": "13.28.0",
|
|
7
|
+
"@dereekb/model": "13.28.0",
|
|
8
|
+
"@dereekb/nestjs": "13.28.0",
|
|
9
|
+
"@dereekb/rxjs": "13.28.0",
|
|
10
|
+
"@dereekb/firebase": "13.28.0",
|
|
11
|
+
"@dereekb/util": "13.28.0",
|
|
12
|
+
"@dereekb/zoho": "13.28.0"
|
|
13
13
|
},
|
|
14
14
|
"exports": {
|
|
15
15
|
"./package.json": "./package.json",
|