@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/oidc/index.cjs.js
CHANGED
|
@@ -2431,6 +2431,9 @@ function _ts_generator$7(thisArg, body) {
|
|
|
2431
2431
|
if (params.dbx_max_session_ttl != null) {
|
|
2432
2432
|
properties.dbx_max_session_ttl = params.dbx_max_session_ttl;
|
|
2433
2433
|
}
|
|
2434
|
+
if (params.dbx_provider_profiles != null) {
|
|
2435
|
+
properties.dbx_provider_profiles = params.dbx_provider_profiles;
|
|
2436
|
+
}
|
|
2434
2437
|
// Merge any pre-validated metadata (e.g., inline jwks for private_key_jwt in tests)
|
|
2435
2438
|
if (validatedMetadata === null || validatedMetadata === void 0 ? void 0 : validatedMetadata.jwks) {
|
|
2436
2439
|
properties.jwks = validatedMetadata.jwks;
|
|
@@ -2488,7 +2491,7 @@ function _ts_generator$7(thisArg, body) {
|
|
|
2488
2491
|
* @throws {Error} When the client is not found.
|
|
2489
2492
|
*/ function updateClient(clientId, params) {
|
|
2490
2493
|
return _async_to_generator$7(function() {
|
|
2491
|
-
var provider, ProviderClient, existing, updatedMetadata, _params_logo_uri, _params_client_uri, _params_dbx_max_session_ttl, client;
|
|
2494
|
+
var provider, ProviderClient, existing, updatedMetadata, _params_logo_uri, _params_client_uri, _params_dbx_max_session_ttl, _params_dbx_provider_profiles, client;
|
|
2492
2495
|
return _ts_generator$7(this, function(_state) {
|
|
2493
2496
|
switch(_state.label){
|
|
2494
2497
|
case 0:
|
|
@@ -2520,6 +2523,12 @@ function _ts_generator$7(thisArg, body) {
|
|
|
2520
2523
|
if (params.dbx_max_session_ttl !== undefined) {
|
|
2521
2524
|
updatedMetadata.dbx_max_session_ttl = (_params_dbx_max_session_ttl = params.dbx_max_session_ttl) !== null && _params_dbx_max_session_ttl !== void 0 ? _params_dbx_max_session_ttl : undefined;
|
|
2522
2525
|
}
|
|
2526
|
+
// Only overwrite the profile assignment when the field is explicitly provided. An omitted value
|
|
2527
|
+
// (including one stripped for a non-admin caller) preserves the existing assignment; `null`/`[]`
|
|
2528
|
+
// clears it. This is what makes the non-admin strip a no-op rather than a wipe.
|
|
2529
|
+
if (params.dbx_provider_profiles !== undefined) {
|
|
2530
|
+
updatedMetadata.dbx_provider_profiles = (_params_dbx_provider_profiles = params.dbx_provider_profiles) !== null && _params_dbx_provider_profiles !== void 0 ? _params_dbx_provider_profiles : undefined;
|
|
2531
|
+
}
|
|
2523
2532
|
// Mirrors oidc-provider's lib/helpers/add_client.js: re-validates and persists.
|
|
2524
2533
|
return [
|
|
2525
2534
|
4,
|
|
@@ -3538,6 +3547,25 @@ exports.OidcProviderConfigService = __decorate([
|
|
|
3538
3547
|
__param(2, common.Inject(firebaseServer.FirebaseServerEnvService))
|
|
3539
3548
|
], exports.OidcProviderConfigService);
|
|
3540
3549
|
|
|
3550
|
+
/**
|
|
3551
|
+
* Custom oidc-provider client metadata field holding the {@link OidcProviderProfile} keys assigned
|
|
3552
|
+
* to a client. Registered via `extraClientMetadata` and persisted on the client's `OidcEntry` payload.
|
|
3553
|
+
*/ var DBX_FIREBASE_SERVER_OIDC_PROVIDER_PROFILES_CLIENT_METADATA = 'dbx_provider_profiles';
|
|
3554
|
+
/**
|
|
3555
|
+
* Resolves the unlocked + required scope sets for a client from the provider-profile registry and
|
|
3556
|
+
* the profile keys assigned to that client.
|
|
3557
|
+
*
|
|
3558
|
+
* @param providerProfiles - The provider-profile registry (from {@link OidcProviderConfig.providerProfiles}).
|
|
3559
|
+
* @param clientProfileKeys - The profile keys assigned to the client (its `dbx_provider_profiles`).
|
|
3560
|
+
* @returns The unlocked and required scope sets for the client.
|
|
3561
|
+
*/ function oidcClientProviderProfileScopes(providerProfiles, clientProfileKeys) {
|
|
3562
|
+
var clientProfiles = firebase.oidcProviderProfilesForKeys(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : [], clientProfileKeys);
|
|
3563
|
+
return {
|
|
3564
|
+
unlocked: firebase.scopesForOidcProviderProfiles(clientProfiles),
|
|
3565
|
+
required: firebase.requiredScopesForOidcProviderProfiles(clientProfiles)
|
|
3566
|
+
};
|
|
3567
|
+
}
|
|
3568
|
+
|
|
3541
3569
|
function _array_like_to_array$4(arr, len) {
|
|
3542
3570
|
if (len == null || len > arr.length) len = arr.length;
|
|
3543
3571
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
@@ -4042,7 +4070,8 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4042
4070
|
logo_uri: existing.logo_uri,
|
|
4043
4071
|
client_uri: existing.client_uri,
|
|
4044
4072
|
created_at: existing.created_at,
|
|
4045
|
-
dbx_max_session_ttl: existing.dbx_max_session_ttl
|
|
4073
|
+
dbx_max_session_ttl: existing.dbx_max_session_ttl,
|
|
4074
|
+
dbx_provider_profiles: existing.dbx_provider_profiles
|
|
4046
4075
|
};
|
|
4047
4076
|
}
|
|
4048
4077
|
return [
|
|
@@ -4149,7 +4178,8 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4149
4178
|
],
|
|
4150
4179
|
extraClientMetadata: {
|
|
4151
4180
|
properties: [
|
|
4152
|
-
DBX_FIREBASE_SERVER_OIDC_MAX_SESSION_TTL_CLIENT_METADATA
|
|
4181
|
+
DBX_FIREBASE_SERVER_OIDC_MAX_SESSION_TTL_CLIENT_METADATA,
|
|
4182
|
+
DBX_FIREBASE_SERVER_OIDC_PROVIDER_PROFILES_CLIENT_METADATA
|
|
4153
4183
|
],
|
|
4154
4184
|
validator: function validator(_ctx, key, value) {
|
|
4155
4185
|
if (key === DBX_FIREBASE_SERVER_OIDC_MAX_SESSION_TTL_CLIENT_METADATA && value !== undefined && value !== null) {
|
|
@@ -4159,6 +4189,22 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4159
4189
|
if (value > serverMaxSeconds) {
|
|
4160
4190
|
throw new oidcProvider.errors.InvalidClientMetadata("".concat(DBX_FIREBASE_SERVER_OIDC_MAX_SESSION_TTL_CLIENT_METADATA, " cannot exceed the server max of ").concat(serverMaxSeconds, " seconds."));
|
|
4161
4191
|
}
|
|
4192
|
+
} else if (key === DBX_FIREBASE_SERVER_OIDC_PROVIDER_PROFILES_CLIENT_METADATA && value !== undefined && value !== null) {
|
|
4193
|
+
var _providerConfig_providerProfiles;
|
|
4194
|
+
if (!Array.isArray(value) || value.some(function(entry) {
|
|
4195
|
+
return typeof entry !== 'string';
|
|
4196
|
+
})) {
|
|
4197
|
+
throw new oidcProvider.errors.InvalidClientMetadata("".concat(DBX_FIREBASE_SERVER_OIDC_PROVIDER_PROFILES_CLIENT_METADATA, " must be an array of provider profile keys."));
|
|
4198
|
+
}
|
|
4199
|
+
var knownProfileKeys = new Set(((_providerConfig_providerProfiles = providerConfig.providerProfiles) !== null && _providerConfig_providerProfiles !== void 0 ? _providerConfig_providerProfiles : []).map(function(profile) {
|
|
4200
|
+
return profile.key;
|
|
4201
|
+
}));
|
|
4202
|
+
var unknownKey = value.find(function(entry) {
|
|
4203
|
+
return !knownProfileKeys.has(entry);
|
|
4204
|
+
});
|
|
4205
|
+
if (unknownKey !== undefined) {
|
|
4206
|
+
throw new oidcProvider.errors.InvalidClientMetadata("".concat(DBX_FIREBASE_SERVER_OIDC_PROVIDER_PROFILES_CLIENT_METADATA, " contains an unknown provider profile key: ").concat(unknownKey, "."));
|
|
4207
|
+
}
|
|
4162
4208
|
}
|
|
4163
4209
|
}
|
|
4164
4210
|
},
|
|
@@ -4186,7 +4232,7 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4186
4232
|
interactions: {
|
|
4187
4233
|
url: function url(_ctx, interaction) {
|
|
4188
4234
|
return _async_to_generator$5(function() {
|
|
4189
|
-
var baseUrl, client_id, paramsToEncode, client, scopes, interactionLoginDetails, paramsString;
|
|
4235
|
+
var baseUrl, client_id, paramsToEncode, client, _client_dbx_provider_profiles, scopes, requestedScopeSet, required, requiredScopes, interactionLoginDetails, paramsString;
|
|
4190
4236
|
return _ts_generator$5(this, function(_state) {
|
|
4191
4237
|
switch(_state.label){
|
|
4192
4238
|
case 0:
|
|
@@ -4214,13 +4260,23 @@ function _ts_generator$5(thisArg, body) {
|
|
|
4214
4260
|
client = _state.sent();
|
|
4215
4261
|
if (client) {
|
|
4216
4262
|
scopes = interaction.params.scope;
|
|
4217
|
-
|
|
4263
|
+
// Surface the scopes the client's provider profiles force-require so the consent UI can
|
|
4264
|
+
// render them as required. Intersect with the actually-requested scopes so only visible
|
|
4265
|
+
// scope rows are flagged.
|
|
4266
|
+
requestedScopeSet = new Set(scopes.split(' ').filter(Boolean));
|
|
4267
|
+
required = oidcClientProviderProfileScopes(providerConfig.providerProfiles, (_client_dbx_provider_profiles = client.dbx_provider_profiles) !== null && _client_dbx_provider_profiles !== void 0 ? _client_dbx_provider_profiles : undefined).required;
|
|
4268
|
+
requiredScopes = Array.from(required).filter(function(scope) {
|
|
4269
|
+
return requestedScopeSet.has(scope);
|
|
4270
|
+
});
|
|
4271
|
+
interactionLoginDetails = _object_spread$3({
|
|
4218
4272
|
client_id: client_id,
|
|
4219
4273
|
client_name: client.client_name,
|
|
4220
4274
|
client_uri: client.client_uri,
|
|
4221
4275
|
logo_uri: client.logo_uri,
|
|
4222
4276
|
scopes: scopes
|
|
4223
|
-
}
|
|
4277
|
+
}, requiredScopes.length > 0 ? {
|
|
4278
|
+
requiredScopes: requiredScopes.join(' ')
|
|
4279
|
+
} : {});
|
|
4224
4280
|
paramsToEncode = _object_spread$3({}, paramsToEncode, interactionLoginDetails);
|
|
4225
4281
|
}
|
|
4226
4282
|
_state.label = 3;
|
|
@@ -6159,7 +6215,7 @@ var OidcInteractionController_1;
|
|
|
6159
6215
|
* @throws {HttpException} HTTP 400 when the consent interaction cannot be completed.
|
|
6160
6216
|
*/ function postConsent(uid, body, res) {
|
|
6161
6217
|
return _async_to_generator$2(function() {
|
|
6162
|
-
var startedAt, clientId, accountId, _ref, _prompt_details_missingOIDCScope, _this_accountService_providerConfig_adminOnlyScopes, _ref1, _ref2, _prompt_details_missingOIDCClaims, _prompt_details_missingResourceScopes, _this_accountService_delegate_isAdminUser, _this_accountService_delegate,
|
|
6218
|
+
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, providerProfiles, _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;
|
|
6163
6219
|
return _ts_generator$2(this, function(_state) {
|
|
6164
6220
|
switch(_state.label){
|
|
6165
6221
|
case 0:
|
|
@@ -6174,9 +6230,9 @@ var OidcInteractionController_1;
|
|
|
6174
6230
|
case 2:
|
|
6175
6231
|
_state.trys.push([
|
|
6176
6232
|
2,
|
|
6177
|
-
|
|
6233
|
+
24,
|
|
6178
6234
|
,
|
|
6179
|
-
|
|
6235
|
+
25
|
|
6180
6236
|
]);
|
|
6181
6237
|
if (!!body.approved) return [
|
|
6182
6238
|
3,
|
|
@@ -6192,7 +6248,7 @@ var OidcInteractionController_1;
|
|
|
6192
6248
|
})
|
|
6193
6249
|
];
|
|
6194
6250
|
case 3:
|
|
6195
|
-
|
|
6251
|
+
_ref4 = _state.sent(), redirectTo = _ref4.returnTo;
|
|
6196
6252
|
res.json({
|
|
6197
6253
|
redirectTo: redirectTo
|
|
6198
6254
|
});
|
|
@@ -6235,6 +6291,12 @@ var OidcInteractionController_1;
|
|
|
6235
6291
|
// and re-submits them all. We accept already-encountered values as silent no-ops so a re-consent on a
|
|
6236
6292
|
// client the user has previously authorized doesn't fail validation.
|
|
6237
6293
|
encounteredOIDCScopes = existingGrant ? existingGrant.getOIDCScopeEncountered().split(' ').filter(Boolean) : [];
|
|
6294
|
+
return [
|
|
6295
|
+
4,
|
|
6296
|
+
this.oidcService.findClientPayload(clientId)
|
|
6297
|
+
];
|
|
6298
|
+
case 9:
|
|
6299
|
+
clientPayload = _state.sent();
|
|
6238
6300
|
// Admin-only scope gate. The requested OIDC scope set is `missingOIDCScope ∪ encounteredOIDCScopes`
|
|
6239
6301
|
// (a fresh consent has everything in `missing`; a re-consent may carry already-granted scopes in
|
|
6240
6302
|
// `encountered`). If that set intersects the provider's `adminOnlyScopes` and the resolving user is
|
|
@@ -6246,26 +6308,26 @@ var OidcInteractionController_1;
|
|
|
6246
6308
|
});
|
|
6247
6309
|
if (!accountId) return [
|
|
6248
6310
|
3,
|
|
6249
|
-
|
|
6311
|
+
11
|
|
6250
6312
|
];
|
|
6251
6313
|
return [
|
|
6252
6314
|
4,
|
|
6253
6315
|
(_ref1 = (_this_accountService_delegate_isAdminUser = (_this_accountService_delegate = this.accountService.delegate).isAdminUser) === null || _this_accountService_delegate_isAdminUser === void 0 ? void 0 : _this_accountService_delegate_isAdminUser.call(_this_accountService_delegate, this.accountService.userContext(accountId).authUserContext)) !== null && _ref1 !== void 0 ? _ref1 : false
|
|
6254
6316
|
];
|
|
6255
|
-
case
|
|
6317
|
+
case 10:
|
|
6256
6318
|
_tmp1 = _state.sent();
|
|
6257
6319
|
return [
|
|
6258
6320
|
3,
|
|
6259
|
-
|
|
6321
|
+
12
|
|
6260
6322
|
];
|
|
6261
|
-
case 10:
|
|
6262
|
-
_tmp1 = false;
|
|
6263
|
-
_state.label = 11;
|
|
6264
6323
|
case 11:
|
|
6324
|
+
_tmp1 = false;
|
|
6325
|
+
_state.label = 12;
|
|
6326
|
+
case 12:
|
|
6265
6327
|
isAdmin = _tmp1;
|
|
6266
6328
|
if (!(requestsServiceToken && !isAdmin)) return [
|
|
6267
6329
|
3,
|
|
6268
|
-
|
|
6330
|
+
14
|
|
6269
6331
|
];
|
|
6270
6332
|
return [
|
|
6271
6333
|
4,
|
|
@@ -6276,8 +6338,8 @@ var OidcInteractionController_1;
|
|
|
6276
6338
|
mergeWithLastSubmission: true
|
|
6277
6339
|
})
|
|
6278
6340
|
];
|
|
6279
|
-
case
|
|
6280
|
-
|
|
6341
|
+
case 13:
|
|
6342
|
+
_ref5 = _state.sent(), redirectTo1 = _ref5.returnTo;
|
|
6281
6343
|
emitOidcAnalyticsEvent(this._analytics, {
|
|
6282
6344
|
type: 'consent',
|
|
6283
6345
|
isSuccessful: false,
|
|
@@ -6294,20 +6356,89 @@ var OidcInteractionController_1;
|
|
|
6294
6356
|
return [
|
|
6295
6357
|
2
|
|
6296
6358
|
];
|
|
6297
|
-
case
|
|
6359
|
+
case 14:
|
|
6360
|
+
// Provider-profile scope gate. Any scope referenced by a provider profile is "gated" — available
|
|
6361
|
+
// only to clients whose assigned profiles unlock it. Independent of the admin-only gate above; a
|
|
6362
|
+
// scope may be subject to both.
|
|
6363
|
+
providerProfiles = this.accountService.providerConfig.providerProfiles;
|
|
6364
|
+
_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;
|
|
6365
|
+
profileGatedScopes = firebase.scopesForOidcProviderProfiles(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : []);
|
|
6366
|
+
// Unlock gate: reject any requested gated scope this client's profiles do not unlock.
|
|
6367
|
+
disallowedGatedScopes = Array.from(requestedOIDCScopeSet).filter(function(scope) {
|
|
6368
|
+
return profileGatedScopes.has(scope) && !clientUnlockedScopes.has(scope);
|
|
6369
|
+
});
|
|
6370
|
+
if (!(disallowedGatedScopes.length > 0)) return [
|
|
6371
|
+
3,
|
|
6372
|
+
16
|
|
6373
|
+
];
|
|
6374
|
+
return [
|
|
6375
|
+
4,
|
|
6376
|
+
this.oidcInteractionService.finishInteractionByUid(uid, {
|
|
6377
|
+
error: 'access_denied',
|
|
6378
|
+
error_description: "The following scope(s) are not available to this client: ".concat(disallowedGatedScopes.join(', '), ".")
|
|
6379
|
+
}, {
|
|
6380
|
+
mergeWithLastSubmission: true
|
|
6381
|
+
})
|
|
6382
|
+
];
|
|
6383
|
+
case 15:
|
|
6384
|
+
_ref6 = _state.sent(), redirectTo2 = _ref6.returnTo;
|
|
6385
|
+
emitOidcAnalyticsEvent(this._analytics, {
|
|
6386
|
+
type: 'consent',
|
|
6387
|
+
isSuccessful: false,
|
|
6388
|
+
uid: accountId,
|
|
6389
|
+
clientId: clientId,
|
|
6390
|
+
reason: 'scope_not_unlocked_for_client',
|
|
6391
|
+
durationMs: Date.now() - startedAt
|
|
6392
|
+
}, this._logger);
|
|
6393
|
+
res.json({
|
|
6394
|
+
redirectTo: redirectTo2
|
|
6395
|
+
});
|
|
6396
|
+
return [
|
|
6397
|
+
2
|
|
6398
|
+
];
|
|
6399
|
+
case 16:
|
|
6400
|
+
// Required gate: a scope a client's profiles force-require (`require: 'required'`) must be present
|
|
6401
|
+
// in the request. Reject when the client did not request a required scope.
|
|
6402
|
+
missingRequiredScopes = Array.from(clientRequiredScopes).filter(function(scope) {
|
|
6403
|
+
return !requestedOIDCScopeSet.has(scope);
|
|
6404
|
+
});
|
|
6405
|
+
if (!(missingRequiredScopes.length > 0)) return [
|
|
6406
|
+
3,
|
|
6407
|
+
18
|
|
6408
|
+
];
|
|
6409
|
+
return [
|
|
6410
|
+
4,
|
|
6411
|
+
this.oidcInteractionService.finishInteractionByUid(uid, {
|
|
6412
|
+
error: 'access_denied',
|
|
6413
|
+
error_description: "This client must request the required scope(s): ".concat(missingRequiredScopes.join(', '), ".")
|
|
6414
|
+
}, {
|
|
6415
|
+
mergeWithLastSubmission: true
|
|
6416
|
+
})
|
|
6417
|
+
];
|
|
6418
|
+
case 17:
|
|
6419
|
+
_ref7 = _state.sent(), redirectTo3 = _ref7.returnTo;
|
|
6420
|
+
emitOidcAnalyticsEvent(this._analytics, {
|
|
6421
|
+
type: 'consent',
|
|
6422
|
+
isSuccessful: false,
|
|
6423
|
+
uid: accountId,
|
|
6424
|
+
clientId: clientId,
|
|
6425
|
+
reason: 'required_scope_missing',
|
|
6426
|
+
durationMs: Date.now() - startedAt
|
|
6427
|
+
}, this._logger);
|
|
6428
|
+
res.json({
|
|
6429
|
+
redirectTo: redirectTo3
|
|
6430
|
+
});
|
|
6431
|
+
return [
|
|
6432
|
+
2
|
|
6433
|
+
];
|
|
6434
|
+
case 18:
|
|
6298
6435
|
// Resolve the requested login duration up-front. The configured Grant TTL function (in
|
|
6299
6436
|
// OidcService.buildProviderConfiguration) only fires when oidc-provider's koa middleware
|
|
6300
6437
|
// drives `grant.save()`, so its `ctx.oidc.params` lookup of `dbx_session_ttl` returns
|
|
6301
6438
|
// undefined when the consent submit runs in this controller. We pre-set `expiresIn` on
|
|
6302
6439
|
// newly-created grants so they persist with the correct (tiered) TTL.
|
|
6303
6440
|
requestedRawTtl = params[DBX_FIREBASE_SERVER_OIDC_SESSION_TTL_PARAM];
|
|
6304
|
-
|
|
6305
|
-
4,
|
|
6306
|
-
this.oidcService.findClientPayload(clientId)
|
|
6307
|
-
];
|
|
6308
|
-
case 14:
|
|
6309
|
-
clientPayload = _state.sent();
|
|
6310
|
-
clientMaxSessionTtl = (_ref2 = clientPayload === null || clientPayload === void 0 ? void 0 : clientPayload.dbx_max_session_ttl) !== null && _ref2 !== void 0 ? _ref2 : undefined;
|
|
6441
|
+
clientMaxSessionTtl = (_ref3 = clientPayload === null || clientPayload === void 0 ? void 0 : clientPayload.dbx_max_session_ttl) !== null && _ref3 !== void 0 ? _ref3 : undefined;
|
|
6311
6442
|
expiresInSeconds = this.oidcService.resolveLoginDurationForGrant(requestedRawTtl, {
|
|
6312
6443
|
dbx_max_session_ttl: clientMaxSessionTtl
|
|
6313
6444
|
}, {
|
|
@@ -6316,28 +6447,30 @@ var OidcInteractionController_1;
|
|
|
6316
6447
|
});
|
|
6317
6448
|
if (!(existingGrant !== null && existingGrant !== void 0)) return [
|
|
6318
6449
|
3,
|
|
6319
|
-
|
|
6450
|
+
19
|
|
6320
6451
|
];
|
|
6321
6452
|
_tmp2 = existingGrant;
|
|
6322
6453
|
return [
|
|
6323
6454
|
3,
|
|
6324
|
-
|
|
6455
|
+
21
|
|
6325
6456
|
];
|
|
6326
|
-
case
|
|
6457
|
+
case 19:
|
|
6327
6458
|
return [
|
|
6328
6459
|
4,
|
|
6329
6460
|
this.oidcInteractionService.findOrCreateGrant(interaction.grantId, accountId, clientId, expiresInSeconds)
|
|
6330
6461
|
];
|
|
6331
|
-
case
|
|
6462
|
+
case 20:
|
|
6332
6463
|
_tmp2 = _state.sent();
|
|
6333
|
-
_state.label =
|
|
6334
|
-
case
|
|
6464
|
+
_state.label = 21;
|
|
6465
|
+
case 21:
|
|
6335
6466
|
grant = _tmp2;
|
|
6336
6467
|
if (missingOIDCScope.length > 0) {
|
|
6468
|
+
// Force-grant the client's required profile scopes (in addition to `openid`) so they cannot be
|
|
6469
|
+
// dropped at consent — the required gate above already guarantees they were requested.
|
|
6337
6470
|
_resolveEffectiveSubset = resolveEffectiveSubset({
|
|
6338
6471
|
missing: missingOIDCScope,
|
|
6339
6472
|
requestedSubset: body.grantedOIDCScopes,
|
|
6340
|
-
alwaysGranted: ALWAYS_GRANTED_OIDC_SCOPES,
|
|
6473
|
+
alwaysGranted: _to_consumable_array$1(ALWAYS_GRANTED_OIDC_SCOPES).concat(_to_consumable_array$1(clientRequiredScopes)),
|
|
6341
6474
|
alreadyEncountered: encounteredOIDCScopes
|
|
6342
6475
|
}), granted = _resolveEffectiveSubset.granted, rejected = _resolveEffectiveSubset.rejected;
|
|
6343
6476
|
if (granted.length > 0) {
|
|
@@ -6434,7 +6567,7 @@ var OidcInteractionController_1;
|
|
|
6434
6567
|
4,
|
|
6435
6568
|
grant.save()
|
|
6436
6569
|
];
|
|
6437
|
-
case
|
|
6570
|
+
case 22:
|
|
6438
6571
|
grantId = _state.sent();
|
|
6439
6572
|
return [
|
|
6440
6573
|
4,
|
|
@@ -6446,8 +6579,8 @@ var OidcInteractionController_1;
|
|
|
6446
6579
|
mergeWithLastSubmission: true
|
|
6447
6580
|
})
|
|
6448
6581
|
];
|
|
6449
|
-
case
|
|
6450
|
-
|
|
6582
|
+
case 23:
|
|
6583
|
+
_ref8 = _state.sent(), redirectTo4 = _ref8.returnTo;
|
|
6451
6584
|
emitOidcAnalyticsEvent(this._analytics, {
|
|
6452
6585
|
type: 'consent',
|
|
6453
6586
|
isSuccessful: true,
|
|
@@ -6459,13 +6592,13 @@ var OidcInteractionController_1;
|
|
|
6459
6592
|
durationMs: Date.now() - startedAt
|
|
6460
6593
|
}, this._logger);
|
|
6461
6594
|
res.json({
|
|
6462
|
-
redirectTo:
|
|
6595
|
+
redirectTo: redirectTo4
|
|
6463
6596
|
});
|
|
6464
6597
|
return [
|
|
6465
6598
|
3,
|
|
6466
|
-
|
|
6599
|
+
25
|
|
6467
6600
|
];
|
|
6468
|
-
case
|
|
6601
|
+
case 24:
|
|
6469
6602
|
err = _state.sent();
|
|
6470
6603
|
emitOidcAnalyticsEvent(this._analytics, {
|
|
6471
6604
|
type: 'consent',
|
|
@@ -6480,7 +6613,7 @@ var OidcInteractionController_1;
|
|
|
6480
6613
|
throw err;
|
|
6481
6614
|
}
|
|
6482
6615
|
throw new common.HttpException('Consent interaction failed', common.HttpStatus.BAD_REQUEST);
|
|
6483
|
-
case
|
|
6616
|
+
case 25:
|
|
6484
6617
|
return [
|
|
6485
6618
|
2
|
|
6486
6619
|
];
|
|
@@ -7650,31 +7783,43 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
7650
7783
|
|
|
7651
7784
|
/**
|
|
7652
7785
|
* Builds a {@link AssertModelCrudRequestFunction} that rejects callModel requests
|
|
7653
|
-
* lacking the OIDC scope
|
|
7786
|
+
* lacking the required OIDC scope(s) for the call.
|
|
7787
|
+
*
|
|
7788
|
+
* Enforcement is additive: an OIDC caller must hold BOTH the per-verb scope mapped
|
|
7789
|
+
* from the call type (`model.<call>`) AND any per-function scope a handler declared
|
|
7790
|
+
* via `withApiDetails({ requiredScope })` — surfaced on `context.requiredScope`.
|
|
7654
7791
|
*
|
|
7655
7792
|
* Bypasses the check (no-op) when the request is not OIDC-authenticated — i.e.
|
|
7656
7793
|
* when {@link getOidcScopesFromRequest} returns `undefined` because there is no
|
|
7657
7794
|
* `auth.token.scope` claim on the request. Regular Firebase ID-token callers are
|
|
7658
7795
|
* unaffected and continue to be gated by auth roles.
|
|
7659
7796
|
*
|
|
7660
|
-
* Bypasses the check for custom (non-CRUD) call types
|
|
7661
|
-
* remain unrestricted unless an app wires its own
|
|
7797
|
+
* Bypasses the check for custom (non-CRUD) call types that declare no per-function
|
|
7798
|
+
* scope, so app-specific verbs remain unrestricted unless an app wires its own
|
|
7799
|
+
* assertion or declares a `requiredScope`.
|
|
7662
7800
|
*
|
|
7663
7801
|
* Wire as the `preAssert` of {@link onCallModel}.
|
|
7664
7802
|
*
|
|
7665
7803
|
* @returns The pre-assertion function ready to plug into `OnCallModelConfig.preAssert`.
|
|
7666
7804
|
*/ function oidcCallModelScopePreAssert() {
|
|
7667
7805
|
var fn = function fn(context) {
|
|
7668
|
-
var
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
|
|
7806
|
+
var requiredScopes = util.filterMaybeArrayValues([
|
|
7807
|
+
firebase.callModelOidcScopeForCallType(context.call),
|
|
7808
|
+
context.requiredScope
|
|
7809
|
+
]);
|
|
7810
|
+
// No requirement (custom verb + no per-function scope) short-circuits without reading scopes.
|
|
7811
|
+
// A non-OIDC caller yields `undefined` scopes below and bypasses just like the per-verb check.
|
|
7812
|
+
var scopes = requiredScopes.length === 0 ? undefined : getOidcScopesFromRequest(context.request);
|
|
7813
|
+
var missingScopes = scopes == null ? [] : requiredScopes.filter(function(scope) {
|
|
7814
|
+
return !scopes.has(scope);
|
|
7815
|
+
});
|
|
7816
|
+
if (missingScopes.length > 0) {
|
|
7672
7817
|
throw firebaseServer.forbiddenError({
|
|
7673
7818
|
status: 403,
|
|
7674
7819
|
code: firebase.CALL_MODEL_MISSING_OIDC_SCOPE_ERROR_CODE,
|
|
7675
|
-
message: "Missing required OIDC scope for callModel: ".concat(
|
|
7820
|
+
message: "Missing required OIDC scope for callModel: ".concat(missingScopes.join(', ')),
|
|
7676
7821
|
data: {
|
|
7677
|
-
|
|
7822
|
+
requiredScopes: missingScopes,
|
|
7678
7823
|
call: context.call
|
|
7679
7824
|
}
|
|
7680
7825
|
});
|
|
@@ -7683,6 +7828,7 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
7683
7828
|
return fn;
|
|
7684
7829
|
}
|
|
7685
7830
|
|
|
7831
|
+
exports.DBX_FIREBASE_SERVER_OIDC_PROVIDER_PROFILES_CLIENT_METADATA = DBX_FIREBASE_SERVER_OIDC_PROVIDER_PROFILES_CLIENT_METADATA;
|
|
7686
7832
|
exports.DEFAULT_APP_OAUTH_CONSENT_PATH_PART = DEFAULT_APP_OAUTH_CONSENT_PATH_PART;
|
|
7687
7833
|
exports.DEFAULT_APP_OAUTH_INTERACTION_PATH = DEFAULT_APP_OAUTH_INTERACTION_PATH;
|
|
7688
7834
|
exports.DEFAULT_APP_OAUTH_LOGIN_PATH_PART = DEFAULT_APP_OAUTH_LOGIN_PATH_PART;
|
|
@@ -7745,6 +7891,7 @@ exports.jwksKeysWithStatusQuery = jwksKeysWithStatusQuery;
|
|
|
7745
7891
|
exports.nonRetiredJwksKeysQuery = nonRetiredJwksKeysQuery;
|
|
7746
7892
|
exports.noopOidcAnalyticsService = noopOidcAnalyticsService;
|
|
7747
7893
|
exports.oidcCallModelScopePreAssert = oidcCallModelScopePreAssert;
|
|
7894
|
+
exports.oidcClientProviderProfileScopes = oidcClientProviderProfileScopes;
|
|
7748
7895
|
exports.oidcCorsOriginDelegate = oidcCorsOriginDelegate;
|
|
7749
7896
|
exports.oidcFirestoreCollectionsFactory = oidcFirestoreCollectionsFactory;
|
|
7750
7897
|
exports.oidcModelServerActions = oidcModelServerActions;
|