@rebasepro/server 0.13.0 → 0.13.1-canary.g18cfeb7
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/dist/{admin_block-CcSGdH7M.js → admin_block-CLeUMG8G.js} +3 -1
- package/dist/admin_block-CLeUMG8G.js.map +1 -0
- package/dist/api/errors.d.ts +0 -6
- package/dist/api/openapi-generator.d.ts +14 -0
- package/dist/api/rest/idempotency.d.ts +41 -4
- package/dist/api/rest/write-validation.d.ts +12 -5
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/jwt.d.ts +12 -0
- package/dist/{auth-CuC9M2x6.js → auth-CtxXQYV_.js} +20 -39
- package/dist/auth-CtxXQYV_.js.map +1 -0
- package/dist/{backup-CVggVhR2.js → backup-BJiY_mM-.js} +2 -2
- package/dist/{backup-CVggVhR2.js.map → backup-BJiY_mM-.js.map} +1 -1
- package/dist/boot/boot.d.ts +19 -0
- package/dist/{contract-routes-Dj8i5AiM.js → contract-routes-FSt0Nyfk.js} +2 -2
- package/dist/{contract-routes-Dj8i5AiM.js.map → contract-routes-FSt0Nyfk.js.map} +1 -1
- package/dist/cron/cron-scheduler.d.ts +8 -3
- package/dist/cron/define-cron.d.ts +5 -3
- package/dist/{cron-routes-CrQ0tK-_.js → cron-routes-D5a9v1HY.js} +2 -2
- package/dist/{cron-routes-CrQ0tK-_.js.map → cron-routes-D5a9v1HY.js.map} +1 -1
- package/dist/{cron-scheduler-B3RFt0HS.js → cron-scheduler-CsQtYLMq.js} +28 -3
- package/dist/cron-scheduler-CsQtYLMq.js.map +1 -0
- package/dist/{cron-store-BywZsyfZ.js → cron-store-CHH7zrif.js} +16 -3
- package/dist/cron-store-CHH7zrif.js.map +1 -0
- package/dist/{errors-CgkCzoj7.js → errors-BpudWAVU.js} +2 -10
- package/dist/errors-BpudWAVU.js.map +1 -0
- package/dist/functions/define-function.d.ts +1 -1
- package/dist/index.es.js +673 -232
- package/dist/index.es.js.map +1 -1
- package/dist/internal-tables-57VaN3o1.js +105 -0
- package/dist/internal-tables-57VaN3o1.js.map +1 -0
- package/dist/{jwt-DD6EtpGj.js → jwt-CzeviDcB.js} +17 -2
- package/dist/{jwt-DD6EtpGj.js.map → jwt-CzeviDcB.js.map} +1 -1
- package/dist/{openapi-generator-BEwyiaAr.js → openapi-generator-CSlEZh7-.js} +306 -128
- package/dist/openapi-generator-CSlEZh7-.js.map +1 -0
- package/dist/{schema-editor-routes-CbF20Mf1.js → schema-editor-routes-BqjzvvWU.js} +4 -4
- package/dist/{schema-editor-routes-CbF20Mf1.js.map → schema-editor-routes-BqjzvvWU.js.map} +1 -1
- package/dist/{src-_qQ3RNCK.js → src-Ca6NhxKs.js} +79 -2
- package/dist/src-Ca6NhxKs.js.map +1 -0
- package/dist/{src-Cum9kox5.js → src-CvaxLgnM.js} +115 -34
- package/dist/src-CvaxLgnM.js.map +1 -0
- package/dist/utils/logging.d.ts +0 -4
- package/dist/utils/sql.d.ts +11 -6
- package/package.json +6 -6
- package/dist/admin_block-CcSGdH7M.js.map +0 -1
- package/dist/auth-CuC9M2x6.js.map +0 -1
- package/dist/backend-CIxN4FVm.js +0 -15
- package/dist/backend-CIxN4FVm.js.map +0 -1
- package/dist/cron-scheduler-B3RFt0HS.js.map +0 -1
- package/dist/cron-store-BywZsyfZ.js.map +0 -1
- package/dist/errors-CgkCzoj7.js.map +0 -1
- package/dist/openapi-generator-BEwyiaAr.js.map +0 -1
- package/dist/src-Cum9kox5.js.map +0 -1
- package/dist/src-_qQ3RNCK.js.map +0 -1
|
@@ -44,6 +44,7 @@ var ADMIN_COLLECTION_KEYS = [
|
|
|
44
44
|
"defaultSize",
|
|
45
45
|
"defaultViewMode",
|
|
46
46
|
"disableDefaultActions",
|
|
47
|
+
"display",
|
|
47
48
|
"enabledViews",
|
|
48
49
|
"entityActions",
|
|
49
50
|
"entityViews",
|
|
@@ -54,6 +55,7 @@ var ADMIN_COLLECTION_KEYS = [
|
|
|
54
55
|
"formAutoSave",
|
|
55
56
|
"formView",
|
|
56
57
|
"group",
|
|
58
|
+
"hideFromEntityViews",
|
|
57
59
|
"hideFromNavigation",
|
|
58
60
|
"hideIdFromCollection",
|
|
59
61
|
"hideIdFromForm",
|
|
@@ -121,4 +123,4 @@ var ADMIN_PROPERTY_KEYS = [
|
|
|
121
123
|
//#endregion
|
|
122
124
|
export { ADMIN_PROPERTY_KEYS as n, ADMIN_COLLECTION_KEYS as t };
|
|
123
125
|
|
|
124
|
-
//# sourceMappingURL=admin_block-
|
|
126
|
+
//# sourceMappingURL=admin_block-CLeUMG8G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin_block-CLeUMG8G.js","names":[],"sources":["../../types/src/types/admin_block.ts"],"sourcesContent":["/**\n * The keys of a collection's admin block, as data.\n *\n * There is no *type* for the block in this package any more, and that is the point:\n * `admin` is not declared on `BaseCollectionConfig` or on any property here, so a\n * BaaS install cannot even write one. `@rebasepro/admin-types` adds the field back by\n * declaration merging, which is why installing it is what makes the admin surface\n * appear.\n *\n * The *list* still has to live here, because three runtime consumers need it and two\n * of them are core — see below.\n */\n\n/**\n * Every key that belongs inside a collection's `admin` block, as data.\n *\n * The type that describes these fields is `AdminCollectionOptions` in\n * `@rebasepro/admin-types`, and it is erased at build time — but three runtime\n * consumers need the list, and two of them are core:\n *\n * - `serializeCollections`, to drop the block from the contract\n * - the ts-morph schema editor in `@rebasepro/server`, which rewrites collection\n * files on disk from the admin panel and has to know where each key goes. A key\n * missing from this list gets written to the *top level* of the file, where the\n * backend ignores it and the panel never finds it again.\n * - the `collections-admin-block` codemod\n *\n * `@rebasepro/admin-types` re-exports this and asserts it names only real option\n * keys; the count is pinned by a test there.\n *\n * @group Models\n */\nexport const ADMIN_COLLECTION_KEYS = [\n \"Actions\",\n \"additionalFields\",\n \"alwaysApplyDefaultValues\",\n \"components\",\n \"defaultEntityAction\",\n \"defaultFilter\",\n \"defaultSelectedView\",\n \"defaultSize\",\n \"defaultViewMode\",\n \"disableDefaultActions\",\n \"display\",\n \"enabledViews\",\n \"entityActions\",\n \"entityViews\",\n \"exportable\",\n \"filterPresets\",\n \"fixedFilter\",\n \"form\",\n \"formAutoSave\",\n \"formView\",\n \"group\",\n \"hideFromEntityViews\",\n \"hideFromNavigation\",\n \"hideIdFromCollection\",\n \"hideIdFromForm\",\n \"icon\",\n \"includeJsonView\",\n \"inlineEditing\",\n \"kanban\",\n \"listProperties\",\n \"localChangesBackup\",\n \"openEntityMode\",\n \"orderProperty\",\n \"pagination\",\n \"previewProperties\",\n \"propertiesOrder\",\n \"selectionController\",\n \"selectionEnabled\",\n \"sideDialogWidth\",\n \"sort\",\n \"titleProperty\"\n] as const;\n\n/** A key of a collection's `admin` block. @group Models */\nexport type AdminCollectionKey = typeof ADMIN_COLLECTION_KEYS[number];\n\n/**\n * Every key that belongs inside a *property's* `admin` block, as data.\n *\n * The union of `AdminPropertyOptions` and its per-type extensions\n * (`AdminStringOptions`, `AdminArrayOptions`, …) in `@rebasepro/admin-types`.\n * It lives here for the same reason {@link ADMIN_COLLECTION_KEYS} does: the\n * runtime consumers are core packages that the BaaS guard forbids from\n * importing `@rebasepro/admin-types`. Here it is the boot-time collection\n * validator in `@rebasepro/server`, which has to tell \"you left `readOnly` at\n * the top of the property, where nothing reads it\" apart from \"you invented a\n * key we have never heard of\".\n *\n * `@rebasepro/admin-types` re-exports this and asserts it names only real\n * option keys.\n *\n * @group Models\n */\nexport const ADMIN_PROPERTY_KEYS = [\n \"canAddElements\",\n \"clearable\",\n \"columnWidth\",\n \"customProps\",\n \"disabled\",\n \"expanded\",\n \"Field\",\n \"Filter\",\n \"filterOperators\",\n \"fixedFilter\",\n \"hideFromCollection\",\n \"includeEntityLink\",\n \"includeId\",\n \"markdown\",\n \"minimalistView\",\n \"multiline\",\n \"Preview\",\n \"previewAsTag\",\n \"previewProperties\",\n \"readOnly\",\n \"sortable\",\n \"span\",\n \"spreadChildren\",\n \"urlPreview\",\n \"widget\",\n] as const;\n\n/** A key of a property's `admin` block. @group Models */\nexport type AdminPropertyKey = typeof ADMIN_PROPERTY_KEYS[number];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAa,wBAAwB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ;;;;;;;;;;;;;;;;;;AAsBA,IAAa,sBAAsB;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ"}
|
package/dist/api/errors.d.ts
CHANGED
|
@@ -55,12 +55,6 @@ export interface RebaseApiError extends Error {
|
|
|
55
55
|
code?: string;
|
|
56
56
|
details?: unknown;
|
|
57
57
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Type guard for errors that carry optional API metadata (statusCode, code, details).
|
|
60
|
-
* Returns true for any Error instance — the optional properties are then
|
|
61
|
-
* checked via normal property access.
|
|
62
|
-
*/
|
|
63
|
-
export declare function isRebaseApiError(error: unknown): error is RebaseApiError;
|
|
64
58
|
/**
|
|
65
59
|
* Hono error-handling middleware (`app.onError`).
|
|
66
60
|
* Converts any error into the canonical `{ error: { message, code } }` shape.
|
|
@@ -12,5 +12,19 @@ export interface OpenApiGeneratorOptions {
|
|
|
12
12
|
basePath?: string;
|
|
13
13
|
/** Whether auth is enabled on data routes. Defaults to true. */
|
|
14
14
|
requireAuth?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The list-pagination bounds the REST layer applies, so the spec states the
|
|
17
|
+
* ones a request will actually meet.
|
|
18
|
+
*
|
|
19
|
+
* These were hardcoded as `default: 20, maximum: 100` — neither of which
|
|
20
|
+
* the server has ever used. The spec drives the API Explorer and is what a
|
|
21
|
+
* generated client is built from, so an understated ceiling is a request
|
|
22
|
+
* the client refuses to make, and an overstated one is a 400 nobody
|
|
23
|
+
* predicted.
|
|
24
|
+
*/
|
|
25
|
+
listLimits?: {
|
|
26
|
+
defaultLimit?: number;
|
|
27
|
+
maxLimit?: number;
|
|
28
|
+
};
|
|
15
29
|
}
|
|
16
30
|
export declare function generateOpenApiSpec(collections: CollectionConfig[], options?: OpenApiGeneratorOptions): Record<string, unknown>;
|
|
@@ -1,9 +1,46 @@
|
|
|
1
1
|
import { DataDriver } from "@rebasepro/types";
|
|
2
|
+
/**
|
|
3
|
+
* What a caller may do with a key.
|
|
4
|
+
*
|
|
5
|
+
* `claimed` is the only outcome that permits the write. Recalling and then
|
|
6
|
+
* writing was not atomic: two requests carrying one key both missed the recall,
|
|
7
|
+
* both wrote, and `ON CONFLICT DO NOTHING` protected only the second row in
|
|
8
|
+
* *this* table — the duplicate row in the caller's collection, which is the
|
|
9
|
+
* thing the mechanism exists to prevent, was inserted anyway. The offline queue
|
|
10
|
+
* is shared across tabs, so two tabs reconnecting together is the ordinary case
|
|
11
|
+
* rather than an exotic one.
|
|
12
|
+
*/
|
|
13
|
+
export type IdempotencyClaim =
|
|
14
|
+
/** This key has already been answered; serve that answer again. */
|
|
15
|
+
{
|
|
16
|
+
status: "replay";
|
|
17
|
+
response: unknown;
|
|
18
|
+
}
|
|
19
|
+
/** Another request holds this key and has not answered yet. */
|
|
20
|
+
| {
|
|
21
|
+
status: "in-flight";
|
|
22
|
+
}
|
|
23
|
+
/** The key is ours; do the write, then `complete` or `release` it. */
|
|
24
|
+
| {
|
|
25
|
+
status: "claimed";
|
|
26
|
+
};
|
|
2
27
|
export interface IdempotencyStore {
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Take the key if it is free, atomically. Never throws — a store that
|
|
30
|
+
* cannot answer reports `claimed`, which degrades to no idempotency rather
|
|
31
|
+
* than to a refused write.
|
|
32
|
+
*/
|
|
33
|
+
claim(key: string, uid: string | undefined): Promise<IdempotencyClaim>;
|
|
34
|
+
/** Record what this key answered. Never throws. */
|
|
35
|
+
complete(key: string, uid: string | undefined, response: unknown): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Give the key back after the write it was claimed for failed.
|
|
38
|
+
*
|
|
39
|
+
* Without this a transient failure strands the key: every retry would be
|
|
40
|
+
* told `in-flight` until the row aged out, turning one failed write into a
|
|
41
|
+
* day of refusals.
|
|
42
|
+
*/
|
|
43
|
+
release(key: string, uid: string | undefined): Promise<void>;
|
|
7
44
|
}
|
|
8
45
|
/**
|
|
9
46
|
* Returns `undefined` when the driver cannot run SQL, which disables the whole
|
|
@@ -33,11 +33,18 @@ export declare function assertKnownWriteFields(values: Record<string, unknown>,
|
|
|
33
33
|
* This shapes the *response*, which is what the parameter says it does; it is
|
|
34
34
|
* not a column pushdown, so it saves bandwidth rather than database work.
|
|
35
35
|
*
|
|
36
|
-
*
|
|
37
|
-
* the admin table, realtime reconciliation, the offline
|
|
38
|
-
* arrives without one is not a smaller row, it is an
|
|
39
|
-
* `fields=title` and being unable to open the record
|
|
40
|
-
* answer than one extra key.
|
|
36
|
+
* The collection's key always survives. Rows are addressed by it everywhere
|
|
37
|
+
* above this layer — the admin table, realtime reconciliation, the offline
|
|
38
|
+
* cache — and a row that arrives without one is not a smaller row, it is an
|
|
39
|
+
* unusable one. Asking for `fields=title` and being unable to open the record
|
|
40
|
+
* you clicked is a worse answer than one extra key.
|
|
41
|
+
*
|
|
42
|
+
* That is a statement about the key, not about the name `id`: a collection
|
|
43
|
+
* keyed on `slug`, or on `user_id + role_id`, was projected down to the fields
|
|
44
|
+
* asked for and nothing else, which is the very outcome the paragraph above
|
|
45
|
+
* describes. `assertKnownWriteFields` one function up already has a dedicated
|
|
46
|
+
* error for collections with no `id` column, so this layer had no excuse for
|
|
47
|
+
* assuming one.
|
|
41
48
|
*/
|
|
42
49
|
export declare function projectResponseFields<T extends Record<string, unknown>>(rows: T[], fields: readonly string[] | undefined, collection: CollectionConfig, options?: {
|
|
43
50
|
include?: readonly string[];
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./interfaces";
|
|
2
|
-
export { configureJwt, generateAccessToken, verifyAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry, generateDownloadToken, verifyDownloadToken } from "./jwt";
|
|
2
|
+
export { configureJwt, isJwtConfigured, generateAccessToken, verifyAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry, generateDownloadToken, verifyDownloadToken } from "./jwt";
|
|
3
3
|
export type { JwtConfig, AccessTokenPayload, DownloadTokenPayload } from "./jwt";
|
|
4
4
|
export { hashPassword, verifyPassword, validatePasswordStrength } from "./password";
|
|
5
5
|
export { safeCompare } from "./crypto-utils";
|
package/dist/auth/jwt.d.ts
CHANGED
|
@@ -30,6 +30,18 @@ export interface AccessTokenPayload {
|
|
|
30
30
|
* Validates the secret strength to prevent deployment with default/weak secrets.
|
|
31
31
|
*/
|
|
32
32
|
export declare function configureJwt(config: JwtConfig): void;
|
|
33
|
+
/**
|
|
34
|
+
* Has this server been given a JWT secret?
|
|
35
|
+
*
|
|
36
|
+
* False on every backend that authenticates through an adapter — Firebase,
|
|
37
|
+
* Clerk, anything with its own tokens — because nothing calls
|
|
38
|
+
* {@link configureJwt} there. Signing paths still throw when it is false, since
|
|
39
|
+
* asking for a token from a server that cannot mint one is a mistake worth
|
|
40
|
+
* hearing about. Paths whose contract is *"tolerate the absence of auth"* must
|
|
41
|
+
* ask first: `optionalAuth` crashing a request because this backend does not do
|
|
42
|
+
* JWT is a 500 on a route that had already decided anonymous was acceptable.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isJwtConfigured(): boolean;
|
|
33
45
|
/**
|
|
34
46
|
* Generate an access token (short-lived, 1 hour by default)
|
|
35
47
|
*/
|
|
@@ -2,38 +2,16 @@ import { createRequire as __createRequire } from "module";
|
|
|
2
2
|
import process from "process";
|
|
3
3
|
__createRequire(import.meta.url);
|
|
4
4
|
import { i as __toESM, n as __exportAll } from "./rolldown-runtime-DSJWtz9O.js";
|
|
5
|
-
import {
|
|
6
|
-
import "./src-
|
|
7
|
-
import {
|
|
5
|
+
import { S as isAnonymousUid, b as resolveClientListLimit, x as ANONYMOUS_USER_ID } from "./src-CvaxLgnM.js";
|
|
6
|
+
import "./src-Ca6NhxKs.js";
|
|
7
|
+
import { n as isSQLAdmin, t as revokeInternalTableSql } from "./internal-tables-57VaN3o1.js";
|
|
8
8
|
import { t as logger } from "./logger-BYU66ENZ.js";
|
|
9
|
-
import { n as errorHandler, t as ApiError } from "./errors-
|
|
10
|
-
import { a as generateRefreshToken, c as getRefreshTokenTtlMs,
|
|
9
|
+
import { n as errorHandler, t as ApiError } from "./errors-BpudWAVU.js";
|
|
10
|
+
import { a as generateRefreshToken, c as getRefreshTokenTtlMs, f as verifyAccessToken, i as generateDownloadToken, l as hashRefreshToken, m as require_jsonwebtoken, n as configureJwt, o as getAccessTokenExpiry, p as verifyDownloadToken, r as generateAccessToken, s as getRefreshTokenExpiry, t as MAX_COOKIE_AGE_MS, u as isJwtConfigured } from "./jwt-CzeviDcB.js";
|
|
11
11
|
import { createHash, randomBytes, randomInt } from "node:crypto";
|
|
12
12
|
import { Hono } from "hono";
|
|
13
13
|
import { promisify } from "util";
|
|
14
14
|
import { createCipheriv, createDecipheriv, createHash as createHash$1, createHmac, randomBytes as randomBytes$1, randomUUID as randomUUID$1, scrypt, timingSafeEqual } from "crypto";
|
|
15
|
-
/** Hard ceiling clamped onto any client-supplied `limit`, on every surface. */
|
|
16
|
-
var MAX_LIST_LIMIT = 1e3;
|
|
17
|
-
/**
|
|
18
|
-
* Resolve a client-supplied list `limit` into a safe, always-defined value.
|
|
19
|
-
*
|
|
20
|
-
* - A provided limit is coerced to an integer and clamped to `[1, maxLimit]`,
|
|
21
|
-
* so `0`, negatives, and absurd values can never bypass the cap.
|
|
22
|
-
* - An absent / blank / non-numeric limit falls back to the mode default:
|
|
23
|
-
* `vectorDefaultLimit` for a vector search, otherwise `defaultLimit`.
|
|
24
|
-
*
|
|
25
|
-
* The return is never `undefined` — no ingress that routes its client limit
|
|
26
|
-
* through this can produce an unbounded read.
|
|
27
|
-
*/
|
|
28
|
-
function resolveClientListLimit(rawLimit, opts = {}) {
|
|
29
|
-
const maxLimit = opts.maxLimit ?? 1e3;
|
|
30
|
-
if (rawLimit != null && String(rawLimit).trim() !== "") {
|
|
31
|
-
const parsed = typeof rawLimit === "number" ? rawLimit : parseInt(String(rawLimit), 10);
|
|
32
|
-
if (Number.isFinite(parsed)) return Math.min(Math.max(1, Math.floor(parsed)), maxLimit);
|
|
33
|
-
}
|
|
34
|
-
return opts.vectorSearch ? opts.vectorDefaultLimit ?? 10 : opts.defaultLimit ?? 50;
|
|
35
|
-
}
|
|
36
|
-
//#endregion
|
|
37
15
|
//#region ../types/src/controllers/storage.ts
|
|
38
16
|
/**
|
|
39
17
|
* Path prefix that marks an object as **public**. Files stored under this
|
|
@@ -551,7 +529,7 @@ var requireAdmin = async (c, next) => {
|
|
|
551
529
|
var optionalAuth = async (c, next) => {
|
|
552
530
|
if (c.get("user")) return next();
|
|
553
531
|
const token = extractBearerToken(c.req.header("authorization"));
|
|
554
|
-
if (token !== void 0) {
|
|
532
|
+
if (token !== void 0 && isJwtConfigured()) {
|
|
555
533
|
const payload = verifyAccessToken(token);
|
|
556
534
|
if (payload) c.set("user", payload);
|
|
557
535
|
}
|
|
@@ -561,6 +539,7 @@ var optionalAuth = async (c, next) => {
|
|
|
561
539
|
* Extract user from token - for WebSocket authentication
|
|
562
540
|
*/
|
|
563
541
|
function extractUserFromToken(token) {
|
|
542
|
+
if (!isJwtConfigured()) return null;
|
|
564
543
|
return verifyAccessToken(token);
|
|
565
544
|
}
|
|
566
545
|
/**
|
|
@@ -711,7 +690,7 @@ function createAuthMiddleware(options) {
|
|
|
711
690
|
var queryTokenAuth = async (c, next) => {
|
|
712
691
|
if (extractBearerToken(c.req.header("authorization")) !== void 0) return next();
|
|
713
692
|
const queryToken = c.req.query("token");
|
|
714
|
-
if (queryToken) {
|
|
693
|
+
if (queryToken && isJwtConfigured()) {
|
|
715
694
|
const payload = verifyAccessToken(queryToken);
|
|
716
695
|
if (payload) c.set("user", payload);
|
|
717
696
|
}
|
|
@@ -1491,6 +1470,11 @@ async function finalizeAdminUserCreation(entity, clearPassword, ctx) {
|
|
|
1491
1470
|
var scryptAsync = promisify(scrypt);
|
|
1492
1471
|
var SALT_LENGTH = 32;
|
|
1493
1472
|
var KEY_LENGTH = 64;
|
|
1473
|
+
var SCRYPT_PARAMS = {
|
|
1474
|
+
N: 16384,
|
|
1475
|
+
r: 8,
|
|
1476
|
+
p: 1
|
|
1477
|
+
};
|
|
1494
1478
|
/**
|
|
1495
1479
|
* Password requirements:
|
|
1496
1480
|
* - Minimum 8 characters
|
|
@@ -1515,7 +1499,7 @@ function validatePasswordStrength(password) {
|
|
|
1515
1499
|
*/
|
|
1516
1500
|
async function hashPassword(password) {
|
|
1517
1501
|
const salt = randomBytes$1(SALT_LENGTH);
|
|
1518
|
-
const derivedKey = await scryptAsync(password, salt, KEY_LENGTH);
|
|
1502
|
+
const derivedKey = await scryptAsync(password, salt, KEY_LENGTH, SCRYPT_PARAMS);
|
|
1519
1503
|
return `${salt.toString("hex")}:${derivedKey.toString("hex")}`;
|
|
1520
1504
|
}
|
|
1521
1505
|
/**
|
|
@@ -1527,7 +1511,7 @@ async function verifyPassword(password, storedHash) {
|
|
|
1527
1511
|
if (!saltHex || !hashHex) return false;
|
|
1528
1512
|
const salt = Buffer.from(saltHex, "hex");
|
|
1529
1513
|
const storedKey = Buffer.from(hashHex, "hex");
|
|
1530
|
-
return timingSafeEqual(await scryptAsync(password, salt, KEY_LENGTH), storedKey);
|
|
1514
|
+
return timingSafeEqual(await scryptAsync(password, salt, KEY_LENGTH, SCRYPT_PARAMS), storedKey);
|
|
1531
1515
|
}
|
|
1532
1516
|
//#endregion
|
|
1533
1517
|
//#region src/auth/auth-hooks.ts
|
|
@@ -6168,7 +6152,7 @@ function mountSessionRoutes(opts) {
|
|
|
6168
6152
|
clearRefreshCookie(c, config.cookieAuth);
|
|
6169
6153
|
const accessToken = extractBearerToken(c.req.header("authorization"));
|
|
6170
6154
|
if (ops.afterLogout && accessToken !== void 0) {
|
|
6171
|
-
const { verifyAccessToken } = await import("./jwt-
|
|
6155
|
+
const { verifyAccessToken } = await import("./jwt-CzeviDcB.js").then((n) => n.d);
|
|
6172
6156
|
const payload = verifyAccessToken(accessToken);
|
|
6173
6157
|
if (payload) ops.afterLogout(payload.uid).catch((err) => {
|
|
6174
6158
|
logger.error("[AuthHooks] afterLogout error", { error: err instanceof Error ? err.message : err });
|
|
@@ -6549,11 +6533,6 @@ function createAuthRoutes(config) {
|
|
|
6549
6533
|
newPassword: string().min(1, "New password is required").max(128)
|
|
6550
6534
|
});
|
|
6551
6535
|
const refreshSchema = object({ refreshToken: string().min(1).optional() });
|
|
6552
|
-
object({ refreshToken: string().optional() });
|
|
6553
|
-
object({
|
|
6554
|
-
displayName: string().max(255).optional(),
|
|
6555
|
-
photoURL: string().url().max(2048).optional()
|
|
6556
|
-
});
|
|
6557
6536
|
/** Parse a Zod schema against the request body, throwing ApiError on failure */
|
|
6558
6537
|
function parseBody(schema, body) {
|
|
6559
6538
|
const result = schema.safeParse(body);
|
|
@@ -8624,6 +8603,7 @@ function createApiKeyStore(driver) {
|
|
|
8624
8603
|
ALTER TABLE ${TABLE}
|
|
8625
8604
|
ADD COLUMN IF NOT EXISTS admin BOOLEAN NOT NULL DEFAULT FALSE
|
|
8626
8605
|
`);
|
|
8606
|
+
await exec(revokeInternalTableSql("rebase", "api_keys"));
|
|
8627
8607
|
logger.info("✅ API keys table ready");
|
|
8628
8608
|
} catch (err) {
|
|
8629
8609
|
logger.error("❌ Failed to create API keys table", { error: err });
|
|
@@ -8939,6 +8919,7 @@ var auth_exports = /* @__PURE__ */ __exportAll({
|
|
|
8939
8919
|
hashToken: () => hashToken,
|
|
8940
8920
|
httpMethodToOperation: () => httpMethodToOperation,
|
|
8941
8921
|
isApiKeyToken: () => isApiKeyToken,
|
|
8922
|
+
isJwtConfigured: () => isJwtConfigured,
|
|
8942
8923
|
isOperationAllowed: () => isOperationAllowed,
|
|
8943
8924
|
mountMagicLinkRoutes: () => mountMagicLinkRoutes,
|
|
8944
8925
|
optionalAuth: () => optionalAuth,
|
|
@@ -8956,6 +8937,6 @@ var auth_exports = /* @__PURE__ */ __exportAll({
|
|
|
8956
8937
|
verifyPassword: () => verifyPassword
|
|
8957
8938
|
});
|
|
8958
8939
|
//#endregion
|
|
8959
|
-
export { httpMethodToOperation as $, getEmailVerificationTemplate as A, optionalAuth as B, createDataRateLimiter as C, validatePasswordStrength as D, hashPassword as E, createAdapterAuthMiddleware as F, createApiKeyPreAuth as G, queryTokenAuth as H, createAuthMiddleware as I, isApiKeyToken as J, createFunctionApiKeyGuard as K, createRequireAuth as L, getPasswordResetTemplate as M, getUserInvitationTemplate as N, verifyPassword as O, getWelcomeEmailTemplate as P, scopeDataDriver as Q, extractUserFromToken as R, _coercedNumber as S, resolveAuthHooks as T, requireAdmin as U, publicObjectAuth as V, requireAuth as W, extractBearerToken as X, validateApiKey as Y, safeCompare as Z, createBuiltinAuthAdapter as _, createSpotifyProvider as a, object as b, createGitLabProvider as c, createFacebookProvider as d, isOperationAllowed as et, createAppleProvider as f, createGoogleProvider as g, createLinkedinProvider as h, createApiKeyStore as i,
|
|
8940
|
+
export { httpMethodToOperation as $, getEmailVerificationTemplate as A, optionalAuth as B, createDataRateLimiter as C, validatePasswordStrength as D, hashPassword as E, createAdapterAuthMiddleware as F, createApiKeyPreAuth as G, queryTokenAuth as H, createAuthMiddleware as I, isApiKeyToken as J, createFunctionApiKeyGuard as K, createRequireAuth as L, getPasswordResetTemplate as M, getUserInvitationTemplate as N, verifyPassword as O, getWelcomeEmailTemplate as P, scopeDataDriver as Q, extractUserFromToken as R, _coercedNumber as S, resolveAuthHooks as T, requireAdmin as U, publicObjectAuth as V, requireAuth as W, extractBearerToken as X, validateApiKey as Y, safeCompare as Z, createBuiltinAuthAdapter as _, createSpotifyProvider as a, object as b, createGitLabProvider as c, createFacebookProvider as d, isOperationAllowed as et, createAppleProvider as f, createGoogleProvider as g, createLinkedinProvider as h, createApiKeyStore as i, getMagicLinkTemplate as j, generateSecurePassword as k, createDiscordProvider as l, createGitHubProvider as m, createCustomAuthAdapter as n, isPublicStoragePath as nt, createSlackProvider as o, createMicrosoftProvider as p, createStorageApiKeyGuard as q, createApiKeyRoutes as r, createBitbucketProvider as s, auth_exports as t, PUBLIC_STORAGE_PREFIX as tt, createTwitterProvider as u, ZodNumber as v, MemoryRateLimitStore as w, string as x, _enum as y, fileTokenAuth as z };
|
|
8960
8941
|
|
|
8961
|
-
//# sourceMappingURL=auth-
|
|
8942
|
+
//# sourceMappingURL=auth-CtxXQYV_.js.map
|