@dereekb/firebase-server 13.28.0 → 13.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js CHANGED
@@ -5486,6 +5486,31 @@ function resolveAnalyticsFromApiDetails(apiDetails, call, modelType, specifier)
5486
5486
  }
5487
5487
  return result;
5488
5488
  }
5489
+ // MARK: Required Scope Resolution
5490
+ /**
5491
+ * Resolves the leaf-level per-function required OIDC scope from the aggregated _apiDetails tree.
5492
+ *
5493
+ * Walks: call -> modelType -> specifier (if specifier-level), then reads the `requiredScope`
5494
+ * field from the handler-level {@link OnCallModelFunctionApiDetails}. Mirrors
5495
+ * {@link resolveAnalyticsFromApiDetails}.
5496
+ *
5497
+ * @param apiDetails - The top-level aggregated API details.
5498
+ * @param call - The CRUD operation type to look up.
5499
+ * @param modelType - The Firestore model type to look up.
5500
+ * @param specifier - Optional specifier key for variant handlers.
5501
+ * @returns The per-function required scope for the resolved handler, or undefined.
5502
+ */ // eslint-disable-next-line @typescript-eslint/max-params
5503
+ function resolveRequiredScopeFromApiDetails(apiDetails, call, modelType, specifier) {
5504
+ var _apiDetails_call;
5505
+ var modelDetails = (_apiDetails_call = apiDetails[call]) === null || _apiDetails_call === void 0 ? void 0 : _apiDetails_call.modelTypes[modelType];
5506
+ var result;
5507
+ if (modelDetails) {
5508
+ var _modelDetails_specifiers_key;
5509
+ var key = specifier !== null && specifier !== void 0 ? specifier : '_';
5510
+ result = (_modelDetails_specifiers_key = modelDetails.specifiers[key]) === null || _modelDetails_specifiers_key === void 0 ? void 0 : _modelDetails_specifiers_key.requiredScope;
5511
+ }
5512
+ return result;
5513
+ }
5489
5514
  /**
5490
5515
  * @deprecated Use {@link isOnCallModelTypeApiDetails} instead.
5491
5516
  */ var isOnCallSpecifierApiDetails = isOnCallModelTypeApiDetails;
@@ -5774,7 +5799,12 @@ function _object_spread_props$c(target, source) {
5774
5799
  data: request.data.data,
5775
5800
  request: request
5776
5801
  };
5777
- preAssert(context);
5802
+ // Resolve the leaf handler's per-function requiredScope (if any) so the preAssert can enforce
5803
+ // it additively with the per-verb OIDC scope. Same call -> modelType -> specifier walk as analytics.
5804
+ var requiredScope = resolveRequiredScopeFromApiDetails(modelApiDetails, call, modelType, specifier);
5805
+ preAssert(_object_spread_props$c(_object_spread$h({}, context), {
5806
+ requiredScope: requiredScope
5807
+ }));
5778
5808
  var result;
5779
5809
  // Resolve analytics from _apiDetails tree — callWithAnalytics handles undefined details
5780
5810
  var analyticsService = getAnalyticsService(request);
