@dereekb/firebase-server 13.28.0 → 13.29.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 +32 -1
- package/index.esm.js +32 -2
- package/mailgun/package.json +9 -9
- package/mcp/index.cjs.js +14 -6
- package/mcp/index.esm.js +15 -7
- package/mcp/package.json +11 -11
- package/mcp/src/lib/service/mcp.visibility.d.ts +6 -4
- package/model/package.json +9 -9
- package/oidc/index.cjs.js +197 -50
- package/oidc/index.esm.js +198 -53
- package/oidc/package.json +10 -10
- package/oidc/src/lib/index.d.ts +1 -0
- package/oidc/src/lib/oidc.config.d.ts +14 -1
- package/oidc/src/lib/profile.d.ts +29 -0
- package/oidc/src/lib/scope.d.ts +8 -3
- package/package.json +10 -10
- package/src/lib/nest/model/api.details.d.ts +25 -1
- package/src/lib/nest/model/crud.assert.function.d.ts +9 -1
- package/test/index.cjs.js +10 -3
- package/test/index.esm.js +11 -4
- package/test/package.json +11 -11
- package/test/src/lib/oidc/oidc.test.flow.d.ts +1 -1
- package/twilio/package.json +8 -8
- package/zoho/package.json +9 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.29.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"exports": {
|
|
6
6
|
"./test": {
|
|
@@ -57,15 +57,15 @@
|
|
|
57
57
|
"types": "./src/index.d.ts",
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"@cantoo/pdf-lib": "^2.6.5",
|
|
60
|
-
"@dereekb/analytics": "13.
|
|
61
|
-
"@dereekb/date": "13.
|
|
62
|
-
"@dereekb/dbx-core": "13.
|
|
63
|
-
"@dereekb/firebase": "13.
|
|
64
|
-
"@dereekb/model": "13.
|
|
65
|
-
"@dereekb/nestjs": "13.
|
|
66
|
-
"@dereekb/rxjs": "13.
|
|
67
|
-
"@dereekb/util": "13.
|
|
68
|
-
"@dereekb/zoho": "13.
|
|
60
|
+
"@dereekb/analytics": "13.29.0",
|
|
61
|
+
"@dereekb/date": "13.29.0",
|
|
62
|
+
"@dereekb/dbx-core": "13.29.0",
|
|
63
|
+
"@dereekb/firebase": "13.29.0",
|
|
64
|
+
"@dereekb/model": "13.29.0",
|
|
65
|
+
"@dereekb/nestjs": "13.29.0",
|
|
66
|
+
"@dereekb/rxjs": "13.29.0",
|
|
67
|
+
"@dereekb/util": "13.29.0",
|
|
68
|
+
"@dereekb/zoho": "13.29.0",
|
|
69
69
|
"@google-cloud/firestore": "^7.11.6",
|
|
70
70
|
"@google-cloud/storage": "^7.19.0",
|
|
71
71
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AuthRole, type Maybe, type PromiseOrValue } from '@dereekb/util';
|
|
2
|
-
import { type OnCallFunctionType, type OnCallTypedModelParams, type FirestoreModelType, type ModelFirebaseCrudFunctionSpecifier } from '@dereekb/firebase';
|
|
2
|
+
import { type OnCallFunctionType, type OnCallTypedModelParams, type FirestoreModelType, type ModelFirebaseCrudFunctionSpecifier, type OidcScope } from '@dereekb/firebase';
|
|
3
3
|
import { type FirebaseServerAuthData } from '../controller/auth.context.server';
|
|
4
4
|
import { type OnCallModelFunctionAnalyticsDetails } from './analytics.details';
|
|
5
5
|
/**
|
|
@@ -302,6 +302,16 @@ export interface OnCallModelFunctionApiDetails<R = unknown, M = unknown> {
|
|
|
302
302
|
* When provided, the dispatch chain will call lifecycle hooks around handler execution.
|
|
303
303
|
*/
|
|
304
304
|
readonly analytics?: OnCallModelFunctionAnalyticsDetails;
|
|
305
|
+
/**
|
|
306
|
+
* Optional per-function OIDC scope an OIDC-authenticated caller must additionally hold to
|
|
307
|
+
* invoke this handler, on top of the per-verb `model.<call>` scope.
|
|
308
|
+
*
|
|
309
|
+
* Composes additively with the CRUD-verb scope enforced by `oidcCallModelScopePreAssert`: an
|
|
310
|
+
* OIDC caller still needs `model.<call>` AND this scope. Non-OIDC callers (Firebase ID tokens)
|
|
311
|
+
* bypass scope enforcement entirely and are unaffected. Also folded into the MCP tool-list
|
|
312
|
+
* visibility filter, so a tool the caller lacks this scope for is neither listed nor callable.
|
|
313
|
+
*/
|
|
314
|
+
readonly requiredScope?: OidcScope;
|
|
305
315
|
}
|
|
306
316
|
/**
|
|
307
317
|
* Ref interface for objects (functions) that carry handler-level _apiDetails.
|
|
@@ -564,6 +574,20 @@ export declare function getModelApiDetails(callModelFn: Maybe<OnCallApiDetailsRe
|
|
|
564
574
|
* @returns The analytics details for the resolved handler, or undefined.
|
|
565
575
|
*/
|
|
566
576
|
export declare function resolveAnalyticsFromApiDetails(apiDetails: OnCallModelApiDetails, call: OnCallFunctionType, modelType: FirestoreModelType, specifier?: ModelFirebaseCrudFunctionSpecifier): Maybe<OnCallModelFunctionAnalyticsDetails>;
|
|
577
|
+
/**
|
|
578
|
+
* Resolves the leaf-level per-function required OIDC scope from the aggregated _apiDetails tree.
|
|
579
|
+
*
|
|
580
|
+
* Walks: call -> modelType -> specifier (if specifier-level), then reads the `requiredScope`
|
|
581
|
+
* field from the handler-level {@link OnCallModelFunctionApiDetails}. Mirrors
|
|
582
|
+
* {@link resolveAnalyticsFromApiDetails}.
|
|
583
|
+
*
|
|
584
|
+
* @param apiDetails - The top-level aggregated API details.
|
|
585
|
+
* @param call - The CRUD operation type to look up.
|
|
586
|
+
* @param modelType - The Firestore model type to look up.
|
|
587
|
+
* @param specifier - Optional specifier key for variant handlers.
|
|
588
|
+
* @returns The per-function required scope for the resolved handler, or undefined.
|
|
589
|
+
*/
|
|
590
|
+
export declare function resolveRequiredScopeFromApiDetails(apiDetails: OnCallModelApiDetails, call: OnCallFunctionType, modelType: FirestoreModelType, specifier?: ModelFirebaseCrudFunctionSpecifier): Maybe<OidcScope>;
|
|
567
591
|
/**
|
|
568
592
|
* @deprecated Use {@link OnCallModelTypeApiDetails} instead.
|
|
569
593
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Maybe } from '@dereekb/util';
|
|
2
2
|
import { type NestContextCallableRequest } from '../function/nest';
|
|
3
|
-
import { type OnCallFunctionType, type FirestoreModelType } from '@dereekb/firebase';
|
|
3
|
+
import { type OnCallFunctionType, type FirestoreModelType, type OidcScope } from '@dereekb/firebase';
|
|
4
4
|
/**
|
|
5
5
|
* Discriminator for the category of CRUD operation being asserted.
|
|
6
6
|
*
|
|
@@ -34,6 +34,14 @@ export interface AssertModelCrudRequestFunctionContext<N, I = unknown> {
|
|
|
34
34
|
* The optional sub-operation specifier (e.g., 'username', 'fromUpload').
|
|
35
35
|
*/
|
|
36
36
|
readonly specifier: Maybe<string>;
|
|
37
|
+
/**
|
|
38
|
+
* The per-function required OIDC scope declared via `withApiDetails({ requiredScope })`, when present.
|
|
39
|
+
*
|
|
40
|
+
* Resolved from the handler's `_apiDetails` at dispatch and handed to the pre-assert so
|
|
41
|
+
* `oidcCallModelScopePreAssert` can require it additively alongside the per-verb `model.<call>`
|
|
42
|
+
* scope. `undefined` when the handler declares no extra scope.
|
|
43
|
+
*/
|
|
44
|
+
readonly requiredScope?: Maybe<OidcScope>;
|
|
37
45
|
}
|
|
38
46
|
/**
|
|
39
47
|
* Pre-assertion hook invoked before a model CRUD handler executes.
|
package/test/index.cjs.js
CHANGED
|
@@ -4922,18 +4922,24 @@ function _ts_generator$1(thisArg, body) {
|
|
|
4922
4922
|
}
|
|
4923
4923
|
/**
|
|
4924
4924
|
* Resolves the scopes string from config, or falls back to all registered scopes
|
|
4925
|
-
* from the provider config — excluding any `adminOnlyScopes
|
|
4925
|
+
* from the provider config — excluding any `adminOnlyScopes` or provider-profile-gated scopes.
|
|
4926
4926
|
*
|
|
4927
4927
|
* Admin-only scopes (e.g. `token.service`) are dropped from the default "all scopes" request because
|
|
4928
4928
|
* the provider hard-rejects them for non-admin users, and this default flow logs in an arbitrary
|
|
4929
4929
|
* (often non-admin) user. Tests that need an admin-only scope pass it explicitly via `config.scopes`.
|
|
4930
4930
|
*
|
|
4931
|
+
* Provider-profile-gated scopes (e.g. `lms`, `reports`) are dropped for the same reason: they are
|
|
4932
|
+
* unlocked only for a client an admin has assigned the corresponding profile to, and this flow creates
|
|
4933
|
+
* a fresh client with no profiles — so the consent unlock gate hard-rejects them (finishing the
|
|
4934
|
+
* interaction with `access_denied` and no `code`). Tests that need a gated scope create a client with
|
|
4935
|
+
* the profile and pass the scope explicitly via `config.scopes`.
|
|
4936
|
+
*
|
|
4931
4937
|
* @param nestApp - Initialized NestJS application used to resolve {@link OidcAccountService} when no scopes override is given.
|
|
4932
4938
|
* @param config - Optional flow config; when `config.scopes` is set, it is returned verbatim.
|
|
4933
4939
|
* @returns The space-separated scope string to pass to the `/oidc/auth` endpoint.
|
|
4934
4940
|
*/ function resolveScopes(nestApp, config) {
|
|
4935
4941
|
return _async_to_generator$1(function() {
|
|
4936
|
-
var result, _providerConfig_adminOnlyScopes, accountService, providerConfig, adminOnlyScopes;
|
|
4942
|
+
var result, _providerConfig_adminOnlyScopes, _providerConfig_providerProfiles, accountService, providerConfig, adminOnlyScopes, profileGatedScopes;
|
|
4937
4943
|
return _ts_generator$1(this, function(_state) {
|
|
4938
4944
|
if (config === null || config === void 0 ? void 0 : config.scopes) {
|
|
4939
4945
|
result = config.scopes;
|
|
@@ -4941,8 +4947,9 @@ function _ts_generator$1(thisArg, body) {
|
|
|
4941
4947
|
accountService = nestApp.get(oidc.OidcAccountService);
|
|
4942
4948
|
providerConfig = accountService.providerConfig;
|
|
4943
4949
|
adminOnlyScopes = new Set((_providerConfig_adminOnlyScopes = providerConfig.adminOnlyScopes) !== null && _providerConfig_adminOnlyScopes !== void 0 ? _providerConfig_adminOnlyScopes : []);
|
|
4950
|
+
profileGatedScopes = firebase.scopesForOidcProviderProfiles((_providerConfig_providerProfiles = providerConfig.providerProfiles) !== null && _providerConfig_providerProfiles !== void 0 ? _providerConfig_providerProfiles : []);
|
|
4944
4951
|
result = Object.keys(providerConfig.claims).filter(function(scope) {
|
|
4945
|
-
return !adminOnlyScopes.has(scope);
|
|
4952
|
+
return !adminOnlyScopes.has(scope) && !profileGatedScopes.has(scope);
|
|
4946
4953
|
}).join(' ');
|
|
4947
4954
|
}
|
|
4948
4955
|
return [
|
package/test/index.esm.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomEmailFactory, randomPhoneNumberFactory, mapGetter, incrementingNumberFactory, asGetter, getValueFromGetter, cachedGetter, asArray, mapObjectMap, unixDateTimeSecondsNumberForNow } from '@dereekb/util';
|
|
2
2
|
import { useTestContextFixture, AbstractChildTestContextFixture, testContextBuilder, AbstractTestContextFixture, useTestFunctionFixture, useTestFunctionMapFixture, ExpectedErrorOfSpecificTypeError } from '@dereekb/util/test';
|
|
3
3
|
import { decode } from 'jsonwebtoken';
|
|
4
|
-
import { flatFirestoreModelKey, twoWayFlatFirestoreModelKey, firestoreContextFactory, firebaseStorageContextFactory } from '@dereekb/firebase';
|
|
4
|
+
import { flatFirestoreModelKey, twoWayFlatFirestoreModelKey, firestoreContextFactory, firebaseStorageContextFactory, scopesForOidcProviderProfiles } from '@dereekb/firebase';
|
|
5
5
|
import admin from 'firebase-admin';
|
|
6
6
|
import functions from 'firebase-functions-test';
|
|
7
7
|
import { makeTestingFirestoreDrivers, TestFirestoreInstance, TestFirestoreContextFixture, makeTestingFirebaseStorageDrivers, TestFirebaseStorageInstance, TestFirebaseStorageContextFixture, mockItemFirestoreCollection, testWithMockItemCollectionFixture, testWithMockItemStorageFixture } from '@dereekb/firebase/test';
|
|
@@ -4921,18 +4921,24 @@ function _ts_generator$1(thisArg, body) {
|
|
|
4921
4921
|
}
|
|
4922
4922
|
/**
|
|
4923
4923
|
* Resolves the scopes string from config, or falls back to all registered scopes
|
|
4924
|
-
* from the provider config — excluding any `adminOnlyScopes
|
|
4924
|
+
* from the provider config — excluding any `adminOnlyScopes` or provider-profile-gated scopes.
|
|
4925
4925
|
*
|
|
4926
4926
|
* Admin-only scopes (e.g. `token.service`) are dropped from the default "all scopes" request because
|
|
4927
4927
|
* the provider hard-rejects them for non-admin users, and this default flow logs in an arbitrary
|
|
4928
4928
|
* (often non-admin) user. Tests that need an admin-only scope pass it explicitly via `config.scopes`.
|
|
4929
4929
|
*
|
|
4930
|
+
* Provider-profile-gated scopes (e.g. `lms`, `reports`) are dropped for the same reason: they are
|
|
4931
|
+
* unlocked only for a client an admin has assigned the corresponding profile to, and this flow creates
|
|
4932
|
+
* a fresh client with no profiles — so the consent unlock gate hard-rejects them (finishing the
|
|
4933
|
+
* interaction with `access_denied` and no `code`). Tests that need a gated scope create a client with
|
|
4934
|
+
* the profile and pass the scope explicitly via `config.scopes`.
|
|
4935
|
+
*
|
|
4930
4936
|
* @param nestApp - Initialized NestJS application used to resolve {@link OidcAccountService} when no scopes override is given.
|
|
4931
4937
|
* @param config - Optional flow config; when `config.scopes` is set, it is returned verbatim.
|
|
4932
4938
|
* @returns The space-separated scope string to pass to the `/oidc/auth` endpoint.
|
|
4933
4939
|
*/ function resolveScopes(nestApp, config) {
|
|
4934
4940
|
return _async_to_generator$1(function() {
|
|
4935
|
-
var result, _providerConfig_adminOnlyScopes, accountService, providerConfig, adminOnlyScopes;
|
|
4941
|
+
var result, _providerConfig_adminOnlyScopes, _providerConfig_providerProfiles, accountService, providerConfig, adminOnlyScopes, profileGatedScopes;
|
|
4936
4942
|
return _ts_generator$1(this, function(_state) {
|
|
4937
4943
|
if (config === null || config === void 0 ? void 0 : config.scopes) {
|
|
4938
4944
|
result = config.scopes;
|
|
@@ -4940,8 +4946,9 @@ function _ts_generator$1(thisArg, body) {
|
|
|
4940
4946
|
accountService = nestApp.get(OidcAccountService);
|
|
4941
4947
|
providerConfig = accountService.providerConfig;
|
|
4942
4948
|
adminOnlyScopes = new Set((_providerConfig_adminOnlyScopes = providerConfig.adminOnlyScopes) !== null && _providerConfig_adminOnlyScopes !== void 0 ? _providerConfig_adminOnlyScopes : []);
|
|
4949
|
+
profileGatedScopes = scopesForOidcProviderProfiles((_providerConfig_providerProfiles = providerConfig.providerProfiles) !== null && _providerConfig_providerProfiles !== void 0 ? _providerConfig_providerProfiles : []);
|
|
4943
4950
|
result = Object.keys(providerConfig.claims).filter(function(scope) {
|
|
4944
|
-
return !adminOnlyScopes.has(scope);
|
|
4951
|
+
return !adminOnlyScopes.has(scope) && !profileGatedScopes.has(scope);
|
|
4945
4952
|
}).join(' ');
|
|
4946
4953
|
}
|
|
4947
4954
|
return [
|
package/test/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/test",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.29.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server": "13.
|
|
9
|
-
"@dereekb/firebase-server/oidc": "13.
|
|
10
|
-
"@dereekb/model": "13.
|
|
11
|
-
"@dereekb/nestjs": "13.
|
|
12
|
-
"@dereekb/rxjs": "13.
|
|
13
|
-
"@dereekb/util": "13.
|
|
5
|
+
"@dereekb/analytics": "13.29.0",
|
|
6
|
+
"@dereekb/date": "13.29.0",
|
|
7
|
+
"@dereekb/firebase": "13.29.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.29.0",
|
|
9
|
+
"@dereekb/firebase-server/oidc": "13.29.0",
|
|
10
|
+
"@dereekb/model": "13.29.0",
|
|
11
|
+
"@dereekb/nestjs": "13.29.0",
|
|
12
|
+
"@dereekb/rxjs": "13.29.0",
|
|
13
|
+
"@dereekb/util": "13.29.0",
|
|
14
14
|
"@google-cloud/firestore": "^7.11.6",
|
|
15
15
|
"@google-cloud/storage": "^7.19.0",
|
|
16
16
|
"@nestjs/common": "^11.1.19",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"supertest": "^7.2.2"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@dereekb/nestjs": "13.
|
|
26
|
+
"@dereekb/nestjs": "13.29.0"
|
|
27
27
|
},
|
|
28
28
|
"exports": {
|
|
29
29
|
"./package.json": "./package.json",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type INestApplication } from '@nestjs/common';
|
|
2
|
-
import type
|
|
2
|
+
import { type OidcTokenEndpointAuthMethod } from '@dereekb/firebase';
|
|
3
3
|
import { OidcClientService } from '@dereekb/firebase-server/oidc';
|
|
4
4
|
/**
|
|
5
5
|
* Configuration for {@link performFullOAuthFlow}.
|
package/twilio/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/twilio",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.29.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/date": "13.
|
|
6
|
-
"@dereekb/firebase": "13.
|
|
7
|
-
"@dereekb/firebase-server": "13.
|
|
8
|
-
"@dereekb/model": "13.
|
|
9
|
-
"@dereekb/nestjs": "13.
|
|
10
|
-
"@dereekb/rxjs": "13.
|
|
11
|
-
"@dereekb/util": "13.
|
|
5
|
+
"@dereekb/date": "13.29.0",
|
|
6
|
+
"@dereekb/firebase": "13.29.0",
|
|
7
|
+
"@dereekb/firebase-server": "13.29.0",
|
|
8
|
+
"@dereekb/model": "13.29.0",
|
|
9
|
+
"@dereekb/nestjs": "13.29.0",
|
|
10
|
+
"@dereekb/rxjs": "13.29.0",
|
|
11
|
+
"@dereekb/util": "13.29.0"
|
|
12
12
|
},
|
|
13
13
|
"exports": {
|
|
14
14
|
"./package.json": "./package.json",
|
package/zoho/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/zoho",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.29.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/model": "13.
|
|
8
|
-
"@dereekb/nestjs": "13.
|
|
9
|
-
"@dereekb/rxjs": "13.
|
|
10
|
-
"@dereekb/firebase": "13.
|
|
11
|
-
"@dereekb/util": "13.
|
|
12
|
-
"@dereekb/zoho": "13.
|
|
5
|
+
"@dereekb/analytics": "13.29.0",
|
|
6
|
+
"@dereekb/date": "13.29.0",
|
|
7
|
+
"@dereekb/model": "13.29.0",
|
|
8
|
+
"@dereekb/nestjs": "13.29.0",
|
|
9
|
+
"@dereekb/rxjs": "13.29.0",
|
|
10
|
+
"@dereekb/firebase": "13.29.0",
|
|
11
|
+
"@dereekb/util": "13.29.0",
|
|
12
|
+
"@dereekb/zoho": "13.29.0"
|
|
13
13
|
},
|
|
14
14
|
"exports": {
|
|
15
15
|
"./package.json": "./package.json",
|