@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.
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server/mailgun",
3
- "version": "13.27.1",
3
+ "version": "13.28.0",
4
4
  "peerDependencies": {
5
- "@dereekb/analytics": "13.27.1",
6
- "@dereekb/firebase": "13.27.1",
7
- "@dereekb/firebase-server": "13.27.1",
8
- "@dereekb/date": "13.27.1",
9
- "@dereekb/nestjs": "13.27.1",
10
- "@dereekb/model": "13.27.1",
11
- "@dereekb/rxjs": "13.27.1",
12
- "@dereekb/util": "13.27.1"
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.27.1",
3
+ "version": "13.28.0",
4
4
  "peerDependencies": {
5
- "@dereekb/analytics": "13.27.1",
6
- "@dereekb/date": "13.27.1",
7
- "@dereekb/firebase": "13.27.1",
8
- "@dereekb/firebase-server": "13.27.1",
9
- "@dereekb/firebase-server/oidc": "13.27.1",
10
- "@dereekb/model": "13.27.1",
11
- "@dereekb/nestjs": "13.27.1",
12
- "@dereekb/rxjs": "13.27.1",
13
- "@dereekb/util": "13.27.1",
14
- "@dereekb/zoho": "13.27.1",
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",
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server/model",
3
- "version": "13.27.1",
3
+ "version": "13.28.0",
4
4
  "peerDependencies": {
5
- "@dereekb/analytics": "13.27.1",
6
- "@dereekb/date": "13.27.1",
7
- "@dereekb/firebase": "13.27.1",
8
- "@dereekb/firebase-server": "13.27.1",
9
- "@dereekb/model": "13.27.1",
10
- "@dereekb/nestjs": "13.27.1",
11
- "@dereekb/rxjs": "13.27.1",
12
- "@dereekb/util": "13.27.1",
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$5(arr, len) {
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$5(arr) {
3234
- if (Array.isArray(arr)) return _array_like_to_array$5(arr);
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$5(iter) {
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$5() {
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$5(arr) {
3274
- return _array_without_holes$5(arr) || _iterable_to_array$5(arr) || _unsupported_iterable_to_array$5(arr) || _non_iterable_spread$5();
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$5(o, minLen) {
3284
+ function _unsupported_iterable_to_array$6(o, minLen) {
3277
3285
  if (!o) return;
3278
- if (typeof o === "string") return _array_like_to_array$5(o, minLen);
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$5(o, minLen);
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$5(OIDC_ENCRYPTED_PAYLOAD_FIELDS)
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$4(arr, len) {
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$4(arr) {
3352
- if (Array.isArray(arr)) return _array_like_to_array$4(arr);
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$4(iter) {
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$4() {
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$4(arr) {
3392
- return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$4(arr) || _non_iterable_spread$4();
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$4(o, minLen) {
3402
+ function _unsupported_iterable_to_array$5(o, minLen) {
3395
3403
  if (!o) return;
3396
- if (typeof o === "string") return _array_like_to_array$4(o, minLen);
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$4(o, minLen);
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$4(DEFAULT_OIDC_TOKEN_ENDPOINT_AUTH_METHODS);
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$4(providerConfig.responseTypes),
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$4(providerConfig.grantTypes),
3515
- subject_types_supported: _to_consumable_array$4(DEFAULT_OIDC_SUBJECT_TYPES),
3516
- id_token_signing_alg_values_supported: _to_consumable_array$4(DEFAULT_OIDC_ID_TOKEN_SIGNING_ALG_VALUES),
3517
- token_endpoint_auth_methods_supported: _to_consumable_array$4(this.tokenEndpointAuthMethodsSupported),
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$4(DEFAULT_OIDC_CODE_CHALLENGE_METHODS)
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$3(arr, len) {
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$3(arr) {
3539
- if (Array.isArray(arr)) return _array_like_to_array$3(arr);
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$3(iter) {
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$3() {
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$3(arr) {
3678
- return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
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$3(o, minLen) {
3688
+ function _unsupported_iterable_to_array$4(o, minLen) {
3681
3689
  if (!o) return;
3682
- if (typeof o === "string") return _array_like_to_array$3(o, minLen);
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$3(o, minLen);
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$3(providerConfig.responseTypes),
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
- * Origin is sourced from `FirebaseServerEnvService.appUrl`, which is the authoritative frontend
4878
- * origin per environment. Single-origin deployments (e.g. local dev where the frontend and the
4879
- * OIDC server share `http://localhost:9010`) still benefit: their cross-origin requests are
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 carry the Firebase ID token in the JSON body, not in cookies, so
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 origin = envService.appUrl;
4901
- if (!origin) {
4988
+ var appUrl = envService.appUrl;
4989
+ if (!appUrl) {
4902
4990
  return;
4903
4991
  }
4904
- nestApp.enableCors({
4905
- origin: origin,
4906
- methods: [
4907
- 'GET',
4908
- 'POST',
4909
- 'OPTIONS'
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$5(arr, len) {
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$5(arr) {
3232
- if (Array.isArray(arr)) return _array_like_to_array$5(arr);
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$5(iter) {
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$5() {
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$5(arr) {
3272
- return _array_without_holes$5(arr) || _iterable_to_array$5(arr) || _unsupported_iterable_to_array$5(arr) || _non_iterable_spread$5();
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$5(o, minLen) {
3282
+ function _unsupported_iterable_to_array$6(o, minLen) {
3275
3283
  if (!o) return;
3276
- if (typeof o === "string") return _array_like_to_array$5(o, minLen);
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$5(o, minLen);
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$5(OIDC_ENCRYPTED_PAYLOAD_FIELDS)
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$4(arr, len) {
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$4(arr) {
3350
- if (Array.isArray(arr)) return _array_like_to_array$4(arr);
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$4(iter) {
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$4() {
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$4(arr) {
3390
- return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$4(arr) || _non_iterable_spread$4();
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$4(o, minLen) {
3400
+ function _unsupported_iterable_to_array$5(o, minLen) {
3393
3401
  if (!o) return;
3394
- if (typeof o === "string") return _array_like_to_array$4(o, minLen);
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$4(o, minLen);
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$4(DEFAULT_OIDC_TOKEN_ENDPOINT_AUTH_METHODS);
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$4(providerConfig.responseTypes),
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$4(providerConfig.grantTypes),
3513
- subject_types_supported: _to_consumable_array$4(DEFAULT_OIDC_SUBJECT_TYPES),
3514
- id_token_signing_alg_values_supported: _to_consumable_array$4(DEFAULT_OIDC_ID_TOKEN_SIGNING_ALG_VALUES),
3515
- token_endpoint_auth_methods_supported: _to_consumable_array$4(this.tokenEndpointAuthMethodsSupported),
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$4(DEFAULT_OIDC_CODE_CHALLENGE_METHODS)
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$3(arr, len) {
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$3(arr) {
3537
- if (Array.isArray(arr)) return _array_like_to_array$3(arr);
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$3(iter) {
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$3() {
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$3(arr) {
3676
- return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
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$3(o, minLen) {
3686
+ function _unsupported_iterable_to_array$4(o, minLen) {
3679
3687
  if (!o) return;
3680
- if (typeof o === "string") return _array_like_to_array$3(o, minLen);
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$3(o, minLen);
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$3(providerConfig.responseTypes),
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
- * Origin is sourced from `FirebaseServerEnvService.appUrl`, which is the authoritative frontend
4876
- * origin per environment. Single-origin deployments (e.g. local dev where the frontend and the
4877
- * OIDC server share `http://localhost:9010`) still benefit: their cross-origin requests are
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 carry the Firebase ID token in the JSON body, not in cookies, so
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 origin = envService.appUrl;
4899
- if (!origin) {
4986
+ var appUrl = envService.appUrl;
4987
+ if (!appUrl) {
4900
4988
  return;
4901
4989
  }
4902
- nestApp.enableCors({
4903
- origin: origin,
4904
- methods: [
4905
- 'GET',
4906
- 'POST',
4907
- 'OPTIONS'
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.27.1",
3
+ "version": "13.28.0",
4
4
  "peerDependencies": {
5
- "@dereekb/analytics": "13.27.1",
6
- "@dereekb/date": "13.27.1",
7
- "@dereekb/firebase": "13.27.1",
8
- "@dereekb/firebase-server": "13.27.1",
9
- "@dereekb/model": "13.27.1",
10
- "@dereekb/nestjs": "13.27.1",
11
- "@dereekb/rxjs": "13.27.1",
12
- "@dereekb/util": "13.27.1",
13
- "@dereekb/zoho": "13.27.1",
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
- * Enables CORS on the NestJS app for OIDC cross-origin requests originating from the frontend.
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
- * Origin is sourced from `FirebaseServerEnvService.appUrl`, which is the authoritative frontend
14
- * origin per environment. Single-origin deployments (e.g. local dev where the frontend and the
15
- * OIDC server share `http://localhost:9010`) still benefit: their cross-origin requests are
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 carry the Firebase ID token in the JSON body, not in cookies, so
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.27.1",
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.27.1",
61
- "@dereekb/date": "13.27.1",
62
- "@dereekb/dbx-core": "13.27.1",
63
- "@dereekb/firebase": "13.27.1",
64
- "@dereekb/model": "13.27.1",
65
- "@dereekb/nestjs": "13.27.1",
66
- "@dereekb/rxjs": "13.27.1",
67
- "@dereekb/util": "13.27.1",
68
- "@dereekb/zoho": "13.27.1",
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.27.1",
3
+ "version": "13.28.0",
4
4
  "peerDependencies": {
5
- "@dereekb/analytics": "13.27.1",
6
- "@dereekb/date": "13.27.1",
7
- "@dereekb/firebase": "13.27.1",
8
- "@dereekb/firebase-server": "13.27.1",
9
- "@dereekb/firebase-server/oidc": "13.27.1",
10
- "@dereekb/model": "13.27.1",
11
- "@dereekb/nestjs": "13.27.1",
12
- "@dereekb/rxjs": "13.27.1",
13
- "@dereekb/util": "13.27.1",
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.27.1"
26
+ "@dereekb/nestjs": "13.28.0"
27
27
  },
28
28
  "exports": {
29
29
  "./package.json": "./package.json",
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server/twilio",
3
- "version": "13.27.1",
3
+ "version": "13.28.0",
4
4
  "peerDependencies": {
5
- "@dereekb/date": "13.27.1",
6
- "@dereekb/firebase": "13.27.1",
7
- "@dereekb/firebase-server": "13.27.1",
8
- "@dereekb/model": "13.27.1",
9
- "@dereekb/nestjs": "13.27.1",
10
- "@dereekb/rxjs": "13.27.1",
11
- "@dereekb/util": "13.27.1"
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.27.1",
3
+ "version": "13.28.0",
4
4
  "peerDependencies": {
5
- "@dereekb/analytics": "13.27.1",
6
- "@dereekb/date": "13.27.1",
7
- "@dereekb/model": "13.27.1",
8
- "@dereekb/nestjs": "13.27.1",
9
- "@dereekb/rxjs": "13.27.1",
10
- "@dereekb/firebase": "13.27.1",
11
- "@dereekb/util": "13.27.1",
12
- "@dereekb/zoho": "13.27.1"
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",