@@ -7029,6 +7059,78 @@ exports.FirebaseServerAuthModule = __decorate([
7029
7059
  return claims[firebase.FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY] != null;
7030
7060
  }
7031
7061
 
7062
+ // MARK: Scope Reading
7063
+ /**
7064
+ * Reads the set of OIDC scopes carried by a model-api request's auth, or `undefined` for a non-OIDC
7065
+ * (regular Firebase ID-token) caller.
7066
+ *
7067
+ * The OIDC bearer-token middleware attaches the validated access-token claims at
7068
+ * `auth.oidcValidatedToken` (with the space-delimited `scope` string); a non-OIDC caller has neither
7069
+ * that field nor a `scope` on `auth.token`. Reading is defensive (the auth shape is only typed as
7070
+ * {@link FirebaseServerAuthData} here — the OIDC-specific `oidcValidatedToken` lives in the
7071
+ * `@dereekb/firebase-server/oidc` sub-package this core layer cannot import), delegating the actual
7072
+ * parse to the shared {@link oidcScopesFromScopeClaim} so there is no drift with `getOidcScopesFromRequest`.
7073
+ *
7074
+ * @param auth - The request auth data, or undefined for unauthenticated requests.
7075
+ * @returns The granted scope set, or `undefined` when the request carries no OIDC `scope` claim.
7076
+ */ function oidcScopesFromModelApiAuth(auth) {
7077
+ var _auth_oidcValidatedToken, _auth_token;
7078
+ var oidcScope = auth === null || auth === void 0 ? void 0 : (_auth_oidcValidatedToken = auth.oidcValidatedToken) === null || _auth_oidcValidatedToken === void 0 ? void 0 : _auth_oidcValidatedToken.scope;
7079
+ var tokenScope = auth === null || auth === void 0 ? void 0 : (_auth_token = auth.token) === null || _auth_token === void 0 ? void 0 : _auth_token.scope;
7080
+ var scope = oidcScope !== null && oidcScope !== void 0 ? oidcScope : tokenScope;
7081
+ return firebase.oidcScopesFromScopeClaim(scope);
7082
+ }
7083
+ /**
7084
+ * Enforces the OIDC scope requirement for a single model-api op, throwing a `403`
7085
+ * {@link CALL_MODEL_MISSING_OIDC_SCOPE_ERROR_CODE} error when the caller does not satisfy it.
7086
+ *
7087
+ * The single home of callModel OIDC scope enforcement. It reuses the shipped composition + evaluation
7088
+ * (`resolveEffectiveOidcScopeTerms` / `oidcScopeTermsSatisfied`) so enforcement and the MCP
7089
+ * tool-visibility filter never drift. Enforcement is AND-of-ORs across the per-verb `model.<call>`
7090
+ * scope and the effective GROUP term (per-function `requiredScope` > per-model requirement >
7091
+ * configured default).
7092
+ *
7093
+ * Bypasses (no-op) when `grantedScopes` is `undefined` — i.e. a non-OIDC caller — and short-circuits
7094
+ * without any check when the op resolves no requirement at all (a custom, non-CRUD verb with no
7095
+ * per-function/model/default term).
7096
+ *
7097
+ * @param input - The verb, model type, per-function scope, group config, and the caller's granted scopes.
7098
+ * @throws A `403` forbidden error (code {@link CALL_MODEL_MISSING_OIDC_SCOPE_ERROR_CODE}) when an OIDC
7099
+ * caller does not satisfy the effective requirement.
7100
+ */ function assertModelApiOidcScope(input) {
7101
+ var call = input.call, modelType = input.modelType, requiredScope = input.requiredScope, defaultRequiredScope = input.defaultRequiredScope, modelRequiredScopes = input.modelRequiredScopes, grantedScopes = input.grantedScopes;
7102
+ var terms = firebase.resolveEffectiveOidcScopeTerms({
7103
+ perVerbScope: firebase.callModelOidcScopeForCallType(call),
7104
+ requiredScope: requiredScope,
7105
+ modelRequirement: modelRequiredScopes === null || modelRequiredScopes === void 0 ? void 0 : modelRequiredScopes[modelType],
7106
+ call: call,
7107
+ defaultRequiredScope: defaultRequiredScope
7108
+ });
7109
+ if (terms.length > 0 && grantedScopes != null && !firebase.oidcScopeTermsSatisfied(terms, grantedScopes)) {
7110
+ var missingTerms = terms.filter(function(term) {
7111
+ return !firebase.oidcScopeTermSatisfied(term, grantedScopes);
7112
+ });
7113
+ throw forbiddenError({
7114
+ status: 403,
7115
+ code: firebase.CALL_MODEL_MISSING_OIDC_SCOPE_ERROR_CODE,
7116
+ message: "Missing required OIDC scope for callModel: ".concat(missingTerms.map(formatModelApiScopeTerm).join(', ')),
7117
+ data: {
7118
+ requiredScopes: missingTerms,
7119
+ call: call
7120
+ }
7121
+ });
7122
+ }
7123
+ }
7124
+ /**
7125
+ * Renders a scope term for the human-readable error message: a single scope as-is, an OR-group as its
7126
+ * alternatives joined by `|` (so a single-scope term reads as itself).
7127
+ *
7128
+ * @param term - The unsatisfied scope term.
7129
+ * @returns The display string for the term.
7130
+ */ function formatModelApiScopeTerm(term) {
7131
+ return typeof term === 'string' ? term : term.join('|');
7132
+ }
7133
+
7032
7134
  function _define_property$n(obj, key, value) {
7033
7135
  if (key in obj) {
7034
7136
  Object.defineProperty(obj, key, {
@@ -7305,6 +7407,15 @@ function _ts_generator$a(thisArg, body) {
7305
7407
  /**
7306
7408
  * Factory to create typed nest context from INestApplicationContext.
7307
7409
  */ _define_property$m(this, "makeNestContext", void 0);
7410
+ /**
7411
+ * Optional model-api-layer OIDC group-scope default. See {@link ModelApiOidcScopeConfig.defaultRequiredScope}.
7412
+ * This is the home for the callModel group-scope default; providing it here enforces it across
7413
+ * dispatch AND the `/get` reads.
7414
+ */ _define_property$m(this, "defaultRequiredScope", void 0);
7415
+ /**
7416
+ * Optional per-model OIDC group-scope overrides. See {@link ModelApiOidcScopeConfig.modelRequiredScopes}.
7417
+ * The only place a plain `/get` read (no per-function handler) can be scope-gated beyond `model.read`.
7418
+ */ _define_property$m(this, "modelRequiredScopes", void 0);
7308
7419
  };
7309
7420
  /**
7310
7421
  * Injection token for providing the NestJS application context to the dispatch service.
@@ -7339,8 +7450,25 @@ function _ts_generator$a(thisArg, body) {
7339
7450
  * @returns The handler's return value.
7340
7451
  */ function dispatch(params, auth, rawRequest) {
7341
7452
  return _async_to_generator$a(function() {
7342
- var callableRequest, appRequest, contextRequest;
7453
+ var call, modelType, specifier, apiDetails, requiredScope, callableRequest, appRequest, contextRequest;
7343
7454
  return _ts_generator$a(this, function(_state) {
7455
+ // Enforce OIDC scope BEFORE dispatching — the relocated home of the callModel scope check.
7456
+ // AND-of-ORs across the per-verb `model.<call>` scope and the effective group term (per-function
7457
+ // `requiredScope` > per-model requirement > module default), bypassing non-OIDC callers. A nullish
7458
+ // `call` is a malformed request the callModel chain rejects downstream (no model op to authorize).
7459
+ call = params.call, modelType = params.modelType, specifier = params.specifier;
7460
+ if (call != null) {
7461
+ apiDetails = this.config.callModelFn._apiDetails;
7462
+ requiredScope = apiDetails == null ? undefined : resolveRequiredScopeFromApiDetails(apiDetails, call, modelType, specifier);
7463
+ assertModelApiOidcScope({
7464
+ call: call,
7465
+ modelType: modelType,
7466
+ requiredScope: requiredScope,
7467
+ defaultRequiredScope: this.config.defaultRequiredScope,
7468
+ modelRequiredScopes: this.config.modelRequiredScopes,
7469
+ grantedScopes: oidcScopesFromModelApiAuth(auth)
7470
+ });
7471
+ }
7344
7472
  // Build a synthetic CallableRequest that the dispatch chain expects. Layer the
7345
7473
  // OIDC-validated claim subset over the base token so standard JWT claims
7346
7474
  // (`iat`, `auth_time`, `email`, …) survive — the callModel chain and any
@@ -7627,12 +7755,38 @@ function _ts_generator$9(thisArg, body) {
7627
7755
  function ModelApiGetService(config, nestApplication) {
7628
7756
  _class_call_check$e(this, ModelApiGetService);
7629
7757
  _define_property$l(this, "_nestContext", void 0);
7758
+ _define_property$l(this, "_defaultRequiredScope", void 0);
7759
+ _define_property$l(this, "_modelRequiredScopes", void 0);
7630
7760
  _define_property$l(this, "_identityByModelType", void 0);
7631
7761
  this._nestContext = config.makeNestContext(nestApplication);
7762
+ this._defaultRequiredScope = config.defaultRequiredScope;
7763
+ this._modelRequiredScopes = config.modelRequiredScopes;
7632
7764
  }
7633
7765
  _create_class$9(ModelApiGetService, [
7634
7766
  {
7635
7767
  /**
7768
+ * Enforces the OIDC read-scope requirement for a direct document read before it hits Firestore.
7769
+ *
7770
+ * A direct `/get` read is the `read` verb: it requires the per-verb `model.read` scope AND any
7771
+ * effective group term for the target model (per-model requirement > module default). This is the
7772
+ * ONLY gate on the direct-read path — it does not touch the callModel dispatch chain — so without it
7773
+ * an OIDC client scoped to a subset could read any model through `/get`. Non-OIDC callers bypass.
7774
+ *
7775
+ * @param modelType - The Firestore model type being read.
7776
+ * @param auth - The request's auth data (OIDC scopes are read from it).
7777
+ */ key: "_assertReadScope",
7778
+ value: function _assertReadScope(modelType, auth) {
7779
+ assertModelApiOidcScope({
7780
+ call: 'read',
7781
+ modelType: modelType,
7782
+ defaultRequiredScope: this._defaultRequiredScope,
7783
+ modelRequiredScopes: this._modelRequiredScopes,
7784
+ grantedScopes: oidcScopesFromModelApiAuth(auth)
7785
+ });
7786
+ }
7787
+ },
7788
+ {
7789
+ /**
7636
7790
  * Returns the registered {@link FirestoreModelIdentity} for the given `modelType` string, or
7637
7791
  * `undefined` when no model of that type is registered.
7638
7792
  *
@@ -7704,6 +7858,7 @@ function _ts_generator$9(thisArg, body) {
7704
7858
  return _ts_generator$9(this, function(_state) {
7705
7859
  switch(_state.label){
7706
7860
  case 0:
7861
+ this._assertReadScope(modelType, auth);
7707
7862
  authRef = this._makeAuthRef(auth);
7708
7863
  return [
7709
7864
  4,
@@ -7752,6 +7907,7 @@ function _ts_generator$9(thisArg, body) {
7752
7907
  return _async_to_generator$9(function() {
7753
7908
  var authRef;
7754
7909
  return _ts_generator$9(this, function(_state) {
7910
+ this._assertReadScope(modelType, auth);
7755
7911
  authRef = this._makeAuthRef(auth);
7756
7912
  return [
7757
7913
  2,
@@ -13155,6 +13311,7 @@ exports.assertHasSignedTosInRequest = assertHasSignedTosInRequest;
13155
13311
  exports.assertIsAdminInRequest = assertIsAdminInRequest;
13156
13312
  exports.assertIsAdminOrTargetUserInRequestData = assertIsAdminOrTargetUserInRequestData;
13157
13313
  exports.assertIsContextWithAuthData = assertIsContextWithAuthData;
13314
+ exports.assertModelApiOidcScope = assertModelApiOidcScope;
13158
13315
  exports.assertRequestRequiresAuthForFunction = assertRequestRequiresAuthForFunction;
13159
13316
  exports.assertSnapshotData = assertSnapshotData;
13160
13317
  exports.assertSnapshotDataWithKey = assertSnapshotDataWithKey;
@@ -13252,6 +13409,7 @@ exports.noRunNameSpecifiedForScheduledFunctionDevelopmentFunction = noRunNameSpe
13252
13409
  exports.noopFirebaseServerAnalyticsServiceListener = noopFirebaseServerAnalyticsServiceListener;
13253
13410
  exports.noopOnCallModelAnalyticsService = noopOnCallModelAnalyticsService;
13254
13411
  exports.notFoundError = notFoundError;
13412
+ exports.oidcScopesFromModelApiAuth = oidcScopesFromModelApiAuth;
13255
13413
  exports.onCallAnalyticsEmitterInstance = onCallAnalyticsEmitterInstance;
13256
13414
  exports.onCallCreateModel = onCallCreateModel;
13257
13415
  exports.onCallDeleteModel = onCallDeleteModel;
@@ -13282,6 +13440,7 @@ exports.readApiDetails = readApiDetails;
13282
13440
  exports.readModelUnknownModelTypeError = readModelUnknownModelTypeError;
13283
13441
  exports.resolveAdminOnlyValue = resolveAdminOnlyValue;
13284
13442
  exports.resolveAnalyticsFromApiDetails = resolveAnalyticsFromApiDetails;
13443
+ exports.resolveRequiredScopeFromApiDetails = resolveRequiredScopeFromApiDetails;
13285
13444
  exports.setNestContextOnRequest = setNestContextOnRequest;
13286
13445
  exports.setNestContextOnScheduleRequest = setNestContextOnScheduleRequest;
13287
13446
  exports.taskQueueFunctionHandlerWithNestContextFactory = taskQueueFunctionHandlerWithNestContextFactory;
package/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { timingSafeEqual } from 'node:crypto';
2
- import { DBX_FIREBASE_SERVER_NO_AUTH_ERROR_CODE, UNAUTHENTICATED_ERROR_CODE, FORBIDDEN_ERROR_CODE, PERMISSION_DENIED_ERROR_CODE, NOT_FOUND_ERROR_CODE, MODEL_NOT_AVAILABLE_ERROR_CODE, BAD_REQUEST_ERROR_CODE, CONFLICT_ERROR_CODE, ALREADY_EXISTS_ERROR_CODE, UNAVAILABLE_ERROR_CODE, UNAVAILABLE_OR_DEACTIVATED_FUNCTION_ERROR_CODE, INTERNAL_SERVER_ERROR_CODE, FIREBASE_AUTH_USER_NOT_FOUND_ERROR, FIREBASE_SERVER_AUTH_CLAIMS_RESET_PASSWORD_KEY, FIREBASE_SERVER_AUTH_CLAIMS_RESET_LAST_COM_DATE_KEY, FIREBASE_SERVER_AUTH_CLAIMS_RESET_EXPIRES_AT_KEY, FIREBASE_AUTH_PHONE_NUMBER_ALREADY_EXISTS_ERROR, FIREBASE_AUTH_EMAIL_ALREADY_EXISTS_ERROR, FIREBASE_AUTH_INVALID_PHONE_NUMBER_ERROR, FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY, FIREBASE_SERVER_AUTH_CLAIMS_SETUP_LAST_COM_DATE_KEY, setIdAndKeyFromKeyIdRefOnDocumentData, DBX_FIREBASE_SERVER_PASSWORD_RESET_INVALID_CODE_ERROR_CODE, DBX_FIREBASE_SERVER_PASSWORD_RESET_NO_CONFIG_ERROR_CODE, DBX_FIREBASE_SERVER_PASSWORD_RESET_SEND_ONCE_ERROR_CODE, DBX_FIREBASE_SERVER_PASSWORD_RESET_THROTTLE_ERROR_CODE, FirestoreDocumentContextType, streamFromOnSnapshot, FIRESTORE_LIMIT_QUERY_CONSTRAINT_TYPE, FIRESTORE_LIMIT_TO_LAST_QUERY_CONSTRAINT_TYPE, FIRESTORE_ORDER_BY_QUERY_CONSTRAINT_TYPE, FIRESTORE_ORDER_BY_DOCUMENT_ID_QUERY_CONSTRAINT_TYPE, FIRESTORE_WHERE_QUERY_CONSTRAINT_TYPE, FIRESTORE_WHERE_DOCUMENT_ID_QUERY_CONSTRAINT_TYPE, FIRESTORE_OFFSET_QUERY_CONSTRAINT_TYPE, FIRESTORE_START_AT_QUERY_CONSTRAINT_TYPE, FIRESTORE_START_AT_VALUE_QUERY_CONSTRAINT_TYPE, FIRESTORE_START_AFTER_QUERY_CONSTRAINT_TYPE, FIRESTORE_END_AT_QUERY_CONSTRAINT_TYPE, FIRESTORE_END_AT_VALUE_QUERY_CONSTRAINT_TYPE, FIRESTORE_END_BEFORE_QUERY_CONSTRAINT_TYPE, makeFirestoreQueryConstraintFunctionsDriver, firestoreContextFactory, firestoreField, optionalFirestoreField, DEFAULT_MODEL_FUNCTION_FIREBASE_CRUD_FUNCTION_SPECIFIER, UNKNOWN_MODEL_TYPE_ERROR_CODE, BAD_DOCUMENT_QUERY_CURSOR_ERROR_CODE, limit, startAfter, DEFAULT_ON_CALL_QUERY_MODEL_LIMIT, MAX_ON_CALL_QUERY_MODEL_LIMIT, ScheduledFunctionDevelopmentFunctionTypeEnum, SCHEDULED_FUNCTION_DEV_FUNCTION_SPECIFIER, storageListFilesResultFactory, assertStorageUploadOptionsStringFormat, firebaseStorageContextFactory, inContextFirebaseModelsServiceFactory, useFirebaseModelsService } from '@dereekb/firebase';
2
+ import { DBX_FIREBASE_SERVER_NO_AUTH_ERROR_CODE, UNAUTHENTICATED_ERROR_CODE, FORBIDDEN_ERROR_CODE, PERMISSION_DENIED_ERROR_CODE, NOT_FOUND_ERROR_CODE, MODEL_NOT_AVAILABLE_ERROR_CODE, BAD_REQUEST_ERROR_CODE, CONFLICT_ERROR_CODE, ALREADY_EXISTS_ERROR_CODE, UNAVAILABLE_ERROR_CODE, UNAVAILABLE_OR_DEACTIVATED_FUNCTION_ERROR_CODE, INTERNAL_SERVER_ERROR_CODE, FIREBASE_AUTH_USER_NOT_FOUND_ERROR, FIREBASE_SERVER_AUTH_CLAIMS_RESET_PASSWORD_KEY, FIREBASE_SERVER_AUTH_CLAIMS_RESET_LAST_COM_DATE_KEY, FIREBASE_SERVER_AUTH_CLAIMS_RESET_EXPIRES_AT_KEY, FIREBASE_AUTH_PHONE_NUMBER_ALREADY_EXISTS_ERROR, FIREBASE_AUTH_EMAIL_ALREADY_EXISTS_ERROR, FIREBASE_AUTH_INVALID_PHONE_NUMBER_ERROR, FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY, FIREBASE_SERVER_AUTH_CLAIMS_SETUP_LAST_COM_DATE_KEY, setIdAndKeyFromKeyIdRefOnDocumentData, DBX_FIREBASE_SERVER_PASSWORD_RESET_INVALID_CODE_ERROR_CODE, DBX_FIREBASE_SERVER_PASSWORD_RESET_NO_CONFIG_ERROR_CODE, DBX_FIREBASE_SERVER_PASSWORD_RESET_SEND_ONCE_ERROR_CODE, DBX_FIREBASE_SERVER_PASSWORD_RESET_THROTTLE_ERROR_CODE, FirestoreDocumentContextType, streamFromOnSnapshot, FIRESTORE_LIMIT_QUERY_CONSTRAINT_TYPE, FIRESTORE_LIMIT_TO_LAST_QUERY_CONSTRAINT_TYPE, FIRESTORE_ORDER_BY_QUERY_CONSTRAINT_TYPE, FIRESTORE_ORDER_BY_DOCUMENT_ID_QUERY_CONSTRAINT_TYPE, FIRESTORE_WHERE_QUERY_CONSTRAINT_TYPE, FIRESTORE_WHERE_DOCUMENT_ID_QUERY_CONSTRAINT_TYPE, FIRESTORE_OFFSET_QUERY_CONSTRAINT_TYPE, FIRESTORE_START_AT_QUERY_CONSTRAINT_TYPE, FIRESTORE_START_AT_VALUE_QUERY_CONSTRAINT_TYPE, FIRESTORE_START_AFTER_QUERY_CONSTRAINT_TYPE, FIRESTORE_END_AT_QUERY_CONSTRAINT_TYPE, FIRESTORE_END_AT_VALUE_QUERY_CONSTRAINT_TYPE, FIRESTORE_END_BEFORE_QUERY_CONSTRAINT_TYPE, makeFirestoreQueryConstraintFunctionsDriver, firestoreContextFactory, firestoreField, optionalFirestoreField, DEFAULT_MODEL_FUNCTION_FIREBASE_CRUD_FUNCTION_SPECIFIER, UNKNOWN_MODEL_TYPE_ERROR_CODE, BAD_DOCUMENT_QUERY_CURSOR_ERROR_CODE, limit, startAfter, DEFAULT_ON_CALL_QUERY_MODEL_LIMIT, MAX_ON_CALL_QUERY_MODEL_LIMIT, resolveEffectiveOidcScopeTerms, callModelOidcScopeForCallType, oidcScopeTermsSatisfied, oidcScopeTermSatisfied, CALL_MODEL_MISSING_OIDC_SCOPE_ERROR_CODE, oidcScopesFromScopeClaim, ScheduledFunctionDevelopmentFunctionTypeEnum, SCHEDULED_FUNCTION_DEV_FUNCTION_SPECIFIER, storageListFilesResultFactory, assertStorageUploadOptionsStringFormat, firebaseStorageContextFactory, inContextFirebaseModelsServiceFactory, useFirebaseModelsService } from '@dereekb/firebase';
3
3
  import { partialServerError, isServerError, randomNumberFactory, cachedGetter, filterNullAndUndefinedValues, asSet, AUTH_ADMIN_ROLE, AUTH_TOS_SIGNED_ROLE, forEachKeyValue, KeyValueTypleValueFilter, filterUndefinedValues, isThrottled, mapObjectMap, batch, objectToMap, serverError, asArray, containsAllValues, websiteUrlDetails, mergeObjects, cronExpressionRepeatingEveryNMinutes, mapIdentityFunction, slashPathName, toRelativeSlashPathStartType, fixMultiSlashesInSlashPath, SLASH_PATH_SEPARATOR, objectHasNoKeys, websiteUrlFromPaths, pushItemOrArrayItemsIntoArray, makeGetter, asGetter, build, performAsyncTasks } from '@dereekb/util';
4
4
  import { HttpsError } from 'firebase-functions/https';
5
5
  import { hoursToMs, minutesToMs, toISODateString } from '@dereekb/date';
@@ -5484,6 +5484,31 @@ function resolveAnalyticsFromApiDetails(apiDetails, call, modelType, specifier)
5484
5484
  }
5485
5485
  return result;
5486
5486
  }
5487
+ // MARK: Required Scope Resolution
5488
+ /**
5489
+ * Resolves the leaf-level per-function required OIDC scope from the aggregated _apiDetails tree.
5490
+ *
5491
+ * Walks: call -> modelType -> specifier (if specifier-level), then reads the `requiredScope`
5492
+ * field from the handler-level {@link OnCallModelFunctionApiDetails}. Mirrors
5493
+ * {@link resolveAnalyticsFromApiDetails}.
5494
+ *
5495
+ * @param apiDetails - The top-level aggregated API details.
5496
+ * @param call - The CRUD operation type to look up.
5497
+ * @param modelType - The Firestore model type to look up.
5498
+ * @param specifier - Optional specifier key for variant handlers.
5499
+ * @returns The per-function required scope for the resolved handler, or undefined.
5500
+ */ // eslint-disable-next-line @typescript-eslint/max-params
5501
+ function resolveRequiredScopeFromApiDetails(apiDetails, call, modelType, specifier) {
5502
+ var _apiDetails_call;
5503
+ var modelDetails = (_apiDetails_call = apiDetails[call]) === null || _apiDetails_call === void 0 ? void 0 : _apiDetails_call.modelTypes[modelType];
5504
+ var result;
5505
+ if (modelDetails) {
5506
+ var _modelDetails_specifiers_key;
5507
+ var key = specifier !== null && specifier !== void 0 ? specifier : '_';
5508
+ result = (_modelDetails_specifiers_key = modelDetails.specifiers[key]) === null || _modelDetails_specifiers_key === void 0 ? void 0 : _modelDetails_specifiers_key.requiredScope;
5509
+ }
5510
+ return result;
5511
+ }
5487
5512
  /**
5488
5513
  * @deprecated Use {@link isOnCallModelTypeApiDetails} instead.
5489
5514
  */ var isOnCallSpecifierApiDetails = isOnCallModelTypeApiDetails;
@@ -5772,7 +5797,12 @@ function _object_spread_props$c(target, source) {
5772
5797
  data: request.data.data,
5773
5798
  request: request
5774
5799
  };
5775
- preAssert(context);
5800
+ // Resolve the leaf handler's per-function requiredScope (if any) so the preAssert can enforce
5801
+ // it additively with the per-verb OIDC scope. Same call -> modelType -> specifier walk as analytics.
5802
+ var requiredScope = resolveRequiredScopeFromApiDetails(modelApiDetails, call, modelType, specifier);
5803
+ preAssert(_object_spread_props$c(_object_spread$h({}, context), {
5804
+ requiredScope: requiredScope
5805
+ }));
5776
5806
  var result;
5777
5807
  // Resolve analytics from _apiDetails tree — callWithAnalytics handles undefined details
5778
5808
  var analyticsService = getAnalyticsService(request);
@@ -7027,6 +7057,78 @@ FirebaseServerAuthModule = __decorate([
7027
7057
  return claims[FIREBASE_SERVER_AUTH_CLAIMS_SETUP_PASSWORD_KEY] != null;
7028
7058
  }
7029
7059
 
7060
+ // MARK: Scope Reading
7061
+ /**
7062
+ * Reads the set of OIDC scopes carried by a model-api request's auth, or `undefined` for a non-OIDC
7063
+ * (regular Firebase ID-token) caller.
7064
+ *
7065
+ * The OIDC bearer-token middleware attaches the validated access-token claims at
7066
+ * `auth.oidcValidatedToken` (with the space-delimited `scope` string); a non-OIDC caller has neither
7067
+ * that field nor a `scope` on `auth.token`. Reading is defensive (the auth shape is only typed as
7068
+ * {@link FirebaseServerAuthData} here — the OIDC-specific `oidcValidatedToken` lives in the
7069
+ * `@dereekb/firebase-server/oidc` sub-package this core layer cannot import), delegating the actual
7070
+ * parse to the shared {@link oidcScopesFromScopeClaim} so there is no drift with `getOidcScopesFromRequest`.
7071
+ *
7072
+ * @param auth - The request auth data, or undefined for unauthenticated requests.
7073
+ * @returns The granted scope set, or `undefined` when the request carries no OIDC `scope` claim.
7074
+ */ function oidcScopesFromModelApiAuth(auth) {
7075
+ var _auth_oidcValidatedToken, _auth_token;
7076
+ var oidcScope = auth === null || auth === void 0 ? void 0 : (_auth_oidcValidatedToken = auth.oidcValidatedToken) === null || _auth_oidcValidatedToken === void 0 ? void 0 : _auth_oidcValidatedToken.scope;
7077
+ var tokenScope = auth === null || auth === void 0 ? void 0 : (_auth_token = auth.token) === null || _auth_token === void 0 ? void 0 : _auth_token.scope;
7078
+ var scope = oidcScope !== null && oidcScope !== void 0 ? oidcScope : tokenScope;
7079
+ return oidcScopesFromScopeClaim(scope);
7080
+ }
7081
+ /**
7082
+ * Enforces the OIDC scope requirement for a single model-api op, throwing a `403`
7083
+ * {@link CALL_MODEL_MISSING_OIDC_SCOPE_ERROR_CODE} error when the caller does not satisfy it.
7084
+ *
7085
+ * The single home of callModel OIDC scope enforcement. It reuses the shipped composition + evaluation
7086
+ * (`resolveEffectiveOidcScopeTerms` / `oidcScopeTermsSatisfied`) so enforcement and the MCP
7087
+ * tool-visibility filter never drift. Enforcement is AND-of-ORs across the per-verb `model.<call>`
7088
+ * scope and the effective GROUP term (per-function `requiredScope` > per-model requirement >
7089
+ * configured default).
7090
+ *
7091
+ * Bypasses (no-op) when `grantedScopes` is `undefined` — i.e. a non-OIDC caller — and short-circuits
7092
+ * without any check when the op resolves no requirement at all (a custom, non-CRUD verb with no
7093
+ * per-function/model/default term).
7094
+ *
7095
+ * @param input - The verb, model type, per-function scope, group config, and the caller's granted scopes.
7096
+ * @throws A `403` forbidden error (code {@link CALL_MODEL_MISSING_OIDC_SCOPE_ERROR_CODE}) when an OIDC
7097
+ * caller does not satisfy the effective requirement.
7098
+ */ function assertModelApiOidcScope(input) {
7099
+ var call = input.call, modelType = input.modelType, requiredScope = input.requiredScope, defaultRequiredScope = input.defaultRequiredScope, modelRequiredScopes = input.modelRequiredScopes, grantedScopes = input.grantedScopes;
7100
+ var terms = resolveEffectiveOidcScopeTerms({
7101
+ perVerbScope: callModelOidcScopeForCallType(call),
7102
+ requiredScope: requiredScope,
7103
+ modelRequirement: modelRequiredScopes === null || modelRequiredScopes === void 0 ? void 0 : modelRequiredScopes[modelType],
7104
+ call: call,
7105
+ defaultRequiredScope: defaultRequiredScope
7106
+ });
7107
+ if (terms.length > 0 && grantedScopes != null && !oidcScopeTermsSatisfied(terms, grantedScopes)) {
7108
+ var missingTerms = terms.filter(function(term) {
7109
+ return !oidcScopeTermSatisfied(term, grantedScopes);
7110
+ });
7111
+ throw forbiddenError({
7112
+ status: 403,
7113
+ code: CALL_MODEL_MISSING_OIDC_SCOPE_ERROR_CODE,
7114
+ message: "Missing required OIDC scope for callModel: ".concat(missingTerms.map(formatModelApiScopeTerm).join(', ')),
7115
+ data: {
7116
+ requiredScopes: missingTerms,
7117
+ call: call
7118
+ }
7119
+ });
7120
+ }
7121
+ }
7122
+ /**
7123
+ * Renders a scope term for the human-readable error message: a single scope as-is, an OR-group as its
7124
+ * alternatives joined by `|` (so a single-scope term reads as itself).
7125
+ *
7126
+ * @param term - The unsatisfied scope term.
7127
+ * @returns The display string for the term.
7128
+ */ function formatModelApiScopeTerm(term) {
7129
+ return typeof term === 'string' ? term : term.join('|');
7130
+ }
7131
+
7030
7132
  function _define_property$n(obj, key, value) {
7031
7133
  if (key in obj) {
7032
7134
  Object.defineProperty(obj, key, {
@@ -7303,6 +7405,15 @@ function _ts_generator$a(thisArg, body) {
7303
7405
  /**
7304
7406
  * Factory to create typed nest context from INestApplicationContext.
7305
7407
  */ _define_property$m(this, "makeNestContext", void 0);
7408
+ /**
7409
+ * Optional model-api-layer OIDC group-scope default. See {@link ModelApiOidcScopeConfig.defaultRequiredScope}.
7410
+ * This is the home for the callModel group-scope default; providing it here enforces it across
7411
+ * dispatch AND the `/get` reads.
7412
+ */ _define_property$m(this, "defaultRequiredScope", void 0);
7413
+ /**
7414
+ * Optional per-model OIDC group-scope overrides. See {@link ModelApiOidcScopeConfig.modelRequiredScopes}.
7415
+ * The only place a plain `/get` read (no per-function handler) can be scope-gated beyond `model.read`.
7416
+ */ _define_property$m(this, "modelRequiredScopes", void 0);
7306
7417
  };
7307
7418
  /**
7308
7419
  * Injection token for providing the NestJS application context to the dispatch service.
@@ -7337,8 +7448,25 @@ function _ts_generator$a(thisArg, body) {
7337
7448
  * @returns The handler's return value.
7338
7449
  */ function dispatch(params, auth, rawRequest) {
7339
7450
  return _async_to_generator$a(function() {
7340
- var callableRequest, appRequest, contextRequest;
7451
+ var call, modelType, specifier, apiDetails, requiredScope, callableRequest, appRequest, contextRequest;
7341
7452
  return _ts_generator$a(this, function(_state) {
7453
+ // Enforce OIDC scope BEFORE dispatching — the relocated home of the callModel scope check.
7454
+ // AND-of-ORs across the per-verb `model.<call>` scope and the effective group term (per-function
7455
+ // `requiredScope` > per-model requirement > module default), bypassing non-OIDC callers. A nullish
7456
+ // `call` is a malformed request the callModel chain rejects downstream (no model op to authorize).
7457
+ call = params.call, modelType = params.modelType, specifier = params.specifier;
7458
+ if (call != null) {
7459
+ apiDetails = this.config.callModelFn._apiDetails;
7460
+ requiredScope = apiDetails == null ? undefined : resolveRequiredScopeFromApiDetails(apiDetails, call, modelType, specifier);
7461
+ assertModelApiOidcScope({
7462
+ call: call,
7463
+ modelType: modelType,
7464
+ requiredScope: requiredScope,
7465
+ defaultRequiredScope: this.config.defaultRequiredScope,
7466
+ modelRequiredScopes: this.config.modelRequiredScopes,
7467
+ grantedScopes: oidcScopesFromModelApiAuth(auth)
7468
+ });
7469
+ }
7342
7470
  // Build a synthetic CallableRequest that the dispatch chain expects. Layer the
7343
7471
  // OIDC-validated claim subset over the base token so standard JWT claims
7344
7472
  // (`iat`, `auth_time`, `email`, …) survive — the callModel chain and any
@@ -7625,12 +7753,38 @@ function _ts_generator$9(thisArg, body) {
7625
7753
  function ModelApiGetService(config, nestApplication) {
7626
7754
  _class_call_check$e(this, ModelApiGetService);
7627
7755
  _define_property$l(this, "_nestContext", void 0);
7756
+ _define_property$l(this, "_defaultRequiredScope", void 0);
7757
+ _define_property$l(this, "_modelRequiredScopes", void 0);
7628
7758
  _define_property$l(this, "_identityByModelType", void 0);
7629
7759
  this._nestContext = config.makeNestContext(nestApplication);
7760
+ this._defaultRequiredScope = config.defaultRequiredScope;
7761
+ this._modelRequiredScopes = config.modelRequiredScopes;
7630
7762
  }
7631
7763
  _create_class$9(ModelApiGetService, [
7632
7764
  {
7633
7765
  /**
7766
+ * Enforces the OIDC read-scope requirement for a direct document read before it hits Firestore.
7767
+ *
7768
+ * A direct `/get` read is the `read` verb: it requires the per-verb `model.read` scope AND any
7769
+ * effective group term for the target model (per-model requirement > module default). This is the
7770
+ * ONLY gate on the direct-read path — it does not touch the callModel dispatch chain — so without it
7771
+ * an OIDC client scoped to a subset could read any model through `/get`. Non-OIDC callers bypass.
7772
+ *
7773
+ * @param modelType - The Firestore model type being read.
7774
+ * @param auth - The request's auth data (OIDC scopes are read from it).
7775
+ */ key: "_assertReadScope",
7776
+ value: function _assertReadScope(modelType, auth) {
7777
+ assertModelApiOidcScope({
7778
+ call: 'read',
7779
+ modelType: modelType,
7780
+ defaultRequiredScope: this._defaultRequiredScope,
7781
+ modelRequiredScopes: this._modelRequiredScopes,
7782
+ grantedScopes: oidcScopesFromModelApiAuth(auth)
7783
+ });
7784
+ }
7785
+ },
7786
+ {
7787
+ /**
7634
7788
  * Returns the registered {@link FirestoreModelIdentity} for the given `modelType` string, or
7635
7789
  * `undefined` when no model of that type is registered.
7636
7790
  *
@@ -7702,6 +7856,7 @@ function _ts_generator$9(thisArg, body) {
7702
7856
  return _ts_generator$9(this, function(_state) {
7703
7857
  switch(_state.label){
7704
7858
  case 0:
7859
+ this._assertReadScope(modelType, auth);
7705
7860
  authRef = this._makeAuthRef(auth);
7706
7861
  return [
7707
7862
  4,
@@ -7750,6 +7905,7 @@ function _ts_generator$9(thisArg, body) {
7750
7905
  return _async_to_generator$9(function() {
7751
7906
  var authRef;
7752
7907
  return _ts_generator$9(this, function(_state) {
7908
+ this._assertReadScope(modelType, auth);
7753
7909
  authRef = this._makeAuthRef(auth);
7754
7910
  return [
7755
7911
  2,
@@ -13086,4 +13242,4 @@ function _define_property(obj, key, value) {
13086
13242
  }
13087
13243
  ();
13088
13244
 
13089
- export { AbstractFirebaseNestContext, AbstractFirebaseServerActionsContext, AbstractFirebaseServerAuthContext, AbstractFirebaseServerAuthService, AbstractFirebaseServerAuthUserContext, AbstractFirebaseServerNewUserService, AbstractFirebaseServerUserPasswordResetService, AbstractNestContext, AbstractServerFirebaseNestContext, ConfigureFirebaseAppCheckMiddlewareModule, ConfigureFirebaseWebhookMiddlewareModule, DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR, DEFAULT_RESET_CODE_EXPIRES_IN, DEFAULT_RESET_COM_THROTTLE_TIME, DEFAULT_SERVER_ASSETS_BASE_PATH, DEFAULT_SETUP_COM_THROTTLE_TIME, DefaultFirebaseServerEnvService, FIREBASE_APP_TOKEN, FIREBASE_AUTH_TOKEN, FIREBASE_FIRESTORE_CONTEXT_TOKEN, FIREBASE_FIRESTORE_TOKEN, FIREBASE_SERVER_ENV_TOKEN, FIREBASE_SERVER_VALIDATION_ERROR_CODE, FIREBASE_STORAGE_CONTEXT_FACTORY_CONFIG_TOKEN, FIREBASE_STORAGE_CONTEXT_TOKEN, FIREBASE_STORAGE_TOKEN, FIRESTORE_CLIENT_QUERY_CONSTRAINT_HANDLER_MAPPING, FirebaseAppCheckMiddleware, FirebaseAppCheckMiddlewareConfig, FirebaseNestServerRootModule, FirebaseRawBodyMiddleware, FirebaseServerAnalyticsSegmentListenerService, FirebaseServerAnalyticsSegmentModule, FirebaseServerAnalyticsService, FirebaseServerAnalyticsServiceListener, FirebaseServerAuthModule, FirebaseServerAuthNewUserSendSetupDetailsNoSetupConfigError, FirebaseServerAuthNewUserSendSetupDetailsSendOnceError, FirebaseServerAuthNewUserSendSetupDetailsThrottleError, FirebaseServerAuthPasswordResetInvalidCodeError, FirebaseServerAuthPasswordResetNoResetConfigError, FirebaseServerAuthPasswordResetSendOnceError, FirebaseServerAuthPasswordResetThrottleError, FirebaseServerAuthService, FirebaseServerAuthUserBadInputError, FirebaseServerAuthUserExistsError, FirebaseServerEnvService, FirebaseServerFirestoreContextModule, FirebaseServerFirestoreModule, FirebaseServerStorageContextModule, FirebaseServerStorageModule, FirebaseServerStorageService, GlobalRoutePrefixConfig, MAX_MODEL_ACCESS_MULTI_READ_KEYS, MODEL_API_NEST_APPLICATION_CONTEXT, ModelApiCallModelDispatchService, ModelApiController, ModelApiDispatchConfig, ModelApiGetService, NO_RUN_NAME_SPECIFIED_FOR_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_CODE, NoContentFirebaseServerUserPasswordResetService, NoSetupContentFirebaseServerNewUserService, ON_CALL_MODEL_ANALYTICS_HANDLER, ON_CALL_MODEL_ANALYTICS_SERVICE, OnCallModelAnalyticsService, PHONE_NUMBER_ALREADY_EXISTS_ERROR_CODE, SkipAppCheck, UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_NAME_CODE, UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_TYPE_CODE, _onCallWithCallTypeFunction, aggregateCrudModelApiDetails, aggregateModelApiDetails, aggregateSpecifierApiDetails, alreadyExistsError, appAnalyticsModuleMetadata, appFirestoreModuleMetadata, assertContextHasAuth, assertDocumentExists, assertHasRolesInRequest, assertHasSignedTosInRequest, assertIsAdminInRequest, assertIsAdminOrTargetUserInRequestData, assertIsContextWithAuthData, assertRequestRequiresAuthForFunction, assertSnapshotData, assertSnapshotDataWithKey, authServicePasswordResetInvalidCodeError, authServicePasswordResetNoConfigError, authServicePasswordResetSendOnceError, authServicePasswordResetThrottleError, badRequestError, blockingFunctionHandlerWithNestContextFactory, buildNestServerRootModule, callWithAnalytics, catchAndThrowPasswordResetServerErrors, cloudEventHandlerWithNestContextFactory, collectionRefForPath, createModelUnknownModelTypeError, decodeFirebaseServerUserPasswordResetOobCode, defaultFirebaseServerActionsTransformFactoryLogErrorFunction, defaultProvideFirebaseServerStorageServiceSimple, deleteModelUnknownModelTypeError, developmentUnknownSpecifierError, docRefForPath, documentModelNotAvailableError, encodeFirebaseServerUserPasswordResetOobCode, executeOnCallQuery, firebaseAuthTokenFromDecodedIdToken, firebaseServerActionsContext, firebaseServerActionsTransformContext, firebaseServerActionsTransformFactory, firebaseServerAppTokenProvider, firebaseServerAuthModuleMetadata, firebaseServerDevFunctions, firebaseServerEnvTokenProvider, firebaseServerEnvTokenProviders, firebaseServerErrorInfo, firebaseServerErrorInfoCodePair, firebaseServerErrorInfoServerErrorCodePair, firebaseServerErrorInfoServerErrorPair, firebaseServerFirestoreContextModuleMetadata, firebaseServerStorageDefaultBucketIdTokenProvider, firebaseServerStorageModuleMetadata, firebaseServerValidationError, firebaseServerValidationServerError, firestoreClientQueryConstraintFunctionsDriver, firestoreEncryptedField, firestoreServerIncrementUpdateToUpdateData, forbiddenError, getAuthUserOrUndefined, getModelApiDetails, googleCloudFileMetadataToStorageMetadata, googleCloudFirebaseStorageContextFactory, googleCloudFirebaseStorageDrivers, googleCloudFirestoreAccessorDriver, googleCloudFirestoreContextFactory, googleCloudFirestoreDrivers, googleCloudFirestoreQueryDriver, googleCloudStorageAccessorFile, googleCloudStorageAccessorFolder, googleCloudStorageBucketForStorageFilePath, googleCloudStorageFileForStorageFilePath, googleCloudStorageFirebaseStorageAccessorDriver, googleCloudStorageFromFirebaseAdminStorage, googleCloudStorageListFilesResultFactory, handleFirebaseAuthError, handleFirebaseError, hasAuthRolesInRequest, hasNewUserSetupPasswordInRequest, hasSignedTosInRequest, inAuthContext, injectNestApplicationContextIntoRequest, injectNestIntoRequest, internalServerError, invokeModelUnknownModelTypeError, isActualSpecifier, isAdminInRequest, isAdminOrTargetUserInRequestData, isContextWithAuthData, isFirebaseError, isFirebaseHttpsError, isOnCallCrudModelApiDetails, isOnCallHandlerApiDetails, isOnCallModelTypeApiDetails, isOnCallSpecifierApiDetails, makeBlockingFunctionWithHandler, makeOnScheduleHandlerWithNestApplicationRequest, makeScheduledFunctionDevelopmentFunction, modelAccessReadErrorFromUseMultipleModelsFailure, modelApiModuleMetadata, modelNotAvailableError, nestAppHasDevelopmentSchedulerEnabled, nestAppIsProductionEnvironment, nestFirebaseDoesNotExistError, nestFirebaseForbiddenPermissionError, nestServerInstance, noRunNameSpecifiedForScheduledFunctionDevelopmentFunction, noopFirebaseServerAnalyticsServiceListener, noopOnCallModelAnalyticsService, notFoundError, onCallAnalyticsEmitterInstance, onCallCreateModel, onCallDeleteModel, onCallDevelopmentFunction, onCallHandlerWithNestApplicationFactory, onCallHandlerWithNestContextFactory, onCallInvokeModel, onCallModel, onCallModelMissingCallTypeError, onCallModelUnknownCallTypeError, onCallQueryModel, onCallReadModel, onCallSpecifierHandler, onCallUpdateModel, onScheduleHandlerWithNestApplicationFactory, onScheduleHandlerWithNestContextFactory, optionalAuthContext, optionalFirestoreEncryptedField, permissionDeniedError, phoneNumberAlreadyExistsError, preconditionConflictError, provideAppFirestoreCollections, provideFirebaseServerAuthService, provideFirebaseServerStorageService, queryModelBadCursorError, queryModelUnknownModelTypeError, readApiDetails, readModelUnknownModelTypeError, resolveAdminOnlyValue, resolveAnalyticsFromApiDetails, setNestContextOnRequest, setNestContextOnScheduleRequest, taskQueueFunctionHandlerWithNestContextFactory, unauthenticatedContextHasNoAuthData, unauthenticatedContextHasNoUidError, unauthenticatedError, unavailableError, unavailableOrDeactivatedFunctionError, unknownModelCrudFunctionSpecifierError, unknownScheduledFunctionDevelopmentFunctionName, unknownScheduledFunctionDevelopmentFunctionType, updateModelUnknownModelTypeError, userContextFromUid, verifyAppCheckInRequest, withApiDetails };
13245
+ export { AbstractFirebaseNestContext, AbstractFirebaseServerActionsContext, AbstractFirebaseServerAuthContext, AbstractFirebaseServerAuthService, AbstractFirebaseServerAuthUserContext, AbstractFirebaseServerNewUserService, AbstractFirebaseServerUserPasswordResetService, AbstractNestContext, AbstractServerFirebaseNestContext, ConfigureFirebaseAppCheckMiddlewareModule, ConfigureFirebaseWebhookMiddlewareModule, DEFAULT_FIREBASE_PASSWORD_NUMBER_GENERATOR, DEFAULT_RESET_CODE_EXPIRES_IN, DEFAULT_RESET_COM_THROTTLE_TIME, DEFAULT_SERVER_ASSETS_BASE_PATH, DEFAULT_SETUP_COM_THROTTLE_TIME, DefaultFirebaseServerEnvService, FIREBASE_APP_TOKEN, FIREBASE_AUTH_TOKEN, FIREBASE_FIRESTORE_CONTEXT_TOKEN, FIREBASE_FIRESTORE_TOKEN, FIREBASE_SERVER_ENV_TOKEN, FIREBASE_SERVER_VALIDATION_ERROR_CODE, FIREBASE_STORAGE_CONTEXT_FACTORY_CONFIG_TOKEN, FIREBASE_STORAGE_CONTEXT_TOKEN, FIREBASE_STORAGE_TOKEN, FIRESTORE_CLIENT_QUERY_CONSTRAINT_HANDLER_MAPPING, FirebaseAppCheckMiddleware, FirebaseAppCheckMiddlewareConfig, FirebaseNestServerRootModule, FirebaseRawBodyMiddleware, FirebaseServerAnalyticsSegmentListenerService, FirebaseServerAnalyticsSegmentModule, FirebaseServerAnalyticsService, FirebaseServerAnalyticsServiceListener, FirebaseServerAuthModule, FirebaseServerAuthNewUserSendSetupDetailsNoSetupConfigError, FirebaseServerAuthNewUserSendSetupDetailsSendOnceError, FirebaseServerAuthNewUserSendSetupDetailsThrottleError, FirebaseServerAuthPasswordResetInvalidCodeError, FirebaseServerAuthPasswordResetNoResetConfigError, FirebaseServerAuthPasswordResetSendOnceError, FirebaseServerAuthPasswordResetThrottleError, FirebaseServerAuthService, FirebaseServerAuthUserBadInputError, FirebaseServerAuthUserExistsError, FirebaseServerEnvService, FirebaseServerFirestoreContextModule, FirebaseServerFirestoreModule, FirebaseServerStorageContextModule, FirebaseServerStorageModule, FirebaseServerStorageService, GlobalRoutePrefixConfig, MAX_MODEL_ACCESS_MULTI_READ_KEYS, MODEL_API_NEST_APPLICATION_CONTEXT, ModelApiCallModelDispatchService, ModelApiController, ModelApiDispatchConfig, ModelApiGetService, NO_RUN_NAME_SPECIFIED_FOR_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_CODE, NoContentFirebaseServerUserPasswordResetService, NoSetupContentFirebaseServerNewUserService, ON_CALL_MODEL_ANALYTICS_HANDLER, ON_CALL_MODEL_ANALYTICS_SERVICE, OnCallModelAnalyticsService, PHONE_NUMBER_ALREADY_EXISTS_ERROR_CODE, SkipAppCheck, UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_NAME_CODE, UNKNOWN_SCHEDULED_FUNCTION_DEVELOPMENT_FUNCTION_TYPE_CODE, _onCallWithCallTypeFunction, aggregateCrudModelApiDetails, aggregateModelApiDetails, aggregateSpecifierApiDetails, alreadyExistsError, appAnalyticsModuleMetadata, appFirestoreModuleMetadata, assertContextHasAuth, assertDocumentExists, assertHasRolesInRequest, assertHasSignedTosInRequest, assertIsAdminInRequest, assertIsAdminOrTargetUserInRequestData, assertIsContextWithAuthData, assertModelApiOidcScope, assertRequestRequiresAuthForFunction, assertSnapshotData, assertSnapshotDataWithKey, authServicePasswordResetInvalidCodeError, authServicePasswordResetNoConfigError, authServicePasswordResetSendOnceError, authServicePasswordResetThrottleError, badRequestError, blockingFunctionHandlerWithNestContextFactory, buildNestServerRootModule, callWithAnalytics, catchAndThrowPasswordResetServerErrors, cloudEventHandlerWithNestContextFactory, collectionRefForPath, createModelUnknownModelTypeError, decodeFirebaseServerUserPasswordResetOobCode, defaultFirebaseServerActionsTransformFactoryLogErrorFunction, defaultProvideFirebaseServerStorageServiceSimple, deleteModelUnknownModelTypeError, developmentUnknownSpecifierError, docRefForPath, documentModelNotAvailableError, encodeFirebaseServerUserPasswordResetOobCode, executeOnCallQuery, firebaseAuthTokenFromDecodedIdToken, firebaseServerActionsContext, firebaseServerActionsTransformContext, firebaseServerActionsTransformFactory, firebaseServerAppTokenProvider, firebaseServerAuthModuleMetadata, firebaseServerDevFunctions, firebaseServerEnvTokenProvider, firebaseServerEnvTokenProviders, firebaseServerErrorInfo, firebaseServerErrorInfoCodePair, firebaseServerErrorInfoServerErrorCodePair, firebaseServerErrorInfoServerErrorPair, firebaseServerFirestoreContextModuleMetadata, firebaseServerStorageDefaultBucketIdTokenProvider, firebaseServerStorageModuleMetadata, firebaseServerValidationError, firebaseServerValidationServerError, firestoreClientQueryConstraintFunctionsDriver, firestoreEncryptedField, firestoreServerIncrementUpdateToUpdateData, forbiddenError, getAuthUserOrUndefined, getModelApiDetails, googleCloudFileMetadataToStorageMetadata, googleCloudFirebaseStorageContextFactory, googleCloudFirebaseStorageDrivers, googleCloudFirestoreAccessorDriver, googleCloudFirestoreContextFactory, googleCloudFirestoreDrivers, googleCloudFirestoreQueryDriver, googleCloudStorageAccessorFile, googleCloudStorageAccessorFolder, googleCloudStorageBucketForStorageFilePath, googleCloudStorageFileForStorageFilePath, googleCloudStorageFirebaseStorageAccessorDriver, googleCloudStorageFromFirebaseAdminStorage, googleCloudStorageListFilesResultFactory, handleFirebaseAuthError, handleFirebaseError, hasAuthRolesInRequest, hasNewUserSetupPasswordInRequest, hasSignedTosInRequest, inAuthContext, injectNestApplicationContextIntoRequest, injectNestIntoRequest, internalServerError, invokeModelUnknownModelTypeError, isActualSpecifier, isAdminInRequest, isAdminOrTargetUserInRequestData, isContextWithAuthData, isFirebaseError, isFirebaseHttpsError, isOnCallCrudModelApiDetails, isOnCallHandlerApiDetails, isOnCallModelTypeApiDetails, isOnCallSpecifierApiDetails, makeBlockingFunctionWithHandler, makeOnScheduleHandlerWithNestApplicationRequest, makeScheduledFunctionDevelopmentFunction, modelAccessReadErrorFromUseMultipleModelsFailure, modelApiModuleMetadata, modelNotAvailableError, nestAppHasDevelopmentSchedulerEnabled, nestAppIsProductionEnvironment, nestFirebaseDoesNotExistError, nestFirebaseForbiddenPermissionError, nestServerInstance, noRunNameSpecifiedForScheduledFunctionDevelopmentFunction, noopFirebaseServerAnalyticsServiceListener, noopOnCallModelAnalyticsService, notFoundError, oidcScopesFromModelApiAuth, onCallAnalyticsEmitterInstance, onCallCreateModel, onCallDeleteModel, onCallDevelopmentFunction, onCallHandlerWithNestApplicationFactory, onCallHandlerWithNestContextFactory, onCallInvokeModel, onCallModel, onCallModelMissingCallTypeError, onCallModelUnknownCallTypeError, onCallQueryModel, onCallReadModel, onCallSpecifierHandler, onCallUpdateModel, onScheduleHandlerWithNestApplicationFactory, onScheduleHandlerWithNestContextFactory, optionalAuthContext, optionalFirestoreEncryptedField, permissionDeniedError, phoneNumberAlreadyExistsError, preconditionConflictError, provideAppFirestoreCollections, provideFirebaseServerAuthService, provideFirebaseServerStorageService, queryModelBadCursorError, queryModelUnknownModelTypeError, readApiDetails, readModelUnknownModelTypeError, resolveAdminOnlyValue, resolveAnalyticsFromApiDetails, resolveRequiredScopeFromApiDetails, setNestContextOnRequest, setNestContextOnScheduleRequest, taskQueueFunctionHandlerWithNestContextFactory, unauthenticatedContextHasNoAuthData, unauthenticatedContextHasNoUidError, unauthenticatedError, unavailableError, unavailableOrDeactivatedFunctionError, unknownModelCrudFunctionSpecifierError, unknownScheduledFunctionDevelopmentFunctionName, unknownScheduledFunctionDevelopmentFunctionType, updateModelUnknownModelTypeError, userContextFromUid, verifyAppCheckInRequest, withApiDetails };
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server/mailgun",
3
- "version": "13.28.0",
3
+ "version": "13.30.0",
4
4
  "peerDependencies": {
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"
5
+ "@dereekb/analytics": "13.30.0",
6
+ "@dereekb/firebase": "13.30.0",
7
+ "@dereekb/firebase-server": "13.30.0",
8
+ "@dereekb/date": "13.30.0",
9
+ "@dereekb/nestjs": "13.30.0",
10
+ "@dereekb/model": "13.30.0",
11
+ "@dereekb/rxjs": "13.30.0",
12
+ "@dereekb/util": "13.30.0"
13
13
  },
14
14
  "exports": {
15
15
  "./package.json": "./package.json",