@dereekb/firebase-server 13.30.0 → 13.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mailgun/package.json +9 -9
- package/mcp/package.json +11 -11
- package/model/package.json +9 -9
- package/oidc/index.cjs.js +28 -12
- package/oidc/index.esm.js +29 -13
- package/oidc/package.json +10 -10
- package/oidc/src/lib/oidc.config.d.ts +11 -0
- package/oidc/src/lib/profile.d.ts +7 -0
- package/package.json +10 -10
- package/test/index.cjs.js +94 -58
- package/test/index.esm.js +95 -59
- package/test/package.json +11 -11
- package/test/src/lib/oidc/oidc.test.fixture.d.ts +9 -1
- package/test/src/lib/oidc/oidc.test.flow.d.ts +13 -3
- package/twilio/package.json +8 -8
- package/zoho/package.json +9 -9
package/mailgun/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/mailgun",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.31.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/firebase": "13.
|
|
7
|
-
"@dereekb/firebase-server": "13.
|
|
8
|
-
"@dereekb/date": "13.
|
|
9
|
-
"@dereekb/nestjs": "13.
|
|
10
|
-
"@dereekb/model": "13.
|
|
11
|
-
"@dereekb/rxjs": "13.
|
|
12
|
-
"@dereekb/util": "13.
|
|
5
|
+
"@dereekb/analytics": "13.31.0",
|
|
6
|
+
"@dereekb/firebase": "13.31.0",
|
|
7
|
+
"@dereekb/firebase-server": "13.31.0",
|
|
8
|
+
"@dereekb/date": "13.31.0",
|
|
9
|
+
"@dereekb/nestjs": "13.31.0",
|
|
10
|
+
"@dereekb/model": "13.31.0",
|
|
11
|
+
"@dereekb/rxjs": "13.31.0",
|
|
12
|
+
"@dereekb/util": "13.31.0"
|
|
13
13
|
},
|
|
14
14
|
"exports": {
|
|
15
15
|
"./package.json": "./package.json",
|
package/mcp/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/mcp",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.31.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server": "13.
|
|
9
|
-
"@dereekb/firebase-server/oidc": "13.
|
|
10
|
-
"@dereekb/model": "13.
|
|
11
|
-
"@dereekb/nestjs": "13.
|
|
12
|
-
"@dereekb/rxjs": "13.
|
|
13
|
-
"@dereekb/util": "13.
|
|
14
|
-
"@dereekb/zoho": "13.
|
|
5
|
+
"@dereekb/analytics": "13.31.0",
|
|
6
|
+
"@dereekb/date": "13.31.0",
|
|
7
|
+
"@dereekb/firebase": "13.31.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.31.0",
|
|
9
|
+
"@dereekb/firebase-server/oidc": "13.31.0",
|
|
10
|
+
"@dereekb/model": "13.31.0",
|
|
11
|
+
"@dereekb/nestjs": "13.31.0",
|
|
12
|
+
"@dereekb/rxjs": "13.31.0",
|
|
13
|
+
"@dereekb/util": "13.31.0",
|
|
14
|
+
"@dereekb/zoho": "13.31.0",
|
|
15
15
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
16
16
|
"@nestjs/common": "^11.1.19",
|
|
17
17
|
"@nestjs/core": "^11.1.19",
|
package/model/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/model",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.31.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server": "13.
|
|
9
|
-
"@dereekb/model": "13.
|
|
10
|
-
"@dereekb/nestjs": "13.
|
|
11
|
-
"@dereekb/rxjs": "13.
|
|
12
|
-
"@dereekb/util": "13.
|
|
5
|
+
"@dereekb/analytics": "13.31.0",
|
|
6
|
+
"@dereekb/date": "13.31.0",
|
|
7
|
+
"@dereekb/firebase": "13.31.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.31.0",
|
|
9
|
+
"@dereekb/model": "13.31.0",
|
|
10
|
+
"@dereekb/nestjs": "13.31.0",
|
|
11
|
+
"@dereekb/rxjs": "13.31.0",
|
|
12
|
+
"@dereekb/util": "13.31.0",
|
|
13
13
|
"@nestjs/common": "^11.1.19",
|
|
14
14
|
"@nestjs/config": "^4.0.4",
|
|
15
15
|
"archiver": "^7.0.1",
|
package/oidc/index.cjs.js
CHANGED
|
@@ -3555,11 +3555,18 @@ exports.OidcProviderConfigService = __decorate([
|
|
|
3555
3555
|
* Resolves the unlocked + required scope sets for a client from the provider-profile registry and
|
|
3556
3556
|
* the profile keys assigned to that client.
|
|
3557
3557
|
*
|
|
3558
|
+
* A client with NO assigned profiles resolves to the registry's default profiles (those marked
|
|
3559
|
+
* `isDefault`), so a registry declaring no default resolves exactly as it would from the assigned
|
|
3560
|
+
* keys alone.
|
|
3561
|
+
*
|
|
3562
|
+
* This is the single choke point for a client's profile resolution — the consent unlock gate, the
|
|
3563
|
+
* consent required gate, and the `requiredScopes` interaction param all read through it.
|
|
3564
|
+
*
|
|
3558
3565
|
* @param providerProfiles - The provider-profile registry (from {@link OidcProviderConfig.providerProfiles}).
|
|
3559
3566
|
* @param clientProfileKeys - The profile keys assigned to the client (its `dbx_provider_profiles`).
|
|
3560
3567
|
* @returns The unlocked and required scope sets for the client.
|
|
3561
3568
|
*/ function oidcClientProviderProfileScopes(providerProfiles, clientProfileKeys) {
|
|
3562
|
-
var clientProfiles = firebase.
|
|
3569
|
+
var clientProfiles = firebase.oidcProviderProfilesForClient(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : [], clientProfileKeys);
|
|
3563
3570
|
return {
|
|
3564
3571
|
unlocked: firebase.scopesForOidcProviderProfiles(clientProfiles),
|
|
3565
3572
|
required: firebase.requiredScopesForOidcProviderProfiles(clientProfiles)
|
|
@@ -6212,7 +6219,7 @@ var OidcInteractionController_1;
|
|
|
6212
6219
|
* @throws {HttpException} HTTP 400 when the consent interaction cannot be completed.
|
|
6213
6220
|
*/ function postConsent(uid, body, res) {
|
|
6214
6221
|
return _async_to_generator$2(function() {
|
|
6215
|
-
var startedAt, clientId, accountId, _ref, _prompt_details_missingOIDCScope, _this_accountService_providerConfig_adminOnlyScopes, _ref1, _ref2, _ref3, _prompt_details_missingOIDCClaims, _prompt_details_missingResourceScopes, _this_accountService_delegate_isAdminUser, _this_accountService_delegate, _ref4, redirectTo, interaction, prompt, params, session, missingOIDCScope, existingGrant, _tmp, encounteredOIDCScopes, clientPayload, requestedOIDCScopeSet, adminOnlyScopes, requestsServiceToken, isAdmin, _tmp1, _ref5, redirectTo1,
|
|
6222
|
+
var startedAt, clientId, accountId, _ref, _prompt_details_missingOIDCScope, _this_accountService_providerConfig_adminOnlyScopes, _ref1, _ref2, _ref3, _prompt_details_missingOIDCClaims, _prompt_details_missingResourceScopes, _this_accountService_delegate_isAdminUser, _this_accountService_delegate, _ref4, redirectTo, interaction, prompt, params, session, missingOIDCScope, existingGrant, _tmp, encounteredOIDCScopes, clientPayload, requestedOIDCScopeSet, providerProfiles, configAdminOnlyScopes, adminOnlyScopes, requestedAdminOnlyScopes, requestsServiceToken, isAdmin, _tmp1, _ref5, redirectTo1, _oidcClientProviderProfileScopes, clientUnlockedScopes, clientRequiredScopes, profileGatedScopes, disallowedGatedScopes, _ref6, redirectTo2, missingRequiredScopes, _ref7, redirectTo3, requestedRawTtl, clientMaxSessionTtl, expiresInSeconds, grant, _tmp2, _resolveEffectiveSubset, granted, rejected, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, value, encounteredOIDCClaims, missingOIDCClaims, _resolveEffectiveSubset1, granted1, rejected1, missingResourceScopes, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _step_value, indicator, scopes, _body_grantedResourceScopes, requestedSubset, encounteredResourceScopes, _resolveEffectiveSubset2, granted2, rejected2, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, value1, grantId, _ref8, redirectTo4, err;
|
|
6216
6223
|
return _ts_generator$2(this, function(_state) {
|
|
6217
6224
|
switch(_state.label){
|
|
6218
6225
|
case 0:
|
|
@@ -6296,11 +6303,20 @@ var OidcInteractionController_1;
|
|
|
6296
6303
|
clientPayload = _state.sent();
|
|
6297
6304
|
// Admin-only scope gate. The requested OIDC scope set is `missingOIDCScope ∪ encounteredOIDCScopes`
|
|
6298
6305
|
// (a fresh consent has everything in `missing`; a re-consent may carry already-granted scopes in
|
|
6299
|
-
// `encountered`). If that set intersects the provider's `adminOnlyScopes`
|
|
6300
|
-
//
|
|
6306
|
+
// `encountered`). If that set intersects the admin-only scopes — the provider's `adminOnlyScopes`
|
|
6307
|
+
// unioned with the scopes of every profile marked `adminOnly` — and the resolving user is not an
|
|
6308
|
+
// admin, hard-reject with `access_denied` rather than silently dropping the scope.
|
|
6301
6309
|
requestedOIDCScopeSet = new Set(_to_consumable_array$1(missingOIDCScope).concat(_to_consumable_array$1(encounteredOIDCScopes)));
|
|
6302
|
-
|
|
6303
|
-
|
|
6310
|
+
providerProfiles = this.accountService.providerConfig.providerProfiles;
|
|
6311
|
+
configAdminOnlyScopes = (_this_accountService_providerConfig_adminOnlyScopes = this.accountService.providerConfig.adminOnlyScopes) !== null && _this_accountService_providerConfig_adminOnlyScopes !== void 0 ? _this_accountService_providerConfig_adminOnlyScopes : [];
|
|
6312
|
+
adminOnlyScopes = new Set(_to_consumable_array$1(configAdminOnlyScopes).concat(_to_consumable_array$1(firebase.adminOnlyScopesForOidcProviderProfiles(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : []))));
|
|
6313
|
+
requestedAdminOnlyScopes = Array.from(adminOnlyScopes).filter(function(scope) {
|
|
6314
|
+
return requestedOIDCScopeSet.has(scope);
|
|
6315
|
+
});
|
|
6316
|
+
// Deliberately sourced from the provider config's `adminOnlyScopes` ALONE, unlike the gate above:
|
|
6317
|
+
// this flag also selects the (highest) service-token TTL tier further down, and a profile marked
|
|
6318
|
+
// `adminOnly` must gate by admin status WITHOUT widening its grant's lifetime to that tier.
|
|
6319
|
+
requestsServiceToken = configAdminOnlyScopes.some(function(scope) {
|
|
6304
6320
|
return requestedOIDCScopeSet.has(scope);
|
|
6305
6321
|
});
|
|
6306
6322
|
if (!accountId) return [
|
|
@@ -6322,7 +6338,7 @@ var OidcInteractionController_1;
|
|
|
6322
6338
|
_state.label = 12;
|
|
6323
6339
|
case 12:
|
|
6324
6340
|
isAdmin = _tmp1;
|
|
6325
|
-
if (!(
|
|
6341
|
+
if (!(requestedAdminOnlyScopes.length > 0 && !isAdmin)) return [
|
|
6326
6342
|
3,
|
|
6327
6343
|
14
|
|
6328
6344
|
];
|
|
@@ -6330,7 +6346,7 @@ var OidcInteractionController_1;
|
|
|
6330
6346
|
4,
|
|
6331
6347
|
this.oidcInteractionService.finishInteractionByUid(uid, {
|
|
6332
6348
|
error: 'access_denied',
|
|
6333
|
-
error_description:
|
|
6349
|
+
error_description: "The following scope(s) are restricted to admins: ".concat(requestedAdminOnlyScopes.join(', '), ".")
|
|
6334
6350
|
}, {
|
|
6335
6351
|
mergeWithLastSubmission: true
|
|
6336
6352
|
})
|
|
@@ -6342,7 +6358,7 @@ var OidcInteractionController_1;
|
|
|
6342
6358
|
isSuccessful: false,
|
|
6343
6359
|
uid: accountId,
|
|
6344
6360
|
clientId: clientId,
|
|
6345
|
-
serviceToken:
|
|
6361
|
+
serviceToken: requestsServiceToken,
|
|
6346
6362
|
isAdmin: false,
|
|
6347
6363
|
reason: 'service_token_non_admin',
|
|
6348
6364
|
durationMs: Date.now() - startedAt
|
|
@@ -6355,9 +6371,9 @@ var OidcInteractionController_1;
|
|
|
6355
6371
|
];
|
|
6356
6372
|
case 14:
|
|
6357
6373
|
// Provider-profile scope gate. Any scope referenced by a provider profile is "gated" — available
|
|
6358
|
-
// only to clients whose assigned profiles unlock it
|
|
6359
|
-
// scope may be
|
|
6360
|
-
|
|
6374
|
+
// only to clients whose assigned profiles unlock it (a client with NO assigned profiles resolves
|
|
6375
|
+
// to the registry's default profiles). Independent of the admin-only gate above; a scope may be
|
|
6376
|
+
// subject to both.
|
|
6361
6377
|
_oidcClientProviderProfileScopes = oidcClientProviderProfileScopes(providerProfiles, (_ref2 = clientPayload === null || clientPayload === void 0 ? void 0 : clientPayload.dbx_provider_profiles) !== null && _ref2 !== void 0 ? _ref2 : undefined), clientUnlockedScopes = _oidcClientProviderProfileScopes.unlocked, clientRequiredScopes = _oidcClientProviderProfileScopes.required;
|
|
6362
6378
|
profileGatedScopes = firebase.scopesForOidcProviderProfiles(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : []);
|
|
6363
6379
|
// Unlock gate: reject any requested gated scope this client's profiles do not unlock.
|
package/oidc/index.esm.js
CHANGED
|
@@ -3,7 +3,7 @@ import { errors } from 'oidc-provider';
|
|
|
3
3
|
import { SECONDS_IN_MINUTE, SECONDS_IN_DAY, cachedGetter, unixDateTimeSecondsNumberToDate, unixDateTimeSecondsNumberForNow, selectiveFieldEncryptor, filterUndefinedValues, websiteUrlFromPaths, firstValue, hasHttpPrefix } from '@dereekb/util';
|
|
4
4
|
import { generateKeyPairSync, randomBytes } from 'node:crypto';
|
|
5
5
|
import { resolveEncryptionKey, encryptValue, decryptValue, createAesStringEncryptionProvider, isValidAES256GCMEncryptionSecret } from '@dereekb/nestjs';
|
|
6
|
-
import { where, iterateFirestoreDocumentSnapshotPairs, firestoreModelIdentity, snapshotConverterFunctions, optionalFirestoreDate, firestoreDate, firestoreEnum, firestorePassThroughField, AbstractFirestoreDocument, createOidcClientParamsType, deleteOidcClientParamsType, deleteOidcTokenParamsType, rotateOidcClientSecretParamsType, updateOidcClientParamsType, firestoreModelKey, oidcEntryIdentity, PUBLIC_PKCE_TOKEN_ENDPOINT_AUTH_METHOD, OIDC_ENTRY_CLIENT_TYPE, oidcEntriesByUserCodeQuery, oidcEntriesByUidQuery, oidcEntriesByGrantIdQuery,
|
|
6
|
+
import { where, iterateFirestoreDocumentSnapshotPairs, firestoreModelIdentity, snapshotConverterFunctions, optionalFirestoreDate, firestoreDate, firestoreEnum, firestorePassThroughField, AbstractFirestoreDocument, createOidcClientParamsType, deleteOidcClientParamsType, deleteOidcTokenParamsType, rotateOidcClientSecretParamsType, updateOidcClientParamsType, firestoreModelKey, oidcEntryIdentity, PUBLIC_PKCE_TOKEN_ENDPOINT_AUTH_METHOD, OIDC_ENTRY_CLIENT_TYPE, oidcEntriesByUserCodeQuery, oidcEntriesByUidQuery, oidcEntriesByGrantIdQuery, oidcProviderProfilesForClient, requiredScopesForOidcProviderProfiles, scopesForOidcProviderProfiles, oidcScopesFromScopeClaim, adminOnlyScopesForOidcProviderProfiles, oidcEntryFirestoreCollection } from '@dereekb/firebase';
|
|
7
7
|
import { firestoreEncryptedField, firebaseServerActionsContext, FirebaseServerEnvService, FirebaseServerAnalyticsService, FIREBASE_FIRESTORE_CONTEXT_TOKEN, FirebaseServerFirestoreContextModule } from '@dereekb/firebase-server';
|
|
8
8
|
import { nanoid } from 'nanoid';
|
|
9
9
|
import { safeToJsDate } from '@dereekb/date';
|
|
@@ -3553,11 +3553,18 @@ OidcProviderConfigService = __decorate([
|
|
|
3553
3553
|
* Resolves the unlocked + required scope sets for a client from the provider-profile registry and
|
|
3554
3554
|
* the profile keys assigned to that client.
|
|
3555
3555
|
*
|
|
3556
|
+
* A client with NO assigned profiles resolves to the registry's default profiles (those marked
|
|
3557
|
+
* `isDefault`), so a registry declaring no default resolves exactly as it would from the assigned
|
|
3558
|
+
* keys alone.
|
|
3559
|
+
*
|
|
3560
|
+
* This is the single choke point for a client's profile resolution — the consent unlock gate, the
|
|
3561
|
+
* consent required gate, and the `requiredScopes` interaction param all read through it.
|
|
3562
|
+
*
|
|
3556
3563
|
* @param providerProfiles - The provider-profile registry (from {@link OidcProviderConfig.providerProfiles}).
|
|
3557
3564
|
* @param clientProfileKeys - The profile keys assigned to the client (its `dbx_provider_profiles`).
|
|
3558
3565
|
* @returns The unlocked and required scope sets for the client.
|
|
3559
3566
|
*/ function oidcClientProviderProfileScopes(providerProfiles, clientProfileKeys) {
|
|
3560
|
-
var clientProfiles =
|
|
3567
|
+
var clientProfiles = oidcProviderProfilesForClient(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : [], clientProfileKeys);
|
|
3561
3568
|
return {
|
|
3562
3569
|
unlocked: scopesForOidcProviderProfiles(clientProfiles),
|
|
3563
3570
|
required: requiredScopesForOidcProviderProfiles(clientProfiles)
|
|
@@ -6210,7 +6217,7 @@ var OidcInteractionController_1;
|
|
|
6210
6217
|
* @throws {HttpException} HTTP 400 when the consent interaction cannot be completed.
|
|
6211
6218
|
*/ function postConsent(uid, body, res) {
|
|
6212
6219
|
return _async_to_generator$2(function() {
|
|
6213
|
-
var startedAt, clientId, accountId, _ref, _prompt_details_missingOIDCScope, _this_accountService_providerConfig_adminOnlyScopes, _ref1, _ref2, _ref3, _prompt_details_missingOIDCClaims, _prompt_details_missingResourceScopes, _this_accountService_delegate_isAdminUser, _this_accountService_delegate, _ref4, redirectTo, interaction, prompt, params, session, missingOIDCScope, existingGrant, _tmp, encounteredOIDCScopes, clientPayload, requestedOIDCScopeSet, adminOnlyScopes, requestsServiceToken, isAdmin, _tmp1, _ref5, redirectTo1,
|
|
6220
|
+
var startedAt, clientId, accountId, _ref, _prompt_details_missingOIDCScope, _this_accountService_providerConfig_adminOnlyScopes, _ref1, _ref2, _ref3, _prompt_details_missingOIDCClaims, _prompt_details_missingResourceScopes, _this_accountService_delegate_isAdminUser, _this_accountService_delegate, _ref4, redirectTo, interaction, prompt, params, session, missingOIDCScope, existingGrant, _tmp, encounteredOIDCScopes, clientPayload, requestedOIDCScopeSet, providerProfiles, configAdminOnlyScopes, adminOnlyScopes, requestedAdminOnlyScopes, requestsServiceToken, isAdmin, _tmp1, _ref5, redirectTo1, _oidcClientProviderProfileScopes, clientUnlockedScopes, clientRequiredScopes, profileGatedScopes, disallowedGatedScopes, _ref6, redirectTo2, missingRequiredScopes, _ref7, redirectTo3, requestedRawTtl, clientMaxSessionTtl, expiresInSeconds, grant, _tmp2, _resolveEffectiveSubset, granted, rejected, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, value, encounteredOIDCClaims, missingOIDCClaims, _resolveEffectiveSubset1, granted1, rejected1, missingResourceScopes, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _step_value, indicator, scopes, _body_grantedResourceScopes, requestedSubset, encounteredResourceScopes, _resolveEffectiveSubset2, granted2, rejected2, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, value1, grantId, _ref8, redirectTo4, err;
|
|
6214
6221
|
return _ts_generator$2(this, function(_state) {
|
|
6215
6222
|
switch(_state.label){
|
|
6216
6223
|
case 0:
|
|
@@ -6294,11 +6301,20 @@ var OidcInteractionController_1;
|
|
|
6294
6301
|
clientPayload = _state.sent();
|
|
6295
6302
|
// Admin-only scope gate. The requested OIDC scope set is `missingOIDCScope ∪ encounteredOIDCScopes`
|
|
6296
6303
|
// (a fresh consent has everything in `missing`; a re-consent may carry already-granted scopes in
|
|
6297
|
-
// `encountered`). If that set intersects the provider's `adminOnlyScopes`
|
|
6298
|
-
//
|
|
6304
|
+
// `encountered`). If that set intersects the admin-only scopes — the provider's `adminOnlyScopes`
|
|
6305
|
+
// unioned with the scopes of every profile marked `adminOnly` — and the resolving user is not an
|
|
6306
|
+
// admin, hard-reject with `access_denied` rather than silently dropping the scope.
|
|
6299
6307
|
requestedOIDCScopeSet = new Set(_to_consumable_array$1(missingOIDCScope).concat(_to_consumable_array$1(encounteredOIDCScopes)));
|
|
6300
|
-
|
|
6301
|
-
|
|
6308
|
+
providerProfiles = this.accountService.providerConfig.providerProfiles;
|
|
6309
|
+
configAdminOnlyScopes = (_this_accountService_providerConfig_adminOnlyScopes = this.accountService.providerConfig.adminOnlyScopes) !== null && _this_accountService_providerConfig_adminOnlyScopes !== void 0 ? _this_accountService_providerConfig_adminOnlyScopes : [];
|
|
6310
|
+
adminOnlyScopes = new Set(_to_consumable_array$1(configAdminOnlyScopes).concat(_to_consumable_array$1(adminOnlyScopesForOidcProviderProfiles(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : []))));
|
|
6311
|
+
requestedAdminOnlyScopes = Array.from(adminOnlyScopes).filter(function(scope) {
|
|
6312
|
+
return requestedOIDCScopeSet.has(scope);
|
|
6313
|
+
});
|
|
6314
|
+
// Deliberately sourced from the provider config's `adminOnlyScopes` ALONE, unlike the gate above:
|
|
6315
|
+
// this flag also selects the (highest) service-token TTL tier further down, and a profile marked
|
|
6316
|
+
// `adminOnly` must gate by admin status WITHOUT widening its grant's lifetime to that tier.
|
|
6317
|
+
requestsServiceToken = configAdminOnlyScopes.some(function(scope) {
|
|
6302
6318
|
return requestedOIDCScopeSet.has(scope);
|
|
6303
6319
|
});
|
|
6304
6320
|
if (!accountId) return [
|
|
@@ -6320,7 +6336,7 @@ var OidcInteractionController_1;
|
|
|
6320
6336
|
_state.label = 12;
|
|
6321
6337
|
case 12:
|
|
6322
6338
|
isAdmin = _tmp1;
|
|
6323
|
-
if (!(
|
|
6339
|
+
if (!(requestedAdminOnlyScopes.length > 0 && !isAdmin)) return [
|
|
6324
6340
|
3,
|
|
6325
6341
|
14
|
|
6326
6342
|
];
|
|
@@ -6328,7 +6344,7 @@ var OidcInteractionController_1;
|
|
|
6328
6344
|
4,
|
|
6329
6345
|
this.oidcInteractionService.finishInteractionByUid(uid, {
|
|
6330
6346
|
error: 'access_denied',
|
|
6331
|
-
error_description:
|
|
6347
|
+
error_description: "The following scope(s) are restricted to admins: ".concat(requestedAdminOnlyScopes.join(', '), ".")
|
|
6332
6348
|
}, {
|
|
6333
6349
|
mergeWithLastSubmission: true
|
|
6334
6350
|
})
|
|
@@ -6340,7 +6356,7 @@ var OidcInteractionController_1;
|
|
|
6340
6356
|
isSuccessful: false,
|
|
6341
6357
|
uid: accountId,
|
|
6342
6358
|
clientId: clientId,
|
|
6343
|
-
serviceToken:
|
|
6359
|
+
serviceToken: requestsServiceToken,
|
|
6344
6360
|
isAdmin: false,
|
|
6345
6361
|
reason: 'service_token_non_admin',
|
|
6346
6362
|
durationMs: Date.now() - startedAt
|
|
@@ -6353,9 +6369,9 @@ var OidcInteractionController_1;
|
|
|
6353
6369
|
];
|
|
6354
6370
|
case 14:
|
|
6355
6371
|
// Provider-profile scope gate. Any scope referenced by a provider profile is "gated" — available
|
|
6356
|
-
// only to clients whose assigned profiles unlock it
|
|
6357
|
-
// scope may be
|
|
6358
|
-
|
|
6372
|
+
// only to clients whose assigned profiles unlock it (a client with NO assigned profiles resolves
|
|
6373
|
+
// to the registry's default profiles). Independent of the admin-only gate above; a scope may be
|
|
6374
|
+
// subject to both.
|
|
6359
6375
|
_oidcClientProviderProfileScopes = oidcClientProviderProfileScopes(providerProfiles, (_ref2 = clientPayload === null || clientPayload === void 0 ? void 0 : clientPayload.dbx_provider_profiles) !== null && _ref2 !== void 0 ? _ref2 : undefined), clientUnlockedScopes = _oidcClientProviderProfileScopes.unlocked, clientRequiredScopes = _oidcClientProviderProfileScopes.required;
|
|
6360
6376
|
profileGatedScopes = scopesForOidcProviderProfiles(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : []);
|
|
6361
6377
|
// Unlock gate: reject any requested gated scope this client's profiles do not unlock.
|
package/oidc/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/oidc",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.31.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@dereekb/analytics": "13.
|
|
6
|
-
"@dereekb/date": "13.
|
|
7
|
-
"@dereekb/firebase": "13.
|
|
8
|
-
"@dereekb/firebase-server": "13.
|
|
9
|
-
"@dereekb/model": "13.
|
|
10
|
-
"@dereekb/nestjs": "13.
|
|
11
|
-
"@dereekb/rxjs": "13.
|
|
12
|
-
"@dereekb/util": "13.
|
|
13
|
-
"@dereekb/zoho": "13.
|
|
5
|
+
"@dereekb/analytics": "13.31.0",
|
|
6
|
+
"@dereekb/date": "13.31.0",
|
|
7
|
+
"@dereekb/firebase": "13.31.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.31.0",
|
|
9
|
+
"@dereekb/model": "13.31.0",
|
|
10
|
+
"@dereekb/nestjs": "13.31.0",
|
|
11
|
+
"@dereekb/rxjs": "13.31.0",
|
|
12
|
+
"@dereekb/util": "13.31.0",
|
|
13
|
+
"@dereekb/zoho": "13.31.0",
|
|
14
14
|
"@nestjs/common": "^11.1.19",
|
|
15
15
|
"@nestjs/config": "^4.0.4",
|
|
16
16
|
"express": "^5.2.1",
|
|
@@ -94,6 +94,11 @@ export interface OidcProviderConfig<S extends OidcScope = OidcScope> {
|
|
|
94
94
|
*
|
|
95
95
|
* Keeps the generic package app-agnostic: apps opt a scope (e.g. `token.service`) into admin-only
|
|
96
96
|
* behavior by listing it here, rather than the package hard-coding any scope name.
|
|
97
|
+
*
|
|
98
|
+
* The consent gate applies this list UNIONED with the scopes of every {@link providerProfiles} entry
|
|
99
|
+
* marked `adminOnly`. Only the scopes listed HERE additionally select the (highest) service-token
|
|
100
|
+
* login-duration tier — a profile marked `adminOnly` gates by admin status without widening its
|
|
101
|
+
* grant's lifetime.
|
|
97
102
|
*/
|
|
98
103
|
readonly adminOnlyScopes?: readonly string[];
|
|
99
104
|
/**
|
|
@@ -111,6 +116,12 @@ export interface OidcProviderConfig<S extends OidcScope = OidcScope> {
|
|
|
111
116
|
* metadata) unlocks it. A profile scope marked `require: 'required'` is force-required — surfaced
|
|
112
117
|
* as a required scope at consent and hard-rejected if not granted.
|
|
113
118
|
*
|
|
119
|
+
* A profile marked `isDefault` applies to a client with NO profiles assigned, so an app can make a
|
|
120
|
+
* coarse, broadly-available scope profile-gated without breaking already-registered clients. The
|
|
121
|
+
* fallback is exclusive — assigning any other profile does not additionally confer the default's
|
|
122
|
+
* scopes. A profile marked `adminOnly` has its scopes unioned into {@link adminOnlyScopes} for the
|
|
123
|
+
* consent gate.
|
|
124
|
+
*
|
|
114
125
|
* Keeps the generic package app-agnostic: apps declare their profiles statically and list them
|
|
115
126
|
* here, rather than the package hard-coding any profile or scope name. This gate is independent of
|
|
116
127
|
* {@link adminOnlyScopes} (which gates by the resolving user's admin status); a scope may be
|
|
@@ -22,6 +22,13 @@ export interface OidcClientProviderProfileScopes<S extends OidcScope = OidcScope
|
|
|
22
22
|
* Resolves the unlocked + required scope sets for a client from the provider-profile registry and
|
|
23
23
|
* the profile keys assigned to that client.
|
|
24
24
|
*
|
|
25
|
+
* A client with NO assigned profiles resolves to the registry's default profiles (those marked
|
|
26
|
+
* `isDefault`), so a registry declaring no default resolves exactly as it would from the assigned
|
|
27
|
+
* keys alone.
|
|
28
|
+
*
|
|
29
|
+
* This is the single choke point for a client's profile resolution — the consent unlock gate, the
|
|
30
|
+
* consent required gate, and the `requiredScopes` interaction param all read through it.
|
|
31
|
+
*
|
|
25
32
|
* @param providerProfiles - The provider-profile registry (from {@link OidcProviderConfig.providerProfiles}).
|
|
26
33
|
* @param clientProfileKeys - The profile keys assigned to the client (its `dbx_provider_profiles`).
|
|
27
34
|
* @returns The unlocked and required scope sets for the client.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.31.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.31.0",
|
|
61
|
+
"@dereekb/date": "13.31.0",
|
|
62
|
+
"@dereekb/dbx-core": "13.31.0",
|
|
63
|
+
"@dereekb/firebase": "13.31.0",
|
|
64
|
+
"@dereekb/model": "13.31.0",
|
|
65
|
+
"@dereekb/nestjs": "13.31.0",
|
|
66
|
+
"@dereekb/rxjs": "13.31.0",
|
|
67
|
+
"@dereekb/util": "13.31.0",
|
|
68
|
+
"@dereekb/zoho": "13.31.0",
|
|
69
69
|
"@google-cloud/firestore": "^7.11.6",
|
|
70
70
|
"@google-cloud/storage": "^7.19.0",
|
|
71
71
|
"@modelcontextprotocol/sdk": "1.29.0",
|