@browserlessapi/inferlo 0.7.0 → 0.8.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.
Files changed (78) hide show
  1. package/README.md +3 -2
  2. package/dist/app.d.ts +24 -0
  3. package/dist/app.js +336 -13
  4. package/dist/app.js.map +1 -1
  5. package/dist/authjs.d.ts +70 -0
  6. package/dist/authjs.js +94 -0
  7. package/dist/authjs.js.map +1 -0
  8. package/dist/better-auth.d.ts +89 -0
  9. package/dist/better-auth.js +75 -0
  10. package/dist/better-auth.js.map +1 -0
  11. package/dist/cli/main.js +1 -1
  12. package/dist/cli/main.js.map +1 -1
  13. package/dist/client-ip.d.ts +5 -0
  14. package/dist/client-ip.js +5 -0
  15. package/dist/client-ip.js.map +1 -1
  16. package/dist/cross-site.d.ts +14 -0
  17. package/dist/cross-site.js +56 -0
  18. package/dist/cross-site.js.map +1 -0
  19. package/dist/db/postgres.js +19 -5
  20. package/dist/db/postgres.js.map +1 -1
  21. package/dist/describe.d.ts +9 -2
  22. package/dist/describe.js +11 -1
  23. package/dist/describe.js.map +1 -1
  24. package/dist/disk-storage.d.ts +6 -0
  25. package/dist/disk-storage.js +96 -0
  26. package/dist/disk-storage.js.map +1 -0
  27. package/dist/files.d.ts +23 -0
  28. package/dist/files.js +168 -0
  29. package/dist/files.js.map +1 -0
  30. package/dist/index.d.ts +15 -4
  31. package/dist/index.js +6 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/jobs.d.ts +10 -4
  34. package/dist/jobs.js +7 -2
  35. package/dist/jobs.js.map +1 -1
  36. package/dist/jwt.d.ts +83 -0
  37. package/dist/jwt.js +312 -0
  38. package/dist/jwt.js.map +1 -0
  39. package/dist/model.js +6 -1
  40. package/dist/model.js.map +1 -1
  41. package/dist/oidc.d.ts +70 -0
  42. package/dist/oidc.js +379 -0
  43. package/dist/oidc.js.map +1 -0
  44. package/dist/openapi.js +17 -2
  45. package/dist/openapi.js.map +1 -1
  46. package/dist/passport.d.ts +54 -0
  47. package/dist/passport.js +68 -0
  48. package/dist/passport.js.map +1 -0
  49. package/dist/postgres-js.d.ts +39 -0
  50. package/dist/postgres-js.js +71 -0
  51. package/dist/postgres-js.js.map +1 -0
  52. package/dist/redis-sockets.d.ts +24 -0
  53. package/dist/redis-sockets.js +75 -0
  54. package/dist/redis-sockets.js.map +1 -0
  55. package/dist/route.d.ts +103 -2
  56. package/dist/route.js +27 -0
  57. package/dist/route.js.map +1 -1
  58. package/dist/schema.d.ts +21 -1
  59. package/dist/schema.js +70 -0
  60. package/dist/schema.js.map +1 -1
  61. package/dist/serve.d.ts +18 -0
  62. package/dist/serve.js +137 -2
  63. package/dist/serve.js.map +1 -1
  64. package/dist/sessions.js +35 -4
  65. package/dist/sessions.js.map +1 -1
  66. package/dist/sockets.d.ts +58 -0
  67. package/dist/sockets.js +111 -0
  68. package/dist/sockets.js.map +1 -0
  69. package/dist/storage.d.ts +47 -0
  70. package/dist/storage.js +123 -0
  71. package/dist/storage.js.map +1 -0
  72. package/dist/websocket.d.ts +81 -0
  73. package/dist/websocket.js +251 -0
  74. package/dist/websocket.js.map +1 -0
  75. package/llms.txt +1 -0
  76. package/package.json +43 -3
  77. package/templates/app/AGENTS.md +5 -3
  78. package/templates/app/test/notes.test.ts +2 -0
