@dereekb/firebase-server 13.11.17 → 13.12.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.
Files changed (67) hide show
  1. package/index.cjs.js +218 -31
  2. package/index.esm.js +217 -34
  3. package/mailgun/package.json +9 -9
  4. package/mcp/index.cjs.default.js +1 -0
  5. package/mcp/index.cjs.js +3646 -0
  6. package/mcp/index.cjs.mjs +2 -0
  7. package/mcp/index.d.ts +1 -0
  8. package/mcp/index.esm.js +3609 -0
  9. package/mcp/package.json +33 -0
  10. package/mcp/src/index.d.ts +1 -0
  11. package/mcp/src/lib/controller/index.d.ts +2 -0
  12. package/mcp/src/lib/controller/mcp.controller.d.ts +19 -0
  13. package/mcp/src/lib/controller/mcp.wellknown.controller.d.ts +25 -0
  14. package/mcp/src/lib/index.d.ts +5 -0
  15. package/mcp/src/lib/mcp.config.d.ts +100 -0
  16. package/mcp/src/lib/mcp.module.d.ts +49 -0
  17. package/mcp/src/lib/service/index.d.ts +8 -0
  18. package/mcp/src/lib/service/mcp.manifest.d.ts +150 -0
  19. package/mcp/src/lib/service/mcp.response-formatter.d.ts +36 -0
  20. package/mcp/src/lib/service/mcp.server.factory.d.ts +124 -0
  21. package/mcp/src/lib/service/mcp.tool-generator.d.ts +235 -0
  22. package/mcp/src/lib/service/mcp.visibility.d.ts +99 -0
  23. package/mcp/src/lib/service/tools/mcp.tool.model-decode.d.ts +87 -0
  24. package/mcp/src/lib/service/tools/mcp.tool.model-get.d.ts +81 -0
  25. package/mcp/src/lib/service/tools/mcp.tool.model-info.d.ts +84 -0
  26. package/mcp/src/lib/service/tools/mcp.tool.whoami.d.ts +72 -0
  27. package/mcp/src/lib/transport/index.d.ts +1 -0
  28. package/mcp/src/lib/transport/streamable-http.transport.d.ts +21 -0
  29. package/model/index.cjs.js +639 -266
  30. package/model/index.esm.js +640 -270
  31. package/model/package.json +9 -9
  32. package/model/src/lib/storagefile/extension/compress.pdf.d.ts +29 -1
  33. package/model/src/lib/storagefile/index.d.ts +1 -0
  34. package/model/src/lib/storagefile/storagefile.action.server.d.ts +29 -2
  35. package/model/src/lib/storagefile/storagefile.mcp.d.ts +32 -0
  36. package/model/src/lib/storagefile/storagefile.module.d.ts +20 -3
  37. package/oidc/index.cjs.js +322 -147
  38. package/oidc/index.esm.js +321 -148
  39. package/oidc/package.json +10 -10
  40. package/oidc/src/lib/controller/oidc.wellknown.controller.d.ts +6 -15
  41. package/oidc/src/lib/middleware/oauth-auth.middleware.d.ts +22 -2
  42. package/oidc/src/lib/middleware/oauth-auth.module.d.ts +57 -0
  43. package/oidc/src/lib/oidc.config.d.ts +73 -0
  44. package/oidc/src/lib/oidc.module.d.ts +44 -2
  45. package/package.json +16 -10
  46. package/src/lib/auth/auth.service.d.ts +16 -1
  47. package/src/lib/auth/auth.service.error.util.d.ts +24 -5
  48. package/src/lib/env/env.config.d.ts +16 -0
  49. package/src/lib/env/env.service.d.ts +9 -0
  50. package/src/lib/nest/controller/model/model.api.get.service.d.ts +35 -1
  51. package/src/lib/nest/env/env.service.d.ts +1 -0
  52. package/src/lib/nest/model/api.details.d.ts +116 -5
  53. package/src/lib/nest/model/crud.assert.function.d.ts +1 -1
  54. package/src/lib/nest/model/index.d.ts +1 -0
  55. package/src/lib/nest/model/invoke.model.function.d.ts +89 -0
  56. package/test/package.json +11 -11
  57. package/twilio/LICENSE +21 -0
  58. package/twilio/index.cjs.default.js +1 -0
  59. package/twilio/index.cjs.js +404 -0
  60. package/twilio/index.cjs.mjs +2 -0
  61. package/twilio/index.d.ts +1 -0
  62. package/twilio/index.esm.js +398 -0
  63. package/twilio/package.json +25 -0
  64. package/twilio/src/index.d.ts +1 -0
  65. package/twilio/src/lib/index.d.ts +1 -0
  66. package/twilio/src/lib/notification.send.service.twilio.d.ts +148 -0
  67. package/zoho/package.json +9 -9
