@rebasepro/server 0.22.0 → 0.24.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/README.md +1 -1
- package/bin/rebase-server.js +4 -2
- package/dist/{GCSStorageController-CLIJXwGS.js → GCSStorageController-BSiP1c-f.js} +57 -29
- package/dist/GCSStorageController-BSiP1c-f.js.map +1 -0
- package/dist/{S3StorageController-Dcuf8lMA.js → S3StorageController-CAwFRgjV.js} +19 -7
- package/dist/S3StorageController-CAwFRgjV.js.map +1 -0
- package/dist/api/ast-schema-editor.d.ts +127 -1
- package/dist/api/errors.d.ts +9 -0
- package/dist/api/live-schema-routes.d.ts +52 -8
- package/dist/api/logs-routes.d.ts +39 -1
- package/dist/api/openapi-generator.d.ts +17 -0
- package/dist/api/rest/api-generator.d.ts +158 -42
- package/dist/api/rest/auth-collection-writes.d.ts +85 -0
- package/dist/api/rest/field-access-query.d.ts +6 -2
- package/dist/api/rest/idempotency.d.ts +7 -1
- package/dist/api/rest/nested-write-access.d.ts +46 -0
- package/dist/api/rest/write-validation.d.ts +34 -2
- package/dist/api/types.d.ts +17 -1
- package/dist/{ast-schema-editor-CslO8Oje.js → ast-schema-editor-CWqS_sLJ.js} +411 -13
- package/dist/ast-schema-editor-CWqS_sLJ.js.map +1 -0
- package/dist/auth/access.d.ts +105 -0
- package/dist/auth/adapter-middleware.d.ts +2 -1
- package/dist/auth/address-ownership.d.ts +68 -0
- package/dist/auth/admin-roles-route.d.ts +4 -2
- package/dist/auth/admin-roles.d.ts +17 -20
- package/dist/auth/admin-user-ops.d.ts +35 -2
- package/dist/auth/admin-users-route.d.ts +1 -0
- package/dist/auth/api-keys/api-key-middleware.d.ts +56 -55
- package/dist/auth/api-keys/api-key-routes.d.ts +41 -11
- package/dist/auth/api-keys/api-key-store.d.ts +31 -8
- package/dist/auth/api-keys/api-key-types.d.ts +14 -16
- package/dist/auth/api-keys/http-operation.d.ts +19 -0
- package/dist/auth/api-keys/index.d.ts +11 -11
- package/dist/auth/api-keys/key-grant.d.ts +41 -0
- package/dist/auth/api-keys/legacy-permissions.d.ts +33 -0
- package/dist/auth/auth-hooks.d.ts +50 -7
- package/dist/auth/builtin-auth-adapter.d.ts +8 -0
- package/dist/auth/captcha.d.ts +5 -0
- package/dist/auth/cookie-utils.d.ts +7 -0
- package/dist/auth/deliverable-address.d.ts +6 -0
- package/dist/auth/email-change-routes.d.ts +41 -0
- package/dist/auth/expired-token-sweep.d.ts +67 -0
- package/dist/auth/impersonation.d.ts +110 -0
- package/dist/auth/index.d.ts +4 -2
- package/dist/auth/interfaces.d.ts +146 -65
- package/dist/auth/jwt.d.ts +66 -3
- package/dist/auth/magic-link-routes.d.ts +2 -6
- package/dist/auth/mfa-routes.d.ts +2 -9
- package/dist/auth/middleware.d.ts +17 -5
- package/dist/auth/oauth-signin-policy.d.ts +25 -8
- package/dist/auth/otp-routes.d.ts +2 -6
- package/dist/auth/passwordless-signup.d.ts +27 -0
- package/dist/auth/platform-token.d.ts +122 -0
- package/dist/auth/rate-limiter.d.ts +72 -1
- package/dist/auth/routes.d.ts +45 -0
- package/dist/auth/scope-routes.d.ts +22 -0
- package/dist/auth/session-routes.d.ts +18 -6
- package/dist/auth/token-revocation.d.ts +53 -1
- package/dist/auth/verify-credential.d.ts +28 -0
- package/dist/{auth-CCDpk2rn.js → auth-DMLngxn_.js} +2712 -711
- package/dist/auth-DMLngxn_.js.map +1 -0
- package/dist/backend-DTAOsLQc.js +30 -0
- package/dist/backend-DTAOsLQc.js.map +1 -0
- package/dist/backup/backup-common.d.ts +29 -0
- package/dist/backup/backup-routes.d.ts +24 -4
- package/dist/backup/backup-schedule.d.ts +33 -0
- package/dist/backup/backup-storage.d.ts +14 -0
- package/dist/backup/index.d.ts +2 -0
- package/dist/backup-CN0s50D2.js +444 -0
- package/dist/backup-CN0s50D2.js.map +1 -0
- package/dist/boot/bundle.d.ts +19 -0
- package/dist/boot/driver.d.ts +10 -0
- package/dist/boot/env.d.ts +51 -6
- package/dist/boot/fetch-bundle.d.ts +18 -1
- package/dist/boot/rls-audit-option.d.ts +26 -0
- package/dist/boot/security-headers.d.ts +26 -0
- package/dist/boot/sources.d.ts +1 -0
- package/dist/boot/static-routing.d.ts +56 -0
- package/dist/collection_patch-BRu-BvDv.js +472 -0
- package/dist/collection_patch-BRu-BvDv.js.map +1 -0
- package/dist/{contract-routes-eLxV0le1.js → contract-routes-fz8i4pxs.js} +17 -4
- package/dist/contract-routes-fz8i4pxs.js.map +1 -0
- package/dist/cron/cron-routes.d.ts +7 -2
- package/dist/cron/cron-scheduler.d.ts +146 -21
- package/dist/cron/cron-store.d.ts +76 -8
- package/dist/cron/index.d.ts +1 -1
- package/dist/{cron-loader-CQjvjpEw.js → cron-loader-CwaANlOG.js} +4 -4
- package/dist/cron-loader-CwaANlOG.js.map +1 -0
- package/dist/cron-routes-Bc-SB0Se.js +96 -0
- package/dist/cron-routes-Bc-SB0Se.js.map +1 -0
- package/dist/{cron-scheduler-COPQxlEq.js → cron-scheduler-CYQgco86.js} +427 -83
- package/dist/cron-scheduler-CYQgco86.js.map +1 -0
- package/dist/{cron-store-BYGZFNWk.js → cron-store-D2Q9-Aco.js} +139 -23
- package/dist/cron-store-D2Q9-Aco.js.map +1 -0
- package/dist/{ddl-bootstrap-CfNvxMuK.js → ddl-bootstrap-BaqMSa4Y.js} +3 -26
- package/dist/ddl-bootstrap-BaqMSa4Y.js.map +1 -0
- package/dist/email/index.d.ts +2 -2
- package/dist/email/link-base.d.ts +5 -4
- package/dist/email/smtp-email-service.d.ts +13 -1
- package/dist/email/templates.d.ts +31 -0
- package/dist/email/types.d.ts +29 -2
- package/dist/env.d.ts +25 -7
- package/dist/{errors-DWsX4yTd.js → errors-D6_y86c5.js} +102 -8
- package/dist/errors-D6_y86c5.js.map +1 -0
- package/dist/{function-loader-xnbDAPfa.js → function-loader-D7o5Epjj.js} +2 -2
- package/dist/{function-loader-xnbDAPfa.js.map → function-loader-D7o5Epjj.js.map} +1 -1
- package/dist/{function-routes-Chet4-lB.js → function-routes-CaNG4waN.js} +24 -12
- package/dist/function-routes-CaNG4waN.js.map +1 -0
- package/dist/functions/context.d.ts +17 -6
- package/dist/functions/guards.d.ts +22 -5
- package/dist/functions/index.d.ts +2 -2
- package/dist/functions/index.js +90 -36
- package/dist/functions/index.js.map +1 -1
- package/dist/{history-recorder-BQmB0P_j.js → history-recorder-Nr8zLvoU.js} +9 -7
- package/dist/history-recorder-Nr8zLvoU.js.map +1 -0
- package/dist/{history-store-CetkrBBD.js → history-store-rcAm_xFR.js} +2 -2
- package/dist/{history-store-CetkrBBD.js.map → history-store-rcAm_xFR.js.map} +1 -1
- package/dist/index.d.ts +14 -4
- package/dist/index.es.js +5733 -1551
- package/dist/index.es.js.map +1 -1
- package/dist/init/docs.d.ts +5 -2
- package/dist/init/health.d.ts +17 -2
- package/dist/init/shutdown.d.ts +18 -3
- package/dist/init.d.ts +54 -0
- package/dist/jobs/index.d.ts +2 -2
- package/dist/jobs/job-queue.d.ts +23 -2
- package/dist/jobs/job-store.d.ts +37 -5
- package/dist/jobs/types.d.ts +8 -6
- package/dist/{jobs-Bjr8DZAi.js → jobs-DqYNfquG.js} +306 -167
- package/dist/jobs-DqYNfquG.js.map +1 -0
- package/dist/{jwt-C4OW-DNq.js → jwt-R6bSPMjk.js} +114 -38
- package/dist/{jwt-C4OW-DNq.js.map → jwt-R6bSPMjk.js.map} +1 -1
- package/dist/{keys-Qfc4XieN.js → keys-GAVZqbqx.js} +18 -17
- package/dist/{keys-Qfc4XieN.js.map → keys-GAVZqbqx.js.map} +1 -1
- package/dist/{logger-DO2PZc4i.js → logger-D-S-hO5e.js} +26 -3
- package/dist/logger-D-S-hO5e.js.map +1 -0
- package/dist/{logs-routes-3EEzPjhl.js → logs-routes-DAdv37GI.js} +54 -11
- package/dist/logs-routes-DAdv37GI.js.map +1 -0
- package/dist/mcp/consent-page.d.ts +1 -1
- package/dist/mcp/mcp-routes.d.ts +45 -2
- package/dist/mcp/mcp-tools.d.ts +22 -10
- package/dist/mcp/oauth-metadata.d.ts +21 -16
- package/dist/mcp/oauth-routes.d.ts +34 -1
- package/dist/mcp/oauth-store.d.ts +29 -13
- package/dist/metrics/history-recorder.d.ts +1 -1
- package/dist/{openapi-generator-D8uFz-LW.js → openapi-generator-DAq_XVDu.js} +135 -22
- package/dist/openapi-generator-DAq_XVDu.js.map +1 -0
- package/dist/{proxy-Czngl3p9.js → proxy-qRlqeUmO.js} +2 -2
- package/dist/{proxy-Czngl3p9.js.map → proxy-qRlqeUmO.js.map} +1 -1
- package/dist/{query-parser-BleZmY18.js → query-parser-BgiKJKvc.js} +41 -82
- package/dist/query-parser-BgiKJKvc.js.map +1 -0
- package/dist/{request-timeout-C_4C2BeR.js → request-timeout-DgH7j8qO.js} +3 -3
- package/dist/{request-timeout-C_4C2BeR.js.map → request-timeout-DgH7j8qO.js.map} +1 -1
- package/dist/rls-audit/index.d.ts +4 -0
- package/dist/schema-edit/apply-schema-change.d.ts +63 -3
- package/dist/schema-edit/project-root.d.ts +3 -2
- package/dist/schema-edit/remote-source.d.ts +9 -4
- package/dist/{schema-editor-routes-DdLihzp0.js → schema-editor-routes-oIyuWl3L.js} +12 -7
- package/dist/schema-editor-routes-oIyuWl3L.js.map +1 -0
- package/dist/serve-spa.d.ts +58 -0
- package/dist/services/routed-realtime-service.d.ts +11 -0
- package/dist/soft-delete-params-BWPilMPF.js +59 -0
- package/dist/soft-delete-params-BWPilMPF.js.map +1 -0
- package/dist/{src-Br6ARbs6.js → src-CatHFUym.js} +439 -45
- package/dist/src-CatHFUym.js.map +1 -0
- package/dist/{src-1vL-I1Po.js → src-I3aG1PcY.js} +371 -81
- package/dist/src-I3aG1PcY.js.map +1 -0
- package/dist/storage/GCSStorageController.d.ts +13 -1
- package/dist/storage/LocalStorageController.d.ts +2 -0
- package/dist/storage/S3StorageController.d.ts +2 -0
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/keys.d.ts +12 -0
- package/dist/storage/property-limits.d.ts +41 -6
- package/dist/storage/rendition-cache.d.ts +11 -1
- package/dist/storage/request-keys.d.ts +82 -0
- package/dist/storage/requested-object.d.ts +74 -0
- package/dist/storage/routes.d.ts +36 -18
- package/dist/storage/tus-handler.d.ts +30 -5
- package/dist/storage/types.d.ts +36 -1
- package/dist/types-BfKcm9do.js.map +1 -1
- package/dist/utils/logger.d.ts +12 -0
- package/package.json +9 -9
- package/dist/GCSStorageController-CLIJXwGS.js.map +0 -1
- package/dist/S3StorageController-Dcuf8lMA.js.map +0 -1
- package/dist/admin-roles-vYdp_Pil.js +0 -36
- package/dist/admin-roles-vYdp_Pil.js.map +0 -1
- package/dist/admin_block-DxKLmdiv.js +0 -206
- package/dist/admin_block-DxKLmdiv.js.map +0 -1
- package/dist/ast-schema-editor-CslO8Oje.js.map +0 -1
- package/dist/auth/api-keys/api-key-permission-guard.d.ts +0 -65
- package/dist/auth-CCDpk2rn.js.map +0 -1
- package/dist/backup-DzI9jLwc.js +0 -192
- package/dist/backup-DzI9jLwc.js.map +0 -1
- package/dist/contract-routes-eLxV0le1.js.map +0 -1
- package/dist/cron-loader-CQjvjpEw.js.map +0 -1
- package/dist/cron-routes-B7CRGfiq.js +0 -72
- package/dist/cron-routes-B7CRGfiq.js.map +0 -1
- package/dist/cron-scheduler-COPQxlEq.js.map +0 -1
- package/dist/cron-store-BYGZFNWk.js.map +0 -1
- package/dist/ddl-bootstrap-CfNvxMuK.js.map +0 -1
- package/dist/errors-DWsX4yTd.js.map +0 -1
- package/dist/function-routes-Chet4-lB.js.map +0 -1
- package/dist/history-recorder-BQmB0P_j.js.map +0 -1
- package/dist/jobs-Bjr8DZAi.js.map +0 -1
- package/dist/logger-DO2PZc4i.js.map +0 -1
- package/dist/logs-routes-3EEzPjhl.js.map +0 -1
- package/dist/openapi-generator-D8uFz-LW.js.map +0 -1
- package/dist/query-parser-BleZmY18.js.map +0 -1
- package/dist/schema-editor-routes-DdLihzp0.js.map +0 -1
- package/dist/src-1vL-I1Po.js.map +0 -1
- package/dist/src-Br6ARbs6.js.map +0 -1
|
@@ -3,8 +3,8 @@ import __rebaseProcess from "process";
|
|
|
3
3
|
globalThis.process ??= __rebaseProcess;
|
|
4
4
|
__rebaseCreateRequire(import.meta.url);
|
|
5
5
|
import { i as __toESM, n as __exportAll, r as __require, t as __commonJSMin } from "./rolldown-runtime-dW7B1o5h.js";
|
|
6
|
-
import { r as logger } from "./logger-
|
|
7
|
-
import {
|
|
6
|
+
import { r as logger } from "./logger-D-S-hO5e.js";
|
|
7
|
+
import { a as canonicalStorageId } from "./keys-GAVZqbqx.js";
|
|
8
8
|
import { createPrivateKey, createPublicKey } from "crypto";
|
|
9
9
|
//#region src/utils/portable-crypto.ts
|
|
10
10
|
/**
|
|
@@ -4423,6 +4423,8 @@ var jwt_exports = /* @__PURE__ */ __exportAll({
|
|
|
4423
4423
|
MCP_ACCESS_PURPOSE: () => MCP_ACCESS_PURPOSE,
|
|
4424
4424
|
MFA_PENDING_PURPOSE: () => MFA_PENDING_PURPOSE,
|
|
4425
4425
|
configureJwt: () => configureJwt,
|
|
4426
|
+
configuredJwtSecret: () => configuredJwtSecret,
|
|
4427
|
+
customClaimsOf: () => customClaimsOf,
|
|
4426
4428
|
generateAccessToken: () => generateAccessToken,
|
|
4427
4429
|
generateDownloadToken: () => generateDownloadToken,
|
|
4428
4430
|
generateMcpAccessToken: () => generateMcpAccessToken,
|
|
@@ -4436,6 +4438,7 @@ var jwt_exports = /* @__PURE__ */ __exportAll({
|
|
|
4436
4438
|
hasAsymmetricSigningKey: () => hasAsymmetricSigningKey,
|
|
4437
4439
|
hashRefreshToken: () => hashRefreshToken,
|
|
4438
4440
|
isJwtConfigured: () => isJwtConfigured,
|
|
4441
|
+
parseDurationMs: () => parseDurationMs,
|
|
4439
4442
|
signPurposeToken: () => signPurposeToken,
|
|
4440
4443
|
verifyAccessToken: () => verifyAccessToken,
|
|
4441
4444
|
verifyDownloadToken: () => verifyDownloadToken,
|
|
@@ -4458,6 +4461,7 @@ var RESERVED_TOKEN_CLAIMS = /* @__PURE__ */ new Set([
|
|
|
4458
4461
|
"roles",
|
|
4459
4462
|
"aal",
|
|
4460
4463
|
"isAnonymous",
|
|
4464
|
+
"sid",
|
|
4461
4465
|
"purpose",
|
|
4462
4466
|
"iat",
|
|
4463
4467
|
"exp",
|
|
@@ -4466,7 +4470,13 @@ var RESERVED_TOKEN_CLAIMS = /* @__PURE__ */ new Set([
|
|
|
4466
4470
|
"aud",
|
|
4467
4471
|
"jti"
|
|
4468
4472
|
]);
|
|
4469
|
-
/**
|
|
4473
|
+
/**
|
|
4474
|
+
* The custom half of a verified token, or nothing when there is none.
|
|
4475
|
+
*
|
|
4476
|
+
* Exported for the one other place that builds a request identity's claims
|
|
4477
|
+
* without a token to verify — `resolveUser`, which reads what a token minted
|
|
4478
|
+
* now would carry — so both drop the same identity claims.
|
|
4479
|
+
*/
|
|
4470
4480
|
function customClaimsOf(decoded) {
|
|
4471
4481
|
const claims = {};
|
|
4472
4482
|
for (const [key, value] of Object.entries(decoded)) {
|
|
@@ -4523,9 +4533,18 @@ function configureJwt(config) {
|
|
|
4523
4533
|
active = resolved.find((key) => key.kid === config.activeKid) ?? null;
|
|
4524
4534
|
if (!active) throw new Error(`auth.activeKid is "${config.activeKid}", which is not among the configured signing keys (${resolved.map((k) => `"${k.kid}"`).join(", ")}). Signing with a key nobody published produces tokens no verifier can check.`);
|
|
4525
4535
|
} else active = resolved[0];
|
|
4536
|
+
const lifetimes = {};
|
|
4537
|
+
for (const key of ["accessExpiresIn", "refreshExpiresIn"]) {
|
|
4538
|
+
const value = config[key];
|
|
4539
|
+
if (value === void 0) continue;
|
|
4540
|
+
if (parseDurationMs(value) === null) throw new Error(`auth.${key} is "${value}", which is not a lifetime. Give a positive number and a unit — "15m", "1h", "30d", "1w", "2 weeks" — in the grammar the token signer reads (vercel/ms). A bare number is refused: the signer reads it as milliseconds.`);
|
|
4541
|
+
lifetimes[key] = value;
|
|
4542
|
+
}
|
|
4526
4543
|
jwtConfig = {
|
|
4527
4544
|
...jwtConfig,
|
|
4528
|
-
...config
|
|
4545
|
+
...config,
|
|
4546
|
+
accessExpiresIn: lifetimes.accessExpiresIn ?? jwtConfig.accessExpiresIn,
|
|
4547
|
+
refreshExpiresIn: lifetimes.refreshExpiresIn ?? jwtConfig.refreshExpiresIn
|
|
4529
4548
|
};
|
|
4530
4549
|
signingKeys = resolved;
|
|
4531
4550
|
activeSigningKey = active;
|
|
@@ -4541,6 +4560,14 @@ function configureJwt(config) {
|
|
|
4541
4560
|
function getJwks() {
|
|
4542
4561
|
return toJwks(signingKeys);
|
|
4543
4562
|
}
|
|
4563
|
+
/**
|
|
4564
|
+
* The secret `configureJwt` was given, or undefined before it is called. For
|
|
4565
|
+
* `mfa-crypto.ts`, which falls back to it when no MFA key is set — the secret
|
|
4566
|
+
* passed in code, not only the one in `JWT_SECRET`.
|
|
4567
|
+
*/
|
|
4568
|
+
function configuredJwtSecret() {
|
|
4569
|
+
return jwtConfig.secret || void 0;
|
|
4570
|
+
}
|
|
4544
4571
|
/** Is this backend signing access tokens asymmetrically? */
|
|
4545
4572
|
function hasAsymmetricSigningKey() {
|
|
4546
4573
|
return activeSigningKey !== null;
|
|
@@ -4562,14 +4589,15 @@ function isJwtConfigured() {
|
|
|
4562
4589
|
/**
|
|
4563
4590
|
* Generate an access token (short-lived, 1 hour by default)
|
|
4564
4591
|
*/
|
|
4565
|
-
async function generateAccessToken(uid, roles, aal = "aal1", customClaims, isAnonymous = false) {
|
|
4592
|
+
async function generateAccessToken(uid, roles, aal = "aal1", customClaims, isAnonymous = false, sessionId) {
|
|
4566
4593
|
if (!jwtConfig.secret) throw new Error("JWT secret not configured. Call configureJwt() first.");
|
|
4567
4594
|
const payload = {
|
|
4568
4595
|
...customClaims,
|
|
4569
4596
|
uid,
|
|
4570
4597
|
roles,
|
|
4571
4598
|
aal,
|
|
4572
|
-
...isAnonymous ? { isAnonymous: true } : {}
|
|
4599
|
+
...isAnonymous ? { isAnonymous: true } : {},
|
|
4600
|
+
...sessionId ? { sid: sessionId } : {}
|
|
4573
4601
|
};
|
|
4574
4602
|
if (activeSigningKey) return signJwt(payload, activeSigningKey.privateKey, {
|
|
4575
4603
|
expiresIn: jwtConfig.accessExpiresIn,
|
|
@@ -4585,16 +4613,59 @@ async function generateAccessToken(uid, roles, aal = "aal1", customClaims, isAno
|
|
|
4585
4613
|
* Get the expiration time of an access token in milliseconds from now
|
|
4586
4614
|
*/
|
|
4587
4615
|
function getAccessTokenExpiryMs() {
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4616
|
+
return parseDurationMs(jwtConfig.accessExpiresIn || "1h") ?? 3600 * 1e3;
|
|
4617
|
+
}
|
|
4618
|
+
var DURATION_UNIT_MS = {
|
|
4619
|
+
ms: 1,
|
|
4620
|
+
msec: 1,
|
|
4621
|
+
msecs: 1,
|
|
4622
|
+
millisecond: 1,
|
|
4623
|
+
milliseconds: 1,
|
|
4624
|
+
s: 1e3,
|
|
4625
|
+
sec: 1e3,
|
|
4626
|
+
secs: 1e3,
|
|
4627
|
+
second: 1e3,
|
|
4628
|
+
seconds: 1e3,
|
|
4629
|
+
m: 6e4,
|
|
4630
|
+
min: 6e4,
|
|
4631
|
+
mins: 6e4,
|
|
4632
|
+
minute: 6e4,
|
|
4633
|
+
minutes: 6e4,
|
|
4634
|
+
h: 36e5,
|
|
4635
|
+
hr: 36e5,
|
|
4636
|
+
hrs: 36e5,
|
|
4637
|
+
hour: 36e5,
|
|
4638
|
+
hours: 36e5,
|
|
4639
|
+
d: 864e5,
|
|
4640
|
+
day: 864e5,
|
|
4641
|
+
days: 864e5,
|
|
4642
|
+
w: 6048e5,
|
|
4643
|
+
week: 6048e5,
|
|
4644
|
+
weeks: 6048e5,
|
|
4645
|
+
y: 315576e5,
|
|
4646
|
+
yr: 315576e5,
|
|
4647
|
+
yrs: 315576e5,
|
|
4648
|
+
year: 315576e5,
|
|
4649
|
+
years: 315576e5
|
|
4650
|
+
};
|
|
4651
|
+
/**
|
|
4652
|
+
* A lifetime setting in milliseconds, or null when it is not one.
|
|
4653
|
+
*
|
|
4654
|
+
* The grammar is vercel/ms, because that is what `jsonwebtoken` reads
|
|
4655
|
+
* `expiresIn` with: the token's `exp` and the expiry this module reports
|
|
4656
|
+
* have to come from one reading of the same string, and they used to come
|
|
4657
|
+
* from two — ours understood `<integer><d|h|m|s>` and nothing else.
|
|
4658
|
+
*
|
|
4659
|
+
* Stricter than ms in two ways, both about values nobody means: a bare number
|
|
4660
|
+
* (ms reads "3600" as 3.6 seconds) and a lifetime of zero or less.
|
|
4661
|
+
*/
|
|
4662
|
+
function parseDurationMs(value) {
|
|
4663
|
+
const match = /^(\d+(?:\.\d+)?|\.\d+) *([a-z]+)$/i.exec(value);
|
|
4664
|
+
if (!match) return null;
|
|
4665
|
+
const unit = DURATION_UNIT_MS[match[2].toLowerCase()];
|
|
4666
|
+
if (unit === void 0) return null;
|
|
4667
|
+
const ms = parseFloat(match[1]) * unit;
|
|
4668
|
+
return ms > 0 && Number.isFinite(ms) ? ms : null;
|
|
4598
4669
|
}
|
|
4599
4670
|
/**
|
|
4600
4671
|
* Get the expiration timestamp for an access token
|
|
@@ -4638,21 +4709,21 @@ async function verifyAccessToken(token) {
|
|
|
4638
4709
|
aal,
|
|
4639
4710
|
...decoded.isAnonymous === true ? { isAnonymous: true } : {},
|
|
4640
4711
|
iat: decoded.iat,
|
|
4712
|
+
...typeof decoded.exp === "number" ? { exp: decoded.exp } : {},
|
|
4713
|
+
...typeof decoded.sid === "string" && decoded.sid ? { sid: decoded.sid } : {},
|
|
4641
4714
|
...(() => {
|
|
4642
4715
|
const claims = customClaimsOf(decoded);
|
|
4643
4716
|
return claims ? { claims } : {};
|
|
4644
4717
|
})()
|
|
4645
4718
|
};
|
|
4646
4719
|
} catch (error) {
|
|
4647
|
-
logger.error("[JWT] Verification failed", {
|
|
4648
|
-
error,
|
|
4649
|
-
detail: token.substring(0, 15)
|
|
4650
|
-
});
|
|
4720
|
+
logger.error("[JWT] Verification failed", { error });
|
|
4651
4721
|
return null;
|
|
4652
4722
|
}
|
|
4653
4723
|
}
|
|
4654
4724
|
/**
|
|
4655
|
-
* Generate a random refresh token
|
|
4725
|
+
* Generate a random refresh token. Long-lived: 400 days by default, sliding —
|
|
4726
|
+
* see {@link getRefreshTokenTtlMs}.
|
|
4656
4727
|
*/
|
|
4657
4728
|
function generateRefreshToken() {
|
|
4658
4729
|
return randomHex(40);
|
|
@@ -4670,7 +4741,7 @@ function hashRefreshToken(token) {
|
|
|
4670
4741
|
* what is actually enforced, which is worse than knowing the ceiling.
|
|
4671
4742
|
*/
|
|
4672
4743
|
var MAX_COOKIE_AGE_MS = 400 * 24 * 60 * 60 * 1e3;
|
|
4673
|
-
/** Fallback when `refreshExpiresIn` is unset
|
|
4744
|
+
/** Fallback when `refreshExpiresIn` is unset. {@link configureJwt} refuses an unparseable one. */
|
|
4674
4745
|
var DEFAULT_REFRESH_TTL_MS = MAX_COOKIE_AGE_MS;
|
|
4675
4746
|
/**
|
|
4676
4747
|
* How long a refresh token is valid for, in milliseconds.
|
|
@@ -4682,16 +4753,8 @@ var DEFAULT_REFRESH_TTL_MS = MAX_COOKIE_AGE_MS;
|
|
|
4682
4753
|
* when they say they expect to still be signed in.
|
|
4683
4754
|
*/
|
|
4684
4755
|
function getRefreshTokenTtlMs() {
|
|
4685
|
-
const
|
|
4686
|
-
|
|
4687
|
-
const value = parseInt(match[1], 10);
|
|
4688
|
-
switch (match[2]) {
|
|
4689
|
-
case "d": return value * 24 * 60 * 60 * 1e3;
|
|
4690
|
-
case "h": return value * 60 * 60 * 1e3;
|
|
4691
|
-
case "m": return value * 60 * 1e3;
|
|
4692
|
-
case "s": return value * 1e3;
|
|
4693
|
-
default: return DEFAULT_REFRESH_TTL_MS;
|
|
4694
|
-
}
|
|
4756
|
+
const duration = jwtConfig.refreshExpiresIn;
|
|
4757
|
+
return (duration ? parseDurationMs(duration) : null) ?? DEFAULT_REFRESH_TTL_MS;
|
|
4695
4758
|
}
|
|
4696
4759
|
/**
|
|
4697
4760
|
* Calculate refresh token expiration date
|
|
@@ -4732,13 +4795,20 @@ async function generateMfaPendingToken(uid, expiresInSeconds = 300) {
|
|
|
4732
4795
|
*
|
|
4733
4796
|
* Returns `null` for anything else — including a perfectly valid *access*
|
|
4734
4797
|
* token, which must not be interchangeable with this one in either direction.
|
|
4798
|
+
*
|
|
4799
|
+
* `iat` comes back with the uid because this token is a first factor that was
|
|
4800
|
+
* accepted at that instant, and a sign-out everywhere after it has to void it
|
|
4801
|
+
* the way it voids an access token — see `isAccessTokenRevoked`.
|
|
4735
4802
|
*/
|
|
4736
4803
|
async function verifyMfaPendingToken(token) {
|
|
4737
4804
|
if (!jwtConfig.secret) throw new Error("JWT secret not configured. Call configureJwt() first.");
|
|
4738
4805
|
try {
|
|
4739
4806
|
const decoded = await verifyJwt(token, jwtConfig.secret, { algorithms: ["HS256"] });
|
|
4740
4807
|
if (decoded.purpose !== "mfa-pending" || !decoded.uid) return null;
|
|
4741
|
-
return {
|
|
4808
|
+
return {
|
|
4809
|
+
uid: decoded.uid,
|
|
4810
|
+
iat: typeof decoded.iat === "number" ? decoded.iat : void 0
|
|
4811
|
+
};
|
|
4742
4812
|
} catch {
|
|
4743
4813
|
return null;
|
|
4744
4814
|
}
|
|
@@ -4760,17 +4830,22 @@ async function verifyMfaPendingToken(token) {
|
|
|
4760
4830
|
* site that forgets to pass a named source produces a default-scoped token,
|
|
4761
4831
|
* which fails closed at `/file/*` rather than over-granting.
|
|
4762
4832
|
*/
|
|
4763
|
-
async function generateDownloadToken(path, expiresInSeconds = 300, storageId) {
|
|
4833
|
+
async function generateDownloadToken(path, expiresInSeconds = 300, storageId, principal) {
|
|
4764
4834
|
if (!jwtConfig.secret) throw new Error("JWT secret not configured. Call configureJwt() first.");
|
|
4765
4835
|
return signJwt({
|
|
4766
4836
|
purpose: "file-read",
|
|
4767
4837
|
path,
|
|
4768
|
-
storageId: canonicalStorageId(storageId)
|
|
4838
|
+
storageId: canonicalStorageId(storageId),
|
|
4839
|
+
...principal ? { rl: await downloadTokenRateLimitMark(principal) } : {}
|
|
4769
4840
|
}, jwtConfig.secret, {
|
|
4770
4841
|
expiresIn: expiresInSeconds,
|
|
4771
4842
|
algorithm: "HS256"
|
|
4772
4843
|
});
|
|
4773
4844
|
}
|
|
4845
|
+
/** See {@link DownloadTokenPayload.rl}. */
|
|
4846
|
+
async function downloadTokenRateLimitMark(principal) {
|
|
4847
|
+
return (await sha256Hex(`download-token-rl:${principal}`)).slice(0, 32);
|
|
4848
|
+
}
|
|
4774
4849
|
/**
|
|
4775
4850
|
* Verify and decode a download token.
|
|
4776
4851
|
*
|
|
@@ -4788,7 +4863,8 @@ async function verifyDownloadToken(token) {
|
|
|
4788
4863
|
if (decoded && decoded.purpose === "file-read" && typeof decoded.path === "string") return {
|
|
4789
4864
|
purpose: "file-read",
|
|
4790
4865
|
path: decoded.path,
|
|
4791
|
-
storageId: canonicalStorageId(typeof decoded.storageId === "string" ? decoded.storageId : null)
|
|
4866
|
+
storageId: canonicalStorageId(typeof decoded.storageId === "string" ? decoded.storageId : null),
|
|
4867
|
+
...typeof decoded.rl === "string" ? { rl: decoded.rl } : {}
|
|
4792
4868
|
};
|
|
4793
4869
|
return null;
|
|
4794
4870
|
} catch (error) {
|
|
@@ -4914,6 +4990,6 @@ async function verifyMcpAccessToken(token, expectedAudience) {
|
|
|
4914
4990
|
}
|
|
4915
4991
|
}
|
|
4916
4992
|
//#endregion
|
|
4917
|
-
export {
|
|
4993
|
+
export { sha256Bytes as A, verifyPurposeToken as C, constantTimeEqual as D, require_jsonwebtoken as E, randomHex as O, verifyMfaPendingToken as S, verifyJwt as T, jwt_exports as _, generateAccessToken as a, verifyDownloadToken as b, generateMfaPendingToken as c, getJwks as d, getRefreshTokenExpiry as f, isJwtConfigured as g, hashRefreshToken as h, customClaimsOf as i, sha256Hex as j, randomInt as k, generateRefreshToken as l, hasAsymmetricSigningKey as m, configureJwt as n, generateDownloadToken as o, getRefreshTokenTtlMs as p, configuredJwtSecret as r, generateMcpAccessToken as s, MAX_COOKIE_AGE_MS as t, getAccessTokenExpiry as u, signPurposeToken as v, normalizePemFromEnv as w, verifyMcpAccessToken as x, verifyAccessToken as y };
|
|
4918
4994
|
|
|
4919
|
-
//# sourceMappingURL=jwt-
|
|
4995
|
+
//# sourceMappingURL=jwt-R6bSPMjk.js.map
|