package/dist/jwt.d.ts ADDED
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Access tokens (JWTs) from an OpenID Connect provider as the app's auth: Auth0, Okta, Microsoft Entra ID, Google,
3
+ * Keycloak, Clerk, WorkOS, Cognito, Supabase and any other issuer that publishes its signing keys (JWKS).
4
+ *
5
+ * createApp({
6
+ * auth: jwt({
7
+ * issuer: "https://acme.eu.auth0.com/",
8
+ * audience: "https://api.acme.com",
9
+ * user: (claims) => ({ id: claims.sub, email: claims.email, roles: claims.permissions ?? [] }),
10
+ * }),
11
+ * });
12
+ *
13
+ * Requests send "Authorization: Bearer <token>". The signature is checked with Web Crypto against the issuer's
14
+ * keys (found through its OpenID configuration, or jwksUrl), then the issuer, audience, expiry and not-before
15
+ * times. Tokens that fail any check sign nobody in (401). No runtime dependencies; runs on every runtime.
16
+ */
17
+ import type { AuthConfig } from "./app.ts";
18
+ import type { AppDb, AppUser } from "./route.ts";
19
+ /** The claims of a verified token. Providers add their own (email, roles, permissions, org_id, scope, ...). */
20
+ export interface JwtClaims {
21
+ /** The user (subject) the token was issued for. */
22
+ sub: string;
23
+ iss: string;
24
+ aud: string | string[];
25
+ exp: number;
26
+ iat?: number;
27
+ nbf?: number;
28
+ [claim: string]: unknown;
29
+ }
30
+ export type JwtAlgorithm = "RS256" | "RS384" | "RS512" | "PS256" | "PS384" | "PS512" | "ES256" | "ES384" | "ES512" | "EdDSA" | "Ed25519" | "HS256" | "HS384" | "HS512";
31
+ export interface JwtOptions {
32
+ /** The issuer (the iss claim) exactly as the provider writes it, such as "https://acme.eu.auth0.com/". */
33
+ issuer: string;
34
+ /** The audience (aud claim) this API accepts: its identifier at the provider. A list accepts any of them. */
35
+ audience: string | string[];
36
+ /**
37
+ * Where the issuer's signing keys are (a JSON Web Key Set). Default: the jwks_uri of the issuer's OpenID
38
+ * configuration (<issuer>/.well-known/openid-configuration). Must be https, except on localhost.
39
+ */
40
+ jwksUrl?: string;
41
+ /** For providers that sign with a shared secret (HS256), at least 32 characters, instead of keys. */
42
+ secret?: string;
43
+ /** Algorithms to accept. Default: every asymmetric algorithm (RS, PS, ES, EdDSA), or HS256 with secret. */
44
+ algorithms?: JwtAlgorithm[];
45
+ /** The app's user for a verified token, or null to refuse it. Default: { id: sub, email, name, roles }. */
46
+ user?: (claims: JwtClaims, ctx: {
47
+ db: AppDb;
48
+ req: Request;
49
+ }) => AppUser | null | undefined | Promise<AppUser | null | undefined>;
50
+ /** Allowed clock difference with the issuer, in seconds, for exp, nbf and iat. Default 60, at most 300. */
51
+ clockToleranceSeconds?: number;
52
+ /** How long fetched keys are kept, in milliseconds. Default 10 minutes, from 1 minute to 1 day. */
53
+ cacheMs?: number;
54
+ /** Roles of a user, checked when a route uses auth: "<role>". Default: user.roles ?? []. */
55
+ roles?: (user: AppUser) => string[];
56
+ /** The tenant of a user, for tenant-scoped models. Default: user.tenantId. */
57
+ tenant?: (user: AppUser) => string | null | undefined;
58
+ }
59
+ export declare const ASYMMETRIC: JwtAlgorithm[];
60
+ export declare function isLocal(url: URL): boolean;
61
+ /**
62
+ * The app's auth from access tokens (JWTs) of an OpenID Connect provider: createApp({ auth: jwt({ issuer,
63
+ * audience }) }). Requests send Authorization: Bearer <token>.
64
+ */
65
+ export declare function jwt(options: JwtOptions): AuthConfig;
66
+ /** What createJwtVerifier needs: the checked options of jwt(), or of oidc() for ID tokens. */
67
+ export interface JwtVerifierConfig {
68
+ issuer: string;
69
+ audiences: string[];
70
+ secret?: string;
71
+ allowed: JwtAlgorithm[];
72
+ tolerance: number;
73
+ cacheMs: number;
74
+ jwksUrl?: string;
75
+ /** Finds the key set's URL another way (oidc() shares its OpenID configuration). Default: the issuer's discovery. */
76
+ discoverJwksUrl?: () => Promise<string>;
77
+ }
78
+ /**
79
+ * Verifies JWTs for an issuer and audience: the signature against the issuer's keys (cached, fetched again for a
80
+ * rotated key) or a shared secret, then iss, aud, exp, nbf, iat and sub. Resolves to the claims, or null for any
81
+ * token that is not valid. Throws 503 IL3008 when no keys could ever be loaded. Internal: used by jwt() and oidc().
82
+ */
83
+ export declare function createJwtVerifier(config: JwtVerifierConfig): (token: string) => Promise<JwtClaims | null>;
package/dist/jwt.js ADDED
@@ -0,0 +1,312 @@
1
+ import { InferloError } from "./errors.js";
2
+ export const ASYMMETRIC = ["RS256", "RS384", "RS512", "PS256", "PS384", "PS512", "ES256", "ES384", "ES512", "EdDSA", "Ed25519"];
3
+ const HMAC = ["HS256", "HS384", "HS512"];
4
+ const OPTIONS = ["issuer", "audience", "jwksUrl", "secret", "algorithms", "user", "clockToleranceSeconds", "cacheMs", "roles", "tenant"];
5
+ const MAX_TOKEN = 16 * 1024;
6
+ const FETCH_TIMEOUT = 5000;
7
+ /** A token with an unknown key id fetches the keys again, but not more often than this. */
8
+ const REFETCH_COOLDOWN = 30_000;
9
+ const fix = 'Use jwt({ issuer: "https://login.example.com/", audience: "https://api.example.com" }), with the issuer and audience your identity provider shows for this API.';
10
+ function invalid(message, fixText = fix) {
11
+ return new InferloError("IL6042", message, { fix: fixText });
12
+ }
13
+ export function isLocal(url) {
14
+ return ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname);
15
+ }
16
+ function checkUrl(value, what) {
17
+ let url;
18
+ try {
19
+ url = new URL(value);
20
+ }
21
+ catch {
22
+ throw invalid(`jwt() ${what} must be a URL, got ${JSON.stringify(value)}.`);
23
+ }
24
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && isLocal(url))) {
25
+ throw invalid(`jwt() ${what} must use https (plain http only on localhost), got ${JSON.stringify(value)}.`);
26
+ }
27
+ return url;
28
+ }
29
+ function base64urlBytes(text) {
30
+ if (!/^[A-Za-z0-9_-]*$/.test(text))
31
+ throw new Error("not base64url");
32
+ const base64 = text.replace(/-/g, "+").replace(/_/g, "/") + "===".slice((text.length + 3) % 4);
33
+ return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
34
+ }
35
+ function decodeJson(text) {
36
+ const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(base64urlBytes(text)));
37
+ if (!value || typeof value !== "object" || Array.isArray(value))
38
+ throw new Error("not an object");
39
+ return value;
40
+ }
41
+ const HASH = { "256": "SHA-256", "384": "SHA-384", "512": "SHA-512" };
42
+ /** Web Crypto import and verify parameters for an algorithm, or null when the key does not fit it. */
43
+ function cryptoParams(alg, jwk) {
44
+ const bits = alg.slice(2);
45
+ if (alg.startsWith("RS")) {
46
+ if (jwk && jwk.kty !== "RSA")
47
+ return null;
48
+ return { importAlg: { name: "RSASSA-PKCS1-v1_5", hash: HASH[bits] }, verifyAlg: { name: "RSASSA-PKCS1-v1_5" } };
49
+ }
50
+ if (alg.startsWith("PS")) {
51
+ if (jwk && jwk.kty !== "RSA")
52
+ return null;
53
+ return { importAlg: { name: "RSA-PSS", hash: HASH[bits] }, verifyAlg: { name: "RSA-PSS", saltLength: Number(bits) / 8 } };
54
+ }
55
+ if (alg.startsWith("ES")) {
56
+ const curve = { ES256: "P-256", ES384: "P-384", ES512: "P-521" }[alg];
57
+ if (jwk && (jwk.kty !== "EC" || jwk.crv !== curve))
58
+ return null;
59
+ return { importAlg: { name: "ECDSA", namedCurve: curve }, verifyAlg: { name: "ECDSA", hash: HASH[bits] } };
60
+ }
61
+ if (alg === "EdDSA" || alg === "Ed25519") {
62
+ if (jwk && (jwk.kty !== "OKP" || jwk.crv !== "Ed25519"))
63
+ return null;
64
+ return { importAlg: { name: "Ed25519" }, verifyAlg: { name: "Ed25519" } };
65
+ }
66
+ return null;
67
+ }
68
+ /** Only the public parts of a key, so Web Crypto does not reject it over use, key_ops or alg fields. */
69
+ function publicJwk(jwk) {
70
+ if (jwk.kty === "RSA")
71
+ return { kty: "RSA", n: jwk.n, e: jwk.e, ext: true };
72
+ if (jwk.kty === "EC")
73
+ return { kty: "EC", crv: jwk.crv, x: jwk.x, y: jwk.y, ext: true };
74
+ return { kty: "OKP", crv: jwk.crv, x: jwk.x, ext: true };
75
+ }
76
+ function defaultUser(claims) {
77
+ const roles = Array.isArray(claims.roles) ? claims.roles.filter((r) => typeof r === "string") : [];
78
+ const user = { id: claims.sub, roles };
79
+ if (typeof claims.email === "string")
80
+ user.email = claims.email;
81
+ if (typeof claims.name === "string")
82
+ user.name = claims.name;
83
+ // Apps that register their own user type (Register) map the claims with options.user.
84
+ return user;
85
+ }
86
+ /**
87
+ * The app's auth from access tokens (JWTs) of an OpenID Connect provider: createApp({ auth: jwt({ issuer,
88
+ * audience }) }). Requests send Authorization: Bearer <token>.
89
+ */
90
+ export function jwt(options) {
91
+ if (!options || typeof options !== "object" || Array.isArray(options))
92
+ throw invalid("jwt() needs { issuer, audience }.");
93
+ for (const key of Object.keys(options))
94
+ if (!OPTIONS.includes(key))
95
+ throw invalid(`jwt() has no option "${key}".`, `Use ${OPTIONS.join(", ")}.`);
96
+ if (typeof options.issuer !== "string" || !options.issuer)
97
+ throw invalid("jwt() needs the issuer: the iss claim of the provider's tokens.");
98
+ const audiences = typeof options.audience === "string" ? [options.audience] : Array.isArray(options.audience) ? options.audience : [];
99
+ if (!audiences.length || audiences.some((a) => typeof a !== "string" || !a)) {
100
+ throw invalid("jwt() needs the audience: this API's identifier at the provider (the aud claim of its tokens), so tokens issued for other apps are refused.");
101
+ }
102
+ for (const key of ["user", "roles", "tenant"]) {
103
+ if (options[key] !== undefined && typeof options[key] !== "function")
104
+ throw invalid(`jwt() ${key} must be a function.`);
105
+ }
106
+ const secret = options.secret;
107
+ if (secret !== undefined) {
108
+ if (typeof secret !== "string" || secret.length < 32)
109
+ throw invalid("jwt() secret must be a string of at least 32 characters.", "Keep the provider's signing secret in config({ secrets }) and pass it as secret.");
110
+ if (options.jwksUrl !== undefined)
111
+ throw invalid("jwt() takes a secret or a jwksUrl, not both.");
112
+ }
113
+ const allowed = options.algorithms ?? (secret === undefined ? ASYMMETRIC : ["HS256"]);
114
+ if (!Array.isArray(allowed) || !allowed.length || allowed.some((a) => ![...ASYMMETRIC, ...HMAC].includes(a))) {
115
+ throw invalid(`jwt() algorithms must be a list of ${[...ASYMMETRIC, ...HMAC].join(", ")}.`);
116
+ }
117
+ if (secret === undefined && allowed.some((a) => HMAC.includes(a)))
118
+ throw invalid("jwt() algorithms HS256, HS384 and HS512 need a secret.");
119
+ if (secret !== undefined && allowed.some((a) => !HMAC.includes(a)))
120
+ throw invalid("jwt() with a secret accepts only HS256, HS384 or HS512.");
121
+ const tolerance = options.clockToleranceSeconds ?? 60;
122
+ if (!Number.isInteger(tolerance) || tolerance < 0 || tolerance > 300)
123
+ throw invalid("jwt() clockToleranceSeconds must be a whole number from 0 to 300.");
124
+ const cacheMs = options.cacheMs ?? 600_000;
125
+ if (!Number.isInteger(cacheMs) || cacheMs < 60_000 || cacheMs > 86_400_000)
126
+ throw invalid("jwt() cacheMs must be a whole number of milliseconds from 60000 (1 minute) to 86400000 (1 day).");
127
+ const issuer = options.issuer;
128
+ const jwksUrl = options.jwksUrl === undefined ? undefined : checkUrl(options.jwksUrl, "jwksUrl").href;
129
+ if (secret === undefined && jwksUrl === undefined)
130
+ checkUrl(issuer, "issuer");
131
+ const toUser = options.user ?? defaultUser;
132
+ const verify = createJwtVerifier({ issuer, audiences, secret, allowed, tolerance, cacheMs, jwksUrl });
133
+ return {
134
+ async resolve(req, { db }) {
135
+ const authorization = req.headers.get("authorization");
136
+ if (!authorization || !/^bearer\s+/i.test(authorization))
137
+ return null;
138
+ const claims = await verify(authorization.replace(/^bearer\s+/i, "").trim());
139
+ if (!claims)
140
+ return null;
141
+ return (await toUser(claims, { db, req })) ?? null;
142
+ },
143
+ ...(options.roles ? { roles: options.roles } : {}),
144
+ ...(options.tenant ? { tenant: options.tenant } : {}),
145
+ };
146
+ }
147
+ /**
148
+ * Verifies JWTs for an issuer and audience: the signature against the issuer's keys (cached, fetched again for a
149
+ * rotated key) or a shared secret, then iss, aud, exp, nbf, iat and sub. Resolves to the claims, or null for any
150
+ * token that is not valid. Throws 503 IL3008 when no keys could ever be loaded. Internal: used by jwt() and oidc().
151
+ */
152
+ export function createJwtVerifier(config) {
153
+ const { issuer, audiences, secret, allowed, tolerance, cacheMs, jwksUrl } = config;
154
+ // Signing keys: fetched on first use, kept for cacheMs, and fetched again (at most every 30 s) for an unknown key id.
155
+ let keys;
156
+ let fetchedAt = 0;
157
+ let loading;
158
+ const imported = new Map();
159
+ const hmacKeys = new Map();
160
+ const getJson = async (url) => {
161
+ const response = await fetch(url, { headers: { accept: "application/json" }, redirect: "error", signal: AbortSignal.timeout(FETCH_TIMEOUT) });
162
+ if (!response.ok)
163
+ throw new Error(`${url} answered ${response.status}`);
164
+ const body = (await response.json());
165
+ if (!body || typeof body !== "object" || Array.isArray(body))
166
+ throw new Error(`${url} did not answer a JSON object`);
167
+ return body;
168
+ };
169
+ const load = async () => {
170
+ let url = jwksUrl;
171
+ if (!url && config.discoverJwksUrl)
172
+ url = await config.discoverJwksUrl();
173
+ if (!url) {
174
+ const discovery = await getJson(`${issuer.replace(/\/+$/, "")}/.well-known/openid-configuration`);
175
+ if (discovery.issuer !== issuer)
176
+ throw new Error(`the OpenID configuration names the issuer ${JSON.stringify(discovery.issuer)}, not ${JSON.stringify(issuer)}`);
177
+ if (typeof discovery.jwks_uri !== "string")
178
+ throw new Error("the OpenID configuration has no jwks_uri");
179
+ url = checkUrl(discovery.jwks_uri, "jwks_uri").href;
180
+ }
181
+ const set = await getJson(url);
182
+ if (!Array.isArray(set.keys))
183
+ throw new Error(`${url} is not a JSON Web Key Set`);
184
+ return set.keys.filter((k) => Boolean(k) && typeof k === "object" && k.use !== "enc");
185
+ };
186
+ const refresh = () => {
187
+ loading ??= load()
188
+ .then((found) => {
189
+ keys = found;
190
+ fetchedAt = Date.now();
191
+ imported.clear();
192
+ return found;
193
+ })
194
+ .finally(() => {
195
+ loading = undefined;
196
+ });
197
+ return loading;
198
+ };
199
+ const unavailable = (cause) => new InferloError("IL3008", "The identity provider's signing keys could not be loaded, so the token cannot be checked.", {
200
+ status: 503,
201
+ fix: `Check that ${jwksUrl ?? `${issuer.replace(/\/+$/, "")}/.well-known/openid-configuration`} is reachable from the server and answers the provider's keys (${cause instanceof Error ? cause.message : String(cause)}).`,
202
+ });
203
+ const candidates = async (kid, alg) => {
204
+ const match = (list) => list.filter((k) => (kid === undefined || k.kid === kid) && (k.alg === undefined || k.alg === alg) && cryptoParams(alg, k) !== null);
205
+ const stale = !keys || Date.now() - fetchedAt > cacheMs;
206
+ if (stale) {
207
+ try {
208
+ await refresh();
209
+ }
210
+ catch (error) {
211
+ // Keep using the keys we have while the provider cannot be reached; without any, nothing can be checked.
212
+ if (!keys)
213
+ throw unavailable(error);
214
+ fetchedAt = Date.now() - cacheMs + REFETCH_COOLDOWN;
215
+ }
216
+ }
217
+ let found = match(keys);
218
+ if (!found.length && kid !== undefined && Date.now() - fetchedAt > REFETCH_COOLDOWN) {
219
+ // A key the provider started using since the last fetch (key rotation).
220
+ try {
221
+ found = match(await refresh());
222
+ }
223
+ catch {
224
+ found = [];
225
+ }
226
+ }
227
+ return found.slice(0, 10);
228
+ };
229
+ const keyFor = (jwk, alg) => {
230
+ const id = `${alg}\u0000${jwk.kid ?? ""}\u0000${jwk.n ?? ""}${jwk.x ?? ""}${jwk.y ?? ""}`;
231
+ let key = imported.get(id);
232
+ if (!key) {
233
+ key = crypto.subtle.importKey("jwk", publicJwk(jwk), cryptoParams(alg).importAlg, false, ["verify"]);
234
+ key.catch(() => imported.delete(id));
235
+ imported.set(id, key);
236
+ }
237
+ return key;
238
+ };
239
+ const hmacKey = (alg) => {
240
+ let key = hmacKeys.get(alg);
241
+ if (!key) {
242
+ key = crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: HASH[alg.slice(2)] }, false, ["verify"]);
243
+ hmacKeys.set(alg, key);
244
+ }
245
+ return key;
246
+ };
247
+ /** The verified claims of a token, or null for any token that is not valid for this API. */
248
+ const verify = async (token) => {
249
+ if (token.length > MAX_TOKEN)
250
+ return null;
251
+ const parts = token.split(".");
252
+ if (parts.length !== 3)
253
+ return null;
254
+ const [headerPart, payloadPart, signaturePart] = parts;
255
+ let header;
256
+ let claims;
257
+ let signature;
258
+ try {
259
+ header = decodeJson(headerPart);
260
+ claims = decodeJson(payloadPart);
261
+ signature = base64urlBytes(signaturePart);
262
+ }
263
+ catch {
264
+ return null;
265
+ }
266
+ const alg = header.alg;
267
+ if (typeof alg !== "string" || !allowed.includes(alg))
268
+ return null;
269
+ // Extensions this verifier does not understand must not be ignored (RFC 7515, section 4.1.11).
270
+ if (header.crit !== undefined)
271
+ return null;
272
+ if (header.kid !== undefined && typeof header.kid !== "string")
273
+ return null;
274
+ const data = new TextEncoder().encode(`${headerPart}.${payloadPart}`);
275
+ let valid = false;
276
+ if (secret !== undefined) {
277
+ valid = await crypto.subtle.verify("HMAC", await hmacKey(alg), signature, data);
278
+ }
279
+ else {
280
+ for (const jwk of await candidates(header.kid, alg)) {
281
+ try {
282
+ if (await crypto.subtle.verify(cryptoParams(alg).verifyAlg, await keyFor(jwk, alg), signature, data)) {
283
+ valid = true;
284
+ break;
285
+ }
286
+ }
287
+ catch {
288
+ // A key Web Crypto cannot use (a malformed key in the set) does not verify anything.
289
+ }
290
+ }
291
+ }
292
+ if (!valid)
293
+ return null;
294
+ const now = Date.now() / 1000;
295
+ if (claims.iss !== issuer)
296
+ return null;
297
+ const aud = typeof claims.aud === "string" ? [claims.aud] : Array.isArray(claims.aud) ? claims.aud : [];
298
+ if (!aud.some((a) => audiences.includes(a)))
299
+ return null;
300
+ if (typeof claims.exp !== "number" || claims.exp + tolerance <= now)
301
+ return null;
302
+ if (claims.nbf !== undefined && (typeof claims.nbf !== "number" || claims.nbf - tolerance > now))
303
+ return null;
304
+ if (claims.iat !== undefined && (typeof claims.iat !== "number" || claims.iat - tolerance > now))
305
+ return null;
306
+ if (typeof claims.sub !== "string" || !claims.sub)
307
+ return null;
308
+ return claims;
309
+ };
310
+ return verify;
311
+ }
312
+ //# sourceMappingURL=jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../src/jwt.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA2C3C,MAAM,CAAC,MAAM,UAAU,GAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AAChJ,MAAM,IAAI,GAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACzD,MAAM,OAAO,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,uBAAuB,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AACzI,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC;AAC5B,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,2FAA2F;AAC3F,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,GAAG,GAAG,iKAAiK,CAAC;AAc9K,SAAS,OAAO,CAAC,OAAe,EAAE,OAAO,GAAG,GAAG;IAC7C,OAAO,IAAI,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAQ;IAC9B,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,IAAY;IAC3C,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,OAAO,CAAC,SAAS,IAAI,uBAAuB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC7E,MAAM,OAAO,CAAC,SAAS,IAAI,uDAAuD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9G,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/F,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAY,CAAC;IAC5G,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IAClG,OAAO,KAAgC,CAAC;AAC1C,CAAC;AAED,MAAM,IAAI,GAA2B,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAE9F,sGAAsG;AACtG,SAAS,YAAY,CAAC,GAAiB,EAAE,GAAS;IAChD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;QAC1C,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAE,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,CAAC;IACnH,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;QAC1C,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAE,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IAC7H,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,GAAc,CAAC,CAAC;QACjF,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAChE,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAE,EAAE,EAAE,CAAC;IAC9G,CAAC;IACD,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACzC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QACrE,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;IAC5E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wGAAwG;AACxG,SAAS,SAAS,CAAC,GAAQ;IACzB,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK;QAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC5E,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IACxF,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,MAAiB;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAChH,MAAM,IAAI,GAA4B,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;IAChE,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;QAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAChE,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IAC7D,sFAAsF;IACtF,OAAO,IAAe,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,OAAmB;IACrC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,MAAM,OAAO,CAAC,mCAAmC,CAAC,CAAC;IAC1H,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,MAAM,OAAO,CAAC,wBAAwB,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjJ,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,MAAM,OAAO,CAAC,iEAAiE,CAAC,CAAC;IAC5I,MAAM,SAAS,GAAG,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACtI,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,MAAM,OAAO,CAAC,6IAA6I,CAAC,CAAC;IAC/J,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAU,EAAE,CAAC;QACvD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,UAAU;YAAE,MAAM,OAAO,CAAC,SAAS,GAAG,sBAAsB,CAAC,CAAC;IAC1H,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE;YAAE,MAAM,OAAO,CAAC,0DAA0D,EAAE,kFAAkF,CAAC,CAAC;QACpN,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;YAAE,MAAM,OAAO,CAAC,8CAA8C,CAAC,CAAC;IACnG,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACtF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7G,MAAM,OAAO,CAAC,sCAAsC,CAAC,GAAG,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,MAAM,OAAO,CAAC,wDAAwD,CAAC,CAAC;IAC3I,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,MAAM,OAAO,CAAC,yDAAyD,CAAC,CAAC;IAC7I,MAAM,SAAS,GAAG,OAAO,CAAC,qBAAqB,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,CAAC,IAAI,SAAS,GAAG,GAAG;QAAE,MAAM,OAAO,CAAC,mEAAmE,CAAC,CAAC;IACzJ,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,MAAM,IAAI,OAAO,GAAG,UAAU;QAAE,MAAM,OAAO,CAAC,iGAAiG,CAAC,CAAC;IAC7L,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC;IACtG,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS;QAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IAE3C,MAAM,MAAM,GAAG,iBAAiB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAEtG,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;YACvB,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACvD,IAAI,CAAC,aAAa,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC;gBAAE,OAAO,IAAI,CAAC;YACtE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC7E,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC;YACzB,OAAO,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QACrD,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC;AACJ,CAAC;AAeD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAyB;IACzD,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IACnF,sHAAsH;IACtH,IAAI,IAAuB,CAAC;IAC5B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,OAAmC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;IACvD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;IAEvD,MAAM,OAAO,GAAG,KAAK,EAAE,GAAW,EAAoC,EAAE;QACtE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAC9I,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,aAAa,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAY,CAAC;QAChD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,+BAA+B,CAAC,CAAC;QACrH,OAAO,IAA+B,CAAC;IACzC,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,KAAK,IAAoB,EAAE;QACtC,IAAI,GAAG,GAAG,OAAO,CAAC;QAClB,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,eAAe;YAAE,GAAG,GAAG,MAAM,MAAM,CAAC,eAAe,EAAE,CAAC;QACzE,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,mCAAmC,CAAC,CAAC;YAClG,IAAI,SAAS,CAAC,MAAM,KAAK,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACjK,IAAI,OAAO,SAAS,CAAC,QAAQ,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACxG,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC;QACtD,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,4BAA4B,CAAC,CAAC;QAClF,OAAQ,GAAG,CAAC,IAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAY,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAK,CAAS,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC;IAC1H,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAmB,EAAE;QACnC,OAAO,KAAK,IAAI,EAAE;aACf,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;YACd,IAAI,GAAG,KAAK,CAAC;YACb,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,OAAO,GAAG,SAAS,CAAC;QACtB,CAAC,CAAC,CAAC;QACL,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,KAAc,EAAE,EAAE,CACrC,IAAI,YAAY,CAAC,QAAQ,EAAE,2FAA2F,EAAE;QACtH,MAAM,EAAE,GAAG;QACX,GAAG,EAAE,cAAc,OAAO,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,mCAAmC,kEAAkE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI;KAC3N,CAAC,CAAC;IAEL,MAAM,UAAU,GAAG,KAAK,EAAE,GAAuB,EAAE,GAAiB,EAAkB,EAAE;QACtF,MAAM,KAAK,GAAG,CAAC,IAAW,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACnK,MAAM,KAAK,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,OAAO,CAAC;QACxD,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC;gBACH,MAAM,OAAO,EAAE,CAAC;YAClB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,yGAAyG;gBACzG,IAAI,CAAC,IAAI;oBAAE,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;gBACpC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,gBAAgB,CAAC;YACtD,CAAC;QACH,CAAC;QACD,IAAI,KAAK,GAAG,KAAK,CAAC,IAAK,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,gBAAgB,EAAE,CAAC;YACpF,wEAAwE;YACxE,IAAI,CAAC;gBACH,KAAK,GAAG,KAAK,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;YACjC,CAAC;YAAC,MAAM,CAAC;gBACP,KAAK,GAAG,EAAE,CAAC;YACb,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,GAAQ,EAAE,GAAiB,EAAsB,EAAE;QACjE,MAAM,EAAE,GAAG,GAAG,GAAG,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1F,IAAI,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,GAAG,CAAE,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;YACtG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YACrC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,CAAC,GAAiB,EAAsB,EAAE;QACxD,IAAI,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,EAAE,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;YACvI,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;IAEF,4FAA4F;IAC5F,MAAM,MAAM,GAAG,KAAK,EAAE,KAAa,EAA6B,EAAE;QAChE,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,MAAM,CAAC,UAAU,EAAE,WAAW,EAAE,aAAa,CAAC,GAAG,KAAiC,CAAC;QACnF,IAAI,MAA+B,CAAC;QACpC,IAAI,MAA+B,CAAC;QACpC,IAAI,SAAkC,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;YAChC,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;YACjC,SAAS,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAmB,CAAC;QACvC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACnE,+FAA+F;QAC/F,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC;QAC3C,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC5E,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,UAAU,IAAI,WAAW,EAAE,CAAC,CAAC;QAEtE,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,GAAG,IAAI,MAAM,UAAU,CAAC,MAAM,CAAC,GAAyB,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC1E,IAAI,CAAC;oBACH,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAE,CAAC,SAAS,EAAE,MAAM,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC;wBACtG,KAAK,GAAG,IAAI,CAAC;wBACb,MAAM;oBACR,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,qFAAqF;gBACvF,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QAC9B,IAAI,MAAM,CAAC,GAAG,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACvC,MAAM,GAAG,GAAG,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACxG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAW,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACnE,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,GAAG,SAAS,IAAI,GAAG;YAAE,OAAO,IAAI,CAAC;QACjF,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,GAAG,SAAS,GAAG,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9G,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,GAAG,SAAS,GAAG,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9G,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QAC/D,OAAO,MAAmB,CAAC;IAC7B,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/model.js CHANGED
@@ -14,7 +14,7 @@
14
14
  * export const Ticket = model("tickets", { title: t.string() }, { tenant: true })