package/oidc/index.esm.js CHANGED
@@ -181,6 +181,46 @@ function _define_property$f(obj, key, value) {
181
181
  * since those are typically protected by AppCheck.
182
182
  */ _define_property$f(this, "protectedPaths", void 0);
183
183
  /**
184
+ * Map of recognized OAuth resource indicator URLs (RFC 8707) to their
185
+ * {@link OidcResourceServerInfo}. When non-empty, oidc-provider's
186
+ * `features.resourceIndicators.getResourceServerInfo` is wired to look up
187
+ * each requested `resource` parameter against this map and reject unknown
188
+ * resources with `invalid_target`.
189
+ *
190
+ * Required for OAuth-aware MCP clients (Claude, mcp-inspector) — they pass
191
+ * the MCP URL from the protected-resource discovery doc as the `resource`
192
+ * parameter on `/authorize` and `/token`, and oidc-provider rejects every
193
+ * such request with `invalid_target` unless that URL is recognized here.
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * resourceServers: {
198
+ * 'http://localhost:9902/dereekb-components/us-central1/api/mcp': {
199
+ * scope: 'openid profile email offline_access demo model.create model.read model.update model.delete model.query model.invoke',
200
+ * audience: 'http://localhost:9902/dereekb-components/us-central1/api/mcp'
201
+ * }
202
+ * }
203
+ * ```
204
+ */ _define_property$f(this, "resourceServers", void 0);
205
+ /**
206
+ * Absolute URL of the OAuth 2.0 Protected Resource Metadata document
207
+ * (RFC 9728) for the resources guarded by {@link protectedPaths}.
208
+ *
209
+ * When set, the OIDC bearer middleware emits
210
+ * `WWW-Authenticate: Bearer resource_metadata="<url>", error="invalid_token"`
211
+ * on 401 responses, so OAuth-aware clients (Claude, mcp-inspector) can
212
+ * locate the discovery doc without relying on RFC 9728's origin-rooted
213
+ * path-walkback rule — which only works when the resource server is
214
+ * actually mounted at the origin root.
215
+ *
216
+ * Typically derived from `appMcpUrl` (or the equivalent protected-resource
217
+ * URL) — e.g. for `appMcpUrl = https://api.example.com/mcp`, the value is
218
+ * `https://api.example.com/.well-known/oauth-protected-resource`.
219
+ *
220
+ * @example
221
+ * resourceMetadataUrl: 'http://localhost:9902/dereekb-components/us-central1/api/.well-known/oauth-protected-resource'
222
+ */ _define_property$f(this, "resourceMetadataUrl", void 0);
223
+ /**
184
224
  * Supported token endpoint authentication methods.
185
225
  *
186
226
  * Overrides the default methods (`client_secret_post`, `client_secret_basic`)
@@ -3861,6 +3901,41 @@ function _ts_generator$5(thisArg, body) {
3861
3901
  },
3862
3902
  registrationManagement: {
3863
3903
  enabled: this.providerConfigService.oidcRegistrationRouteEnabled
3904
+ },
3905
+ resourceIndicators: {
3906
+ enabled: true,
3907
+ // useGrantedResource: return true so the token endpoint will bind tokens to a previously
3908
+ // granted resource without requiring the client to re-send the `resource` parameter on each
3909
+ // refresh — Claude and other MCP clients send `resource` on `/authorize` but not on
3910
+ // `/token` refresh.
3911
+ useGrantedResource: function useGrantedResource() {
3912
+ return true;
3913
+ },
3914
+ getResourceServerInfo: function getResourceServerInfo(_ctx, resourceIndicator) {
3915
+ return _async_to_generator$5(function() {
3916
+ var _config_resourceServers, info;
3917
+ return _ts_generator$5(this, function(_state) {
3918
+ info = (_config_resourceServers = config.resourceServers) === null || _config_resourceServers === void 0 ? void 0 : _config_resourceServers[resourceIndicator];
3919
+ if (!info) {
3920
+ throw new errors.InvalidTarget("Unrecognized resource indicator: ".concat(resourceIndicator));
3921
+ }
3922
+ return [
3923
+ 2,
3924
+ _object_spread$2({
3925
+ scope: info.scope
3926
+ }, info.audience === undefined ? {} : {
3927
+ audience: info.audience
3928
+ }, info.accessTokenTTL === undefined ? {} : {
3929
+ accessTokenTTL: info.accessTokenTTL
3930
+ }, info.accessTokenFormat === undefined ? {
3931
+ accessTokenFormat: 'opaque'
3932
+ } : {
3933
+ accessTokenFormat: info.accessTokenFormat
3934
+ })
3935
+ ];
3936
+ });
3937
+ })();
3938
+ }
3864
3939
  }
3865
3940
  },
3866
3941
  extraParams: [
@@ -4096,6 +4171,175 @@ OidcService = __decorate([
4096
4171
  __param(5, Inject(OidcEncryptionService))
4097
4172
  ], OidcService);
4098
4173
 
4174
+ function _class_call_check$5(instance, Constructor) {
4175
+ if (!(instance instanceof Constructor)) {
4176
+ throw new TypeError("Cannot call a class as a function");
4177
+ }
4178
+ }
4179
+ function _define_property$6(obj, key, value) {
4180
+ if (key in obj) {
4181
+ Object.defineProperty(obj, key, {
4182
+ value: value,
4183
+ enumerable: true,
4184
+ configurable: true,
4185
+ writable: true
4186
+ });
4187
+ } else {
4188
+ obj[key] = value;
4189
+ }
4190
+ return obj;
4191
+ }
4192
+ // MARK: Config
4193
+ /**
4194
+ * Configuration for `OidcAuthBearerTokenMiddleware` route protection.
4195
+ *
4196
+ * Works in reverse of `FirebaseAppCheckMiddlewareConfig`: instead of protecting
4197
+ * all routes and ignoring some, this only protects explicitly specified paths.
4198
+ * Routes under the global API prefix (protected by AppCheck) are excluded.
4199
+ *
4200
+ * @example
4201
+ * Manual configuration without going through `oidcModuleMetadata`:
4202
+ * ```ts
4203
+ * @Module({
4204
+ * providers: [
4205
+ * {
4206
+ * provide: OidcAuthMiddlewareConfig,
4207
+ * useValue: {
4208
+ * protectedPaths: ['/api/model', '/mcp'],
4209
+ * resourceMetadataUrl: 'https://api.example.com/.well-known/oauth-protected-resource'
4210
+ * } satisfies OidcAuthMiddlewareConfig
4211
+ * }
4212
+ * ]
4213
+ * })
4214
+ * export class MyApiModule {}
4215
+ * ```
4216
+ */ var OidcAuthMiddlewareConfig = function OidcAuthMiddlewareConfig() {
4217
+ _class_call_check$5(this, OidcAuthMiddlewareConfig);
4218
+ /**
4219
+ * Path prefixes that require OAuth bearer token verification.
4220
+ *
4221
+ * Only requests matching one of these prefixes will be checked.
4222
+ * Paths under the global API route prefix should not be included
4223
+ * since those are protected by AppCheck.
4224
+ */ _define_property$6(this, "protectedPaths", void 0);
4225
+ /**
4226
+ * Absolute URL of the OAuth 2.0 Protected Resource Metadata document
4227
+ * (RFC 9728). When set, included as the `resource_metadata` parameter
4228
+ * of the `WWW-Authenticate: Bearer` header on 401 responses so OAuth
4229
+ * clients can locate the discovery doc explicitly rather than relying on
4230
+ * origin-rooted path-walkback (which fails when the function isn't
4231
+ * mounted at `/` — e.g. behind the Firebase Functions emulator URL prefix).
4232
+ */ _define_property$6(this, "resourceMetadataUrl", void 0);
4233
+ };
4234
+ // MARK: WWW-Authenticate
4235
+ /**
4236
+ * Builds the `WWW-Authenticate: Bearer ...` challenge string emitted on 401
4237
+ * responses to OAuth-protected routes.
4238
+ *
4239
+ * Per RFC 6750 §3 / RFC 7235, auth-params are comma-separated (optionally
4240
+ * with surrounding whitespace). When `resourceMetadataUrl` is provided, it's
4241
+ * included as the RFC 9728 `resource_metadata` hint so clients can locate the
4242
+ * discovery doc directly instead of relying on origin-rooted path-walkback.
4243
+ *
4244
+ * @param error - The RFC 6750 `error` token (e.g. `invalid_token`, `invalid_request`).
4245
+ * @param resourceMetadataUrl - Optional protected-resource metadata URL.
4246
+ * @returns Header value, e.g. `Bearer resource_metadata="…", error="invalid_token"`.
4247
+ */ function buildBearerChallenge(error, resourceMetadataUrl) {
4248
+ var params = [];
4249
+ if (resourceMetadataUrl) {
4250
+ params.push('resource_metadata="'.concat(resourceMetadataUrl, '"'));
4251
+ }
4252
+ params.push('error="'.concat(error, '"'));
4253
+ return "Bearer ".concat(params.join(', '));
4254
+ }
4255
+ // MARK: Module
4256
+ var _logger = new Logger('applyOidcAuthMiddleware');
4257
+ // MARK: Express-Level Helper
4258
+ /**
4259
+ * Applies OAuth bearer token verification as global Express middleware on
4260
+ * the given NestJS application.
4261
+ *
4262
+ * Resolves `OidcService` and `OidcAuthMiddlewareConfig` from the app's DI container,
4263
+ * then registers an Express middleware that verifies bearer tokens for the configured
4264
+ * protected paths and attaches auth data to `req.auth`.
4265
+ *
4266
+ * This is an alternative to {@link ConfigureOidcAuthMiddlewareModule} for cases where
4267
+ * NestJS module scoping makes the module approach impractical.
4268
+ *
4269
+ * @param nestApp - The NestJS application instance used to resolve dependencies and register the middleware.
4270
+ *
4271
+ * @example
4272
+ * ```ts
4273
+ * export const APP_NEST_SERVER_CONFIG: NestServerInstanceConfig<AppModule> = {
4274
+ * moduleClass: AppModule,
4275
+ * configureNestServerInstance: (nestApp) => {
4276
+ * applyOidcAuthMiddleware(nestApp);
4277
+ * }
4278
+ * };
4279
+ * ```
4280
+ *
4281
+ * Pair with `oidcModuleMetadata` (passing `resourceMetadataUrl` on `config`) so
4282
+ * the 401 emits an RFC 9728 `WWW-Authenticate: Bearer resource_metadata="..."`
4283
+ * header — required when the resource server isn't mounted at the origin root
4284
+ * (e.g. behind the Firebase Functions emulator URL prefix), since RFC 9728's
4285
+ * default path-walkback lands at a 404 in that case.
4286
+ *
4287
+ * @example
4288
+ * ```ts
4289
+ * oidcModuleMetadata({
4290
+ * dependencyModule: MyOidcDependencyModule,
4291
+ * config: {
4292
+ * protectedPaths: ['/api/model', '/mcp'],
4293
+ * resourceMetadataUrl: 'http://localhost:9902/dereekb-components/us-central1/api/.well-known/oauth-protected-resource'
4294
+ * }
4295
+ * })
4296
+ * ```
4297
+ */ function applyOidcAuthMiddleware(nestApp) {
4298
+ var _ref;
4299
+ var oidcService = nestApp.get(OidcService);
4300
+ var config = nestApp.get(OidcAuthMiddlewareConfig);
4301
+ var protectedPaths = (_ref = config === null || config === void 0 ? void 0 : config.protectedPaths) !== null && _ref !== void 0 ? _ref : [];
4302
+ var resourceMetadataUrl = config === null || config === void 0 ? void 0 : config.resourceMetadataUrl;
4303
+ if (protectedPaths.length === 0) {
4304
+ return;
4305
+ }
4306
+ var logger = new Logger('OidcAuthMiddleware');
4307
+ var respond401 = function respond401(res, error, message) {
4308
+ res.setHeader('WWW-Authenticate', buildBearerChallenge(error, resourceMetadataUrl));
4309
+ res.status(401).json({
4310
+ statusCode: 401,
4311
+ message: message
4312
+ });
4313
+ };
4314
+ nestApp.use(function(req, res, next) {
4315
+ var isProtected = protectedPaths.some(function(prefix) {
4316
+ return req.path.startsWith(prefix);
4317
+ });
4318
+ if (isProtected) {
4319
+ var authHeader = req.headers.authorization;
4320
+ if (authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith('Bearer ')) {
4321
+ var token = authHeader.slice(7);
4322
+ oidcService.verifyAccessToken(token).then(function(oauthAuth) {
4323
+ if (oauthAuth) {
4324
+ req.auth = oauthAuth;
4325
+ next();
4326
+ } else {
4327
+ respond401(res, 'invalid_token', 'Invalid or expired access token');
4328
+ }
4329
+ }).catch(function(err) {
4330
+ logger.error('Bearer token verification failed', err);
4331
+ respond401(res, 'invalid_token', 'Token verification failed');
4332
+ });
4333
+ } else {
4334
+ respond401(res, 'invalid_request', 'Missing or invalid Authorization header');
4335
+ }
4336
+ } else {
4337
+ next();
4338
+ }
4339
+ });
4340
+ _logger.debug("Applied OAuth bearer token middleware for paths: ".concat(protectedPaths.join(', ')));
4341
+ }
4342
+
4099
4343
  function asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, key, arg) {
4100
4344
  try {
4101
4345
  var info = gen[key](arg);
@@ -4125,7 +4369,7 @@ function _async_to_generator$4(fn) {
4125
4369
  });
4126
4370
  };
