@rebasepro/server 0.14.1-canary.g7e666eb → 0.14.1
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/api/rest/query-parser.d.ts +22 -0
- package/dist/auth/index.d.ts +3 -1
- package/dist/auth/jwks-routes.d.ts +17 -0
- package/dist/auth/jwt-keys.d.ts +108 -0
- package/dist/auth/jwt.d.ts +32 -0
- package/dist/{auth-BQcdhMBL.js → auth-BobZVd0j.js} +82 -6
- package/dist/auth-BobZVd0j.js.map +1 -0
- package/dist/boot/boot.d.ts +36 -50
- package/dist/boot/ddl-bootstrap.d.ts +15 -0
- package/dist/boot/env.d.ts +20 -0
- package/dist/boot/provision.d.ts +182 -0
- package/dist/boot/role.d.ts +88 -0
- package/dist/{cron-store-D5dUNviq.js → cron-store-CB1x-Ken.js} +2 -2
- package/dist/{cron-store-D5dUNviq.js.map → cron-store-CB1x-Ken.js.map} +1 -1
- package/dist/{ddl-bootstrap-BhXbTnBl.js → ddl-bootstrap-Cywoj8Ta.js} +40 -2
- package/dist/{ddl-bootstrap-BhXbTnBl.js.map → ddl-bootstrap-Cywoj8Ta.js.map} +1 -1
- package/dist/env.d.ts +2 -0
- package/dist/functions/proxy.d.ts +41 -0
- package/dist/functions/selection.d.ts +45 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.es.js +815 -351
- package/dist/index.es.js.map +1 -1
- package/dist/init/shutdown.d.ts +4 -0
- package/dist/init/surfaces.d.ts +79 -0
- package/dist/init.d.ts +121 -1
- package/dist/jobs/index.d.ts +5 -0
- package/dist/jobs/job-queue.d.ts +14 -0
- package/dist/jobs/job-store.d.ts +22 -0
- package/dist/jobs/types.d.ts +125 -0
- package/dist/jobs-DR4SjGrD.js +326 -0
- package/dist/jobs-DR4SjGrD.js.map +1 -0
- package/dist/{jwt-CYGFT0ih.js → jwt-VJyXTdQQ.js} +152 -6
- package/dist/jwt-VJyXTdQQ.js.map +1 -0
- package/dist/{openapi-generator-BWL8F2La.js → openapi-generator-DQeQ_q2f.js} +45 -1
- package/dist/openapi-generator-DQeQ_q2f.js.map +1 -0
- package/dist/proxy-Bj5DVllb.js +139 -0
- package/dist/proxy-Bj5DVllb.js.map +1 -0
- package/dist/selection-_z6TM1DB.js +64 -0
- package/dist/selection-_z6TM1DB.js.map +1 -0
- package/dist/services/webhook-service.d.ts +43 -5
- package/dist/src-8XDWyDfR.js.map +1 -1
- package/package.json +5 -5
- package/dist/auth-BQcdhMBL.js.map +0 -1
- package/dist/jwt-CYGFT0ih.js.map +0 -1
- package/dist/openapi-generator-BWL8F2La.js.map +0 -1
|
@@ -15,6 +15,28 @@ type OrderByEntry = {
|
|
|
15
15
|
* `roles` alone and returned the ties in whatever order Postgres pleased.
|
|
16
16
|
*/
|
|
17
17
|
export declare function orderByEntriesToTuples(entries?: OrderByEntry[]): OrderByTuple[] | undefined;
|
|
18
|
+
export interface ParsedAggregate {
|
|
19
|
+
fn: "count" | "sum" | "avg" | "min" | "max";
|
|
20
|
+
/** Absent only for `count()`, which counts rows rather than values. */
|
|
21
|
+
field?: string;
|
|
22
|
+
/** The key this appears under in the response. */
|
|
23
|
+
alias: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse `?select=count(),sum(total),avg(total)`.
|
|
27
|
+
*
|
|
28
|
+
* The spelling is SQL's, because whoever writes it is thinking in SQL and
|
|
29
|
+
* because any other spelling has to be learned first. `count()` with no field
|
|
30
|
+
* counts rows; every other function names a column.
|
|
31
|
+
*
|
|
32
|
+
* Aliases are derived rather than accepted: `sum(total)` returns as
|
|
33
|
+
* `sum_total`, `count()` as `count`. Letting a caller choose would mean
|
|
34
|
+
* checking their alias is not also a `groupBy` field — a rule nobody would
|
|
35
|
+
* guess, and a silently overwritten value if it went unchecked.
|
|
36
|
+
*/
|
|
37
|
+
export declare function parseAggregateSelect(raw: unknown): ParsedAggregate[] | undefined;
|
|
38
|
+
/** Parse `?groupBy=status,country`. */
|
|
39
|
+
export declare function parseGroupBy(raw: unknown): string[] | undefined;
|
|
18
40
|
export { DEFAULT_LIST_LIMIT, DEFAULT_VECTOR_LIST_LIMIT, MAX_LIST_LIMIT } from "@rebasepro/types";
|
|
19
41
|
/**
|
|
20
42
|
* Overridable list-pagination bounds for {@link parseQueryOptions}. Without
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from "./interfaces";
|
|
2
|
-
export { configureJwt, isJwtConfigured, generateAccessToken, verifyAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry, generateDownloadToken, verifyDownloadToken } from "./jwt";
|
|
2
|
+
export { configureJwt, isJwtConfigured, generateAccessToken, verifyAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry, generateDownloadToken, verifyDownloadToken, getJwks, hasAsymmetricSigningKey } from "./jwt";
|
|
3
3
|
export type { JwtConfig, AccessTokenPayload, DownloadTokenPayload } from "./jwt";
|
|
4
|
+
export { createJwksRoutes } from "./jwks-routes";
|
|
5
|
+
export type { JwtSigningKeyConfig, JwtSigningAlgorithm, PublicJwk } from "./jwt-keys";
|
|
4
6
|
export { hashPassword, verifyPassword, validatePasswordStrength } from "./password";
|
|
5
7
|
export { safeCompare } from "./crypto-utils";
|
|
6
8
|
export type { PasswordValidationResult } from "./password";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import type { HonoEnv } from "../api/types";
|
|
3
|
+
/**
|
|
4
|
+
* `GET /.well-known/jwks.json` — the public keys that verify this issuer's
|
|
5
|
+
* access tokens.
|
|
6
|
+
*
|
|
7
|
+
* Deliberately unauthenticated and world-readable: the whole point is that a
|
|
8
|
+
* gateway, an edge function or a neighbouring service can check a Rebase token
|
|
9
|
+
* without being trusted with anything. Public keys are not a secret, and
|
|
10
|
+
* `jwt-keys.ts` derives what is served here from the public half of each pair.
|
|
11
|
+
*
|
|
12
|
+
* Mounted at the root rather than under `basePath`, because `/.well-known/` is
|
|
13
|
+
* where every verifier looks — an issuer of `https://api.example.com` implies
|
|
14
|
+
* `https://api.example.com/.well-known/jwks.json`, whatever the API happens to
|
|
15
|
+
* be prefixed with.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createJwksRoutes(): Hono<HonoEnv>;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { type KeyObject } from "crypto";
|
|
2
|
+
/**
|
|
3
|
+
* Asymmetric signing keys for access tokens, and the JWKS built from them.
|
|
4
|
+
*
|
|
5
|
+
* The symmetric secret this replaces is not going away — it still signs every
|
|
6
|
+
* purpose-scoped token (download, MFA-pending, password reset), which are read
|
|
7
|
+
* only by the server that minted them and are better off short. What a shared
|
|
8
|
+
* secret cannot do is let *anybody else* verify a session:
|
|
9
|
+
*
|
|
10
|
+
* - a gateway, an edge worker, or a second service that wants to check a token
|
|
11
|
+
* has to be handed the key that mints them, so every verifier becomes a
|
|
12
|
+
* forger;
|
|
13
|
+
* - and rotating it invalidates every token in circulation at once, which is
|
|
14
|
+
* why in practice it never gets rotated at all.
|
|
15
|
+
*
|
|
16
|
+
* A private key signs, the matching public key verifies, and the public half is
|
|
17
|
+
* published at `/.well-known/jwks.json` for anyone to fetch. Rotation stops
|
|
18
|
+
* being an outage: mint with the new key, keep the old one in the list until
|
|
19
|
+
* the last token signed by it has expired, then drop it.
|
|
20
|
+
*
|
|
21
|
+
* **The key is chosen by `kid`, and the algorithm comes from the key — never
|
|
22
|
+
* from the token.** A verifier that reads `alg` out of the header it is
|
|
23
|
+
* checking will accept an `HS256` token whose "secret" is the RSA public key it
|
|
24
|
+
* published, which is a complete authentication bypass and the best-known way
|
|
25
|
+
* to get this wrong. {@link resolveVerificationKey} therefore returns the
|
|
26
|
+
* algorithm alongside the key, and the caller pins it.
|
|
27
|
+
*/
|
|
28
|
+
/** The algorithms a signing key may use. Both are widely supported by verifiers. */
|
|
29
|
+
export type JwtSigningAlgorithm = "RS256" | "ES256";
|
|
30
|
+
/**
|
|
31
|
+
* One asymmetric key pair, as an operator configures it.
|
|
32
|
+
*
|
|
33
|
+
* Only the private key is supplied: the public half is derived from it, so a
|
|
34
|
+
* mismatched pair — a configuration error that produces tokens nobody can
|
|
35
|
+
* verify, and which no amount of local testing catches because the signer never
|
|
36
|
+
* consults the public key — cannot be expressed.
|
|
37
|
+
*/
|
|
38
|
+
export interface JwtSigningKeyConfig {
|
|
39
|
+
/**
|
|
40
|
+
* Names this key in the token header and in the JWKS. Any stable string;
|
|
41
|
+
* something that identifies *when* it was minted (`"2026-08"`) is the usual
|
|
42
|
+
* choice, because the question you ask of a `kid` later is always "is this
|
|
43
|
+
* the old one?".
|
|
44
|
+
*/
|
|
45
|
+
kid: string;
|
|
46
|
+
/** PEM-encoded PKCS#8 or SEC1 private key. */
|
|
47
|
+
privateKey: string;
|
|
48
|
+
/**
|
|
49
|
+
* Defaults to the algorithm implied by the key type — RSA keys sign RS256,
|
|
50
|
+
* EC keys sign ES256. Worth setting only to be explicit.
|
|
51
|
+
*/
|
|
52
|
+
algorithm?: JwtSigningAlgorithm;
|
|
53
|
+
}
|
|
54
|
+
/** A configured key, parsed and ready to sign or verify with. */
|
|
55
|
+
export interface ResolvedJwtKey {
|
|
56
|
+
kid: string;
|
|
57
|
+
algorithm: JwtSigningAlgorithm;
|
|
58
|
+
privateKey: KeyObject;
|
|
59
|
+
publicKey: KeyObject;
|
|
60
|
+
}
|
|
61
|
+
/** A JSON Web Key, as served by the JWKS endpoint. Public parameters only. */
|
|
62
|
+
export type PublicJwk = Record<string, unknown> & {
|
|
63
|
+
kid: string;
|
|
64
|
+
alg: JwtSigningAlgorithm;
|
|
65
|
+
use: "sig";
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Parse the configured keys, deriving each public half from its private key.
|
|
69
|
+
*
|
|
70
|
+
* Throws on anything malformed. This runs at boot, from `configureJwt`, so a
|
|
71
|
+
* key that cannot sign takes the process down at start rather than at the first
|
|
72
|
+
* login — the same bargain every other credential in this file makes.
|
|
73
|
+
*/
|
|
74
|
+
export declare function resolveSigningKeys(configs: JwtSigningKeyConfig[]): ResolvedJwtKey[];
|
|
75
|
+
/**
|
|
76
|
+
* The key a token names, or `null` if it names none we hold.
|
|
77
|
+
*
|
|
78
|
+
* The returned algorithm is the *key's*, and the caller must verify with that
|
|
79
|
+
* one alone. See the module docblock for what happens otherwise.
|
|
80
|
+
*/
|
|
81
|
+
export declare function resolveVerificationKey(keys: ResolvedJwtKey[], kid: string | undefined): ResolvedJwtKey | null;
|
|
82
|
+
/**
|
|
83
|
+
* A PEM as an environment variable can actually carry it.
|
|
84
|
+
*
|
|
85
|
+
* A PEM is multi-line and environment variables are not, so every deployment
|
|
86
|
+
* tool solves it differently: `.env` files and most secret managers escape the
|
|
87
|
+
* newlines to `\n`, Kubernetes and Docker secrets pass the bytes through
|
|
88
|
+
* intact, and CI systems that mangle both are usually fed base64. All three
|
|
89
|
+
* arrive here, and guessing wrong produces "not a readable PEM private key" at
|
|
90
|
+
* boot with a key the operator can see is perfectly valid.
|
|
91
|
+
*
|
|
92
|
+
* Detection is on content, not on a flag: a PEM says so on its first line, and
|
|
93
|
+
* anything that does not is tried as base64.
|
|
94
|
+
*/
|
|
95
|
+
export declare function normalizePemFromEnv(value: string): string;
|
|
96
|
+
/**
|
|
97
|
+
* The public halves, in JWKS form.
|
|
98
|
+
*
|
|
99
|
+
* Node exports a JWK containing only public parameters for a public
|
|
100
|
+
* `KeyObject` — no `d`, no primes — so the private material cannot leak
|
|
101
|
+
* through this path even if a private key were passed by mistake. The keys are
|
|
102
|
+
* derived from `publicKey` regardless, and this is asserted in the tests,
|
|
103
|
+
* because "cannot" is worth checking on the one endpoint whose entire job is to
|
|
104
|
+
* be world-readable.
|
|
105
|
+
*/
|
|
106
|
+
export declare function toJwks(keys: ResolvedJwtKey[]): {
|
|
107
|
+
keys: PublicJwk[];
|
|
108
|
+
};
|
package/dist/auth/jwt.d.ts
CHANGED
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
import { type JwtSigningKeyConfig, type PublicJwk } from "./jwt-keys";
|
|
1
2
|
export interface JwtConfig {
|
|
2
3
|
secret: string;
|
|
3
4
|
accessExpiresIn?: string;
|
|
4
5
|
refreshExpiresIn?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Asymmetric keys for signing **access tokens**, newest first.
|
|
8
|
+
*
|
|
9
|
+
* Optional and additive: with none configured everything below behaves
|
|
10
|
+
* exactly as it did, signing HS256 with {@link JwtConfig.secret}. With one
|
|
11
|
+
* configured, access tokens are signed by {@link JwtConfig.activeKid} (or
|
|
12
|
+
* the first entry) and carry its `kid`, and every key in the list keeps
|
|
13
|
+
* verifying — which is what makes rotation a deploy rather than a mass
|
|
14
|
+
* sign-out. Tokens minted before any key existed carry no `kid` and are
|
|
15
|
+
* still verified against the secret until they expire.
|
|
16
|
+
*
|
|
17
|
+
* The secret stays required regardless: purpose-scoped tokens (download,
|
|
18
|
+
* MFA-pending, password reset) are read only by this server, and are
|
|
19
|
+
* shorter and cheaper symmetric. See `jwt-keys.ts`.
|
|
20
|
+
*/
|
|
21
|
+
signingKeys?: JwtSigningKeyConfig[];
|
|
22
|
+
/** Which key signs. Defaults to the first entry of {@link JwtConfig.signingKeys}. */
|
|
23
|
+
activeKid?: string;
|
|
5
24
|
}
|
|
6
25
|
export interface AccessTokenPayload {
|
|
7
26
|
/**
|
|
@@ -42,6 +61,19 @@ export interface AccessTokenPayload {
|
|
|
42
61
|
* Validates the secret strength to prevent deployment with default/weak secrets.
|
|
43
62
|
*/
|
|
44
63
|
export declare function configureJwt(config: JwtConfig): void;
|
|
64
|
+
/**
|
|
65
|
+
* The public keys, in JWKS form, for `/.well-known/jwks.json`.
|
|
66
|
+
*
|
|
67
|
+
* An empty `keys` array on a backend with no asymmetric keys configured is the
|
|
68
|
+
* correct answer rather than a 404: it says "this issuer publishes none",
|
|
69
|
+
* which a verifier can act on, where a 404 is indistinguishable from a
|
|
70
|
+
* misconfigured URL.
|
|
71
|
+
*/
|
|
72
|
+
export declare function getJwks(): {
|
|
73
|
+
keys: PublicJwk[];
|
|
74
|
+
};
|
|
75
|
+
/** Is this backend signing access tokens asymmetrically? */
|
|
76
|
+
export declare function hasAsymmetricSigningKey(): boolean;
|
|
45
77
|
/**
|
|
46
78
|
* Has this server been given a JWT secret?
|
|
47
79
|
*
|
|
@@ -4,8 +4,8 @@ __createRequire(import.meta.url);
|
|
|
4
4
|
import { i as __toESM, n as __exportAll } from "./rolldown-runtime-DSJWtz9O.js";
|
|
5
5
|
import { C as ListLimitError, D as isAnonymousUid, E as ANONYMOUS_USER_ID, T as resolveClientListLimit, a as deserializeLogicalCondition, i as deserializeFilter, r as UnknownFilterOperatorError } from "./src-8XDWyDfR.js";
|
|
6
6
|
import "./src-Cz9nMgUR.js";
|
|
7
|
-
import {
|
|
8
|
-
import { S as require_jsonwebtoken, a as generateMfaPendingToken, c as
|
|
7
|
+
import { n as createDdlBootstrapper, o as revokeInternalTableSql, s as isSQLAdmin } from "./ddl-bootstrap-Cywoj8Ta.js";
|
|
8
|
+
import { S as canonicalStorageId, T as require_jsonwebtoken, _ as verifyMfaPendingToken, a as generateMfaPendingToken, c as getJwks, d as hasAsymmetricSigningKey, f as hashRefreshToken, g as verifyDownloadToken, h as verifyAccessToken, i as generateDownloadToken, l as getRefreshTokenExpiry, n as configureJwt, o as generateRefreshToken, p as isJwtConfigured, r as generateAccessToken, s as getAccessTokenExpiry, t as MAX_COOKIE_AGE_MS, u as getRefreshTokenTtlMs, w as tryCanonicalStorageKey } from "./jwt-VJyXTdQQ.js";
|
|
9
9
|
import { t as logger } from "./logger-DfvF_8r-.js";
|
|
10
10
|
import { n as errorHandler, t as ApiError } from "./errors-EBYiaJ2E.js";
|
|
11
11
|
import { createHash, randomBytes, randomInt } from "node:crypto";
|
|
@@ -187,6 +187,52 @@ function orderByEntriesToTuples(entries) {
|
|
|
187
187
|
function invalidOrderBy(detail) {
|
|
188
188
|
throw invalidParam(`Invalid \`orderBy\` parameter: ${detail}. Expected \`field\`, \`field:desc\`, or a JSON array like [{"field":"created_at","direction":"desc"}]`, "INVALID_ORDER_BY");
|
|
189
189
|
}
|
|
190
|
+
/** The aggregate functions `?select=` accepts. */
|
|
191
|
+
var AGGREGATE_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
192
|
+
"count",
|
|
193
|
+
"sum",
|
|
194
|
+
"avg",
|
|
195
|
+
"min",
|
|
196
|
+
"max"
|
|
197
|
+
]);
|
|
198
|
+
/**
|
|
199
|
+
* Parse `?select=count(),sum(total),avg(total)`.
|
|
200
|
+
*
|
|
201
|
+
* The spelling is SQL's, because whoever writes it is thinking in SQL and
|
|
202
|
+
* because any other spelling has to be learned first. `count()` with no field
|
|
203
|
+
* counts rows; every other function names a column.
|
|
204
|
+
*
|
|
205
|
+
* Aliases are derived rather than accepted: `sum(total)` returns as
|
|
206
|
+
* `sum_total`, `count()` as `count`. Letting a caller choose would mean
|
|
207
|
+
* checking their alias is not also a `groupBy` field — a rule nobody would
|
|
208
|
+
* guess, and a silently overwritten value if it went unchecked.
|
|
209
|
+
*/
|
|
210
|
+
function parseAggregateSelect(raw) {
|
|
211
|
+
const value = getLastValue(raw);
|
|
212
|
+
if (!value) return void 0;
|
|
213
|
+
const entries = String(value).split(",").map((s) => s.trim()).filter(Boolean);
|
|
214
|
+
if (entries.length === 0) return void 0;
|
|
215
|
+
return entries.map((entry) => {
|
|
216
|
+
const match = /^([a-z]+)\(\s*([A-Za-z0-9_]*)\s*\)$/i.exec(entry);
|
|
217
|
+
if (!match) throw invalidParam(`Invalid \`select\` entry "${entry}". Expected \`fn(field)\`, e.g. \`sum(total)\` or \`count()\`.`, "INVALID_AGGREGATE_SELECT");
|
|
218
|
+
const fn = match[1].toLowerCase();
|
|
219
|
+
const field = match[2] || void 0;
|
|
220
|
+
if (!AGGREGATE_FUNCTIONS.has(fn)) throw invalidParam(`Unknown aggregate function "${fn}". Expected: ${[...AGGREGATE_FUNCTIONS].join(", ")}.`, "INVALID_AGGREGATE_FUNCTION");
|
|
221
|
+
if (fn !== "count" && !field) throw invalidParam(`\`${fn}()\` needs a field, e.g. \`${fn}(total)\`. Only \`count()\` may be empty.`, "INVALID_AGGREGATE_SELECT");
|
|
222
|
+
return {
|
|
223
|
+
fn,
|
|
224
|
+
field,
|
|
225
|
+
alias: field ? `${fn}_${field}` : fn
|
|
226
|
+
};
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/** Parse `?groupBy=status,country`. */
|
|
230
|
+
function parseGroupBy(raw) {
|
|
231
|
+
const value = getLastValue(raw);
|
|
232
|
+
if (!value) return void 0;
|
|
233
|
+
const fields = String(value).split(",").map((s) => s.trim()).filter(Boolean);
|
|
234
|
+
return fields.length > 0 ? fields : void 0;
|
|
235
|
+
}
|
|
190
236
|
/** `asc`/`desc`, in any case. Anything else is a request to sort in a way that does not exist. */
|
|
191
237
|
function toDirection(raw, context) {
|
|
192
238
|
if (raw === void 0 || raw === null) return "asc";
|
|
@@ -311,7 +357,9 @@ function parseQueryOptions(query, limits = {}) {
|
|
|
311
357
|
"vector_threshold",
|
|
312
358
|
"or",
|
|
313
359
|
"and",
|
|
314
|
-
"where"
|
|
360
|
+
"where",
|
|
361
|
+
"select",
|
|
362
|
+
"groupBy"
|
|
315
363
|
];
|
|
316
364
|
const filterDict = {};
|
|
317
365
|
for (const [key, rawValue] of Object.entries(query)) {
|
|
@@ -7318,7 +7366,7 @@ function mountSessionRoutes(opts) {
|
|
|
7318
7366
|
clearRefreshCookie(c, config.cookieAuth);
|
|
7319
7367
|
const accessToken = extractBearerToken(c.req.header("authorization"));
|
|
7320
7368
|
if (ops.afterLogout && accessToken !== void 0) {
|
|
7321
|
-
const { verifyAccessToken } = await import("./jwt-
|
|
7369
|
+
const { verifyAccessToken } = await import("./jwt-VJyXTdQQ.js").then((n) => n.m);
|
|
7322
7370
|
const payload = verifyAccessToken(accessToken);
|
|
7323
7371
|
if (payload) ops.afterLogout(payload.uid).catch((err) => {
|
|
7324
7372
|
logger.error("[AuthHooks] afterLogout error", { error: err instanceof Error ? err.message : err });
|
|
@@ -8948,6 +8996,31 @@ function toAuthUserData(user) {
|
|
|
8948
8996
|
};
|
|
8949
8997
|
}
|
|
8950
8998
|
//#endregion
|
|
8999
|
+
//#region src/auth/jwks-routes.ts
|
|
9000
|
+
/**
|
|
9001
|
+
* `GET /.well-known/jwks.json` — the public keys that verify this issuer's
|
|
9002
|
+
* access tokens.
|
|
9003
|
+
*
|
|
9004
|
+
* Deliberately unauthenticated and world-readable: the whole point is that a
|
|
9005
|
+
* gateway, an edge function or a neighbouring service can check a Rebase token
|
|
9006
|
+
* without being trusted with anything. Public keys are not a secret, and
|
|
9007
|
+
* `jwt-keys.ts` derives what is served here from the public half of each pair.
|
|
9008
|
+
*
|
|
9009
|
+
* Mounted at the root rather than under `basePath`, because `/.well-known/` is
|
|
9010
|
+
* where every verifier looks — an issuer of `https://api.example.com` implies
|
|
9011
|
+
* `https://api.example.com/.well-known/jwks.json`, whatever the API happens to
|
|
9012
|
+
* be prefixed with.
|
|
9013
|
+
*/
|
|
9014
|
+
function createJwksRoutes() {
|
|
9015
|
+
const router = new Hono();
|
|
9016
|
+
router.get("/jwks.json", (c) => {
|
|
9017
|
+
const jwks = getJwks();
|
|
9018
|
+
c.header("Cache-Control", "public, max-age=300");
|
|
9019
|
+
return c.json(jwks);
|
|
9020
|
+
});
|
|
9021
|
+
return router;
|
|
9022
|
+
}
|
|
9023
|
+
//#endregion
|
|
8951
9024
|
//#region src/auth/oauth-code-flow.ts
|
|
8952
9025
|
/**
|
|
8953
9026
|
* Build the request schema for an authorization-code provider.
|
|
@@ -10377,6 +10450,7 @@ var auth_exports = /* @__PURE__ */ __exportAll({
|
|
|
10377
10450
|
createGitHubProvider: () => createGitHubProvider,
|
|
10378
10451
|
createGitLabProvider: () => createGitLabProvider,
|
|
10379
10452
|
createGoogleProvider: () => createGoogleProvider,
|
|
10453
|
+
createJwksRoutes: () => createJwksRoutes,
|
|
10380
10454
|
createLinkedinProvider: () => createLinkedinProvider,
|
|
10381
10455
|
createMicrosoftProvider: () => createMicrosoftProvider,
|
|
10382
10456
|
createRateLimiter: () => createRateLimiter,
|
|
@@ -10395,7 +10469,9 @@ var auth_exports = /* @__PURE__ */ __exportAll({
|
|
|
10395
10469
|
generateSecurePassword: () => generateSecurePassword,
|
|
10396
10470
|
generateSecureToken: () => generateSecureToken,
|
|
10397
10471
|
getAccessTokenExpiry: () => getAccessTokenExpiry,
|
|
10472
|
+
getJwks: () => getJwks,
|
|
10398
10473
|
getRefreshTokenExpiry: () => getRefreshTokenExpiry,
|
|
10474
|
+
hasAsymmetricSigningKey: () => hasAsymmetricSigningKey,
|
|
10399
10475
|
hashPassword: () => hashPassword,
|
|
10400
10476
|
hashRefreshToken: () => hashRefreshToken,
|
|
10401
10477
|
hashToken: () => hashToken,
|
|
@@ -10425,6 +10501,6 @@ var auth_exports = /* @__PURE__ */ __exportAll({
|
|
|
10425
10501
|
verifyPassword: () => verifyPassword
|
|
10426
10502
|
});
|
|
10427
10503
|
//#endregion
|
|
10428
|
-
export {
|
|
10504
|
+
export { extractUserFromToken as $, createDataRateLimiter as A, generateSecurePassword as B, createBuiltinAuthAdapter as C, isPublicStoragePath as Ct, string as D, object as E, resolveEmailLinkBase as F, getWelcomeEmailTemplate as G, getMagicLinkTemplate as H, resolveAuthHooks as I, html as J, RawHtml as K, hashPassword as L, SMTPEmailService as M, createEmailService as N, _coercedNumber as O, assertEmailLinkBases as P, createRequireAuth as Q, validatePasswordStrength as R, createJwksRoutes as S, PUBLIC_STORAGE_PREFIX as St, _enum as T, getPasswordResetTemplate as U, getEmailVerificationTemplate as V, getUserInvitationTemplate as W, createAdapterAuthMiddleware as X, raw as Y, createAuthMiddleware as Z, createLinkedinProvider as _, orderByEntriesToTuples as _t, createSpotifyProvider as a, requireAuth as at, pkceTokenParams as b, parseQueryOptions as bt, createGitLabProvider as c, createStorageApiKeyGuard as ct, createFacebookProvider as d, extractBearerToken as dt, fileTokenAuth as et, createAppleProvider as f, safeCompare as ft, createGitHubProvider as g, isOperationAllowed as gt, verifyOidcIdToken as h, httpMethodToOperation as ht, createApiKeyStore as i, requireAdmin as it, MemoryRateLimitStore as j, DEFAULT_FUNCTIONS_ANONYMOUS_LIMIT as k, createDiscordProvider as l, isApiKeyToken as lt, tryVerifyOidcIdToken as m, scopeDataDriver as mt, createCustomAuthAdapter as n, publicObjectAuth as nt, createSlackProvider as o, createApiKeyPreAuth as ot, createMicrosoftProvider as p, SERVICE_IDENTITY as pt, escapeHtml as q, createApiKeyRoutes as r, queryTokenAuth as rt, createBitbucketProvider as s, createFunctionApiKeyGuard as st, auth_exports as t, optionalAuth as tt, createTwitterProvider as u, validateApiKey as ut, createGoogleProvider as v, parseAggregateSelect as vt, ZodNumber as w, providerVerifiedEmail as x, resolveListLimitParam as xt, oauthCodeFlowSchema as y, parseGroupBy as yt, verifyPassword as z };
|
|
10429
10505
|
|
|
10430
|
-
//# sourceMappingURL=auth-
|
|
10506
|
+
//# sourceMappingURL=auth-BobZVd0j.js.map
|