@frontmcp/auth 1.7.1 → 1.7.2
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/authorization/authorization.class.d.ts +10 -1
- package/authorization/authorization.class.d.ts.map +1 -1
- package/esm/index.mjs +80 -29
- package/esm/package.json +5 -5
- package/index.d.ts +2 -2
- package/index.d.ts.map +1 -1
- package/index.js +157 -103
- package/package.json +5 -5
- package/session/authorization.store.d.ts +9 -0
- package/session/authorization.store.d.ts.map +1 -1
- package/session/incremental-auth-ticket.d.ts +69 -0
- package/session/incremental-auth-ticket.d.ts.map +1 -0
- package/session/index.d.ts +2 -0
- package/session/index.d.ts.map +1 -1
- package/ui/templates.d.ts.map +1 -1
package/index.js
CHANGED
|
@@ -262,15 +262,16 @@ __export(index_exports, {
|
|
|
262
262
|
CredentialProviderAlreadyRegisteredError: () => CredentialProviderAlreadyRegisteredError,
|
|
263
263
|
CredentialStorageError: () => CredentialStorageError,
|
|
264
264
|
CredentialsAccessorImpl: () => CredentialsAccessorImpl,
|
|
265
|
+
DEFAULT_INCREMENTAL_TICKET_TTL_MS: () => DEFAULT_INCREMENTAL_TICKET_TTL_MS,
|
|
265
266
|
DEFAULT_RESUME_TTL_MS: () => DEFAULT_RESUME_TTL_MS,
|
|
266
267
|
DEFAULT_THEME: () => DEFAULT_THEME,
|
|
267
268
|
DcrClientRegistry: () => DcrClientRegistry,
|
|
268
269
|
EagerCredentialLoader: () => EagerCredentialLoader,
|
|
269
270
|
ElicitationSecretRequiredError: () => ElicitationSecretRequiredError,
|
|
270
271
|
EncryptedRedisVault: () => EncryptedRedisVault,
|
|
271
|
-
EncryptedStorageError: () =>
|
|
272
|
+
EncryptedStorageError: () => import_utils23.EncryptedStorageError,
|
|
272
273
|
EncryptedStorageSecureStoreBackend: () => EncryptedStorageSecureStoreBackend,
|
|
273
|
-
EncryptedTypedStorage: () =>
|
|
274
|
+
EncryptedTypedStorage: () => import_utils23.EncryptedTypedStorage,
|
|
274
275
|
EncryptionContextNotSetError: () => EncryptionContextNotSetError,
|
|
275
276
|
EncryptionKeyNotConfiguredError: () => EncryptionKeyNotConfiguredError,
|
|
276
277
|
FetchCredentialMiddleware: () => FetchCredentialMiddleware,
|
|
@@ -316,7 +317,7 @@ __export(index_exports, {
|
|
|
316
317
|
TokenVault: () => TokenVault,
|
|
317
318
|
TransparentAuthorization: () => TransparentAuthorization,
|
|
318
319
|
TransportIdGenerator: () => TransportIdGenerator,
|
|
319
|
-
TypedStorage: () =>
|
|
320
|
+
TypedStorage: () => import_utils22.TypedStorage,
|
|
320
321
|
VaultEncryption: () => VaultEncryption,
|
|
321
322
|
VaultLoadError: () => VaultLoadError,
|
|
322
323
|
VaultNotFoundError: () => VaultNotFoundError,
|
|
@@ -398,9 +399,9 @@ __export(index_exports, {
|
|
|
398
399
|
credentialTypeSchema: () => credentialTypeSchema,
|
|
399
400
|
customCredentialSchema: () => customCredentialSchema,
|
|
400
401
|
decodeJwtPayloadSafe: () => decodeJwtPayloadSafe,
|
|
401
|
-
decryptAesGcm: () =>
|
|
402
|
+
decryptAesGcm: () => import_utils33.decryptAesGcm,
|
|
402
403
|
decryptSessionJson: () => decryptSessionJson,
|
|
403
|
-
decryptValue: () =>
|
|
404
|
+
decryptValue: () => import_utils33.decryptValue,
|
|
404
405
|
defaultSessionRateLimiter: () => defaultSessionRateLimiter,
|
|
405
406
|
deriveAuthorizationId: () => deriveAuthorizationId,
|
|
406
407
|
deriveExpectedAudience: () => deriveExpectedAudience,
|
|
@@ -408,9 +409,9 @@ __export(index_exports, {
|
|
|
408
409
|
deriveTypedUser: () => deriveTypedUser,
|
|
409
410
|
detectAuthProviders: () => detectAuthProviders,
|
|
410
411
|
detectedAuthProviderSchema: () => detectedAuthProviderSchema,
|
|
411
|
-
encryptAesGcm: () =>
|
|
412
|
+
encryptAesGcm: () => import_utils33.encryptAesGcm,
|
|
412
413
|
encryptJson: () => encryptJson,
|
|
413
|
-
encryptValue: () =>
|
|
414
|
+
encryptValue: () => import_utils33.encryptValue,
|
|
414
415
|
encryptedBlobSchema: () => encryptedBlobSchema,
|
|
415
416
|
encryptedDataSchema: () => encryptedDataSchema,
|
|
416
417
|
encryptedVaultEntrySchema: () => encryptedVaultEntrySchema,
|
|
@@ -436,7 +437,7 @@ __export(index_exports, {
|
|
|
436
437
|
getTokenSignatureFingerprint: () => getTokenSignatureFingerprint,
|
|
437
438
|
hasOnlyLocalhostRedirectUris: () => hasOnlyLocalhostRedirectUris,
|
|
438
439
|
headerApplier: () => headerApplier,
|
|
439
|
-
hkdfSha256: () =>
|
|
440
|
+
hkdfSha256: () => import_utils33.hkdfSha256,
|
|
440
441
|
incrementalAuthConfigSchema: () => incrementalAuthConfigSchema,
|
|
441
442
|
isCimdClientId: () => isCimdClientId,
|
|
442
443
|
isFrontMcpCredentials: () => isFrontMcpCredentials,
|
|
@@ -450,7 +451,7 @@ __export(index_exports, {
|
|
|
450
451
|
isRedisTokenStorage: () => isRedisTokenStorage,
|
|
451
452
|
isRemoteMode: () => isRemoteMode,
|
|
452
453
|
isSessionComplete: () => isSessionComplete,
|
|
453
|
-
isSignedSession: () =>
|
|
454
|
+
isSignedSession: () => import_utils15.isSignedData,
|
|
454
455
|
isSoonExpiring: () => isSoonExpiring,
|
|
455
456
|
isSoonExpiringProvider: () => isSoonExpiringProvider,
|
|
456
457
|
isSqliteTokenStorage: () => isSqliteTokenStorage,
|
|
@@ -505,6 +506,7 @@ __export(index_exports, {
|
|
|
505
506
|
sessionIdPayloadSchema: () => sessionIdPayloadSchema,
|
|
506
507
|
sessionJwtPayloadSchema: () => sessionJwtPayloadSchema,
|
|
507
508
|
signCredentialResumeToken: () => signCredentialResumeToken,
|
|
509
|
+
signIncrementalAuthTicket: () => signIncrementalAuthTicket,
|
|
508
510
|
signSession: () => signSession,
|
|
509
511
|
skippedAppBehaviorSchema: () => skippedAppBehaviorSchema,
|
|
510
512
|
sseTransportStateSchema: () => sseTransportStateSchema,
|
|
@@ -533,6 +535,7 @@ __export(index_exports, {
|
|
|
533
535
|
vaultConsentRecordSchema: () => vaultConsentRecordSchema,
|
|
534
536
|
vaultFederatedRecordSchema: () => vaultFederatedRecordSchema,
|
|
535
537
|
verifyCredentialResumeToken: () => verifyCredentialResumeToken,
|
|
538
|
+
verifyIncrementalAuthTicket: () => verifyIncrementalAuthTicket,
|
|
536
539
|
verifyOrParseSession: () => verifyOrParseSession,
|
|
537
540
|
verifyPkce: () => verifyPkce,
|
|
538
541
|
verifySession: () => verifySession,
|
|
@@ -1641,8 +1644,6 @@ function buildIncrementalAuthPage(params) {
|
|
|
1641
1644
|
|
|
1642
1645
|
<form method="GET" action="${escapeHtml3(callbackPath)}" class="flex gap-3 pt-4 border-t border-gray-100">
|
|
1643
1646
|
<input type="hidden" name="pending_auth_id" value="${escapeHtml3(sessionHint)}">
|
|
1644
|
-
<input type="hidden" name="app_id" value="${escapeHtml3(app.appId)}">
|
|
1645
|
-
<input type="hidden" name="incremental" value="true">
|
|
1646
1647
|
<button type="button" onclick="window.close()"
|
|
1647
1648
|
class="flex-1 px-4 py-2.5 text-gray-600 hover:text-gray-900 hover:bg-gray-100 font-medium rounded-lg transition-colors">
|
|
1648
1649
|
Cancel
|
|
@@ -2126,6 +2127,7 @@ function buildPendingRecord(params) {
|
|
|
2126
2127
|
createdAt: now,
|
|
2127
2128
|
expiresAt: now + PENDING_AUTH_TTL_MS,
|
|
2128
2129
|
isIncremental: params.isIncremental,
|
|
2130
|
+
incrementalSub: params.incrementalSub,
|
|
2129
2131
|
targetAppId: params.targetAppId,
|
|
2130
2132
|
targetToolId: params.targetToolId,
|
|
2131
2133
|
existingSessionId: params.existingSessionId,
|
|
@@ -3260,6 +3262,44 @@ function buildCredentialResumeUrl(basePath, token) {
|
|
|
3260
3262
|
return `${trimmed}/oauth/connect?token=${encodeURIComponent(token)}`;
|
|
3261
3263
|
}
|
|
3262
3264
|
|
|
3265
|
+
// libs/auth/src/session/incremental-auth-ticket.ts
|
|
3266
|
+
var import_utils10 = require("@frontmcp/utils");
|
|
3267
|
+
var DEFAULT_INCREMENTAL_TICKET_TTL_MS = 3e5;
|
|
3268
|
+
function signIncrementalAuthTicket(input, secret) {
|
|
3269
|
+
const payload = {
|
|
3270
|
+
sub: input.sub,
|
|
3271
|
+
appId: input.appId,
|
|
3272
|
+
...input.toolId !== void 0 ? { toolId: input.toolId } : {},
|
|
3273
|
+
...input.priorAppIds !== void 0 ? { priorAppIds: input.priorAppIds } : {},
|
|
3274
|
+
jti: (0, import_utils10.randomUUID)(),
|
|
3275
|
+
exp: Date.now() + (input.ttlMs ?? DEFAULT_INCREMENTAL_TICKET_TTL_MS)
|
|
3276
|
+
};
|
|
3277
|
+
const signedJson = (0, import_utils10.signData)(payload, { secret });
|
|
3278
|
+
return Buffer.from(signedJson, "utf8").toString("base64url");
|
|
3279
|
+
}
|
|
3280
|
+
function verifyIncrementalAuthTicket(token, secret, now = Date.now()) {
|
|
3281
|
+
let signedJson;
|
|
3282
|
+
try {
|
|
3283
|
+
signedJson = Buffer.from(token, "base64url").toString("utf8");
|
|
3284
|
+
} catch {
|
|
3285
|
+
return null;
|
|
3286
|
+
}
|
|
3287
|
+
const payload = (0, import_utils10.verifyData)(signedJson, { secret });
|
|
3288
|
+
if (!payload) return null;
|
|
3289
|
+
if (typeof payload.sub !== "string" || payload.sub.length === 0) return null;
|
|
3290
|
+
if (typeof payload.appId !== "string" || payload.appId.length === 0) return null;
|
|
3291
|
+
if (typeof payload.jti !== "string" || payload.jti.length === 0) return null;
|
|
3292
|
+
if (!Number.isFinite(payload.exp)) return null;
|
|
3293
|
+
if (payload.toolId !== void 0 && typeof payload.toolId !== "string") return null;
|
|
3294
|
+
if (payload.priorAppIds !== void 0 && (!Array.isArray(payload.priorAppIds) || payload.priorAppIds.some((id) => typeof id !== "string"))) {
|
|
3295
|
+
return null;
|
|
3296
|
+
}
|
|
3297
|
+
if (now >= payload.exp) {
|
|
3298
|
+
return null;
|
|
3299
|
+
}
|
|
3300
|
+
return payload;
|
|
3301
|
+
}
|
|
3302
|
+
|
|
3263
3303
|
// libs/auth/src/session/credentials-accessor.ts
|
|
3264
3304
|
var CREDENTIALS_ACCESSOR = /* @__PURE__ */ Symbol.for("frontmcp:CREDENTIALS_ACCESSOR");
|
|
3265
3305
|
|
|
@@ -3424,7 +3464,7 @@ function errMsg2(err) {
|
|
|
3424
3464
|
var SECURE_STORE_ACCESSOR = /* @__PURE__ */ Symbol.for("frontmcp:SECURE_STORE_ACCESSOR");
|
|
3425
3465
|
|
|
3426
3466
|
// libs/auth/src/session/secure-store-accessor.impl.ts
|
|
3427
|
-
var
|
|
3467
|
+
var import_utils11 = require("@frontmcp/utils");
|
|
3428
3468
|
var GLOBAL_NAMESPACE = "global";
|
|
3429
3469
|
var SecureStoreAccessorImpl = class {
|
|
3430
3470
|
backend;
|
|
@@ -3453,12 +3493,12 @@ var SecureStoreAccessorImpl = class {
|
|
|
3453
3493
|
return GLOBAL_NAMESPACE;
|
|
3454
3494
|
case "session": {
|
|
3455
3495
|
const sid = this.resolveSessionId();
|
|
3456
|
-
return sid ? `s:${(0,
|
|
3496
|
+
return sid ? `s:${(0, import_utils11.sha256Hex)(sid).slice(0, 32)}` : void 0;
|
|
3457
3497
|
}
|
|
3458
3498
|
case "user":
|
|
3459
3499
|
default: {
|
|
3460
3500
|
const sub = this.resolveSub();
|
|
3461
|
-
return sub ? `u:${(0,
|
|
3501
|
+
return sub ? `u:${(0, import_utils11.sha256Hex)(sub).slice(0, 32)}` : void 0;
|
|
3462
3502
|
}
|
|
3463
3503
|
}
|
|
3464
3504
|
}
|
|
@@ -3499,7 +3539,7 @@ function errMsg3(err) {
|
|
|
3499
3539
|
}
|
|
3500
3540
|
|
|
3501
3541
|
// libs/auth/src/session/secure-store.factory.ts
|
|
3502
|
-
var
|
|
3542
|
+
var import_utils12 = require("@frontmcp/utils");
|
|
3503
3543
|
function isCustomBackendConfig(config) {
|
|
3504
3544
|
return typeof config === "object" && config !== null && "backend" in config && !!config.backend;
|
|
3505
3545
|
}
|
|
@@ -3548,7 +3588,7 @@ async function createSecureStore(options) {
|
|
|
3548
3588
|
if (storage) {
|
|
3549
3589
|
adapter = storage;
|
|
3550
3590
|
} else if (kind === "memory") {
|
|
3551
|
-
adapter = new
|
|
3591
|
+
adapter = new import_utils12.MemoryStorageAdapter();
|
|
3552
3592
|
await adapter.connect();
|
|
3553
3593
|
} else {
|
|
3554
3594
|
adapter = await createTokenStorageAdapter(toTokenStorageConfig(config));
|
|
@@ -3562,7 +3602,7 @@ async function createSecureStore(options) {
|
|
|
3562
3602
|
}
|
|
3563
3603
|
|
|
3564
3604
|
// libs/auth/src/session/token.vault.ts
|
|
3565
|
-
var
|
|
3605
|
+
var import_utils13 = require("@frontmcp/utils");
|
|
3566
3606
|
var TokenVault = class {
|
|
3567
3607
|
/** Active key used for new encryptions */
|
|
3568
3608
|
active;
|
|
@@ -3591,14 +3631,14 @@ var TokenVault = class {
|
|
|
3591
3631
|
this.keys.set(k.kid, k.key);
|
|
3592
3632
|
}
|
|
3593
3633
|
async encrypt(plaintext, opts) {
|
|
3594
|
-
const iv = (0,
|
|
3595
|
-
const { ciphertext, tag } = await (0,
|
|
3634
|
+
const iv = (0, import_utils13.randomBytes)(12);
|
|
3635
|
+
const { ciphertext, tag } = await (0, import_utils13.encryptAesGcm)(this.active.key, new TextEncoder().encode(plaintext), iv);
|
|
3596
3636
|
return {
|
|
3597
3637
|
alg: "A256GCM",
|
|
3598
3638
|
kid: this.active.kid,
|
|
3599
|
-
iv: (0,
|
|
3600
|
-
tag: (0,
|
|
3601
|
-
data: (0,
|
|
3639
|
+
iv: (0, import_utils13.base64urlEncode)(iv),
|
|
3640
|
+
tag: (0, import_utils13.base64urlEncode)(tag),
|
|
3641
|
+
data: (0, import_utils13.base64urlEncode)(ciphertext),
|
|
3602
3642
|
exp: opts?.exp,
|
|
3603
3643
|
meta: opts?.meta
|
|
3604
3644
|
};
|
|
@@ -3612,16 +3652,16 @@ var TokenVault = class {
|
|
|
3612
3652
|
}
|
|
3613
3653
|
const key = this.keys.get(blob.kid);
|
|
3614
3654
|
if (!key) throw new Error(`vault_unknown_kid:${blob.kid}`);
|
|
3615
|
-
const iv = (0,
|
|
3616
|
-
const tag = (0,
|
|
3617
|
-
const data = (0,
|
|
3618
|
-
const plaintext = await (0,
|
|
3655
|
+
const iv = (0, import_utils13.base64urlDecode)(blob.iv);
|
|
3656
|
+
const tag = (0, import_utils13.base64urlDecode)(blob.tag);
|
|
3657
|
+
const data = (0, import_utils13.base64urlDecode)(blob.data);
|
|
3658
|
+
const plaintext = await (0, import_utils13.decryptAesGcm)(key, data, iv, tag);
|
|
3619
3659
|
return new TextDecoder().decode(plaintext);
|
|
3620
3660
|
}
|
|
3621
3661
|
};
|
|
3622
3662
|
|
|
3623
3663
|
// libs/auth/src/session/index.ts
|
|
3624
|
-
var
|
|
3664
|
+
var import_utils33 = require("@frontmcp/utils");
|
|
3625
3665
|
|
|
3626
3666
|
// libs/auth/src/session/transport-session.types.ts
|
|
3627
3667
|
var import_lazy_zod4 = require("@frontmcp/lazy-zod");
|
|
@@ -3717,10 +3757,10 @@ var redisConfigSchema = import_lazy_zod4.z.object({
|
|
|
3717
3757
|
});
|
|
3718
3758
|
|
|
3719
3759
|
// libs/auth/src/session/session-crypto.ts
|
|
3720
|
-
var
|
|
3760
|
+
var import_utils15 = require("@frontmcp/utils");
|
|
3721
3761
|
|
|
3722
3762
|
// libs/auth/src/errors/auth-internal.error.ts
|
|
3723
|
-
var
|
|
3763
|
+
var import_utils14 = require("@frontmcp/utils");
|
|
3724
3764
|
var AuthInternalError = class extends Error {
|
|
3725
3765
|
/**
|
|
3726
3766
|
* Unique error ID for tracking in logs.
|
|
@@ -3742,7 +3782,7 @@ var AuthInternalError = class extends Error {
|
|
|
3742
3782
|
super(message);
|
|
3743
3783
|
this.name = this.constructor.name;
|
|
3744
3784
|
this.code = code;
|
|
3745
|
-
this.errorId = `err_${(0,
|
|
3785
|
+
this.errorId = `err_${(0, import_utils14.bytesToHex)((0, import_utils14.randomBytes)(8))}`;
|
|
3746
3786
|
Error.captureStackTrace(this, this.constructor);
|
|
3747
3787
|
}
|
|
3748
3788
|
/**
|
|
@@ -3865,9 +3905,9 @@ var AuthFlowError = class extends AuthInternalError {
|
|
|
3865
3905
|
|
|
3866
3906
|
// libs/auth/src/session/session-crypto.ts
|
|
3867
3907
|
function getSigningSecret(config) {
|
|
3868
|
-
const secret = config?.secret || (0,
|
|
3908
|
+
const secret = config?.secret || (0, import_utils15.getEnv)("MCP_SESSION_SECRET");
|
|
3869
3909
|
if (!secret) {
|
|
3870
|
-
if ((0,
|
|
3910
|
+
if ((0, import_utils15.isProduction)()) {
|
|
3871
3911
|
throw new SessionSecretRequiredError("session signing");
|
|
3872
3912
|
}
|
|
3873
3913
|
console.warn("[SessionCrypto] MCP_SESSION_SECRET not set. Using insecure default for development only.");
|
|
@@ -3879,13 +3919,13 @@ function resolveConfig(config) {
|
|
|
3879
3919
|
return { secret: getSigningSecret(config) };
|
|
3880
3920
|
}
|
|
3881
3921
|
function signSession(session, config) {
|
|
3882
|
-
return (0,
|
|
3922
|
+
return (0, import_utils15.signData)(session, resolveConfig(config));
|
|
3883
3923
|
}
|
|
3884
3924
|
function verifySession(signedData, config) {
|
|
3885
|
-
return (0,
|
|
3925
|
+
return (0, import_utils15.verifyData)(signedData, resolveConfig(config));
|
|
3886
3926
|
}
|
|
3887
3927
|
function verifyOrParseSession(data, config) {
|
|
3888
|
-
return (0,
|
|
3928
|
+
return (0, import_utils15.verifyOrParseData)(data, resolveConfig(config));
|
|
3889
3929
|
}
|
|
3890
3930
|
|
|
3891
3931
|
// libs/auth/src/session/session-rate-limiter.ts
|
|
@@ -4012,7 +4052,7 @@ var SessionRateLimiter = class {
|
|
|
4012
4052
|
var defaultSessionRateLimiter = new SessionRateLimiter();
|
|
4013
4053
|
|
|
4014
4054
|
// libs/auth/src/session/session.transport.ts
|
|
4015
|
-
var
|
|
4055
|
+
var import_utils16 = require("@frontmcp/utils");
|
|
4016
4056
|
var TransportIdGenerator = class {
|
|
4017
4057
|
/**
|
|
4018
4058
|
* Create a transport session ID.
|
|
@@ -4021,7 +4061,7 @@ var TransportIdGenerator = class {
|
|
|
4021
4061
|
* @returns A transport session ID (UUID without dashes)
|
|
4022
4062
|
*/
|
|
4023
4063
|
static createId() {
|
|
4024
|
-
return (0,
|
|
4064
|
+
return (0, import_utils16.randomUUID)().replace(/-/g, "");
|
|
4025
4065
|
}
|
|
4026
4066
|
};
|
|
4027
4067
|
|
|
@@ -4070,7 +4110,7 @@ var TinyTtlCache = class {
|
|
|
4070
4110
|
};
|
|
4071
4111
|
|
|
4072
4112
|
// libs/auth/src/session/utils/auth-token.utils.ts
|
|
4073
|
-
var
|
|
4113
|
+
var import_utils17 = require("@frontmcp/utils");
|
|
4074
4114
|
function isJwt(token) {
|
|
4075
4115
|
if (!token) return false;
|
|
4076
4116
|
return token.split(".").length === 3;
|
|
@@ -4080,7 +4120,7 @@ function getTokenSignatureFingerprint(token) {
|
|
|
4080
4120
|
const sig = token.split(".")[2];
|
|
4081
4121
|
if (sig) return sig;
|
|
4082
4122
|
}
|
|
4083
|
-
return (0,
|
|
4123
|
+
return (0, import_utils17.sha256Base64url)(token);
|
|
4084
4124
|
}
|
|
4085
4125
|
function extractClaimValue(claims, key, validator) {
|
|
4086
4126
|
const value = claims[key];
|
|
@@ -4112,26 +4152,26 @@ function extractBearerToken(header) {
|
|
|
4112
4152
|
}
|
|
4113
4153
|
|
|
4114
4154
|
// libs/auth/src/session/utils/session-crypto.utils.ts
|
|
4115
|
-
var
|
|
4155
|
+
var import_utils18 = require("@frontmcp/utils");
|
|
4116
4156
|
var cachedKey = null;
|
|
4117
4157
|
function getKey() {
|
|
4118
4158
|
if (cachedKey) return cachedKey;
|
|
4119
|
-
const secret = (0,
|
|
4159
|
+
const secret = (0, import_utils18.getEnv)("MCP_SESSION_SECRET");
|
|
4120
4160
|
if (!secret) {
|
|
4121
|
-
if ((0,
|
|
4161
|
+
if ((0, import_utils18.isProduction)()) {
|
|
4122
4162
|
throw new SessionSecretRequiredError("session ID encryption");
|
|
4123
4163
|
}
|
|
4124
4164
|
console.warn(
|
|
4125
4165
|
"[SessionIdUtils] Using machine ID as session encryption secret - NOT SECURE FOR PRODUCTION. Set MCP_SESSION_SECRET environment variable for secure session encryption."
|
|
4126
4166
|
);
|
|
4127
4167
|
}
|
|
4128
|
-
const base = secret || (0,
|
|
4129
|
-
cachedKey = (0,
|
|
4168
|
+
const base = secret || (0, import_utils18.getMachineId)();
|
|
4169
|
+
cachedKey = (0, import_utils18.sha256)(new TextEncoder().encode(base));
|
|
4130
4170
|
return cachedKey;
|
|
4131
4171
|
}
|
|
4132
4172
|
function encryptJson(obj) {
|
|
4133
4173
|
const key = getKey();
|
|
4134
|
-
const encrypted = (0,
|
|
4174
|
+
const encrypted = (0, import_utils18.encryptValue)(obj, key);
|
|
4135
4175
|
return `${encrypted.iv}.${encrypted.tag}.${encrypted.data}`;
|
|
4136
4176
|
}
|
|
4137
4177
|
function decryptSessionJson(sessionId) {
|
|
@@ -4140,7 +4180,7 @@ function decryptSessionJson(sessionId) {
|
|
|
4140
4180
|
const [ivB64, tagB64, ctB64] = parts;
|
|
4141
4181
|
if (!ivB64 || !tagB64 || !ctB64) return null;
|
|
4142
4182
|
const key = getKey();
|
|
4143
|
-
return (0,
|
|
4183
|
+
return (0, import_utils18.decryptValue)({ alg: "A256GCM", iv: ivB64, tag: tagB64, data: ctB64 }, key);
|
|
4144
4184
|
}
|
|
4145
4185
|
function safeDecrypt(sessionId) {
|
|
4146
4186
|
try {
|
|
@@ -4154,11 +4194,11 @@ function resetCachedKey() {
|
|
|
4154
4194
|
}
|
|
4155
4195
|
|
|
4156
4196
|
// libs/auth/src/session/storage/index.ts
|
|
4157
|
-
var import_utils21 = require("@frontmcp/utils");
|
|
4158
4197
|
var import_utils22 = require("@frontmcp/utils");
|
|
4198
|
+
var import_utils23 = require("@frontmcp/utils");
|
|
4159
4199
|
|
|
4160
4200
|
// libs/auth/src/session/storage/storage-token-store.ts
|
|
4161
|
-
var
|
|
4201
|
+
var import_utils19 = require("@frontmcp/utils");
|
|
4162
4202
|
var StorageTokenStore = class {
|
|
4163
4203
|
storage;
|
|
4164
4204
|
namespace;
|
|
@@ -4170,13 +4210,13 @@ var StorageTokenStore = class {
|
|
|
4170
4210
|
this.defaultTtlSeconds = options.defaultTtlSeconds;
|
|
4171
4211
|
this.storageIsNamespaced = "namespace" in storage && typeof storage.namespace === "function";
|
|
4172
4212
|
const namespacedStorage = this.storageIsNamespaced ? storage.namespace(this.namespace) : storage;
|
|
4173
|
-
this.storage = new
|
|
4213
|
+
this.storage = new import_utils19.TypedStorage(namespacedStorage);
|
|
4174
4214
|
}
|
|
4175
4215
|
/**
|
|
4176
4216
|
* Allocate a new unique ID for a token record.
|
|
4177
4217
|
*/
|
|
4178
4218
|
allocId() {
|
|
4179
|
-
return (0,
|
|
4219
|
+
return (0, import_utils19.randomUUID)();
|
|
4180
4220
|
}
|
|
4181
4221
|
/**
|
|
4182
4222
|
* Store an encrypted token blob.
|
|
@@ -4239,7 +4279,7 @@ var StorageTokenStore = class {
|
|
|
4239
4279
|
};
|
|
4240
4280
|
|
|
4241
4281
|
// libs/auth/src/session/storage/storage-authorization-vault.ts
|
|
4242
|
-
var
|
|
4282
|
+
var import_utils20 = require("@frontmcp/utils");
|
|
4243
4283
|
var StorageAuthorizationVault = class {
|
|
4244
4284
|
storage;
|
|
4245
4285
|
namespace;
|
|
@@ -4248,7 +4288,7 @@ var StorageAuthorizationVault = class {
|
|
|
4248
4288
|
this.namespace = options.namespace ?? "vault";
|
|
4249
4289
|
this.pendingAuthTtlMs = options.pendingAuthTtlMs ?? 10 * 60 * 1e3;
|
|
4250
4290
|
const namespacedStorage = this.isNamespacedStorage(storage) ? storage.namespace(this.namespace) : storage;
|
|
4251
|
-
this.storage = new
|
|
4291
|
+
this.storage = new import_utils20.TypedStorage(namespacedStorage, {
|
|
4252
4292
|
schema: options.validateOnRead ? authorizationVaultEntrySchema : void 0,
|
|
4253
4293
|
throwOnInvalid: false
|
|
4254
4294
|
});
|
|
@@ -4259,7 +4299,7 @@ var StorageAuthorizationVault = class {
|
|
|
4259
4299
|
async create(params) {
|
|
4260
4300
|
const now = Date.now();
|
|
4261
4301
|
const entry = {
|
|
4262
|
-
id: (0,
|
|
4302
|
+
id: (0, import_utils20.randomUUID)(),
|
|
4263
4303
|
userSub: params.userSub,
|
|
4264
4304
|
userEmail: params.userEmail,
|
|
4265
4305
|
userName: params.userName,
|
|
@@ -4333,7 +4373,7 @@ var StorageAuthorizationVault = class {
|
|
|
4333
4373
|
}
|
|
4334
4374
|
const now = Date.now();
|
|
4335
4375
|
const pendingAuth = {
|
|
4336
|
-
id: (0,
|
|
4376
|
+
id: (0, import_utils20.randomUUID)(),
|
|
4337
4377
|
appId: params.appId,
|
|
4338
4378
|
toolId: params.toolId,
|
|
4339
4379
|
authUrl: params.authUrl,
|
|
@@ -4537,11 +4577,11 @@ var StorageAuthorizationVault = class {
|
|
|
4537
4577
|
};
|
|
4538
4578
|
|
|
4539
4579
|
// libs/auth/src/session/storage/in-memory-authorization-vault.ts
|
|
4540
|
-
var
|
|
4580
|
+
var import_utils21 = require("@frontmcp/utils");
|
|
4541
4581
|
var InMemoryAuthorizationVault = class extends StorageAuthorizationVault {
|
|
4542
4582
|
memoryAdapter;
|
|
4543
4583
|
constructor(options = {}) {
|
|
4544
|
-
const memoryAdapter = new
|
|
4584
|
+
const memoryAdapter = new import_utils21.MemoryStorageAdapter();
|
|
4545
4585
|
super(memoryAdapter, {
|
|
4546
4586
|
namespace: options.namespace ?? "vault",
|
|
4547
4587
|
pendingAuthTtlMs: options.pendingAuthTtlMs
|
|
@@ -4562,7 +4602,7 @@ var InMemoryAuthorizationVault = class extends StorageAuthorizationVault {
|
|
|
4562
4602
|
};
|
|
4563
4603
|
|
|
4564
4604
|
// libs/auth/src/session/redis-session.store.ts
|
|
4565
|
-
var
|
|
4605
|
+
var import_utils24 = require("@frontmcp/utils");
|
|
4566
4606
|
var RedisSessionStore = class {
|
|
4567
4607
|
storage;
|
|
4568
4608
|
keyPrefix;
|
|
@@ -4584,14 +4624,14 @@ var RedisSessionStore = class {
|
|
|
4584
4624
|
});
|
|
4585
4625
|
}
|
|
4586
4626
|
if ("redis" in config && config.redis) {
|
|
4587
|
-
this.storage = new
|
|
4627
|
+
this.storage = new import_utils24.RedisStorageAdapter({
|
|
4588
4628
|
client: config.redis,
|
|
4589
4629
|
keyPrefix: this.keyPrefix
|
|
4590
4630
|
});
|
|
4591
4631
|
this.externalInstance = true;
|
|
4592
4632
|
} else {
|
|
4593
4633
|
const redisConfig = config;
|
|
4594
|
-
this.storage = new
|
|
4634
|
+
this.storage = new import_utils24.RedisStorageAdapter({
|
|
4595
4635
|
config: {
|
|
4596
4636
|
host: redisConfig.host,
|
|
4597
4637
|
port: redisConfig.port ?? 6379,
|
|
@@ -4773,7 +4813,7 @@ var RedisSessionStore = class {
|
|
|
4773
4813
|
* Allocate a new session ID
|
|
4774
4814
|
*/
|
|
4775
4815
|
allocId() {
|
|
4776
|
-
return (0,
|
|
4816
|
+
return (0, import_utils24.randomUUID)();
|
|
4777
4817
|
}
|
|
4778
4818
|
/**
|
|
4779
4819
|
* Disconnect from Redis (only if we created the connection)
|
|
@@ -4809,7 +4849,7 @@ var RedisSessionStore = class {
|
|
|
4809
4849
|
};
|
|
4810
4850
|
|
|
4811
4851
|
// libs/auth/src/session/vercel-kv-session.store.ts
|
|
4812
|
-
var
|
|
4852
|
+
var import_utils25 = require("@frontmcp/utils");
|
|
4813
4853
|
var VercelKvSessionStore = class {
|
|
4814
4854
|
storage;
|
|
4815
4855
|
keyPrefix;
|
|
@@ -4829,7 +4869,7 @@ var VercelKvSessionStore = class {
|
|
|
4829
4869
|
maxRequests: this.security.rateLimiting?.maxRequests
|
|
4830
4870
|
});
|
|
4831
4871
|
}
|
|
4832
|
-
this.storage = new
|
|
4872
|
+
this.storage = new import_utils25.VercelKvStorageAdapter({
|
|
4833
4873
|
url: config.url,
|
|
4834
4874
|
token: config.token,
|
|
4835
4875
|
keyPrefix: this.keyPrefix
|
|
@@ -5003,7 +5043,7 @@ var VercelKvSessionStore = class {
|
|
|
5003
5043
|
* Allocate a new session ID
|
|
5004
5044
|
*/
|
|
5005
5045
|
allocId() {
|
|
5006
|
-
return (0,
|
|
5046
|
+
return (0, import_utils25.randomUUID)();
|
|
5007
5047
|
}
|
|
5008
5048
|
/**
|
|
5009
5049
|
* Disconnect from Vercel KV
|
|
@@ -5032,7 +5072,7 @@ var VercelKvSessionStore = class {
|
|
|
5032
5072
|
};
|
|
5033
5073
|
|
|
5034
5074
|
// libs/auth/src/session/orchestrated-token.store.ts
|
|
5035
|
-
var
|
|
5075
|
+
var import_utils26 = require("@frontmcp/utils");
|
|
5036
5076
|
var InMemoryOrchestratedTokenStore = class {
|
|
5037
5077
|
/** Token storage: Map<compositeKey, ProviderTokenRecord> */
|
|
5038
5078
|
tokens = /* @__PURE__ */ new Map();
|
|
@@ -5074,7 +5114,7 @@ var InMemoryOrchestratedTokenStore = class {
|
|
|
5074
5114
|
}
|
|
5075
5115
|
const info = new TextEncoder().encode(`orchestrated-token:${compositeKey}`);
|
|
5076
5116
|
const salt = new TextEncoder().encode("frontmcp-token-store");
|
|
5077
|
-
const derivedKey = (0,
|
|
5117
|
+
const derivedKey = (0, import_utils26.hkdfSha256)(this.encryptionKey, salt, info, 32);
|
|
5078
5118
|
this.derivedKeys.set(compositeKey, derivedKey);
|
|
5079
5119
|
return derivedKey;
|
|
5080
5120
|
}
|
|
@@ -5084,8 +5124,8 @@ var InMemoryOrchestratedTokenStore = class {
|
|
|
5084
5124
|
async encryptRecord(compositeKey, record) {
|
|
5085
5125
|
const key = await this.deriveKeyForRecord(compositeKey);
|
|
5086
5126
|
const plaintext = JSON.stringify(record);
|
|
5087
|
-
const iv = (0,
|
|
5088
|
-
const { ciphertext, tag } = (0,
|
|
5127
|
+
const iv = (0, import_utils26.randomBytes)(12);
|
|
5128
|
+
const { ciphertext, tag } = (0, import_utils26.encryptAesGcm)(key, new TextEncoder().encode(plaintext), iv);
|
|
5089
5129
|
return JSON.stringify({
|
|
5090
5130
|
iv: Buffer.from(iv).toString("base64url"),
|
|
5091
5131
|
tag: Buffer.from(tag).toString("base64url"),
|
|
@@ -5101,7 +5141,7 @@ var InMemoryOrchestratedTokenStore = class {
|
|
|
5101
5141
|
const ivBytes = Buffer.from(iv, "base64url");
|
|
5102
5142
|
const tagBytes = Buffer.from(tag, "base64url");
|
|
5103
5143
|
const ciphertextBytes = Buffer.from(data, "base64url");
|
|
5104
|
-
const plaintext = (0,
|
|
5144
|
+
const plaintext = (0, import_utils26.decryptAesGcm)(key, ciphertextBytes, ivBytes, tagBytes);
|
|
5105
5145
|
return JSON.parse(new TextDecoder().decode(plaintext));
|
|
5106
5146
|
}
|
|
5107
5147
|
/**
|
|
@@ -5303,7 +5343,7 @@ var InMemoryOrchestratedTokenStore = class {
|
|
|
5303
5343
|
};
|
|
5304
5344
|
|
|
5305
5345
|
// libs/auth/src/session/orchestrated-token.crypto.ts
|
|
5306
|
-
var
|
|
5346
|
+
var import_utils27 = require("@frontmcp/utils");
|
|
5307
5347
|
var HKDF_SALT = new TextEncoder().encode("frontmcp-token-store");
|
|
5308
5348
|
function deriveKeyForRecord(masterKey, compositeKey, cache) {
|
|
5309
5349
|
const cached = cache.get(compositeKey);
|
|
@@ -5311,14 +5351,14 @@ function deriveKeyForRecord(masterKey, compositeKey, cache) {
|
|
|
5311
5351
|
return cached;
|
|
5312
5352
|
}
|
|
5313
5353
|
const info = new TextEncoder().encode(`orchestrated-token:${compositeKey}`);
|
|
5314
|
-
const derived = (0,
|
|
5354
|
+
const derived = (0, import_utils27.hkdfSha256)(masterKey, HKDF_SALT, info, 32);
|
|
5315
5355
|
cache.set(compositeKey, derived);
|
|
5316
5356
|
return derived;
|
|
5317
5357
|
}
|
|
5318
5358
|
function encryptRecord(key, record) {
|
|
5319
5359
|
const plaintext = JSON.stringify(record);
|
|
5320
|
-
const iv = (0,
|
|
5321
|
-
const { ciphertext, tag } = (0,
|
|
5360
|
+
const iv = (0, import_utils27.randomBytes)(12);
|
|
5361
|
+
const { ciphertext, tag } = (0, import_utils27.encryptAesGcm)(key, new TextEncoder().encode(plaintext), iv);
|
|
5322
5362
|
return JSON.stringify({
|
|
5323
5363
|
iv: Buffer.from(iv).toString("base64url"),
|
|
5324
5364
|
tag: Buffer.from(tag).toString("base64url"),
|
|
@@ -5330,7 +5370,7 @@ function decryptRecord(key, encrypted) {
|
|
|
5330
5370
|
const ivBytes = Buffer.from(iv, "base64url");
|
|
5331
5371
|
const tagBytes = Buffer.from(tag, "base64url");
|
|
5332
5372
|
const ciphertextBytes = Buffer.from(data, "base64url");
|
|
5333
|
-
const plaintext = (0,
|
|
5373
|
+
const plaintext = (0, import_utils27.decryptAesGcm)(key, ciphertextBytes, ivBytes, tagBytes);
|
|
5334
5374
|
return JSON.parse(new TextDecoder().decode(plaintext));
|
|
5335
5375
|
}
|
|
5336
5376
|
|
|
@@ -5509,7 +5549,7 @@ var StorageOrchestratedTokenStore = class {
|
|
|
5509
5549
|
};
|
|
5510
5550
|
|
|
5511
5551
|
// libs/auth/src/session/federated-auth.session.ts
|
|
5512
|
-
var
|
|
5552
|
+
var import_utils28 = require("@frontmcp/utils");
|
|
5513
5553
|
function toSessionRecord(session) {
|
|
5514
5554
|
return {
|
|
5515
5555
|
...session,
|
|
@@ -5584,7 +5624,7 @@ var InMemoryFederatedAuthSessionStore = class {
|
|
|
5584
5624
|
createSession(params) {
|
|
5585
5625
|
const now = Date.now();
|
|
5586
5626
|
return {
|
|
5587
|
-
id: (0,
|
|
5627
|
+
id: (0, import_utils28.randomUUID)(),
|
|
5588
5628
|
pendingAuthId: params.pendingAuthId,
|
|
5589
5629
|
clientId: params.clientId,
|
|
5590
5630
|
redirectUri: params.redirectUri,
|
|
@@ -5616,7 +5656,7 @@ var InMemoryFederatedAuthSessionStore = class {
|
|
|
5616
5656
|
function createFederatedAuthSession(params, ttlMs = 15 * 60 * 1e3) {
|
|
5617
5657
|
const now = Date.now();
|
|
5618
5658
|
return {
|
|
5619
|
-
id: (0,
|
|
5659
|
+
id: (0, import_utils28.randomUUID)(),
|
|
5620
5660
|
pendingAuthId: params.pendingAuthId,
|
|
5621
5661
|
clientId: params.clientId,
|
|
5622
5662
|
redirectUri: params.redirectUri,
|
|
@@ -5673,7 +5713,7 @@ function startNextProvider(session, pkce, state) {
|
|
|
5673
5713
|
}
|
|
5674
5714
|
|
|
5675
5715
|
// libs/auth/src/session/storage-federated-auth.session.ts
|
|
5676
|
-
var
|
|
5716
|
+
var import_utils29 = require("@frontmcp/utils");
|
|
5677
5717
|
var StorageFederatedAuthSessionStore = class {
|
|
5678
5718
|
storage;
|
|
5679
5719
|
namespace;
|
|
@@ -5682,7 +5722,7 @@ var StorageFederatedAuthSessionStore = class {
|
|
|
5682
5722
|
this.namespace = options.namespace ?? "fed";
|
|
5683
5723
|
this.storageIsNamespaced = this.isNamespacedStorage(storage);
|
|
5684
5724
|
const namespacedStorage = this.storageIsNamespaced ? storage.namespace(this.namespace) : storage;
|
|
5685
|
-
this.storage = new
|
|
5725
|
+
this.storage = new import_utils29.TypedStorage(namespacedStorage);
|
|
5686
5726
|
}
|
|
5687
5727
|
async store(session) {
|
|
5688
5728
|
await this.put(session);
|
|
@@ -5753,7 +5793,7 @@ var InMemoryConsentStore = class {
|
|
|
5753
5793
|
};
|
|
5754
5794
|
|
|
5755
5795
|
// libs/auth/src/session/storage-consent.store.ts
|
|
5756
|
-
var
|
|
5796
|
+
var import_utils30 = require("@frontmcp/utils");
|
|
5757
5797
|
var StorageConsentStore = class {
|
|
5758
5798
|
storage;
|
|
5759
5799
|
namespace;
|
|
@@ -5762,7 +5802,7 @@ var StorageConsentStore = class {
|
|
|
5762
5802
|
this.namespace = options.namespace ?? "remembered-consent";
|
|
5763
5803
|
this.storageIsNamespaced = this.isNamespacedStorage(storage);
|
|
5764
5804
|
const namespacedStorage = this.storageIsNamespaced ? storage.namespace(this.namespace) : storage;
|
|
5765
|
-
this.storage = new
|
|
5805
|
+
this.storage = new import_utils30.TypedStorage(namespacedStorage);
|
|
5766
5806
|
}
|
|
5767
5807
|
async get(userSub, clientId) {
|
|
5768
5808
|
return this.storage.get(this.key(userSub, clientId));
|
|
@@ -5784,7 +5824,7 @@ var StorageConsentStore = class {
|
|
|
5784
5824
|
|
|
5785
5825
|
// libs/auth/src/session/encrypted-authorization-vault.ts
|
|
5786
5826
|
var import_lazy_zod5 = require("@frontmcp/lazy-zod");
|
|
5787
|
-
var
|
|
5827
|
+
var import_utils31 = require("@frontmcp/utils");
|
|
5788
5828
|
var redisVaultEntrySchema = import_lazy_zod5.z.object({
|
|
5789
5829
|
/** Vault ID */
|
|
5790
5830
|
id: import_lazy_zod5.z.string(),
|
|
@@ -5809,7 +5849,7 @@ var redisVaultEntrySchema = import_lazy_zod5.z.object({
|
|
|
5809
5849
|
/** Encrypted sensitive data blob */
|
|
5810
5850
|
encrypted: encryptedDataSchema
|
|
5811
5851
|
});
|
|
5812
|
-
var encryptionContextStorage = new
|
|
5852
|
+
var encryptionContextStorage = new import_utils31.AsyncLocalStorage();
|
|
5813
5853
|
var EncryptedRedisVault = class {
|
|
5814
5854
|
constructor(redis, encryption, namespace = "vault:") {
|
|
5815
5855
|
this.redis = redis;
|
|
@@ -5945,7 +5985,7 @@ var EncryptedRedisVault = class {
|
|
|
5945
5985
|
async create(params) {
|
|
5946
5986
|
const now = Date.now();
|
|
5947
5987
|
const entry = {
|
|
5948
|
-
id: (0,
|
|
5988
|
+
id: (0, import_utils31.randomUUID)(),
|
|
5949
5989
|
userSub: params.userSub,
|
|
5950
5990
|
userEmail: params.userEmail,
|
|
5951
5991
|
userName: params.userName,
|
|
@@ -6004,7 +6044,7 @@ var EncryptedRedisVault = class {
|
|
|
6004
6044
|
}
|
|
6005
6045
|
const now = Date.now();
|
|
6006
6046
|
const pendingAuth = {
|
|
6007
|
-
id: (0,
|
|
6047
|
+
id: (0, import_utils31.randomUUID)(),
|
|
6008
6048
|
appId: params.appId,
|
|
6009
6049
|
toolId: params.toolId,
|
|
6010
6050
|
authUrl: params.authUrl,
|
|
@@ -6182,7 +6222,7 @@ function createEncryptedVault(redis, config = {}) {
|
|
|
6182
6222
|
}
|
|
6183
6223
|
|
|
6184
6224
|
// libs/auth/src/session/token.refresh.ts
|
|
6185
|
-
var
|
|
6225
|
+
var import_utils32 = require("@frontmcp/utils");
|
|
6186
6226
|
function toEpochSeconds(exp) {
|
|
6187
6227
|
if (exp == null) return void 0;
|
|
6188
6228
|
if (exp instanceof Date) return Math.floor(exp.getTime() / 1e3);
|
|
@@ -6204,7 +6244,7 @@ function tryJwtExp(token) {
|
|
|
6204
6244
|
const parts = token.split(".");
|
|
6205
6245
|
if (parts.length < 2) return void 0;
|
|
6206
6246
|
try {
|
|
6207
|
-
const json = JSON.parse(new TextDecoder().decode((0,
|
|
6247
|
+
const json = JSON.parse(new TextDecoder().decode((0, import_utils32.base64urlDecode)(parts[1])));
|
|
6208
6248
|
const e = json?.exp;
|
|
6209
6249
|
return typeof e === "number" ? toEpochSeconds(e) : void 0;
|
|
6210
6250
|
} catch {
|
|
@@ -6267,7 +6307,7 @@ var progressiveAuthStateSchema = import_lazy_zod6.z.object({
|
|
|
6267
6307
|
});
|
|
6268
6308
|
|
|
6269
6309
|
// libs/auth/src/authorization/authorization.class.ts
|
|
6270
|
-
var
|
|
6310
|
+
var import_utils35 = require("@frontmcp/utils");
|
|
6271
6311
|
var AuthorizationBase = class _AuthorizationBase {
|
|
6272
6312
|
id;
|
|
6273
6313
|
isAnonymous;
|
|
@@ -6315,14 +6355,14 @@ var AuthorizationBase = class _AuthorizationBase {
|
|
|
6315
6355
|
* @param fingerprint - Optional client fingerprint for tracking
|
|
6316
6356
|
*/
|
|
6317
6357
|
createTransportSession(protocol, fingerprint) {
|
|
6318
|
-
const sessionId = (0,
|
|
6358
|
+
const sessionId = (0, import_utils35.randomUUID)();
|
|
6319
6359
|
const session = {
|
|
6320
6360
|
id: sessionId,
|
|
6321
6361
|
authorizationId: this.id,
|
|
6322
6362
|
protocol,
|
|
6323
6363
|
createdAt: Date.now(),
|
|
6324
6364
|
expiresAt: this.expiresAt,
|
|
6325
|
-
nodeId: (0,
|
|
6365
|
+
nodeId: (0, import_utils35.getMachineId)(),
|
|
6326
6366
|
clientFingerprint: fingerprint
|
|
6327
6367
|
};
|
|
6328
6368
|
this.#sessions.set(session.id, session);
|
|
@@ -6393,11 +6433,22 @@ var AuthorizationBase = class _AuthorizationBase {
|
|
|
6393
6433
|
/**
|
|
6394
6434
|
* Build URL for progressive/incremental authorization.
|
|
6395
6435
|
* Used when a tool requires authorization for an app that was skipped during initial auth.
|
|
6436
|
+
*
|
|
6437
|
+
* The URL only SKIPS the login step when it carries a valid incremental
|
|
6438
|
+
* ticket (GHSA-2c4g-9c8x-6m8g) — mint one with
|
|
6439
|
+
* {@link signIncrementalAuthTicket} using the server signing secret and pass
|
|
6440
|
+
* it here. Without a ticket the link still works, but the user completes an
|
|
6441
|
+
* ordinary login; `mode=incremental` alone is no longer an authorization
|
|
6442
|
+
* signal and is not emitted.
|
|
6443
|
+
*
|
|
6396
6444
|
* @param appId - App ID that requires authorization
|
|
6397
6445
|
* @param baseUrl - Base URL of the server
|
|
6446
|
+
* @param ticket - Signed incremental-authorization ticket for this subject
|
|
6398
6447
|
*/
|
|
6399
|
-
getProgressiveAuthUrl(appId, baseUrl) {
|
|
6400
|
-
|
|
6448
|
+
getProgressiveAuthUrl(appId, baseUrl, ticket) {
|
|
6449
|
+
const params = new URLSearchParams({ app: appId });
|
|
6450
|
+
if (ticket) params.set("ticket", ticket);
|
|
6451
|
+
return `${baseUrl}/oauth/authorize?${params.toString()}`;
|
|
6401
6452
|
}
|
|
6402
6453
|
/**
|
|
6403
6454
|
* Check if the authorization is expired
|
|
@@ -6452,7 +6503,7 @@ var AuthorizationBase = class _AuthorizationBase {
|
|
|
6452
6503
|
*/
|
|
6453
6504
|
static isJwtHeader(segment) {
|
|
6454
6505
|
try {
|
|
6455
|
-
const bytes = (0,
|
|
6506
|
+
const bytes = (0, import_utils35.base64urlDecode)(segment);
|
|
6456
6507
|
const text = new TextDecoder().decode(bytes);
|
|
6457
6508
|
const parsed = JSON.parse(text);
|
|
6458
6509
|
return typeof parsed === "object" && parsed !== null && typeof parsed.alg === "string";
|
|
@@ -6504,7 +6555,7 @@ var AuthorizationBase = class _AuthorizationBase {
|
|
|
6504
6555
|
};
|
|
6505
6556
|
|
|
6506
6557
|
// libs/auth/src/authorization/public.authorization.ts
|
|
6507
|
-
var
|
|
6558
|
+
var import_utils36 = require("@frontmcp/utils");
|
|
6508
6559
|
var PublicAuthorization = class _PublicAuthorization extends AuthorizationBase {
|
|
6509
6560
|
mode = "public";
|
|
6510
6561
|
/**
|
|
@@ -6540,7 +6591,7 @@ var PublicAuthorization = class _PublicAuthorization extends AuthorizationBase {
|
|
|
6540
6591
|
allowedTools = "all",
|
|
6541
6592
|
allowedPrompts = "all"
|
|
6542
6593
|
} = ctx;
|
|
6543
|
-
const uuid = (0,
|
|
6594
|
+
const uuid = (0, import_utils36.randomUUID)();
|
|
6544
6595
|
const sub = `${prefix}:${uuid}`;
|
|
6545
6596
|
const user = {
|
|
6546
6597
|
sub,
|
|
@@ -6624,7 +6675,7 @@ var PublicAuthorization = class _PublicAuthorization extends AuthorizationBase {
|
|
|
6624
6675
|
};
|
|
6625
6676
|
|
|
6626
6677
|
// libs/auth/src/authorization/transparent.authorization.ts
|
|
6627
|
-
var
|
|
6678
|
+
var import_utils37 = require("@frontmcp/utils");
|
|
6628
6679
|
var TransparentAuthorization = class _TransparentAuthorization extends AuthorizationBase {
|
|
6629
6680
|
mode = "transparent";
|
|
6630
6681
|
/**
|
|
@@ -6724,7 +6775,7 @@ var TransparentAuthorization = class _TransparentAuthorization extends Authoriza
|
|
|
6724
6775
|
static generateAuthorizationId(token) {
|
|
6725
6776
|
const parts = token.split(".");
|
|
6726
6777
|
const signature = parts[2] || token;
|
|
6727
|
-
return (0,
|
|
6778
|
+
return (0, import_utils37.sha256Hex)(signature).substring(0, 16);
|
|
6728
6779
|
}
|
|
6729
6780
|
/**
|
|
6730
6781
|
* Get the issuer from the token claims
|
|
@@ -6750,11 +6801,11 @@ var TransparentAuthorization = class _TransparentAuthorization extends Authoriza
|
|
|
6750
6801
|
};
|
|
6751
6802
|
|
|
6752
6803
|
// libs/auth/src/utils/authorization-id.utils.ts
|
|
6753
|
-
var
|
|
6804
|
+
var import_utils38 = require("@frontmcp/utils");
|
|
6754
6805
|
function deriveAuthorizationId(token) {
|
|
6755
6806
|
const parts = token.split(".");
|
|
6756
6807
|
const signature = parts[2] || token;
|
|
6757
|
-
return (0,
|
|
6808
|
+
return (0, import_utils38.sha256Hex)(signature).substring(0, 16);
|
|
6758
6809
|
}
|
|
6759
6810
|
|
|
6760
6811
|
// libs/auth/src/authorization/orchestrated.authorization.ts
|
|
@@ -7123,7 +7174,7 @@ var OrchestratedAuthAccessorAdapter = class {
|
|
|
7123
7174
|
};
|
|
7124
7175
|
|
|
7125
7176
|
// libs/auth/src/authorization/dcr-client.registry.ts
|
|
7126
|
-
var
|
|
7177
|
+
var import_utils39 = require("@frontmcp/utils");
|
|
7127
7178
|
var DEFAULT_MAX_DYNAMIC_CLIENTS = 1e3;
|
|
7128
7179
|
function globMatch(pattern, input) {
|
|
7129
7180
|
let p = 0;
|
|
@@ -7249,7 +7300,7 @@ var DcrClientRegistry = class {
|
|
|
7249
7300
|
if (!isConfidential) return "ok";
|
|
7250
7301
|
if (!client.client_secret) return "invalid";
|
|
7251
7302
|
if (!presentedSecret) return "invalid";
|
|
7252
|
-
return (0,
|
|
7303
|
+
return (0, import_utils39.timingSafeEqual)((0, import_utils39.sha256)(presentedSecret), (0, import_utils39.sha256)(client.client_secret)) ? "ok" : "invalid";
|
|
7253
7304
|
}
|
|
7254
7305
|
/** Whether a client id is known to the registry. */
|
|
7255
7306
|
has(clientId) {
|
|
@@ -7337,7 +7388,7 @@ var DcrClientRegistry = class {
|
|
|
7337
7388
|
if (typeof presented !== "string" || presented.length === 0) {
|
|
7338
7389
|
return false;
|
|
7339
7390
|
}
|
|
7340
|
-
return (0,
|
|
7391
|
+
return (0, import_utils39.timingSafeEqual)((0, import_utils39.sha256)(presented), (0, import_utils39.sha256)(expected));
|
|
7341
7392
|
}
|
|
7342
7393
|
};
|
|
7343
7394
|
|
|
@@ -9383,7 +9434,7 @@ var CredentialCache = class {
|
|
|
9383
9434
|
var AUTH_PROVIDERS_ACCESSOR = /* @__PURE__ */ Symbol.for("frontmcp:AUTH_PROVIDERS_ACCESSOR");
|
|
9384
9435
|
|
|
9385
9436
|
// libs/auth/src/vault/auth-providers.accessor.impl.ts
|
|
9386
|
-
var
|
|
9437
|
+
var import_utils42 = require("@frontmcp/utils");
|
|
9387
9438
|
var AuthProvidersAccessorImpl = class {
|
|
9388
9439
|
constructor(registry, vault, cache, loader, context, logger) {
|
|
9389
9440
|
this.registry = registry;
|
|
@@ -9598,7 +9649,7 @@ var AuthProvidersAccessorImpl = class {
|
|
|
9598
9649
|
return { [credential.headerName]: credential.key };
|
|
9599
9650
|
case "basic": {
|
|
9600
9651
|
const value = `${credential.username}:${credential.password}`;
|
|
9601
|
-
const encoded = credential.encodedValue ?? (0,
|
|
9652
|
+
const encoded = credential.encodedValue ?? (0, import_utils42.base64Encode)(new TextEncoder().encode(value));
|
|
9602
9653
|
return { Authorization: `Basic ${encoded}` };
|
|
9603
9654
|
}
|
|
9604
9655
|
case "custom":
|
|
@@ -11157,6 +11208,7 @@ var FetchCredentialMiddleware = class {
|
|
|
11157
11208
|
CredentialProviderAlreadyRegisteredError,
|
|
11158
11209
|
CredentialStorageError,
|
|
11159
11210
|
CredentialsAccessorImpl,
|
|
11211
|
+
DEFAULT_INCREMENTAL_TICKET_TTL_MS,
|
|
11160
11212
|
DEFAULT_RESUME_TTL_MS,
|
|
11161
11213
|
DEFAULT_THEME,
|
|
11162
11214
|
DcrClientRegistry,
|
|
@@ -11400,6 +11452,7 @@ var FetchCredentialMiddleware = class {
|
|
|
11400
11452
|
sessionIdPayloadSchema,
|
|
11401
11453
|
sessionJwtPayloadSchema,
|
|
11402
11454
|
signCredentialResumeToken,
|
|
11455
|
+
signIncrementalAuthTicket,
|
|
11403
11456
|
signSession,
|
|
11404
11457
|
skippedAppBehaviorSchema,
|
|
11405
11458
|
sseTransportStateSchema,
|
|
@@ -11428,6 +11481,7 @@ var FetchCredentialMiddleware = class {
|
|
|
11428
11481
|
vaultConsentRecordSchema,
|
|
11429
11482
|
vaultFederatedRecordSchema,
|
|
11430
11483
|
verifyCredentialResumeToken,
|
|
11484
|
+
verifyIncrementalAuthTicket,
|
|
11431
11485
|
verifyOrParseSession,
|
|
11432
11486
|
verifyPkce,
|
|
11433
11487
|
verifySession,
|