15
15
  */
16
16
  import { InferloError } from "./errors.js";
17
- import { ObjectSchema, Schema, t } from "./schema.js";
17
+ import { ObjectSchema, Schema, containsFile, t } from "./schema.js";
18
18
  const TABLE_NAME = /^[a-z][a-z0-9_]{0,62}$/;
19
19
  const FIELD_NAME = /^[a-zA-Z][a-zA-Z0-9]{0,62}$/;
20
20
  const RESERVED = new Set(["id", "createdAt", "updatedAt"]);
@@ -65,6 +65,11 @@ export class Model {
65
65
  fix: `Remove "${key}" from the model. Every model already has id, createdAt and updatedAt.`,
66
66
  });
67
67
  }
68
+ if (containsFile(fields[key])) {
69
+ throw new InferloError("IL1004", `Field "${name}.${key}" uses t.file(), which only works in route bodies.`, {
70
+ fix: "Accept the upload in a route body (body: t.object({ file: t.file() })), store the file elsewhere, and keep its key or URL in a t.string() field of the model.",
71
+ });
72
+ }
68
73
  if (!FIELD_NAME.test(key)) {
69
74
  throw new InferloError("IL4005", `Field "${name}.${key}" is not a valid field name.`, {
70
75
  fix: "Use camelCase letters and digits, e.g. ownerId. Inferlo stores it as owner_id.",
package/dist/model.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
package/dist/oidc.d.ts ADDED
@@ -0,0 +1,70 @@
1
+ import { type JwtClaims } from "./jwt.ts";
2
+ import { type AppDb, type RouteDef } from "./route.ts";
3
+ import type { Sessions } from "./sessions.ts";
4
+ /** The claims of a verified ID token. Providers add their own (email, email_verified, name, groups, tid, hd, ...). */
5
+ export interface OidcClaims extends JwtClaims {
6
+ nonce?: string;
7
+ email?: string;
8
+ email_verified?: boolean;
9
+ name?: string;
10
+ }
11
+ /** The provider's answer to the code exchange. */
12
+ export interface OidcTokens {
13
+ idToken: string;
14
+ /** For calling the provider's APIs (userinfo, Microsoft Graph, ...); never stored by Inferlo. */
15
+ accessToken?: string;
16
+ refreshToken?: string;
17
+ /** Seconds until the access token expires, as the provider says. */
18
+ expiresIn?: number;
19
+ scope?: string;
20
+ }
21
+ export interface OidcOptions {
22
+ /** The provider's issuer exactly as its OpenID configuration names it, such as "https://acme.okta.com". https, except on localhost. */
23
+ issuer: string;
24
+ /** The app's client id at the provider. */
25
+ clientId: string;
26
+ /** The app's client secret (keep it in config({ secrets })). Leave it out for a public client, which PKCE protects. */
27
+ clientSecret?: string;
28
+ /** The sessions() the sign-in ends in; also the app's auth: createApp({ auth: session }). */
29
+ session: Sessions;
30
+ /**
31
+ * The id of the app's user for a verified ID token (find or create the user), or null to refuse the sign-in
32
+ * (403 IL3011). Check claims.email_verified before trusting claims.email.
33
+ */
34
+ userId: (claims: OidcClaims, ctx: {
35
+ db: AppDb;
36
+ req: Request;
37
+ tokens: OidcTokens;
38
+ }) => string | null | undefined | Promise<string | null | undefined>;
39
+ /** Where the provider sends the browser back, registered at the provider. Default: <the request's origin><basePath>/callback. */
40
+ redirectUri?: string;
41
+ /** Scopes to ask for. Default ["openid", "email", "profile"]; "openid" is always sent. */
42
+ scopes?: string[];
43
+ /** Where the login, callback and logout routes are. Default "/auth": GET /auth/login, GET /auth/callback and POST /auth/logout. */
44
+ basePath?: string;
45
+ /**
46
+ * Extra parameters for every sign-in at the provider, such as { prompt: "select_account" }, Google's
47
+ * { hd: "acme.com" } or Entra ID's { domain_hint: "acme.com" }. The flow's own parameters cannot be changed.
48
+ */
49
+ authorizationParams?: Record<string, string>;
50
+ /** Where the provider sends the browser after signing out, registered at the provider. Default: <the request's origin>/. */
51
+ postLogoutRedirectUri?: string;
52
+ }
53
+ /** routes: [sso] adds the two routes; oidcLogin starts a sign-in, oidcCallback finishes it. */
54
+ export type Oidc = {
55
+ /** GET <basePath>/login?returnTo=/path: sends the browser to the provider. */
56
+ oidcLogin: RouteDef;
57
+ /** GET <basePath>/callback: the redirect URI registered at the provider. */
58
+ oidcCallback: RouteDef;
59
+ /** POST <basePath>/logout (with the session's _csrf field): ends the session, then signs out at the provider. */
60
+ oidcLogout: RouteDef;
61
+ /** The login route's path, for links: <a href={sso.loginPath}>. */
62
+ loginPath: string;
63
+ /** The logout route's path, for a form: <form method="post" action={sso.logoutPath}>. */
64
+ logoutPath: string;
65
+ };
66
+ /**
67
+ * OpenID Connect sign-in for browser apps: routes: [sso] with sso = oidc({ issuer, clientId, clientSecret,
68
+ * session, userId }). The sign-in ends in the session's cookie.
69
+ */
70
+ export declare function oidc(options: OidcOptions): Oidc;