@rebasepro/server 0.23.0 → 0.24.1-canary.g56af4a4
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-DivE9bAx.js +402 -0
- package/dist/GCSStorageController-DivE9bAx.js.map +1 -0
- package/dist/S3StorageController-D_vKs4kP.js +480 -0
- package/dist/S3StorageController-D_vKs4kP.js.map +1 -0
- package/dist/api/ast-schema-editor.d.ts +92 -1
- package/dist/api/errors.d.ts +9 -0
- package/dist/api/live-schema-routes.d.ts +38 -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 +97 -11
- package/dist/api/rest/auth-collection-writes.d.ts +28 -21
- package/dist/api/rest/field-access-query.d.ts +28 -8
- package/dist/api/rest/field-ops.d.ts +19 -7
- package/dist/api/rest/query-body.d.ts +10 -0
- package/dist/api/rest/write-validation.d.ts +9 -7
- package/dist/api/schema-editor-routes.d.ts +10 -1
- package/dist/api/sql-export-routes.d.ts +8 -0
- package/dist/api/types.d.ts +28 -1
- package/dist/{ast-schema-editor-Mvr50v_S.js → ast-schema-editor-CSdL0iCk.js} +310 -12
- package/dist/ast-schema-editor-CSdL0iCk.js.map +1 -0
- package/dist/auth/access.d.ts +121 -0
- package/dist/auth/adapter-middleware.d.ts +2 -1
- package/dist/auth/address-ownership.d.ts +16 -1
- 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 +24 -2
- package/dist/auth/admin-users-route.d.ts +2 -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 +46 -7
- package/dist/auth/builtin-auth-adapter.d.ts +8 -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 +71 -0
- package/dist/auth/impersonation.d.ts +110 -0
- package/dist/auth/index.d.ts +4 -2
- package/dist/auth/interfaces.d.ts +120 -59
- package/dist/auth/jwt-crypto.d.ts +7 -0
- package/dist/auth/jwt-keys.d.ts +4 -0
- package/dist/auth/jwt.d.ts +54 -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/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 +54 -1
- package/dist/auth/registration-policy.d.ts +17 -0
- package/dist/auth/routes.d.ts +45 -0
- package/dist/auth/scope-routes.d.ts +22 -0
- package/dist/auth/session-routes.d.ts +11 -6
- package/dist/auth/token-revocation.d.ts +50 -1
- package/dist/auth/user-picking.d.ts +35 -0
- package/dist/auth/verify-credential.d.ts +28 -0
- package/dist/{auth-B-GIMpDG.js → auth-OPq_FeMs.js} +3115 -638
- package/dist/auth-OPq_FeMs.js.map +1 -0
- package/dist/auth_adapter-CIItCTc8.js +21 -0
- package/dist/auth_adapter-CIItCTc8.js.map +1 -0
- package/dist/backend-DTAOsLQc.js.map +1 -1
- package/dist/backup/backup-common.d.ts +24 -3
- package/dist/backup/backup-routes.d.ts +46 -5
- package/dist/backup/backup-schedule.d.ts +33 -0
- package/dist/backup/backup-storage.d.ts +16 -0
- package/dist/backup/index.d.ts +5 -1
- package/dist/backup-5d7XhLX3.js +581 -0
- package/dist/backup-5d7XhLX3.js.map +1 -0
- package/dist/boot/bundle.d.ts +19 -0
- package/dist/boot/driver.d.ts +3 -0
- package/dist/boot/env.d.ts +56 -4
- package/dist/boot/http-server.d.ts +22 -0
- package/dist/boot/options.d.ts +16 -1
- package/dist/boot/runtime-cors.d.ts +17 -0
- package/dist/boot/security-headers.d.ts +26 -0
- package/dist/boot/static-routing.d.ts +65 -0
- package/dist/collection_patch-BRu-BvDv.js +472 -0
- package/dist/collection_patch-BRu-BvDv.js.map +1 -0
- package/dist/{contract-routes-CbFjuBwa.js → contract-routes-02lASyJI.js} +5 -8
- package/dist/contract-routes-02lASyJI.js.map +1 -0
- package/dist/cron/cron-routes.d.ts +1 -1
- package/dist/cron/cron-scheduler.d.ts +94 -23
- package/dist/cron/cron-store.d.ts +31 -4
- package/dist/cron/define-cron.d.ts +6 -2
- package/dist/cron/index.d.ts +1 -1
- package/dist/{cron-loader-DfTj2Hbi.js → cron-loader-D7OmleAb.js} +11 -7
- package/dist/cron-loader-D7OmleAb.js.map +1 -0
- package/dist/{cron-routes-eE8nif_b.js → cron-routes-CBfiaqEL.js} +34 -8
- package/dist/cron-routes-CBfiaqEL.js.map +1 -0
- package/dist/{cron-scheduler-B0pLfAix.js → cron-scheduler-C2vbETMo.js} +349 -65
- package/dist/cron-scheduler-C2vbETMo.js.map +1 -0
- package/dist/cron-store-B2Ih0gCN.js +540 -0
- package/dist/cron-store-B2Ih0gCN.js.map +1 -0
- package/dist/{ddl-bootstrap-C6mo0Kmz.js → ddl-bootstrap-BaqMSa4Y.js} +2 -2
- package/dist/{ddl-bootstrap-C6mo0Kmz.js.map → ddl-bootstrap-BaqMSa4Y.js.map} +1 -1
- package/dist/email/index.d.ts +2 -2
- package/dist/email/smtp-email-service.d.ts +23 -0
- package/dist/email/templates.d.ts +22 -0
- package/dist/email/types.d.ts +44 -0
- package/dist/env.d.ts +1 -39
- package/dist/{errors-DWsX4yTd.js → errors-D6_y86c5.js} +102 -8
- package/dist/errors-D6_y86c5.js.map +1 -0
- package/dist/filter-dialect-REl-TjZr.js +1628 -0
- package/dist/filter-dialect-REl-TjZr.js.map +1 -0
- package/dist/{function-loader-xnbDAPfa.js → function-loader-BDKKiBmy.js} +5 -4
- package/dist/function-loader-BDKKiBmy.js.map +1 -0
- package/dist/{function-routes-Chet4-lB.js → function-routes-DWB7BBsi.js} +25 -13
- package/dist/function-routes-DWB7BBsi.js.map +1 -0
- package/dist/functions/context.d.ts +26 -6
- package/dist/functions/define-function.d.ts +7 -4
- package/dist/functions/guards.d.ts +22 -5
- package/dist/functions/index.d.ts +2 -2
- package/dist/functions/index.js +114 -37
- package/dist/functions/index.js.map +1 -1
- package/dist/functions/request-timeout.d.ts +7 -5
- package/dist/history/history-routes.d.ts +9 -0
- package/dist/history/retention-sweep.d.ts +81 -0
- package/dist/{history-recorder-B4MpJfJK.js → history-recorder-DHenr3lm.js} +4 -4
- package/dist/{history-recorder-B4MpJfJK.js.map → history-recorder-DHenr3lm.js.map} +1 -1
- package/dist/{history-store-BhxWOuz9.js → history-store-DPofGVDp.js} +2 -2
- package/dist/{history-store-BhxWOuz9.js.map → history-store-DPofGVDp.js.map} +1 -1
- package/dist/index.d.ts +14 -7
- package/dist/index.es.js +23363 -17552
- package/dist/index.es.js.map +1 -1
- package/dist/init/health.d.ts +17 -2
- package/dist/init/shutdown.d.ts +20 -0
- package/dist/init.d.ts +70 -6
- package/dist/internal-tables-L2t39RdT.js +136 -0
- package/dist/internal-tables-L2t39RdT.js.map +1 -0
- package/dist/jobs/job-queue.d.ts +8 -0
- package/dist/jobs/job-store.d.ts +24 -0
- package/dist/jobs/types.d.ts +25 -4
- package/dist/{jobs-CazMYhyy.js → jobs-BpD4Q0qR.js} +235 -25
- package/dist/jobs-BpD4Q0qR.js.map +1 -0
- package/dist/{jwt-DnQHNFCl.js → jwt-Bqcu7cGt.js} +207 -77
- package/dist/jwt-Bqcu7cGt.js.map +1 -0
- package/dist/{keys-CogCQpxG.js → keys-GAVZqbqx.js} +3 -17
- package/dist/{keys-CogCQpxG.js.map → keys-GAVZqbqx.js.map} +1 -1
- package/dist/load-failure-UvzZgGXT.js +48 -0
- package/dist/load-failure-UvzZgGXT.js.map +1 -0
- 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-Bj4TYYUl.js → logs-routes-DAdv37GI.js} +48 -8
- 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 +7 -0
- package/dist/mcp/mcp-tools.d.ts +23 -9
- package/dist/mcp/oauth-metadata.d.ts +21 -16
- package/dist/mcp/oauth-routes.d.ts +7 -1
- package/dist/metrics/index.d.ts +18 -0
- package/dist/metrics/pool-wait.d.ts +50 -0
- package/dist/offline-8Ks3yp9n-CadBKm2D.js +3305 -0
- package/dist/offline-8Ks3yp9n-CadBKm2D.js.map +1 -0
- package/dist/offline-store-D9ytNNaa-BCr2vsFB.js +1903 -0
- package/dist/offline-store-D9ytNNaa-BCr2vsFB.js.map +1 -0
- package/dist/{openapi-generator-O_O24MAT.js → openapi-generator-BqoUh4Ij.js} +455 -80
- package/dist/openapi-generator-BqoUh4Ij.js.map +1 -0
- package/dist/policy-PdzX-Opd.js +121 -0
- package/dist/policy-PdzX-Opd.js.map +1 -0
- package/dist/project_manifest-R6y_KHms.js +59 -0
- package/dist/project_manifest-R6y_KHms.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-DGRVFNM3.js → query-parser-DK9eMkb9.js} +497 -52
- package/dist/query-parser-DK9eMkb9.js.map +1 -0
- package/dist/{request-timeout-C_4C2BeR.js → request-timeout-Dnl2_OBc.js} +17 -10
- package/dist/request-timeout-Dnl2_OBc.js.map +1 -0
- package/dist/resumable-upload-threshold-CKv-Ry0l.js +24 -0
- package/dist/resumable-upload-threshold-CKv-Ry0l.js.map +1 -0
- package/dist/schema-edit/apply-schema-change.d.ts +73 -3
- package/dist/schema-edit/local-source.d.ts +29 -0
- package/dist/schema-edit/project-root.d.ts +3 -2
- package/dist/schema-edit/remote-source.d.ts +20 -5
- package/dist/schema-edit/source-editor.d.ts +28 -0
- package/dist/schema-editor-routes-BFf3i8jm.js +136 -0
- package/dist/schema-editor-routes-BFf3i8jm.js.map +1 -0
- package/dist/serve-spa.d.ts +58 -0
- package/dist/services/outbound-post.d.ts +50 -0
- package/dist/services/outbound-url-guard.d.ts +34 -5
- package/dist/services/routed-realtime-service.d.ts +16 -0
- package/dist/services/webhook-service.d.ts +66 -14
- package/dist/soft-delete-params-47yBGs3_.js +668 -0
- package/dist/soft-delete-params-47yBGs3_.js.map +1 -0
- package/dist/sql-export-routes-BNNuGGLP.js +240 -0
- package/dist/sql-export-routes-BNNuGGLP.js.map +1 -0
- package/dist/{src-vkcwKXbT.js → src-CatHFUym.js} +439 -20
- package/dist/src-CatHFUym.js.map +1 -0
- package/dist/storage/GCSStorageController.d.ts +48 -2
- package/dist/storage/LocalStorageController.d.ts +69 -2
- package/dist/storage/S3StorageController.d.ts +39 -3
- package/dist/storage/image-transform.d.ts +5 -0
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/maintenance-routes.d.ts +23 -0
- package/dist/storage/maintenance.d.ts +126 -0
- package/dist/storage/property-limits.d.ts +41 -6
- package/dist/storage/rendition-cache.d.ts +9 -11
- package/dist/storage/request-keys.d.ts +15 -0
- package/dist/storage/request-principals.d.ts +30 -0
- package/dist/storage/requested-object.d.ts +74 -0
- package/dist/storage/routes.d.ts +52 -14
- package/dist/storage/source-variables.d.ts +10 -0
- package/dist/storage/streams.d.ts +42 -0
- package/dist/storage/tus-handler.d.ts +76 -7
- package/dist/storage/types.d.ts +101 -7
- package/dist/storage/upload-validation.d.ts +13 -0
- package/dist/storage-resumable-VO-cMpse-C_YX71pO.js +125 -0
- package/dist/storage-resumable-VO-cMpse-C_YX71pO.js.map +1 -0
- package/dist/strings.es-BeZWAodn.js +256 -0
- package/dist/strings.es-BeZWAodn.js.map +1 -0
- package/dist/upload-validation-Dd-fnsbA.js +172 -0
- package/dist/upload-validation-Dd-fnsbA.js.map +1 -0
- package/dist/utils/byte-size.d.ts +10 -0
- package/dist/utils/compression.d.ts +6 -0
- package/dist/utils/load-failure.d.ts +14 -0
- package/dist/utils/logger.d.ts +12 -0
- package/package.json +5 -5
- package/dist/GCSStorageController-CjrA4PMo.js +0 -242
- package/dist/GCSStorageController-CjrA4PMo.js.map +0 -1
- package/dist/S3StorageController-B6pKDNVj.js +0 -264
- package/dist/S3StorageController-B6pKDNVj.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-Mvr50v_S.js.map +0 -1
- package/dist/auth/api-keys/api-key-permission-guard.d.ts +0 -65
- package/dist/auth-B-GIMpDG.js.map +0 -1
- package/dist/backup-D7YR94N3.js +0 -253
- package/dist/backup-D7YR94N3.js.map +0 -1
- package/dist/contract-routes-CbFjuBwa.js.map +0 -1
- package/dist/cron-loader-DfTj2Hbi.js.map +0 -1
- package/dist/cron-routes-eE8nif_b.js.map +0 -1
- package/dist/cron-scheduler-B0pLfAix.js.map +0 -1
- package/dist/cron-store-TcoGz-xS.js +0 -305
- package/dist/cron-store-TcoGz-xS.js.map +0 -1
- package/dist/dynamic-import-X40pTZUQ.js +0 -23
- package/dist/dynamic-import-X40pTZUQ.js.map +0 -1
- package/dist/errors-DWsX4yTd.js.map +0 -1
- package/dist/function-loader-xnbDAPfa.js.map +0 -1
- package/dist/function-routes-Chet4-lB.js.map +0 -1
- package/dist/jobs-CazMYhyy.js.map +0 -1
- package/dist/jwt-DnQHNFCl.js.map +0 -1
- package/dist/logger-DO2PZc4i.js.map +0 -1
- package/dist/logs-routes-Bj4TYYUl.js.map +0 -1
- package/dist/openapi-generator-O_O24MAT.js.map +0 -1
- package/dist/query-parser-DGRVFNM3.js.map +0 -1
- package/dist/request-timeout-C_4C2BeR.js.map +0 -1
- package/dist/schema-editor-routes-C5-lh_jO.js +0 -87
- package/dist/schema-editor-routes-C5-lh_jO.js.map +0 -1
- package/dist/src-pmvW7BFx.js +0 -6688
- package/dist/src-pmvW7BFx.js.map +0 -1
- package/dist/src-vkcwKXbT.js.map +0 -1
- package/dist/types-BfKcm9do.js +0 -39
- package/dist/types-BfKcm9do.js.map +0 -1
|
@@ -3,9 +3,9 @@ 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 { a as canonicalStorageId } from "./keys-
|
|
8
|
-
import { createPrivateKey, createPublicKey } from "crypto";
|
|
6
|
+
import { r as logger } from "./logger-D-S-hO5e.js";
|
|
7
|
+
import { a as canonicalStorageId } from "./keys-GAVZqbqx.js";
|
|
8
|
+
import { createPrivateKey, createPublicKey, createSecretKey } from "crypto";
|
|
9
9
|
//#region src/utils/portable-crypto.ts
|
|
10
10
|
/**
|
|
11
11
|
* The cryptography the request path needs, on primitives every runtime has.
|
|
@@ -2386,7 +2386,7 @@ var require_verify = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
2386
2386
|
var validateAsymmetricKey = require_validateAsymmetricKey();
|
|
2387
2387
|
var PS_SUPPORTED = require_psSupported();
|
|
2388
2388
|
var jws = require_jws();
|
|
2389
|
-
var { KeyObject: KeyObject$1, createSecretKey: createSecretKey$
|
|
2389
|
+
var { KeyObject: KeyObject$1, createSecretKey: createSecretKey$2, createPublicKey: createPublicKey$1 } = __require("crypto");
|
|
2390
2390
|
var PUB_KEY_ALGS = [
|
|
2391
2391
|
"RS256",
|
|
2392
2392
|
"RS384",
|
|
@@ -2457,7 +2457,7 @@ var require_verify = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
2457
2457
|
secretOrPublicKey = createPublicKey$1(secretOrPublicKey);
|
|
2458
2458
|
} catch (_) {
|
|
2459
2459
|
try {
|
|
2460
|
-
secretOrPublicKey = createSecretKey$
|
|
2460
|
+
secretOrPublicKey = createSecretKey$2(typeof secretOrPublicKey === "string" ? Buffer.from(secretOrPublicKey) : secretOrPublicKey);
|
|
2461
2461
|
} catch (_) {
|
|
2462
2462
|
return done(new JsonWebTokenError("secretOrPublicKey is not valid key material"));
|
|
2463
2463
|
}
|
|
@@ -4015,7 +4015,7 @@ var require_sign = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
4015
4015
|
var isPlainObject = require_lodash_isplainobject();
|
|
4016
4016
|
var isString = require_lodash_isstring();
|
|
4017
4017
|
var once = require_lodash_once();
|
|
4018
|
-
var { KeyObject, createSecretKey, createPrivateKey: createPrivateKey$1 } = __require("crypto");
|
|
4018
|
+
var { KeyObject, createSecretKey: createSecretKey$1, createPrivateKey: createPrivateKey$1 } = __require("crypto");
|
|
4019
4019
|
var SUPPORTED_ALGS = [
|
|
4020
4020
|
"RS256",
|
|
4021
4021
|
"RS384",
|
|
@@ -4159,7 +4159,7 @@ var require_sign = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
4159
4159
|
secretOrPrivateKey = createPrivateKey$1(secretOrPrivateKey);
|
|
4160
4160
|
} catch (_) {
|
|
4161
4161
|
try {
|
|
4162
|
-
secretOrPrivateKey = createSecretKey(typeof secretOrPrivateKey === "string" ? Buffer.from(secretOrPrivateKey) : secretOrPrivateKey);
|
|
4162
|
+
secretOrPrivateKey = createSecretKey$1(typeof secretOrPrivateKey === "string" ? Buffer.from(secretOrPrivateKey) : secretOrPrivateKey);
|
|
4163
4163
|
} catch (_) {
|
|
4164
4164
|
return failure(/* @__PURE__ */ new Error("secretOrPrivateKey is not valid key material"));
|
|
4165
4165
|
}
|
|
@@ -4258,61 +4258,8 @@ var require_jsonwebtoken = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
4258
4258
|
};
|
|
4259
4259
|
}));
|
|
4260
4260
|
//#endregion
|
|
4261
|
-
//#region src/auth/jwt-crypto.ts
|
|
4262
|
-
var import_jsonwebtoken = /* @__PURE__ */ __toESM(require_jsonwebtoken(), 1);
|
|
4263
|
-
/** Sign a set of claims. Rejects if the key and algorithm disagree. */
|
|
4264
|
-
async function signJwt(payload, key, options) {
|
|
4265
|
-
return import_jsonwebtoken.default.sign(payload, key, {
|
|
4266
|
-
algorithm: options.algorithm,
|
|
4267
|
-
...options.expiresIn === void 0 ? {} : { expiresIn: options.expiresIn },
|
|
4268
|
-
...options.keyid === void 0 ? {} : { keyid: options.keyid }
|
|
4269
|
-
});
|
|
4270
|
-
}
|
|
4271
|
-
/**
|
|
4272
|
-
* Verify a token against one key and an explicit algorithm list, and return its
|
|
4273
|
-
* claims. Rejects — never returns null — when the token is not valid.
|
|
4274
|
-
*
|
|
4275
|
-
* `algorithms` has no default and must not acquire one. Letting the verifier
|
|
4276
|
-
* read `alg` out of the token's own header is the canonical JWT vulnerability:
|
|
4277
|
-
* an attacker takes a published RSA public key, HMACs a payload of their
|
|
4278
|
-
* choosing with it, sets `alg: HS256`, and a verifier holding that same public
|
|
4279
|
-
* key as "the secret" agrees. The caller decides the algorithm from the key it
|
|
4280
|
-
* chose, and {@link decodeProtectedHeader} exists so it can choose that key
|
|
4281
|
-
* without trusting anything the token asserts.
|
|
4282
|
-
*/
|
|
4283
|
-
async function verifyJwt(token, key, options) {
|
|
4284
|
-
return import_jsonwebtoken.default.verify(token, key, { algorithms: options.algorithms });
|
|
4285
|
-
}
|
|
4286
|
-
/**
|
|
4287
|
-
* The token's unverified header — `kid` and `alg` — or an empty object.
|
|
4288
|
-
*
|
|
4289
|
-
* Unverified is the point: this is read *in order to* pick the key that will
|
|
4290
|
-
* verify it, so it cannot itself be verified first. Nothing but key selection
|
|
4291
|
-
* may depend on it, and key selection then pins the algorithm.
|
|
4292
|
-
*
|
|
4293
|
-
* Implemented here rather than via the JWT library because it is plain
|
|
4294
|
-
* base64url and JSON, needs no cryptography, and there is no reason for the
|
|
4295
|
-
* portable half of this module to wait on the non-portable half.
|
|
4296
|
-
*/
|
|
4297
|
-
function decodeProtectedHeader(token) {
|
|
4298
|
-
const encoded = token.split(".")[0];
|
|
4299
|
-
if (!encoded) return {};
|
|
4300
|
-
try {
|
|
4301
|
-
const base64 = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
4302
|
-
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
|
|
4303
|
-
const header = JSON.parse(atob(padded));
|
|
4304
|
-
if (typeof header !== "object" || header === null) return {};
|
|
4305
|
-
const { kid, alg } = header;
|
|
4306
|
-
return {
|
|
4307
|
-
...typeof kid === "string" ? { kid } : {},
|
|
4308
|
-
...typeof alg === "string" ? { alg } : {}
|
|
4309
|
-
};
|
|
4310
|
-
} catch {
|
|
4311
|
-
return {};
|
|
4312
|
-
}
|
|
4313
|
-
}
|
|
4314
|
-
//#endregion
|
|
4315
4261
|
//#region src/auth/jwt-keys.ts
|
|
4262
|
+
var import_jsonwebtoken = /* @__PURE__ */ __toESM(require_jsonwebtoken(), 1);
|
|
4316
4263
|
/**
|
|
4317
4264
|
* The algorithm a key type implies.
|
|
4318
4265
|
*
|
|
@@ -4416,13 +4363,170 @@ function toJwks(keys) {
|
|
|
4416
4363
|
use: "sig"
|
|
4417
4364
|
})) };
|
|
4418
4365
|
}
|
|
4366
|
+
/**
|
|
4367
|
+
* Key strings handed to the JWT library, imported once each.
|
|
4368
|
+
*
|
|
4369
|
+
* `jsonwebtoken` turns every key that is not a `KeyObject` into one on every
|
|
4370
|
+
* call: `createPublicKey` (verify) or `createPrivateKey` (sign) first, and
|
|
4371
|
+
* when that throws — as it does for every HMAC secret, which is not PEM —
|
|
4372
|
+
* `createSecretKey`. The failed parse and its exception were about 15 of the
|
|
4373
|
+
* 21 µs of each access-token verify. These are that same conversion, in the
|
|
4374
|
+
* same order, done once per string; `jwt-crypto.ts` hands the library the
|
|
4375
|
+
* `KeyObject` it produces. Here rather than there because key parsing lives
|
|
4376
|
+
* here (see `jwt-crypto.ts`), and so does this module's `node:crypto`.
|
|
4377
|
+
*
|
|
4378
|
+
* Keyed by the key string itself, so a rotated secret (`configureJwt`) is a
|
|
4379
|
+
* new entry and the old one is simply no longer asked for; bounded, oldest
|
|
4380
|
+
* first, so a process cycling through secrets does not keep all of them. Only
|
|
4381
|
+
* keys live here — never a verification result. Empty strings and anything
|
|
4382
|
+
* not a string pass through untouched, so `jsonwebtoken` refuses them exactly
|
|
4383
|
+
* as it did ("secret or public key must be provided" and the like), and so
|
|
4384
|
+
* does a string no conversion accepts.
|
|
4385
|
+
*/
|
|
4386
|
+
var IMPORTED_KEY_LIMIT = 16;
|
|
4387
|
+
var importedVerificationKeys = /* @__PURE__ */ new Map();
|
|
4388
|
+
var importedSigningKeys = /* @__PURE__ */ new Map();
|
|
4389
|
+
function importedKey(key, cache, asymmetric) {
|
|
4390
|
+
if (typeof key !== "string" || key === "") return key;
|
|
4391
|
+
const cached = cache.get(key);
|
|
4392
|
+
if (cached) return cached;
|
|
4393
|
+
let keyObject;
|
|
4394
|
+
try {
|
|
4395
|
+
keyObject = asymmetric(key);
|
|
4396
|
+
} catch {
|
|
4397
|
+
try {
|
|
4398
|
+
keyObject = createSecretKey(Buffer.from(key));
|
|
4399
|
+
} catch {
|
|
4400
|
+
return key;
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
4403
|
+
if (cache.size >= IMPORTED_KEY_LIMIT) {
|
|
4404
|
+
const oldest = cache.keys().next();
|
|
4405
|
+
if (!oldest.done) cache.delete(oldest.value);
|
|
4406
|
+
}
|
|
4407
|
+
cache.set(key, keyObject);
|
|
4408
|
+
return keyObject;
|
|
4409
|
+
}
|
|
4410
|
+
/** A verification key, as `jsonwebtoken.verify` would import it, once per string. */
|
|
4411
|
+
function importedVerificationKey(key) {
|
|
4412
|
+
return importedKey(key, importedVerificationKeys, createPublicKey);
|
|
4413
|
+
}
|
|
4414
|
+
/** A signing key, as `jsonwebtoken.sign` would import it, once per string. */
|
|
4415
|
+
function importedSigningKey(key) {
|
|
4416
|
+
return importedKey(key, importedSigningKeys, createPrivateKey);
|
|
4417
|
+
}
|
|
4418
|
+
//#endregion
|
|
4419
|
+
//#region src/auth/jwt-crypto.ts
|
|
4420
|
+
/**
|
|
4421
|
+
* The one module in the request path that knows what signs a JWT.
|
|
4422
|
+
*
|
|
4423
|
+
* `jsonwebtoken` is built on `node:crypto` and is synchronous. Every portable
|
|
4424
|
+
* JWT implementation — WebCrypto directly, or `jose` on top of it — is
|
|
4425
|
+
* asynchronous, because `crypto.subtle` is. So the shape of the boundary
|
|
4426
|
+
* matters more than what is behind it right now: **these functions are async
|
|
4427
|
+
* and `jsonwebtoken` is confined to this file.**
|
|
4428
|
+
*
|
|
4429
|
+
* That is the expensive half of the change, and it is why it was made before
|
|
4430
|
+
* anything actually needed it. Swapping the implementation touches one file.
|
|
4431
|
+
* Going from synchronous to asynchronous verification touches every caller of
|
|
4432
|
+
* every function that verifies a token — which, at the time of writing, is
|
|
4433
|
+
* eleven call sites in `src` and about a hundred and eighty in the suite. Doing
|
|
4434
|
+
* that as a line item inside a runtime port, on top of everything else moving
|
|
4435
|
+
* at once, is how a port stalls.
|
|
4436
|
+
*
|
|
4437
|
+
* What is **not** here: key parsing. `jwt-keys.ts` turns PEM into
|
|
4438
|
+
* `node:crypto` `KeyObject`s, and the portable replacement for that is
|
|
4439
|
+
* `jose`'s `importSPKI`/`importPKCS8` — a dependency this package does not
|
|
4440
|
+
* carry yet. It stays recorded in `contracts/portable-core.txt` rather than
|
|
4441
|
+
* wrapped in something that would imply it had moved.
|
|
4442
|
+
*
|
|
4443
|
+
* ## Replacing this with jose
|
|
4444
|
+
*
|
|
4445
|
+
* Add `jose` (a lockfile change, so it happens in the primary checkout), then:
|
|
4446
|
+
* `signJwt` becomes `new SignJWT(payload).setProtectedHeader({ alg, kid })
|
|
4447
|
+
* .setExpirationTime(...).sign(key)`, `verifyJwt` becomes `jwtVerify(token,
|
|
4448
|
+
* key, { algorithms })`, and `decodeProtectedHeader` is already what jose's
|
|
4449
|
+
* function of that name does. Nothing outside this file changes — with one
|
|
4450
|
+
* exception worth writing down, because nothing would fail loudly:
|
|
4451
|
+
* **`jsonwebtoken` stamps `iat` on every token it signs and jose does not**
|
|
4452
|
+
* (it wants an explicit `.setIssuedAt()`). `iat` is what the revocation
|
|
4453
|
+
* watermark compares against — `logout`, `change-password`, `reset-password`
|
|
4454
|
+
* and `DELETE /auth/sessions` all stamp `tokensValidAfter` on the user, and
|
|
4455
|
+
* every access token issued before that mark is void. Tokens minted without
|
|
4456
|
+
* `iat` would verify perfectly well and simply stop being revocable.
|
|
4457
|
+
*
|
|
4458
|
+
* @module
|
|
4459
|
+
*/
|
|
4460
|
+
/** Sign a set of claims. Rejects if the key and algorithm disagree. */
|
|
4461
|
+
async function signJwt(payload, key, options) {
|
|
4462
|
+
return import_jsonwebtoken.default.sign(payload, importedSigningKey(key), {
|
|
4463
|
+
algorithm: options.algorithm,
|
|
4464
|
+
...options.expiresIn === void 0 ? {} : { expiresIn: options.expiresIn },
|
|
4465
|
+
...options.keyid === void 0 ? {} : { keyid: options.keyid }
|
|
4466
|
+
});
|
|
4467
|
+
}
|
|
4468
|
+
/**
|
|
4469
|
+
* Verify a token against one key and an explicit algorithm list, and return its
|
|
4470
|
+
* claims. Rejects — never returns null — when the token is not valid.
|
|
4471
|
+
*
|
|
4472
|
+
* `algorithms` has no default and must not acquire one. Letting the verifier
|
|
4473
|
+
* read `alg` out of the token's own header is the canonical JWT vulnerability:
|
|
4474
|
+
* an attacker takes a published RSA public key, HMACs a payload of their
|
|
4475
|
+
* choosing with it, sets `alg: HS256`, and a verifier holding that same public
|
|
4476
|
+
* key as "the secret" agrees. The caller decides the algorithm from the key it
|
|
4477
|
+
* chose, and {@link decodeProtectedHeader} exists so it can choose that key
|
|
4478
|
+
* without trusting anything the token asserts.
|
|
4479
|
+
*/
|
|
4480
|
+
async function verifyJwt(token, key, options) {
|
|
4481
|
+
return import_jsonwebtoken.default.verify(token, importedVerificationKey(key), { algorithms: options.algorithms });
|
|
4482
|
+
}
|
|
4483
|
+
/**
|
|
4484
|
+
* Whether a {@link verifyJwt} rejection says only that the token's `exp` has
|
|
4485
|
+
* passed — the routine refusal that sends a client to refresh — rather than
|
|
4486
|
+
* that the token is not one we signed. Here because the library decides how
|
|
4487
|
+
* that is spelled.
|
|
4488
|
+
*/
|
|
4489
|
+
function isExpiredJwtError(error) {
|
|
4490
|
+
return error instanceof import_jsonwebtoken.default.TokenExpiredError;
|
|
4491
|
+
}
|
|
4492
|
+
/**
|
|
4493
|
+
* The token's unverified header — `kid` and `alg` — or an empty object.
|
|
4494
|
+
*
|
|
4495
|
+
* Unverified is the point: this is read *in order to* pick the key that will
|
|
4496
|
+
* verify it, so it cannot itself be verified first. Nothing but key selection
|
|
4497
|
+
* may depend on it, and key selection then pins the algorithm.
|
|
4498
|
+
*
|
|
4499
|
+
* Implemented here rather than via the JWT library because it is plain
|
|
4500
|
+
* base64url and JSON, needs no cryptography, and there is no reason for the
|
|
4501
|
+
* portable half of this module to wait on the non-portable half.
|
|
4502
|
+
*/
|
|
4503
|
+
function decodeProtectedHeader(token) {
|
|
4504
|
+
const encoded = token.split(".")[0];
|
|
4505
|
+
if (!encoded) return {};
|
|
4506
|
+
try {
|
|
4507
|
+
const base64 = encoded.replace(/-/g, "+").replace(/_/g, "/");
|
|
4508
|
+
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
|
|
4509
|
+
const header = JSON.parse(atob(padded));
|
|
4510
|
+
if (typeof header !== "object" || header === null) return {};
|
|
4511
|
+
const { kid, alg } = header;
|
|
4512
|
+
return {
|
|
4513
|
+
...typeof kid === "string" ? { kid } : {},
|
|
4514
|
+
...typeof alg === "string" ? { alg } : {}
|
|
4515
|
+
};
|
|
4516
|
+
} catch {
|
|
4517
|
+
return {};
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4419
4520
|
//#endregion
|
|
4420
4521
|
//#region src/auth/jwt.ts
|
|
4421
4522
|
var jwt_exports = /* @__PURE__ */ __exportAll({
|
|
4523
|
+
DEFAULT_REFRESH_EXPIRES_IN: () => "30d",
|
|
4422
4524
|
MAX_COOKIE_AGE_MS: () => MAX_COOKIE_AGE_MS,
|
|
4423
4525
|
MCP_ACCESS_PURPOSE: () => MCP_ACCESS_PURPOSE,
|
|
4424
4526
|
MFA_PENDING_PURPOSE: () => MFA_PENDING_PURPOSE,
|
|
4425
4527
|
configureJwt: () => configureJwt,
|
|
4528
|
+
configuredJwtSecret: () => configuredJwtSecret,
|
|
4529
|
+
customClaimsOf: () => customClaimsOf,
|
|
4426
4530
|
generateAccessToken: () => generateAccessToken,
|
|
4427
4531
|
generateDownloadToken: () => generateDownloadToken,
|
|
4428
4532
|
generateMcpAccessToken: () => generateMcpAccessToken,
|
|
@@ -4459,6 +4563,7 @@ var RESERVED_TOKEN_CLAIMS = /* @__PURE__ */ new Set([
|
|
|
4459
4563
|
"roles",
|
|
4460
4564
|
"aal",
|
|
4461
4565
|
"isAnonymous",
|
|
4566
|
+
"sid",
|
|
4462
4567
|
"purpose",
|
|
4463
4568
|
"iat",
|
|
4464
4569
|
"exp",
|
|
@@ -4467,7 +4572,13 @@ var RESERVED_TOKEN_CLAIMS = /* @__PURE__ */ new Set([
|
|
|
4467
4572
|
"aud",
|
|
4468
4573
|
"jti"
|
|
4469
4574
|
]);
|
|
4470
|
-
/**
|
|
4575
|
+
/**
|
|
4576
|
+
* The custom half of a verified token, or nothing when there is none.
|
|
4577
|
+
*
|
|
4578
|
+
* Exported for the one other place that builds a request identity's claims
|
|
4579
|
+
* without a token to verify — `resolveUser`, which reads what a token minted
|
|
4580
|
+
* now would carry — so both drop the same identity claims.
|
|
4581
|
+
*/
|
|
4471
4582
|
function customClaimsOf(decoded) {
|
|
4472
4583
|
const claims = {};
|
|
4473
4584
|
for (const [key, value] of Object.entries(decoded)) {
|
|
@@ -4479,7 +4590,7 @@ function customClaimsOf(decoded) {
|
|
|
4479
4590
|
var jwtConfig = {
|
|
4480
4591
|
secret: "",
|
|
4481
4592
|
accessExpiresIn: "1h",
|
|
4482
|
-
refreshExpiresIn: "
|
|
4593
|
+
refreshExpiresIn: "30d"
|
|
4483
4594
|
};
|
|
4484
4595
|
/**
|
|
4485
4596
|
* The parsed signing keys, and which one mints new access tokens.
|
|
@@ -4551,6 +4662,14 @@ function configureJwt(config) {
|
|
|
4551
4662
|
function getJwks() {
|
|
4552
4663
|
return toJwks(signingKeys);
|
|
4553
4664
|
}
|
|
4665
|
+
/**
|
|
4666
|
+
* The secret `configureJwt` was given, or undefined before it is called. For
|
|
4667
|
+
* `mfa-crypto.ts`, which falls back to it when no MFA key is set — the secret
|
|
4668
|
+
* passed in code, not only the one in `JWT_SECRET`.
|
|
4669
|
+
*/
|
|
4670
|
+
function configuredJwtSecret() {
|
|
4671
|
+
return jwtConfig.secret || void 0;
|
|
4672
|
+
}
|
|
4554
4673
|
/** Is this backend signing access tokens asymmetrically? */
|
|
4555
4674
|
function hasAsymmetricSigningKey() {
|
|
4556
4675
|
return activeSigningKey !== null;
|
|
@@ -4572,14 +4691,15 @@ function isJwtConfigured() {
|
|
|
4572
4691
|
/**
|
|
4573
4692
|
* Generate an access token (short-lived, 1 hour by default)
|
|
4574
4693
|
*/
|
|
4575
|
-
async function generateAccessToken(uid, roles, aal = "aal1", customClaims, isAnonymous = false) {
|
|
4694
|
+
async function generateAccessToken(uid, roles, aal = "aal1", customClaims, isAnonymous = false, sessionId) {
|
|
4576
4695
|
if (!jwtConfig.secret) throw new Error("JWT secret not configured. Call configureJwt() first.");
|
|
4577
4696
|
const payload = {
|
|
4578
4697
|
...customClaims,
|
|
4579
4698
|
uid,
|
|
4580
4699
|
roles,
|
|
4581
4700
|
aal,
|
|
4582
|
-
...isAnonymous ? { isAnonymous: true } : {}
|
|
4701
|
+
...isAnonymous ? { isAnonymous: true } : {},
|
|
4702
|
+
...sessionId ? { sid: sessionId } : {}
|
|
4583
4703
|
};
|
|
4584
4704
|
if (activeSigningKey) return signJwt(payload, activeSigningKey.privateKey, {
|
|
4585
4705
|
expiresIn: jwtConfig.accessExpiresIn,
|
|
@@ -4691,21 +4811,25 @@ async function verifyAccessToken(token) {
|
|
|
4691
4811
|
aal,
|
|
4692
4812
|
...decoded.isAnonymous === true ? { isAnonymous: true } : {},
|
|
4693
4813
|
iat: decoded.iat,
|
|
4814
|
+
...typeof decoded.exp === "number" ? { exp: decoded.exp } : {},
|
|
4815
|
+
...typeof decoded.sid === "string" && decoded.sid ? { sid: decoded.sid } : {},
|
|
4694
4816
|
...(() => {
|
|
4695
4817
|
const claims = customClaimsOf(decoded);
|
|
4696
4818
|
return claims ? { claims } : {};
|
|
4697
4819
|
})()
|
|
4698
4820
|
};
|
|
4699
4821
|
} catch (error) {
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
}
|
|
4822
|
+
if (isExpiredJwtError(error)) {
|
|
4823
|
+
logger.debug("[JWT] Access token expired");
|
|
4824
|
+
return null;
|
|
4825
|
+
}
|
|
4826
|
+
logger.error("[JWT] Verification failed", { error });
|
|
4704
4827
|
return null;
|
|
4705
4828
|
}
|
|
4706
4829
|
}
|
|
4707
4830
|
/**
|
|
4708
|
-
* Generate a random refresh token
|
|
4831
|
+
* Generate a random refresh token. Long-lived: 30 days by default, sliding —
|
|
4832
|
+
* see {@link getRefreshTokenTtlMs}.
|
|
4709
4833
|
*/
|
|
4710
4834
|
function generateRefreshToken() {
|
|
4711
4835
|
return randomHex(40);
|
|
@@ -4724,7 +4848,7 @@ function hashRefreshToken(token) {
|
|
|
4724
4848
|
*/
|
|
4725
4849
|
var MAX_COOKIE_AGE_MS = 400 * 24 * 60 * 60 * 1e3;
|
|
4726
4850
|
/** Fallback when `refreshExpiresIn` is unset. {@link configureJwt} refuses an unparseable one. */
|
|
4727
|
-
var DEFAULT_REFRESH_TTL_MS =
|
|
4851
|
+
var DEFAULT_REFRESH_TTL_MS = 720 * 60 * 60 * 1e3;
|
|
4728
4852
|
/**
|
|
4729
4853
|
* How long a refresh token is valid for, in milliseconds.
|
|
4730
4854
|
*
|
|
@@ -4812,17 +4936,22 @@ async function verifyMfaPendingToken(token) {
|
|
|
4812
4936
|
* site that forgets to pass a named source produces a default-scoped token,
|
|
4813
4937
|
* which fails closed at `/file/*` rather than over-granting.
|
|
4814
4938
|
*/
|
|
4815
|
-
async function generateDownloadToken(path, expiresInSeconds = 300, storageId) {
|
|
4939
|
+
async function generateDownloadToken(path, expiresInSeconds = 300, storageId, principal) {
|
|
4816
4940
|
if (!jwtConfig.secret) throw new Error("JWT secret not configured. Call configureJwt() first.");
|
|
4817
4941
|
return signJwt({
|
|
4818
4942
|
purpose: "file-read",
|
|
4819
4943
|
path,
|
|
4820
|
-
storageId: canonicalStorageId(storageId)
|
|
4944
|
+
storageId: canonicalStorageId(storageId),
|
|
4945
|
+
...principal ? { rl: await downloadTokenRateLimitMark(principal) } : {}
|
|
4821
4946
|
}, jwtConfig.secret, {
|
|
4822
4947
|
expiresIn: expiresInSeconds,
|
|
4823
4948
|
algorithm: "HS256"
|
|
4824
4949
|
});
|
|
4825
4950
|
}
|
|
4951
|
+
/** See {@link DownloadTokenPayload.rl}. */
|
|
4952
|
+
async function downloadTokenRateLimitMark(principal) {
|
|
4953
|
+
return (await sha256Hex(`download-token-rl:${principal}`)).slice(0, 32);
|
|
4954
|
+
}
|
|
4826
4955
|
/**
|
|
4827
4956
|
* Verify and decode a download token.
|
|
4828
4957
|
*
|
|
@@ -4840,11 +4969,12 @@ async function verifyDownloadToken(token) {
|
|
|
4840
4969
|
if (decoded && decoded.purpose === "file-read" && typeof decoded.path === "string") return {
|
|
4841
4970
|
purpose: "file-read",
|
|
4842
4971
|
path: decoded.path,
|
|
4843
|
-
storageId: canonicalStorageId(typeof decoded.storageId === "string" ? decoded.storageId : null)
|
|
4972
|
+
storageId: canonicalStorageId(typeof decoded.storageId === "string" ? decoded.storageId : null),
|
|
4973
|
+
...typeof decoded.rl === "string" ? { rl: decoded.rl } : {}
|
|
4844
4974
|
};
|
|
4845
4975
|
return null;
|
|
4846
4976
|
} catch (error) {
|
|
4847
|
-
logger.
|
|
4977
|
+
logger.debug("[JWT] Download token verification failed", { error });
|
|
4848
4978
|
return null;
|
|
4849
4979
|
}
|
|
4850
4980
|
}
|
|
@@ -4966,6 +5096,6 @@ async function verifyMcpAccessToken(token, expectedAudience) {
|
|
|
4966
5096
|
}
|
|
4967
5097
|
}
|
|
4968
5098
|
//#endregion
|
|
4969
|
-
export {
|
|
5099
|
+
export { sha256Bytes as A, verifyPurposeToken as C, constantTimeEqual as D, require_jsonwebtoken as E, randomHex as O, verifyMfaPendingToken as S, normalizePemFromEnv 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, verifyJwt as w, verifyMcpAccessToken as x, verifyAccessToken as y };
|
|
4970
5100
|
|
|
4971
|
-
//# sourceMappingURL=jwt-
|
|
5101
|
+
//# sourceMappingURL=jwt-Bqcu7cGt.js.map
|