4127
4371
  }
4128
- function _class_call_check$5(instance, Constructor) {
4372
+ function _class_call_check$4(instance, Constructor) {
4129
4373
  if (!(instance instanceof Constructor)) {
4130
4374
  throw new TypeError("Cannot call a class as a function");
4131
4375
  }
@@ -4143,7 +4387,7 @@ function _create_class$4(Constructor, protoProps, staticProps) {
4143
4387
  if (protoProps) _defineProperties$4(Constructor.prototype, protoProps);
4144
4388
  return Constructor;
4145
4389
  }
4146
- function _define_property$6(obj, key, value) {
4390
+ function _define_property$5(obj, key, value) {
4147
4391
  if (key in obj) {
4148
4392
  Object.defineProperty(obj, key, {
4149
4393
  value: value,
@@ -4271,20 +4515,39 @@ function _ts_generator$4(thisArg, body) {
4271
4515
  * verifies it via the provider's AccessToken model, and attaches the
4272
4516
  * auth context to the request as {@link OidcAuthData}.
4273
4517
  *
4518
+ * On 401, emits an RFC 9728 `WWW-Authenticate: Bearer ...` header — including
4519
+ * the `resource_metadata` discovery URL when `OidcAuthMiddlewareConfig.resourceMetadataUrl`
4520
+ * is configured — so OAuth-aware clients (Claude, mcp-inspector, etc.) can
4521
+ * locate the discovery doc explicitly.
4522
+ *
4274
4523
  * Applied to routes via {@link ConfigureOidcAuthMiddlewareModule}.
4275
4524
  *
4525
+ * @example
4526
+ * Wired automatically when `protectedPaths` is set on `oidcModuleMetadata`:
4527
+ * ```ts
4528
+ * oidcModuleMetadata({
4529
+ * dependencyModule: MyOidcDependencyModule,
4530
+ * config: {
4531
+ * protectedPaths: ['/api/model', '/mcp'],
4532
+ * resourceMetadataUrl: 'https://api.example.com/.well-known/oauth-protected-resource'
4533
+ * }
4534
+ * })
4535
+ * ```
4536
+ *
4276
4537
  * @throws {UnauthorizedException} When the Authorization header is missing, malformed, or the token is invalid/expired.
4277
4538
  */ var OidcAuthBearerTokenMiddleware = /*#__PURE__*/ function() {
4278
- function OidcAuthBearerTokenMiddleware(oidcService) {
4279
- _class_call_check$5(this, OidcAuthBearerTokenMiddleware);
4280
- _define_property$6(this, "oidcService", void 0);
4281
- _define_property$6(this, "logger", new Logger('OidcAuthBearerTokenMiddleware'));
4539
+ function OidcAuthBearerTokenMiddleware(oidcService, config) {
4540
+ _class_call_check$4(this, OidcAuthBearerTokenMiddleware);
4541
+ _define_property$5(this, "oidcService", void 0);
4542
+ _define_property$5(this, "config", void 0);
4543
+ _define_property$5(this, "logger", new Logger('OidcAuthBearerTokenMiddleware'));
4282
4544
  this.oidcService = oidcService;
4545
+ this.config = config;
4283
4546
  }
4284
4547
  _create_class$4(OidcAuthBearerTokenMiddleware, [
4285
4548
  {
4286
4549
  key: "use",
4287
- value: function use(req, _res, next) {
4550
+ value: function use(req, res, next) {
4288
4551
  return _async_to_generator$4(function() {
4289
4552
  var authHeader, token, oauthAuth, err;
4290
4553
  return _ts_generator$4(this, function(_state) {
@@ -4292,6 +4555,7 @@ function _ts_generator$4(thisArg, body) {
4292
4555
  case 0:
4293
4556
  authHeader = req.headers.authorization;
4294
4557
  if (!(authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith('Bearer '))) {
4558
+ this._setWwwAuthenticate(res, 'invalid_request');
4295
4559
  throw new UnauthorizedException('Missing or invalid Authorization header');
4296
4560
  }
4297
4561
  token = authHeader.slice(7);
@@ -4310,6 +4574,7 @@ function _ts_generator$4(thisArg, body) {
4310
4574
  case 2:
4311
4575
  oauthAuth = _state.sent();
4312
4576
  if (!oauthAuth) {
4577
+ this._setWwwAuthenticate(res, 'invalid_token');
4313
4578
  throw new UnauthorizedException('Invalid or expired access token');
4314
4579
  }
4315
4580
  req.auth = oauthAuth;
@@ -4324,6 +4589,7 @@ function _ts_generator$4(thisArg, body) {
4324
4589
  throw err;
4325
4590
  }
4326
4591
  this.logger.error('Bearer token verification failed', err);
4592
+ this._setWwwAuthenticate(res, 'invalid_token');
4327
4593
  throw new UnauthorizedException('Token verification failed');
4328
4594
  case 4:
4329
4595
  return [
@@ -4333,122 +4599,23 @@ function _ts_generator$4(thisArg, body) {
4333
4599
  });
4334
4600
  }).call(this);
4335
4601
  }
4602
+ },
4603
+ {
4604
+ key: "_setWwwAuthenticate",
4605
+ value: function _setWwwAuthenticate(res, error) {
4606
+ var _this_config;
4607
+ res.setHeader('WWW-Authenticate', buildBearerChallenge(error, (_this_config = this.config) === null || _this_config === void 0 ? void 0 : _this_config.resourceMetadataUrl));
4608
+ }
4336
4609
  }
4337
4610
  ]);
4338
4611
  return OidcAuthBearerTokenMiddleware;
4339
4612
  }();
4340
4613
  OidcAuthBearerTokenMiddleware = __decorate([
4341
4614
  Injectable(),
4342
- __param(0, Inject(OidcService))
4615
+ __param(0, Inject(OidcService)),
4616
+ __param(1, Inject(OidcAuthMiddlewareConfig))
4343
4617
  ], OidcAuthBearerTokenMiddleware);
4344
4618
 
4345
- function _class_call_check$4(instance, Constructor) {
4346
- if (!(instance instanceof Constructor)) {
4347
- throw new TypeError("Cannot call a class as a function");
4348
- }
4349
- }
4350
- function _define_property$5(obj, key, value) {
4351
- if (key in obj) {
4352
- Object.defineProperty(obj, key, {
4353
- value: value,
4354
- enumerable: true,
4355
- configurable: true,
4356
- writable: true
4357
- });
4358
- } else {
4359
- obj[key] = value;
4360
- }
4361
- return obj;
4362
- }
4363
- // MARK: Config
4364
- /**
4365
- * Configuration for `OidcAuthBearerTokenMiddleware` route protection.
4366
- *
4367
- * Works in reverse of `FirebaseAppCheckMiddlewareConfig`: instead of protecting
4368
- * all routes and ignoring some, this only protects explicitly specified paths.
4369
- * Routes under the global API prefix (protected by AppCheck) are excluded.
4370
- */ var OidcAuthMiddlewareConfig = function OidcAuthMiddlewareConfig() {
4371
- _class_call_check$4(this, OidcAuthMiddlewareConfig);
4372
- /**
4373
- * Path prefixes that require OAuth bearer token verification.
4374
- *
4375
- * Only requests matching one of these prefixes will be checked.
4376
- * Paths under the global API route prefix should not be included
4377
- * since those are protected by AppCheck.
4378
- */ _define_property$5(this, "protectedPaths", void 0);
4379
- };
4380
- // MARK: Module
4381
- var _logger = new Logger('applyOidcAuthMiddleware');
4382
- // MARK: Express-Level Helper
4383
- /**
4384
- * Applies OAuth bearer token verification as global Express middleware on
4385
- * the given NestJS application.
4386
- *
4387
- * Resolves `OidcService` and `OidcAuthMiddlewareConfig` from the app's DI container,
4388
- * then registers an Express middleware that verifies bearer tokens for the configured
4389
- * protected paths and attaches auth data to `req.auth`.
4390
- *
4391
- * This is an alternative to {@link ConfigureOidcAuthMiddlewareModule} for cases where
4392
- * NestJS module scoping makes the module approach impractical.
4393
- *
4394
- * @param nestApp - The NestJS application instance used to resolve dependencies and register the middleware.
4395
- *
4396
- * @example
4397
- * ```ts
4398
- * export const APP_NEST_SERVER_CONFIG: NestServerInstanceConfig<AppModule> = {
4399
- * moduleClass: AppModule,
4400
- * configureNestServerInstance: (nestApp) => {
4401
- * applyOidcAuthMiddleware(nestApp);
4402
- * }
4403
- * };
4404
- * ```
4405
- */ function applyOidcAuthMiddleware(nestApp) {
4406
- var _ref;
4407
- var oidcService = nestApp.get(OidcService);
4408
- var config = nestApp.get(OidcAuthMiddlewareConfig);
4409
- var protectedPaths = (_ref = config === null || config === void 0 ? void 0 : config.protectedPaths) !== null && _ref !== void 0 ? _ref : [];
4410
- if (protectedPaths.length === 0) {
4411
- return;
4412
- }
4413
- var logger = new Logger('OidcAuthMiddleware');
4414
- nestApp.use(function(req, res, next) {
4415
- var isProtected = protectedPaths.some(function(prefix) {
4416
- return req.path.startsWith(prefix);
4417
- });
4418
- if (isProtected) {
4419
- var authHeader = req.headers.authorization;
4420
- if (authHeader === null || authHeader === void 0 ? void 0 : authHeader.startsWith('Bearer ')) {
4421
- var token = authHeader.slice(7);
4422
- oidcService.verifyAccessToken(token).then(function(oauthAuth) {
4423
- if (oauthAuth) {
4424
- req.auth = oauthAuth;
4425
- next();
4426
- } else {
4427
- res.status(401).json({
4428
- statusCode: 401,
4429
- message: 'Invalid or expired access token'
4430
- });
4431
- }
4432
- }).catch(function(err) {
4433
- logger.error('Bearer token verification failed', err);
4434
- res.status(401).json({
4435
- statusCode: 401,
4436
- message: 'Token verification failed'
4437
- });
4438
- });
4439
- } else {
4440
- res.status(401).json({
4441
- statusCode: 401,
4442
- message: 'Missing or invalid Authorization header'
4443
- });
4444
- }
4445
- } else {
4446
- next();
4447
- }
4448
- });
4449
- _logger.debug("Applied OAuth bearer token middleware for paths: ".concat(protectedPaths.join(', ')));
4450
- }
4451
-
4452
4619
  // MARK: Express-Level Helper
4453
4620
  /**
4454
4621
  * Enables CORS on the NestJS app for OIDC cross-origin requests originating from the frontend.
@@ -6102,14 +6269,16 @@ function _ts_generator(thisArg, body) {
6102
6269
  }
6103
6270
  // MARK: Well-Known Controller
6104
6271
  /**
6105
- * Controller for OAuth/OIDC discovery and metadata endpoints.
6272
+ * Controller for OIDC discovery and JWKS endpoints under `/.well-known`.
6273
+ *
6274
+ * The protected-resource discovery doc (`/.well-known/oauth-protected-resource`)
6275
+ * is owned by the protected resource itself (the MCP module's
6276
+ * `McpWellKnownController`), not the authorization server, per RFC 9728.
6106
6277
  */ var OidcWellKnownController = /*#__PURE__*/ function() {
6107
- function OidcWellKnownController(config, providerConfigService, jwksService) {
6278
+ function OidcWellKnownController(providerConfigService, jwksService) {
6108
6279
  _class_call_check(this, OidcWellKnownController);
6109
- _define_property$1(this, "config", void 0);
6110
6280
  _define_property$1(this, "providerConfigService", void 0);
6111
6281
  _define_property$1(this, "jwksService", void 0);
6112
- this.config = config;
6113
6282
  this.providerConfigService = providerConfigService;
6114
6283
  this.jwksService = jwksService;
6115
6284
  }
@@ -6162,23 +6331,6 @@ function _ts_generator(thisArg, body) {
6162
6331
  });
6163
6332
  }).call(this);
6164
6333
  }
6165
- },
6166
- {
6167
- /**
6168
- * OAuth Protected Resource discovery endpoint (RFC 8707).
6169
- *
6170
- * Returns the authorization server(s) that protect this resource,
6171
- * allowing clients to discover which authorization server to use.
6172
- *
6173
- * @returns The protected resource metadata with authorization server URLs.
6174
- */ key: "getProtectedResource",
6175
- value: function getProtectedResource() {
6176
- return {
6177
- authorization_servers: [
6178
- this.config.issuer
6179
- ]
6180
- };
6181
- }
6182
6334
  }
6183
6335
  ]);
6184
6336
  return OidcWellKnownController;
@@ -6189,14 +6341,10 @@ __decorate([
6189
6341
  __decorate([
6190
6342
  Get('jwks.json')
6191
6343
  ], OidcWellKnownController.prototype, "getJwks", null);
6192
- __decorate([
6193
- Get('oauth-protected-resource')
6194
- ], OidcWellKnownController.prototype, "getProtectedResource", null);
6195
6344
  OidcWellKnownController = __decorate([
6196
6345
  Controller('.well-known'),
6197
- __param(0, Inject(OidcModuleConfig)),
6198
- __param(1, Inject(OidcProviderConfigService)),
6199
- __param(2, Inject(JwksService))
6346
+ __param(0, Inject(OidcProviderConfigService)),
6347
+ __param(1, Inject(JwksService))
6200
6348
  ], OidcWellKnownController);
6201
6349
 
6202
6350
  function _array_like_to_array(arr, len) {
@@ -6393,6 +6541,7 @@ function _unsupported_iterable_to_array(o, minLen) {
6393
6541
  tokenLifetimes: DEFAULT_OIDC_TOKEN_LIFETIMES,
6394
6542
  trustProxy: envService.isProduction,
6395
6543
  trustProxyInNonProduction: false,
6544
+ resourceMetadataUrl: deriveResourceMetadataUrlFromEnv(envService),
6396
6545
  jwksServiceConfig: {
6397
6546
  encryptionSecret: encryptionSecret
6398
6547
  },
@@ -6403,6 +6552,27 @@ function _unsupported_iterable_to_array(o, minLen) {
6403
6552
  OidcModuleConfig.assertValidConfig(config);
6404
6553
  return config;
6405
6554
  }
6555
+ /**
6556
+ * Derives the RFC 9728 protected-resource metadata URL from `envService.appMcpUrl`.
6557
+ *
6558
+ * For `appMcpUrl = http://localhost:9902/dereekb-components/us-central1/api/mcp`, this
6559
+ * returns `http://localhost:9902/dereekb-components/us-central1/api/.well-known/oauth-protected-resource` —
6560
+ * i.e. the discovery doc colocated with the MCP endpoint, regardless of any URL prefix
6561
+ * imposed by the runtime (Firebase Functions emulator, Cloud Run path, etc.).
6562
+ *
6563
+ * Returns `undefined` when no `appMcpUrl` is configured.
6564
+ *
6565
+ * @param envService - The Firebase server environment service.
6566
+ * @returns The discovery URL, or `undefined` if `appMcpUrl` is not set.
6567
+ */ function deriveResourceMetadataUrlFromEnv(envService) {
6568
+ var mcpUrl = envService.appMcpUrl;
6569
+ if (!mcpUrl) {
6570
+ return undefined;
6571
+ }
6572
+ var parsed = new URL(mcpUrl);
6573
+ var trimmedPath = parsed.pathname.replace(/\/[^/]*\/?$/, '');
6574
+ return "".concat(parsed.origin).concat(trimmedPath, "/.well-known/oauth-protected-resource");
6575
+ }
6406
6576
  /**
6407
6577
  * Factory that creates {@link OidcServerFirestoreCollections} using the provided Firestore context
6408
6578
  * and JWKS encryption config from {@link OidcModuleConfig}.
@@ -6433,7 +6603,7 @@ function _unsupported_iterable_to_array(o, minLen) {
6433
6603
  * @param metadataConfig - The configuration for generating the OIDC module metadata.
6434
6604
  * @returns The NestJS module metadata for the OIDC module.
6435
6605
  */ function oidcModuleMetadata(metadataConfig) {
6436
- var dependencyModule = metadataConfig.dependencyModule, config = metadataConfig.config, imports = metadataConfig.imports, exports = metadataConfig.exports, providers = metadataConfig.providers;
6606
+ var dependencyModule = metadataConfig.dependencyModule, config = metadataConfig.config, configFactory = metadataConfig.configFactory, imports = metadataConfig.imports, exports = metadataConfig.exports, providers = metadataConfig.providers;
6437
6607
  var dependencyModuleImport = [
6438
6608
  dependencyModule
6439
6609
  ];
@@ -6463,10 +6633,12 @@ function _unsupported_iterable_to_array(o, minLen) {
6463
6633
  ],
6464
6634
  useFactory: function useFactory(configService, envService) {
6465
6635
  var moduleConfig = oidcModuleConfigFactory(configService, envService);
6636
+ var dynamicOverrides = configFactory ? configFactory(envService, configService) : undefined;
6637
+ var merged = config || dynamicOverrides ? _object_spread({}, config, dynamicOverrides) : undefined;
6466
6638
  var result = moduleConfig;
6467
- if (config) {
6468
- result = _object_spread({}, moduleConfig, config);
6469
- if (config.trustProxyInNonProduction && !envService.isProduction) {
6639
+ if (merged) {
6640
+ result = _object_spread({}, moduleConfig, merged);
6641
+ if (merged.trustProxyInNonProduction && !envService.isProduction) {
6470
6642
  result.trustProxy = true;
6471
6643
  }
6472
6644
  }
@@ -6478,7 +6650,8 @@ function _unsupported_iterable_to_array(o, minLen) {
6478
6650
  useFactory: function useFactory(x) {
6479
6651
  var _x_protectedPaths;
6480
6652
  return {
6481
- protectedPaths: (_x_protectedPaths = x.protectedPaths) !== null && _x_protectedPaths !== void 0 ? _x_protectedPaths : []
6653
+ protectedPaths: (_x_protectedPaths = x.protectedPaths) !== null && _x_protectedPaths !== void 0 ? _x_protectedPaths : [],
6654
+ resourceMetadataUrl: x.resourceMetadataUrl
6482
6655
  };
6483
6656
  },
6484
6657
  inject: [
@@ -6555,4 +6728,4 @@ function _unsupported_iterable_to_array(o, minLen) {
6555
6728
  return fn;
6556
6729
  }
6557
6730
 
6558
- export { DEFAULT_APP_OAUTH_CONSENT_PATH_PART, DEFAULT_APP_OAUTH_INTERACTION_PATH, DEFAULT_APP_OAUTH_LOGIN_PATH_PART, DEFAULT_MAX_REQUESTED_LOGIN_DURATION_SECONDS, DEFAULT_MIN_REQUESTED_LOGIN_DURATION_SECONDS, 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_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE, GRANTABLE_MODEL_NAMES, JwksFirestoreCollections, JwksKeyDocument, JwksService, JwksServiceConfig, JwksServiceStorageConfig, OIDC_ENCRYPTED_PAYLOAD_FIELDS, OIDC_JWKS_ENCRYPTION_SECRET_ENV_KEY, OidcAccountService, OidcAccountServiceDelegate, OidcAccountServiceUserContext, OidcAuth, OidcAuthBearerTokenMiddleware, OidcAuthMiddlewareConfig, OidcClientService, OidcEncryptionService, OidcInteractionController, OidcInteractionService, OidcModelServerActions, OidcModuleConfig, OidcProviderConfigService, OidcProviderController, OidcServerFirestoreCollections, OidcService, OidcWellKnownController, activeJwksKeysQuery, appOidcModelModuleMetadata, applyOidcAuthMiddleware, applyOidcCorsMiddleware, createAdapterFactory, createOidcClientFactory, deleteOidcClientFactory, deleteOidcTokenFactory, getOidcScopesFromRequest, jwksKeyCollectionReference, jwksKeyConverter, jwksKeyFirestoreCollection, jwksKeyIdentity, jwksKeysWithStatusQuery, nonRetiredJwksKeysQuery, oidcCallModelScopePreAssert, oidcFirestoreCollectionsFactory, oidcModelServerActions, oidcModelServerActionsFactory, oidcModuleConfigFactory, oidcModuleMetadata, resolveEffectiveSubset, rotateOidcClientSecretFactory, rotatedJwksKeysQuery, updateOidcClientFactory };
6731
+ export { DEFAULT_APP_OAUTH_CONSENT_PATH_PART, DEFAULT_APP_OAUTH_INTERACTION_PATH, DEFAULT_APP_OAUTH_LOGIN_PATH_PART, DEFAULT_MAX_REQUESTED_LOGIN_DURATION_SECONDS, DEFAULT_MIN_REQUESTED_LOGIN_DURATION_SECONDS, 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_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE, GRANTABLE_MODEL_NAMES, JwksFirestoreCollections, JwksKeyDocument, JwksService, JwksServiceConfig, JwksServiceStorageConfig, OIDC_ENCRYPTED_PAYLOAD_FIELDS, OIDC_JWKS_ENCRYPTION_SECRET_ENV_KEY, OidcAccountService, OidcAccountServiceDelegate, OidcAccountServiceUserContext, OidcAuth, OidcAuthBearerTokenMiddleware, OidcAuthMiddlewareConfig, OidcClientService, OidcEncryptionService, OidcInteractionController, OidcInteractionService, OidcModelServerActions, OidcModuleConfig, OidcProviderConfigService, OidcProviderController, OidcServerFirestoreCollections, OidcService, OidcWellKnownController, activeJwksKeysQuery, appOidcModelModuleMetadata, applyOidcAuthMiddleware, applyOidcCorsMiddleware, buildBearerChallenge, createAdapterFactory, createOidcClientFactory, deleteOidcClientFactory, deleteOidcTokenFactory, deriveResourceMetadataUrlFromEnv, getOidcScopesFromRequest, jwksKeyCollectionReference, jwksKeyConverter, jwksKeyFirestoreCollection, jwksKeyIdentity, jwksKeysWithStatusQuery, nonRetiredJwksKeysQuery, oidcCallModelScopePreAssert, 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.11.17",
3
+ "version": "13.12.0",
4
4
  "peerDependencies": {
5
- "@dereekb/analytics": "13.11.17",
6
- "@dereekb/date": "13.11.17",
7
- "@dereekb/firebase": "13.11.17",
8
- "@dereekb/firebase-server": "13.11.17",
9
- "@dereekb/model": "13.11.17",
10
- "@dereekb/nestjs": "13.11.17",
11
- "@dereekb/rxjs": "13.11.17",
12
- "@dereekb/util": "13.11.17",
13
- "@dereekb/zoho": "13.11.17",
5
+ "@dereekb/analytics": "13.12.0",
6
+ "@dereekb/date": "13.12.0",
7
+ "@dereekb/firebase": "13.12.0",
8
+ "@dereekb/firebase-server": "13.12.0",
9
+ "@dereekb/model": "13.12.0",
10
+ "@dereekb/nestjs": "13.12.0",
11
+ "@dereekb/rxjs": "13.12.0",
12
+ "@dereekb/util": "13.12.0",
13
+ "@dereekb/zoho": "13.12.0",
14
14
  "@nestjs/common": "^11.1.19",
15
15
  "@nestjs/config": "^4.0.4",
16
16
  "express": "^5.2.1",