@dereekb/firebase-server 13.32.0 → 13.34.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/calcom/index.cjs.default.js +1 -0
- package/calcom/index.cjs.js +1451 -0
- package/calcom/index.cjs.mjs +2 -0
- package/calcom/index.d.ts +1 -0
- package/calcom/index.esm.js +1437 -0
- package/calcom/package.json +29 -0
- package/calcom/src/index.d.ts +1 -0
- package/calcom/src/lib/calcom.oauth.connection.cache.d.ts +49 -0
- package/calcom/src/lib/calcom.oauth.connection.config.d.ts +75 -0
- package/calcom/src/lib/calcom.oauth.connection.context.d.ts +84 -0
- package/calcom/src/lib/calcom.oauth.connection.controller.d.ts +18 -0
- package/calcom/src/lib/calcom.oauth.connection.module.d.ts +55 -0
- package/calcom/src/lib/calcom.oauth.connection.service.d.ts +33 -0
- package/calcom/src/lib/index.d.ts +6 -0
- package/discord/index.cjs.default.js +1 -0
- package/discord/index.cjs.js +761 -0
- package/discord/index.cjs.mjs +2 -0
- package/discord/index.d.ts +1 -0
- package/discord/index.esm.js +753 -0
- package/discord/package.json +29 -0
- package/discord/src/index.d.ts +1 -0
- package/discord/src/lib/discord.oauth.connection.config.d.ts +69 -0
- package/discord/src/lib/discord.oauth.connection.controller.d.ts +18 -0
- package/discord/src/lib/discord.oauth.connection.module.d.ts +39 -0
- package/discord/src/lib/discord.oauth.connection.service.d.ts +43 -0
- package/discord/src/lib/index.d.ts +4 -0
- package/index.cjs.js +42 -9
- package/index.esm.js +42 -9
- package/mailgun/package.json +9 -9
- package/mcp/package.json +11 -11
- package/model/index.cjs.js +4243 -855
- package/model/index.esm.js +4183 -862
- package/model/package.json +10 -9
- package/model/src/lib/index.d.ts +2 -0
- package/model/src/lib/system/index.d.ts +2 -0
- package/model/src/lib/system/system.private.d.ts +63 -0
- package/model/src/lib/system/system.private.module.d.ts +70 -0
- package/model/src/lib/userexternalconnection/index.d.ts +8 -0
- package/model/src/lib/userexternalconnection/oauth/index.d.ts +7 -0
- package/model/src/lib/userexternalconnection/oauth/userexternalconnection.oauth.config.d.ts +110 -0
- package/model/src/lib/userexternalconnection/oauth/userexternalconnection.oauth.controller.d.ts +68 -0
- package/model/src/lib/userexternalconnection/oauth/userexternalconnection.oauth.error.d.ts +29 -0
- package/model/src/lib/userexternalconnection/oauth/userexternalconnection.oauth.refresh.d.ts +24 -0
- package/model/src/lib/userexternalconnection/oauth/userexternalconnection.oauth.registry.d.ts +54 -0
- package/model/src/lib/userexternalconnection/oauth/userexternalconnection.oauth.service.d.ts +216 -0
- package/model/src/lib/userexternalconnection/oauth/userexternalconnection.oauth.state.d.ts +114 -0
- package/model/src/lib/userexternalconnection/userexternalconnection.accessor.service.d.ts +111 -0
- package/model/src/lib/userexternalconnection/userexternalconnection.action.server.d.ts +172 -0
- package/model/src/lib/userexternalconnection/userexternalconnection.error.d.ts +44 -0
- package/model/src/lib/userexternalconnection/userexternalconnection.module.d.ts +129 -0
- package/model/src/lib/userexternalconnection/userexternalconnection.private.d.ts +192 -0
- package/model/src/lib/userexternalconnection/userexternalconnection.reader.service.d.ts +157 -0
- package/model/src/lib/userexternalconnection/userexternalconnection.refresh.service.d.ts +46 -0
- package/oidc/index.cjs.js +104 -78
- package/oidc/index.esm.js +104 -78
- package/oidc/package.json +10 -10
- package/package.json +24 -10
- package/src/lib/env/env.config.d.ts +15 -0
- package/src/lib/env/env.service.d.ts +7 -0
- package/src/lib/firestore/snapshot/snapshot.field.encrypt.d.ts +21 -2
- package/src/lib/nest/env/env.service.d.ts +1 -0
- package/test/index.cjs.js +14 -2
- package/test/index.esm.js +15 -3
- package/test/package.json +11 -11
- package/test/src/lib/firebase/firebase.admin.auth.d.ts +1 -1
- package/twilio/package.json +8 -8
- package/zoho/README.md +38 -0
- package/zoho/index.cjs.js +1418 -64
- package/zoho/index.esm.js +1401 -67
- package/zoho/package.json +13 -9
- package/zoho/src/lib/index.d.ts +6 -0
- package/zoho/src/lib/zoho.accounts.firebase.d.ts +10 -3
- package/zoho/src/lib/zoho.accounts.firebase.module.d.ts +51 -0
- package/zoho/src/lib/zoho.accounts.firebase.system.d.ts +51 -8
- package/zoho/src/lib/zoho.oauth.connection.cache.d.ts +45 -0
- package/zoho/src/lib/zoho.oauth.connection.config.d.ts +80 -0
- package/zoho/src/lib/zoho.oauth.connection.controller.d.ts +18 -0
- package/zoho/src/lib/zoho.oauth.connection.module.d.ts +43 -0
- package/zoho/src/lib/zoho.oauth.connection.service.d.ts +107 -0
package/oidc/index.esm.js
CHANGED
|
@@ -6217,7 +6217,7 @@ var OidcInteractionController_1;
|
|
|
6217
6217
|
* @throws {HttpException} HTTP 400 when the consent interaction cannot be completed.
|
|
6218
6218
|
*/ function postConsent(uid, body, res) {
|
|
6219
6219
|
return _async_to_generator$2(function() {
|
|
6220
|
-
var startedAt, clientId, accountId, _ref, _prompt_details_missingOIDCScope,
|
|
6220
|
+
var startedAt, clientId, accountId, _ref, _prompt_details_missingOIDCScope, _ref1, _this_accountService_providerConfig_adminOnlyScopes, _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, _oidcClientProviderProfileScopes, clientUnlockedScopes, clientRequiredScopes, profileGatedScopes, disallowedGatedScopes, _ref5, redirectTo1, missingRequiredScopes, _ref6, redirectTo2, effectiveOIDCScopes, heldOIDCScopes, consentedOIDCScopeSet, configAdminOnlyScopes, adminOnlyScopes, consentedAdminOnlyScopes, requestsServiceToken, isAdmin, _tmp1, _ref7, redirectTo3, requestedRawTtl, clientMaxSessionTtl, expiresInSeconds, grant, _tmp2, granted, rejected, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, value, encounteredOIDCClaims, missingOIDCClaims, _resolveEffectiveSubset, granted1, rejected1, missingResourceScopes, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _step_value, indicator, scopes, _ref8, _body_grantedResourceScopes, requestedSubset, encounteredResourceScopes, _resolveEffectiveSubset1, granted2, rejected2, _iteratorNormalCompletion2, _didIteratorError2, _iteratorError2, _iterator2, _step2, value1, grantId, _ref9, redirectTo4, err;
|
|
6221
6221
|
return _ts_generator$2(this, function(_state) {
|
|
6222
6222
|
switch(_state.label){
|
|
6223
6223
|
case 0:
|
|
@@ -6299,66 +6299,44 @@ var OidcInteractionController_1;
|
|
|
6299
6299
|
];
|
|
6300
6300
|
case 9:
|
|
6301
6301
|
clientPayload = _state.sent();
|
|
6302
|
-
//
|
|
6303
|
-
//
|
|
6304
|
-
//
|
|
6305
|
-
//
|
|
6306
|
-
//
|
|
6302
|
+
// The requested OIDC scope set is `missingOIDCScope ∪ encounteredOIDCScopes` (a fresh consent has
|
|
6303
|
+
// everything in `missing`; a re-consent may carry already-granted scopes in `encountered`). The two
|
|
6304
|
+
// provider-profile gates below judge the REQUEST — what this client may ask for at all — so they
|
|
6305
|
+
// read this set. The admin-only gate further down judges what the user actually consented to
|
|
6306
|
+
// instead, and reads `consentedOIDCScopeSet`.
|
|
6307
6307
|
requestedOIDCScopeSet = new Set(_to_consumable_array$1(missingOIDCScope).concat(_to_consumable_array$1(encounteredOIDCScopes)));
|
|
6308
6308
|
providerProfiles = this.accountService.providerConfig.providerProfiles;
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
//
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
return requestedOIDCScopeSet.has(scope);
|
|
6309
|
+
// Provider-profile scope gate. Any scope referenced by a provider profile is "gated" — available
|
|
6310
|
+
// only to clients whose assigned profiles unlock it (a client with NO assigned profiles resolves
|
|
6311
|
+
// to the registry's default profiles). Independent of the admin-only gate below; a scope may be
|
|
6312
|
+
// subject to both.
|
|
6313
|
+
_oidcClientProviderProfileScopes = oidcClientProviderProfileScopes(providerProfiles, (_ref1 = clientPayload === null || clientPayload === void 0 ? void 0 : clientPayload.dbx_provider_profiles) !== null && _ref1 !== void 0 ? _ref1 : undefined), clientUnlockedScopes = _oidcClientProviderProfileScopes.unlocked, clientRequiredScopes = _oidcClientProviderProfileScopes.required;
|
|
6314
|
+
profileGatedScopes = scopesForOidcProviderProfiles(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : []);
|
|
6315
|
+
// Unlock gate: reject any requested gated scope this client's profiles do not unlock.
|
|
6316
|
+
disallowedGatedScopes = Array.from(requestedOIDCScopeSet).filter(function(scope) {
|
|
6317
|
+
return profileGatedScopes.has(scope) && !clientUnlockedScopes.has(scope);
|
|
6319
6318
|
});
|
|
6320
|
-
if (!
|
|
6319
|
+
if (!(disallowedGatedScopes.length > 0)) return [
|
|
6321
6320
|
3,
|
|
6322
6321
|
11
|
|
6323
6322
|
];
|
|
6324
|
-
return [
|
|
6325
|
-
4,
|
|
6326
|
-
(_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
|
|
6327
|
-
];
|
|
6328
|
-
case 10:
|
|
6329
|
-
_tmp1 = _state.sent();
|
|
6330
|
-
return [
|
|
6331
|
-
3,
|
|
6332
|
-
12
|
|
6333
|
-
];
|
|
6334
|
-
case 11:
|
|
6335
|
-
_tmp1 = false;
|
|
6336
|
-
_state.label = 12;
|
|
6337
|
-
case 12:
|
|
6338
|
-
isAdmin = _tmp1;
|
|
6339
|
-
if (!(requestedAdminOnlyScopes.length > 0 && !isAdmin)) return [
|
|
6340
|
-
3,
|
|
6341
|
-
14
|
|
6342
|
-
];
|
|
6343
6323
|
return [
|
|
6344
6324
|
4,
|
|
6345
6325
|
this.oidcInteractionService.finishInteractionByUid(uid, {
|
|
6346
6326
|
error: 'access_denied',
|
|
6347
|
-
error_description: "The following scope(s) are
|
|
6327
|
+
error_description: "The following scope(s) are not available to this client: ".concat(disallowedGatedScopes.join(', '), ".")
|
|
6348
6328
|
}, {
|
|
6349
6329
|
mergeWithLastSubmission: true
|
|
6350
6330
|
})
|
|
6351
6331
|
];
|
|
6352
|
-
case
|
|
6332
|
+
case 10:
|
|
6353
6333
|
_ref5 = _state.sent(), redirectTo1 = _ref5.returnTo;
|
|
6354
6334
|
emitOidcAnalyticsEvent(this._analytics, {
|
|
6355
6335
|
type: 'consent',
|
|
6356
6336
|
isSuccessful: false,
|
|
6357
6337
|
uid: accountId,
|
|
6358
6338
|
clientId: clientId,
|
|
6359
|
-
|
|
6360
|
-
isAdmin: false,
|
|
6361
|
-
reason: 'service_token_non_admin',
|
|
6339
|
+
reason: 'scope_not_unlocked_for_client',
|
|
6362
6340
|
durationMs: Date.now() - startedAt
|
|
6363
6341
|
}, this._logger);
|
|
6364
6342
|
res.json({
|
|
@@ -6367,38 +6345,33 @@ var OidcInteractionController_1;
|
|
|
6367
6345
|
return [
|
|
6368
6346
|
2
|
|
6369
6347
|
];
|
|
6370
|
-
case
|
|
6371
|
-
//
|
|
6372
|
-
//
|
|
6373
|
-
|
|
6374
|
-
|
|
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;
|
|
6376
|
-
profileGatedScopes = scopesForOidcProviderProfiles(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : []);
|
|
6377
|
-
// Unlock gate: reject any requested gated scope this client's profiles do not unlock.
|
|
6378
|
-
disallowedGatedScopes = Array.from(requestedOIDCScopeSet).filter(function(scope) {
|
|
6379
|
-
return profileGatedScopes.has(scope) && !clientUnlockedScopes.has(scope);
|
|
6348
|
+
case 11:
|
|
6349
|
+
// Required gate: a scope a client's profiles force-require (`require: 'required'`) must be present
|
|
6350
|
+
// in the request. Reject when the client did not request a required scope.
|
|
6351
|
+
missingRequiredScopes = Array.from(clientRequiredScopes).filter(function(scope) {
|
|
6352
|
+
return !requestedOIDCScopeSet.has(scope);
|
|
6380
6353
|
});
|
|
6381
|
-
if (!(
|
|
6354
|
+
if (!(missingRequiredScopes.length > 0)) return [
|
|
6382
6355
|
3,
|
|
6383
|
-
|
|
6356
|
+
13
|
|
6384
6357
|
];
|
|
6385
6358
|
return [
|
|
6386
6359
|
4,
|
|
6387
6360
|
this.oidcInteractionService.finishInteractionByUid(uid, {
|
|
6388
6361
|
error: 'access_denied',
|
|
6389
|
-
error_description: "
|
|
6362
|
+
error_description: "This client must request the required scope(s): ".concat(missingRequiredScopes.join(', '), ".")
|
|
6390
6363
|
}, {
|
|
6391
6364
|
mergeWithLastSubmission: true
|
|
6392
6365
|
})
|
|
6393
6366
|
];
|
|
6394
|
-
case
|
|
6367
|
+
case 12:
|
|
6395
6368
|
_ref6 = _state.sent(), redirectTo2 = _ref6.returnTo;
|
|
6396
6369
|
emitOidcAnalyticsEvent(this._analytics, {
|
|
6397
6370
|
type: 'consent',
|
|
6398
6371
|
isSuccessful: false,
|
|
6399
6372
|
uid: accountId,
|
|
6400
6373
|
clientId: clientId,
|
|
6401
|
-
reason: '
|
|
6374
|
+
reason: 'required_scope_missing',
|
|
6402
6375
|
durationMs: Date.now() - startedAt
|
|
6403
6376
|
}, this._logger);
|
|
6404
6377
|
res.json({
|
|
@@ -6407,13 +6380,62 @@ var OidcInteractionController_1;
|
|
|
6407
6380
|
return [
|
|
6408
6381
|
2
|
|
6409
6382
|
];
|
|
6410
|
-
case
|
|
6411
|
-
//
|
|
6412
|
-
//
|
|
6413
|
-
|
|
6414
|
-
|
|
6383
|
+
case 13:
|
|
6384
|
+
// The scopes this consent actually puts in force. Resolved once here and re-applied to the grant
|
|
6385
|
+
// further down, so the admin-only gate below judges exactly the set that will be granted.
|
|
6386
|
+
//
|
|
6387
|
+
// Force-grants the client's required profile scopes (in addition to `openid`) so they cannot be
|
|
6388
|
+
// dropped at consent — the required gate above already guarantees they were requested.
|
|
6389
|
+
effectiveOIDCScopes = resolveEffectiveSubset({
|
|
6390
|
+
missing: missingOIDCScope,
|
|
6391
|
+
requestedSubset: body.grantedOIDCScopes,
|
|
6392
|
+
alwaysGranted: _to_consumable_array$1(ALWAYS_GRANTED_OIDC_SCOPES).concat(_to_consumable_array$1(clientRequiredScopes)),
|
|
6393
|
+
alreadyEncountered: encounteredOIDCScopes
|
|
6415
6394
|
});
|
|
6416
|
-
|
|
6395
|
+
// Scopes the existing Grant already holds (granted, minus any it rejected). Nothing here revokes
|
|
6396
|
+
// them, so they stay in force through this consent and the gate below has to count them too.
|
|
6397
|
+
heldOIDCScopes = existingGrant ? existingGrant.getOIDCScope().split(' ').filter(Boolean) : [];
|
|
6398
|
+
consentedOIDCScopeSet = new Set(_to_consumable_array$1(heldOIDCScopes).concat(_to_consumable_array$1(effectiveOIDCScopes.granted)));
|
|
6399
|
+
// Admin-only scope gate. If the consented set intersects the admin-only scopes — the provider's
|
|
6400
|
+
// `adminOnlyScopes` unioned with the scopes of every profile marked `adminOnly` — and the resolving
|
|
6401
|
+
// user is not an admin, hard-reject with `access_denied` rather than silently dropping the scope.
|
|
6402
|
+
//
|
|
6403
|
+
// Deliberately gated on what the user CONSENTED to rather than on what the client requested: the
|
|
6404
|
+
// consent UI renders a deselectable checkbox for every scope in the auth request, and a client
|
|
6405
|
+
// cannot know the caller's admin status when it builds that request. Gating on the request would
|
|
6406
|
+
// make an admin-only scope in `scopes_supported` fatal for every non-admin — deselecting it at
|
|
6407
|
+
// consent has to be a way through.
|
|
6408
|
+
configAdminOnlyScopes = (_this_accountService_providerConfig_adminOnlyScopes = this.accountService.providerConfig.adminOnlyScopes) !== null && _this_accountService_providerConfig_adminOnlyScopes !== void 0 ? _this_accountService_providerConfig_adminOnlyScopes : [];
|
|
6409
|
+
adminOnlyScopes = new Set(_to_consumable_array$1(configAdminOnlyScopes).concat(_to_consumable_array$1(adminOnlyScopesForOidcProviderProfiles(providerProfiles !== null && providerProfiles !== void 0 ? providerProfiles : []))));
|
|
6410
|
+
consentedAdminOnlyScopes = Array.from(adminOnlyScopes).filter(function(scope) {
|
|
6411
|
+
return consentedOIDCScopeSet.has(scope);
|
|
6412
|
+
});
|
|
6413
|
+
// Deliberately sourced from the provider config's `adminOnlyScopes` ALONE, unlike the gate above:
|
|
6414
|
+
// this flag also selects the (highest) service-token TTL tier further down, and a profile marked
|
|
6415
|
+
// `adminOnly` must gate by admin status WITHOUT widening its grant's lifetime to that tier.
|
|
6416
|
+
requestsServiceToken = configAdminOnlyScopes.some(function(scope) {
|
|
6417
|
+
return consentedOIDCScopeSet.has(scope);
|
|
6418
|
+
});
|
|
6419
|
+
if (!accountId) return [
|
|
6420
|
+
3,
|
|
6421
|
+
15
|
|
6422
|
+
];
|
|
6423
|
+
return [
|
|
6424
|
+
4,
|
|
6425
|
+
(_ref2 = (_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 && _ref2 !== void 0 ? _ref2 : false
|
|
6426
|
+
];
|
|
6427
|
+
case 14:
|
|
6428
|
+
_tmp1 = _state.sent();
|
|
6429
|
+
return [
|
|
6430
|
+
3,
|
|
6431
|
+
16
|
|
6432
|
+
];
|
|
6433
|
+
case 15:
|
|
6434
|
+
_tmp1 = false;
|
|
6435
|
+
_state.label = 16;
|
|
6436
|
+
case 16:
|
|
6437
|
+
isAdmin = _tmp1;
|
|
6438
|
+
if (!(consentedAdminOnlyScopes.length > 0 && !isAdmin)) return [
|
|
6417
6439
|
3,
|
|
6418
6440
|
18
|
|
6419
6441
|
];
|
|
@@ -6421,7 +6443,7 @@ var OidcInteractionController_1;
|
|
|
6421
6443
|
4,
|
|
6422
6444
|
this.oidcInteractionService.finishInteractionByUid(uid, {
|
|
6423
6445
|
error: 'access_denied',
|
|
6424
|
-
error_description: "
|
|
6446
|
+
error_description: "The following scope(s) are restricted to admins: ".concat(consentedAdminOnlyScopes.join(', '), ".")
|
|
6425
6447
|
}, {
|
|
6426
6448
|
mergeWithLastSubmission: true
|
|
6427
6449
|
})
|
|
@@ -6433,7 +6455,9 @@ var OidcInteractionController_1;
|
|
|
6433
6455
|
isSuccessful: false,
|
|
6434
6456
|
uid: accountId,
|
|
6435
6457
|
clientId: clientId,
|
|
6436
|
-
|
|
6458
|
+
serviceToken: requestsServiceToken,
|
|
6459
|
+
isAdmin: false,
|
|
6460
|
+
reason: 'service_token_non_admin',
|
|
6437
6461
|
durationMs: Date.now() - startedAt
|
|
6438
6462
|
}, this._logger);
|
|
6439
6463
|
res.json({
|
|
@@ -6476,14 +6500,7 @@ var OidcInteractionController_1;
|
|
|
6476
6500
|
case 21:
|
|
6477
6501
|
grant = _tmp2;
|
|
6478
6502
|
if (missingOIDCScope.length > 0) {
|
|
6479
|
-
|
|
6480
|
-
// dropped at consent — the required gate above already guarantees they were requested.
|
|
6481
|
-
_resolveEffectiveSubset = resolveEffectiveSubset({
|
|
6482
|
-
missing: missingOIDCScope,
|
|
6483
|
-
requestedSubset: body.grantedOIDCScopes,
|
|
6484
|
-
alwaysGranted: _to_consumable_array$1(ALWAYS_GRANTED_OIDC_SCOPES).concat(_to_consumable_array$1(clientRequiredScopes)),
|
|
6485
|
-
alreadyEncountered: encounteredOIDCScopes
|
|
6486
|
-
}), granted = _resolveEffectiveSubset.granted, rejected = _resolveEffectiveSubset.rejected;
|
|
6503
|
+
granted = effectiveOIDCScopes.granted, rejected = effectiveOIDCScopes.rejected;
|
|
6487
6504
|
if (granted.length > 0) {
|
|
6488
6505
|
grant.addOIDCScope(granted.join(' '));
|
|
6489
6506
|
}
|
|
@@ -6511,11 +6528,11 @@ var OidcInteractionController_1;
|
|
|
6511
6528
|
encounteredOIDCClaims = grant.getOIDCClaimsEncountered();
|
|
6512
6529
|
missingOIDCClaims = (_prompt_details_missingOIDCClaims = prompt.details.missingOIDCClaims) !== null && _prompt_details_missingOIDCClaims !== void 0 ? _prompt_details_missingOIDCClaims : [];
|
|
6513
6530
|
if (missingOIDCClaims.length > 0) {
|
|
6514
|
-
|
|
6531
|
+
_resolveEffectiveSubset = resolveEffectiveSubset({
|
|
6515
6532
|
missing: missingOIDCClaims,
|
|
6516
6533
|
requestedSubset: body.grantedOIDCClaims,
|
|
6517
6534
|
alreadyEncountered: encounteredOIDCClaims
|
|
6518
|
-
}), granted1 =
|
|
6535
|
+
}), granted1 = _resolveEffectiveSubset.granted, rejected1 = _resolveEffectiveSubset.rejected;
|
|
6519
6536
|
if (granted1.length > 0) {
|
|
6520
6537
|
grant.addOIDCClaims(granted1);
|
|
6521
6538
|
}
|
|
@@ -6529,13 +6546,22 @@ var OidcInteractionController_1;
|
|
|
6529
6546
|
for(_iterator1 = Object.entries(missingResourceScopes)[Symbol.iterator](); !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
6530
6547
|
_step_value = _sliced_to_array(_step1.value, 2), indicator = _step_value[0], scopes = _step_value[1];
|
|
6531
6548
|
;
|
|
6532
|
-
|
|
6549
|
+
;
|
|
6550
|
+
// A submission with no explicit per-resource selection falls back to the OIDC scope selection
|
|
6551
|
+
// rather than granting everything the resource server declares. A resource server's scope list
|
|
6552
|
+
// is drawn from the same provider scopes the consent UI renders as one checkbox list, so a scope
|
|
6553
|
+
// deselected there must not reappear on the resource-bound access token — otherwise deselecting
|
|
6554
|
+
// an admin-only scope would clear the gate above while the token still carried it.
|
|
6555
|
+
// `grantedOIDCScopes` being absent still means "grant everything requested".
|
|
6556
|
+
requestedSubset = (_ref8 = (_body_grantedResourceScopes = body.grantedResourceScopes) === null || _body_grantedResourceScopes === void 0 ? void 0 : _body_grantedResourceScopes[indicator]) !== null && _ref8 !== void 0 ? _ref8 : body.grantedOIDCScopes ? scopes.filter(function(scope) {
|
|
6557
|
+
return consentedOIDCScopeSet.has(scope);
|
|
6558
|
+
}) : undefined;
|
|
6533
6559
|
encounteredResourceScopes = grant.getResourceScopeEncountered(indicator).split(' ').filter(Boolean);
|
|
6534
|
-
|
|
6560
|
+
_resolveEffectiveSubset1 = resolveEffectiveSubset({
|
|
6535
6561
|
missing: scopes,
|
|
6536
6562
|
requestedSubset: requestedSubset,
|
|
6537
6563
|
alreadyEncountered: encounteredResourceScopes
|
|
6538
|
-
}), granted2 =
|
|
6564
|
+
}), granted2 = _resolveEffectiveSubset1.granted, rejected2 = _resolveEffectiveSubset1.rejected;
|
|
6539
6565
|
if (granted2.length > 0) {
|
|
6540
6566
|
grant.addResourceScope(indicator, granted2.join(' '));
|
|
6541
6567
|
}
|
|
@@ -6591,7 +6617,7 @@ var OidcInteractionController_1;
|
|
|
6591
6617
|
})
|
|
6592
6618
|
];
|
|
6593
6619
|
case 23:
|
|
6594
|
-
|
|
6620
|
+
_ref9 = _state.sent(), redirectTo4 = _ref9.returnTo;
|
|
6595
6621
|
emitOidcAnalyticsEvent(this._analytics, {
|
|
6596
6622
|
type: 'consent',
|
|
6597
6623
|
isSuccessful: true,
|
package/oidc/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/oidc",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.34.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.34.0",
|
|
6
|
+
"@dereekb/date": "13.34.0",
|
|
7
|
+
"@dereekb/firebase": "13.34.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.34.0",
|
|
9
|
+
"@dereekb/model": "13.34.0",
|
|
10
|
+
"@dereekb/nestjs": "13.34.0",
|
|
11
|
+
"@dereekb/rxjs": "13.34.0",
|
|
12
|
+
"@dereekb/util": "13.34.0",
|
|
13
|
+
"@dereekb/zoho": "13.34.0",
|
|
14
14
|
"@nestjs/common": "^11.1.19",
|
|
15
15
|
"@nestjs/config": "^4.0.4",
|
|
16
16
|
"express": "^5.2.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.34.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"exports": {
|
|
6
6
|
"./test": {
|
|
@@ -9,6 +9,18 @@
|
|
|
9
9
|
"import": "./test/index.cjs.mjs",
|
|
10
10
|
"default": "./test/index.cjs.js"
|
|
11
11
|
},
|
|
12
|
+
"./calcom": {
|
|
13
|
+
"module": "./calcom/index.esm.js",
|
|
14
|
+
"types": "./calcom/index.d.ts",
|
|
15
|
+
"import": "./calcom/index.cjs.mjs",
|
|
16
|
+
"default": "./calcom/index.cjs.js"
|
|
17
|
+
},
|
|
18
|
+
"./discord": {
|
|
19
|
+
"module": "./discord/index.esm.js",
|
|
20
|
+
"types": "./discord/index.d.ts",
|
|
21
|
+
"import": "./discord/index.cjs.mjs",
|
|
22
|
+
"default": "./discord/index.cjs.js"
|
|
23
|
+
},
|
|
12
24
|
"./mailgun": {
|
|
13
25
|
"module": "./mailgun/index.esm.js",
|
|
14
26
|
"types": "./mailgun/index.d.ts",
|
|
@@ -57,15 +69,17 @@
|
|
|
57
69
|
"types": "./src/index.d.ts",
|
|
58
70
|
"peerDependencies": {
|
|
59
71
|
"@cantoo/pdf-lib": "^2.6.5",
|
|
60
|
-
"@dereekb/analytics": "13.
|
|
61
|
-
"@dereekb/
|
|
62
|
-
"@dereekb/
|
|
63
|
-
"@dereekb/
|
|
64
|
-
"@dereekb/
|
|
65
|
-
"@dereekb/
|
|
66
|
-
"@dereekb/
|
|
67
|
-
"@dereekb/
|
|
68
|
-
"@dereekb/
|
|
72
|
+
"@dereekb/analytics": "13.34.0",
|
|
73
|
+
"@dereekb/calcom": "13.34.0",
|
|
74
|
+
"@dereekb/date": "13.34.0",
|
|
75
|
+
"@dereekb/dbx-core": "13.34.0",
|
|
76
|
+
"@dereekb/discord": "13.34.0",
|
|
77
|
+
"@dereekb/firebase": "13.34.0",
|
|
78
|
+
"@dereekb/model": "13.34.0",
|
|
79
|
+
"@dereekb/nestjs": "13.34.0",
|
|
80
|
+
"@dereekb/rxjs": "13.34.0",
|
|
81
|
+
"@dereekb/util": "13.34.0",
|
|
82
|
+
"@dereekb/zoho": "13.34.0",
|
|
69
83
|
"@google-cloud/firestore": "^7.11.6",
|
|
70
84
|
"@google-cloud/storage": "^7.19.0",
|
|
71
85
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
@@ -29,6 +29,21 @@ export interface FirebaseServerEnvironmentConfig extends ServerEnvironmentConfig
|
|
|
29
29
|
* `appApiUrl` (or `appUrl`).
|
|
30
30
|
*/
|
|
31
31
|
readonly appMcpUrl?: Maybe<WebsiteUrlWithPrefix>;
|
|
32
|
+
/**
|
|
33
|
+
* The origin external-connection OAuth endpoints are reachable at (e.g. 'https://example.com').
|
|
34
|
+
*
|
|
35
|
+
* The `/oauth/<providerType>/{authorize,callback}` routes are excluded from the global API route
|
|
36
|
+
* prefix, so they are served from the site origin rather than from `appApiUrl`. The redirect URI
|
|
37
|
+
* registered with each provider is derived from this value, and providers require a byte-identical
|
|
38
|
+
* match.
|
|
39
|
+
*
|
|
40
|
+
* Set explicitly when those routes are not reachable at `appUrl` — in local development `appUrl`
|
|
41
|
+
* is typically the Angular dev server while the `/oauth/**` hosting rewrite is served by the
|
|
42
|
+
* hosting emulator on another port. In production the two normally coincide, so it can be omitted.
|
|
43
|
+
*
|
|
44
|
+
* When omitted, modules fall back to `appUrl`.
|
|
45
|
+
*/
|
|
46
|
+
readonly appOAuthUrl?: Maybe<WebsiteUrlWithPrefix>;
|
|
32
47
|
/**
|
|
33
48
|
* The webhook URL. When not set explicitly, `buildNestServerRootModule()` computes
|
|
34
49
|
* it from `appUrl + /webhook`.
|
|
@@ -54,6 +54,13 @@ export declare abstract class FirebaseServerEnvService {
|
|
|
54
54
|
* URL from `appApiUrl` / `appUrl`.
|
|
55
55
|
*/
|
|
56
56
|
abstract readonly appMcpUrl: Maybe<WebsiteUrl>;
|
|
57
|
+
/**
|
|
58
|
+
* The origin external-connection OAuth endpoints are reachable at (e.g., 'https://app.example.com').
|
|
59
|
+
*
|
|
60
|
+
* Used to derive each provider's registered redirect URI. When omitted, modules fall back to
|
|
61
|
+
* `appUrl`.
|
|
62
|
+
*/
|
|
63
|
+
abstract readonly appOAuthUrl: Maybe<WebsiteUrl>;
|
|
57
64
|
/**
|
|
58
65
|
* The full webhook URL (e.g., 'https://app.example.com/webhook').
|
|
59
66
|
*/
|
|
@@ -14,6 +14,18 @@ export interface FirestoreEncryptedFieldConfig<T> {
|
|
|
14
14
|
* Default value when the field is missing from Firestore.
|
|
15
15
|
*/
|
|
16
16
|
readonly default: GetterOrValue<T>;
|
|
17
|
+
/**
|
|
18
|
+
* Called when a stored value is present but cannot be decrypted — a wrong or rotated key, a
|
|
19
|
+
* corrupt value, or data written before the field was encrypted. Its return value is used in
|
|
20
|
+
* place of the decrypted value.
|
|
21
|
+
*
|
|
22
|
+
* When omitted the decode throws, which is the correct behavior for a field of record: a
|
|
23
|
+
* credential that silently becomes `undefined` is far worse than a loud failure.
|
|
24
|
+
*
|
|
25
|
+
* Only supply this for data that can be regenerated — a cache. See the Zoho access token cache,
|
|
26
|
+
* where an undecryptable entry is a cache miss and the next call re-mints the token.
|
|
27
|
+
*/
|
|
28
|
+
readonly onDecodeFailure?: Maybe<(error: unknown, data: string) => T>;
|
|
17
29
|
}
|
|
18
30
|
/**
|
|
19
31
|
* Configuration for an optional encrypted Firestore field.
|
|
@@ -25,13 +37,20 @@ export interface OptionalFirestoreEncryptedFieldConfig<T> {
|
|
|
25
37
|
* Secret source for the encryption key.
|
|
26
38
|
*/
|
|
27
39
|
readonly secret: GetterOrValue<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Called when a stored value is present but cannot be decrypted. See
|
|
42
|
+
* {@link FirestoreEncryptedFieldConfig.onDecodeFailure}. When omitted the decode throws.
|
|
43
|
+
*/
|
|
44
|
+
readonly onDecodeFailure?: Maybe<(error: unknown, data: string) => Maybe<T>>;
|
|
28
45
|
}
|
|
29
46
|
/**
|
|
30
47
|
* Creates a Firestore field mapping that encrypts/decrypts a JSON-serializable value
|
|
31
48
|
* using AES-256-GCM. The value is stored in Firestore as a base64-encoded string.
|
|
32
49
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
50
|
+
* IMPORTANT: there is NO key rotation. `resolveEncryptionKey()` reads and validates the secret once,
|
|
51
|
+
* here at construction, and closes over the resulting key — changing the secret afterwards orphans
|
|
52
|
+
* every value already written with the old one. Rotation is only survivable for fields that supply
|
|
53
|
+
* {@link FirestoreEncryptedFieldConfig.onDecodeFailure} and hold regenerable data.
|
|
35
54
|
*
|
|
36
55
|
* @param config - Encryption field configuration.
|
|
37
56
|
* @returns A field mapping configuration for encrypted values.
|
|
@@ -17,6 +17,7 @@ export declare class DefaultFirebaseServerEnvService extends ServerEnvironmentSe
|
|
|
17
17
|
get developmentSchedulerEnabled(): boolean;
|
|
18
18
|
get appUrlDetails(): Maybe<WebsiteUrlDetails>;
|
|
19
19
|
get appMcpUrl(): Maybe<WebsiteUrl>;
|
|
20
|
+
get appOAuthUrl(): Maybe<WebsiteUrl>;
|
|
20
21
|
get appWebhookUrl(): Maybe<WebsiteUrl>;
|
|
21
22
|
get isApiEnabled(): boolean;
|
|
22
23
|
get isWebhooksEnabled(): boolean;
|
package/test/index.cjs.js
CHANGED
|
@@ -707,12 +707,24 @@ function _ts_generator$a(thisArg, body) {
|
|
|
707
707
|
});
|
|
708
708
|
};
|
|
709
709
|
}
|
|
710
|
+
/**
|
|
711
|
+
* Random component of a generated test uid.
|
|
712
|
+
*
|
|
713
|
+
* The counter and the timestamp alone are not enough to keep uids unique: the counter is per-module, so
|
|
714
|
+
* every spec FILE starts it at 1, and two files whose first user is created in the same millisecond
|
|
715
|
+
* would otherwise be handed the identical uid — which fails as "the user with the provided uid already
|
|
716
|
+
* exists" in whichever file loses. Kept numeric so a uid stays digits-only.
|
|
717
|
+
*/ var testUidRandomFactory = util.randomNumberFactory({
|
|
718
|
+
min: 100000,
|
|
719
|
+
max: 1000000,
|
|
720
|
+
round: 'floor'
|
|
721
|
+
});
|
|
710
722
|
/**
|
|
711
723
|
* Incrementing number factory for generating test UID values.
|
|
712
724
|
*
|
|
713
|
-
* Has the format '
|
|
725
|
+
* Has the format '<timestamp>0<counter><random>'
|
|
714
726
|
*/ var testUidFactory = util.mapGetter(util.incrementingNumberFactory(), function(i) {
|
|
715
|
-
return "".concat(Date.now(), "0").concat(i);
|
|
727
|
+
return "".concat(Date.now(), "0").concat(i).concat(testUidRandomFactory());
|
|
716
728
|
});
|
|
717
729
|
/**
|
|
718
730
|
* Creates a CallableContextOptions with auth attached corresponding to the input UserRecord.
|
package/test/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomEmailFactory, randomPhoneNumberFactory, mapGetter, incrementingNumberFactory, asGetter, getValueFromGetter, cachedGetter, asArray, mapObjectMap, unixDateTimeSecondsNumberForNow } from '@dereekb/util';
|
|
1
|
+
import { randomEmailFactory, randomPhoneNumberFactory, randomNumberFactory, 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
4
|
import { flatFirestoreModelKey, twoWayFlatFirestoreModelKey, firestoreContextFactory, firebaseStorageContextFactory, adminOnlyScopesForOidcProviderProfiles, assignmentOnlyScopesForOidcProviderProfiles } from '@dereekb/firebase';
|
|
@@ -706,12 +706,24 @@ function _ts_generator$a(thisArg, body) {
|
|
|
706
706
|
});
|
|
707
707
|
};
|
|
708
708
|
}
|
|
709
|
+
/**
|
|
710
|
+
* Random component of a generated test uid.
|
|
711
|
+
*
|
|
712
|
+
* The counter and the timestamp alone are not enough to keep uids unique: the counter is per-module, so
|
|
713
|
+
* every spec FILE starts it at 1, and two files whose first user is created in the same millisecond
|
|
714
|
+
* would otherwise be handed the identical uid — which fails as "the user with the provided uid already
|
|
715
|
+
* exists" in whichever file loses. Kept numeric so a uid stays digits-only.
|
|
716
|
+
*/ var testUidRandomFactory = randomNumberFactory({
|
|
717
|
+
min: 100000,
|
|
718
|
+
max: 1000000,
|
|
719
|
+
round: 'floor'
|
|
720
|
+
});
|
|
709
721
|
/**
|
|
710
722
|
* Incrementing number factory for generating test UID values.
|
|
711
723
|
*
|
|
712
|
-
* Has the format '
|
|
724
|
+
* Has the format '<timestamp>0<counter><random>'
|
|
713
725
|
*/ var testUidFactory = mapGetter(incrementingNumberFactory(), function(i) {
|
|
714
|
-
return "".concat(Date.now(), "0").concat(i);
|
|
726
|
+
return "".concat(Date.now(), "0").concat(i).concat(testUidRandomFactory());
|
|
715
727
|
});
|
|
716
728
|
/**
|
|
717
729
|
* Creates a CallableContextOptions with auth attached corresponding to the input UserRecord.
|
package/test/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/test",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.34.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.34.0",
|
|
6
|
+
"@dereekb/date": "13.34.0",
|
|
7
|
+
"@dereekb/firebase": "13.34.0",
|
|
8
|
+
"@dereekb/firebase-server": "13.34.0",
|
|
9
|
+
"@dereekb/firebase-server/oidc": "13.34.0",
|
|
10
|
+
"@dereekb/model": "13.34.0",
|
|
11
|
+
"@dereekb/nestjs": "13.34.0",
|
|
12
|
+
"@dereekb/rxjs": "13.34.0",
|
|
13
|
+
"@dereekb/util": "13.34.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.34.0"
|
|
27
27
|
},
|
|
28
28
|
"exports": {
|
|
29
29
|
"./package.json": "./package.json",
|
|
@@ -283,7 +283,7 @@ export declare function authorizedUserContextFactory<PI extends FirebaseAdminTes
|
|
|
283
283
|
/**
|
|
284
284
|
* Incrementing number factory for generating test UID values.
|
|
285
285
|
*
|
|
286
|
-
* Has the format '
|
|
286
|
+
* Has the format '<timestamp>0<counter><random>'
|
|
287
287
|
*/
|
|
288
288
|
export declare const testUidFactory: Factory<FirebaseAuthUserId>;
|
|
289
289
|
/**
|
package/twilio/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dereekb/firebase-server/twilio",
|
|
3
|
-
"version": "13.
|
|
3
|
+
"version": "13.34.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.34.0",
|
|
6
|
+
"@dereekb/firebase": "13.34.0",
|
|
7
|
+
"@dereekb/firebase-server": "13.34.0",
|
|
8
|
+
"@dereekb/model": "13.34.0",
|
|
9
|
+
"@dereekb/nestjs": "13.34.0",
|
|
10
|
+
"@dereekb/rxjs": "13.34.0",
|
|
11
|
+
"@dereekb/util": "13.34.0"
|
|
12
12
|
},
|
|
13
13
|
"exports": {
|
|
14
14
|
"./package.json": "./package.json",
|