@run402/functions 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.d.ts +3 -3
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +44 -6
- package/dist/auth.js.map +1 -1
- package/dist/cache.d.ts +122 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +243 -0
- package/dist/cache.js.map +1 -0
- package/dist/db.d.ts +26 -7
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +38 -8
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/jwt.d.ts +55 -0
- package/dist/lib/jwt.d.ts.map +1 -0
- package/dist/lib/jwt.js +196 -0
- package/dist/lib/jwt.js.map +1 -0
- package/dist/runtime-context.d.ts +152 -0
- package/dist/runtime-context.d.ts.map +1 -0
- package/dist/runtime-context.js +170 -0
- package/dist/runtime-context.js.map +1 -0
- package/package.json +2 -7
package/dist/index.d.ts
CHANGED
|
@@ -9,4 +9,9 @@ export { assets } from "./assets.js";
|
|
|
9
9
|
export type { AssetPutOptions, AssetPutSource, AssetPutSourceInput, AssetRef, AssetVisibility, AssetVariant, AssetListRow, AssetsListFilter, AssetsListOptions, AssetsListResult, AssetsListSort, ImageInfo, } from "./assets.js";
|
|
10
10
|
export { bytes, isRequest, json, routedHttp, text } from "./routed-http.js";
|
|
11
11
|
export type { RoutedHttpHeaderList, RoutedHttpRequestV1, RoutedHttpResponseInit, RoutedHttpResponseV1, } from "./routed-http.js";
|
|
12
|
+
export { cache } from "./cache.js";
|
|
13
|
+
export type { Cache, CacheInvalidateResult, InvalidatePrefixOptions, InvalidateAllOptions, } from "./cache.js";
|
|
14
|
+
export { CacheInvalidationHostRequiredError, CacheInvalidationHostForbiddenError, } from "./cache.js";
|
|
15
|
+
export { als, getCurrentContext, runWithContext, requireActiveContext, taintCacheBypass, withPaymentTaint, PAYMENT_PRIMITIVES, Run402OutsideRequestContextError, } from "./runtime-context.js";
|
|
16
|
+
export type { RunRequestContext } from "./runtime-context.js";
|
|
12
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,eAAe,EACf,YAAY,EAEZ,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,YAAY,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,QAAQ,EACR,eAAe,EACf,YAAY,EAEZ,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC5E,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EACV,KAAK,EACL,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,YAAY,CAAC;AAKpB,OAAO,EACL,GAAG,EACH,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,4 +4,14 @@ export { email } from "./email.js";
|
|
|
4
4
|
export { ai } from "./ai.js";
|
|
5
5
|
export { assets } from "./assets.js";
|
|
6
6
|
export { bytes, isRequest, json, routedHttp, text } from "./routed-http.js";
|
|
7
|
+
// Capability `astro-ssr-runtime` (v1.52).
|
|
8
|
+
// `cache.*` — sub-second admin-edit visibility via origin-side ISR
|
|
9
|
+
// cache invalidation. Server-side (function-context) only.
|
|
10
|
+
export { cache } from "./cache.js";
|
|
11
|
+
export { CacheInvalidationHostRequiredError, CacheInvalidationHostForbiddenError, } from "./cache.js";
|
|
12
|
+
// Runtime context primitives — used internally by SDK functions to read
|
|
13
|
+
// the current SSR request from AsyncLocalStorage. The SSR Lambda runtime
|
|
14
|
+
// (in @run402/astro) uses `runWithContext` to establish the store; user
|
|
15
|
+
// code typically does not import these directly.
|
|
16
|
+
export { als, getCurrentContext, runWithContext, requireActiveContext, taintCacheBypass, withPaymentTaint, PAYMENT_PRIMITIVES, Run402OutsideRequestContextError, } from "./runtime-context.js";
|
|
7
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAS7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAgBrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAExD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAS7B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAgBrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAO5E,0CAA0C;AAC1C,mEAAmE;AACnE,2DAA2D;AAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAOnC,OAAO,EACL,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,YAAY,CAAC;AACpB,wEAAwE;AACxE,yEAAyE;AACzE,wEAAwE;AACxE,iDAAiD;AACjD,OAAO,EACL,GAAG,EACH,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal HS256/HS512 JWT sign + verify built directly on `node:crypto`.
|
|
3
|
+
*
|
|
4
|
+
* Used internally by `@run402/functions` to verify project JWTs in
|
|
5
|
+
* `getUser`. Replaces a runtime dependency on the `jsonwebtoken` package
|
|
6
|
+
* (and its transitive tree `jws` / `jwa` / `ecdsa-sig-formatter` /
|
|
7
|
+
* `lodash.*` / `ms` / `semver` / `safe-buffer`), so this published SDK
|
|
8
|
+
* has zero crypto deps beyond `node:crypto`. The companion file in
|
|
9
|
+
* the private gateway package (`packages/gateway/src/lib/jwt.ts`) is
|
|
10
|
+
* intentionally a verbatim duplicate — the published SDK cannot pull
|
|
11
|
+
* from the workspace-private `@run402/shared`.
|
|
12
|
+
*/
|
|
13
|
+
export interface JwtPayload {
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
iat?: number;
|
|
16
|
+
exp?: number;
|
|
17
|
+
nbf?: number;
|
|
18
|
+
iss?: string;
|
|
19
|
+
aud?: string | string[];
|
|
20
|
+
sub?: string;
|
|
21
|
+
jti?: string;
|
|
22
|
+
}
|
|
23
|
+
export type SupportedAlgorithm = "HS256" | "HS512";
|
|
24
|
+
export interface SignOptions {
|
|
25
|
+
algorithm?: SupportedAlgorithm;
|
|
26
|
+
expiresIn?: string | number;
|
|
27
|
+
noTimestamp?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface VerifyOptions {
|
|
30
|
+
algorithms?: ReadonlyArray<SupportedAlgorithm>;
|
|
31
|
+
issuer?: string;
|
|
32
|
+
audience?: string | string[];
|
|
33
|
+
clockTolerance?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare class JsonWebTokenError extends Error {
|
|
36
|
+
constructor(message: string);
|
|
37
|
+
}
|
|
38
|
+
export declare class TokenExpiredError extends JsonWebTokenError {
|
|
39
|
+
expiredAt: Date;
|
|
40
|
+
constructor(message: string, expiredAt: Date);
|
|
41
|
+
}
|
|
42
|
+
export declare class NotBeforeError extends JsonWebTokenError {
|
|
43
|
+
date: Date;
|
|
44
|
+
constructor(message: string, date: Date);
|
|
45
|
+
}
|
|
46
|
+
export declare function sign(payload: object, secret: string, options?: SignOptions): string;
|
|
47
|
+
export declare function verify<T = JwtPayload>(token: string, secret: string, options?: VerifyOptions): T;
|
|
48
|
+
export declare function decode<T = JwtPayload>(token: string): T | null;
|
|
49
|
+
declare const jwt: {
|
|
50
|
+
sign: typeof sign;
|
|
51
|
+
verify: typeof verify;
|
|
52
|
+
decode: typeof decode;
|
|
53
|
+
};
|
|
54
|
+
export default jwt;
|
|
55
|
+
//# sourceMappingURL=jwt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/lib/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,OAAO,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,kBAAkB,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,iBAAkB,SAAQ,iBAAiB;IACtD,SAAS,EAAE,IAAI,CAAC;gBACJ,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI;CAK7C;AAED,qBAAa,cAAe,SAAQ,iBAAiB;IACnD,IAAI,EAAE,IAAI,CAAC;gBACC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI;CAKxC;AAqCD,wBAAgB,IAAI,CAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,WAAW,GACpB,MAAM,CAmCR;AAED,wBAAgB,MAAM,CAAC,CAAC,GAAG,UAAU,EACnC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,aAAa,GACtB,CAAC,CA4EH;AAED,wBAAgB,MAAM,CAAC,CAAC,GAAG,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAW9D;AAED,QAAA,MAAM,GAAG;;;;CAA2B,CAAC;AACrC,eAAe,GAAG,CAAC"}
|
package/dist/lib/jwt.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal HS256/HS512 JWT sign + verify built directly on `node:crypto`.
|
|
3
|
+
*
|
|
4
|
+
* Used internally by `@run402/functions` to verify project JWTs in
|
|
5
|
+
* `getUser`. Replaces a runtime dependency on the `jsonwebtoken` package
|
|
6
|
+
* (and its transitive tree `jws` / `jwa` / `ecdsa-sig-formatter` /
|
|
7
|
+
* `lodash.*` / `ms` / `semver` / `safe-buffer`), so this published SDK
|
|
8
|
+
* has zero crypto deps beyond `node:crypto`. The companion file in
|
|
9
|
+
* the private gateway package (`packages/gateway/src/lib/jwt.ts`) is
|
|
10
|
+
* intentionally a verbatim duplicate — the published SDK cannot pull
|
|
11
|
+
* from the workspace-private `@run402/shared`.
|
|
12
|
+
*/
|
|
13
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
14
|
+
export class JsonWebTokenError extends Error {
|
|
15
|
+
constructor(message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = "JsonWebTokenError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class TokenExpiredError extends JsonWebTokenError {
|
|
21
|
+
expiredAt;
|
|
22
|
+
constructor(message, expiredAt) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = "TokenExpiredError";
|
|
25
|
+
this.expiredAt = expiredAt;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export class NotBeforeError extends JsonWebTokenError {
|
|
29
|
+
date;
|
|
30
|
+
constructor(message, date) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = "NotBeforeError";
|
|
33
|
+
this.date = date;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function b64urlEncode(input) {
|
|
37
|
+
const buf = typeof input === "string" ? Buffer.from(input, "utf8") : input;
|
|
38
|
+
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
39
|
+
}
|
|
40
|
+
function b64urlDecodeToBuffer(input) {
|
|
41
|
+
if (!/^[A-Za-z0-9_-]*$/.test(input))
|
|
42
|
+
throw new JsonWebTokenError("invalid token");
|
|
43
|
+
const norm = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
44
|
+
const pad = norm.length % 4 === 0 ? "" : "=".repeat(4 - (norm.length % 4));
|
|
45
|
+
return Buffer.from(norm + pad, "base64");
|
|
46
|
+
}
|
|
47
|
+
const DURATION_RE = /^(-?\d+(?:\.\d+)?)\s*(s|sec|secs|seconds?|m|min|mins|minutes?|h|hr|hrs|hours?|d|days?|w|weeks?|y|years?)?$/i;
|
|
48
|
+
function parseDurationSeconds(input) {
|
|
49
|
+
if (typeof input === "number") {
|
|
50
|
+
if (!Number.isFinite(input))
|
|
51
|
+
throw new TypeError(`Invalid expiresIn: ${input}`);
|
|
52
|
+
return Math.floor(input);
|
|
53
|
+
}
|
|
54
|
+
const m = DURATION_RE.exec(input.trim());
|
|
55
|
+
if (!m)
|
|
56
|
+
throw new TypeError(`Invalid expiresIn duration: ${input}`);
|
|
57
|
+
const n = parseFloat(m[1]);
|
|
58
|
+
const unit = (m[2] ?? "s").toLowerCase();
|
|
59
|
+
if (unit.startsWith("y"))
|
|
60
|
+
return Math.floor(n * 31_557_600);
|
|
61
|
+
if (unit.startsWith("w"))
|
|
62
|
+
return Math.floor(n * 604_800);
|
|
63
|
+
if (unit.startsWith("d"))
|
|
64
|
+
return Math.floor(n * 86_400);
|
|
65
|
+
if (unit.startsWith("h"))
|
|
66
|
+
return Math.floor(n * 3_600);
|
|
67
|
+
if (unit === "m" || unit.startsWith("min"))
|
|
68
|
+
return Math.floor(n * 60);
|
|
69
|
+
return Math.floor(n);
|
|
70
|
+
}
|
|
71
|
+
function hmacForAlg(alg) {
|
|
72
|
+
return alg === "HS256" ? "sha256" : "sha512";
|
|
73
|
+
}
|
|
74
|
+
export function sign(payload, secret, options) {
|
|
75
|
+
const alg = options?.algorithm ?? "HS256";
|
|
76
|
+
if (alg !== "HS256" && alg !== "HS512") {
|
|
77
|
+
throw new JsonWebTokenError(`Unsupported algorithm: ${alg}`);
|
|
78
|
+
}
|
|
79
|
+
if (typeof secret !== "string" || secret.length === 0) {
|
|
80
|
+
throw new JsonWebTokenError("secretOrPrivateKey must be provided");
|
|
81
|
+
}
|
|
82
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
83
|
+
throw new JsonWebTokenError("payload must be a plain object");
|
|
84
|
+
}
|
|
85
|
+
const claims = { ...payload };
|
|
86
|
+
const noTimestamp = options?.noTimestamp ?? false;
|
|
87
|
+
if (!noTimestamp && claims.iat === undefined) {
|
|
88
|
+
claims.iat = Math.floor(Date.now() / 1000);
|
|
89
|
+
}
|
|
90
|
+
if (options?.expiresIn !== undefined) {
|
|
91
|
+
if (claims.exp !== undefined) {
|
|
92
|
+
throw new JsonWebTokenError("Bad options.expiresIn option the payload already has an exp property");
|
|
93
|
+
}
|
|
94
|
+
const offset = parseDurationSeconds(options.expiresIn);
|
|
95
|
+
const iatRef = typeof claims.iat === "number" ? claims.iat : Math.floor(Date.now() / 1000);
|
|
96
|
+
claims.exp = iatRef + offset;
|
|
97
|
+
}
|
|
98
|
+
const header = { alg, typ: "JWT" };
|
|
99
|
+
const headerB64 = b64urlEncode(JSON.stringify(header));
|
|
100
|
+
const payloadB64 = b64urlEncode(JSON.stringify(claims));
|
|
101
|
+
const sig = createHmac(hmacForAlg(alg), secret)
|
|
102
|
+
.update(`${headerB64}.${payloadB64}`)
|
|
103
|
+
.digest();
|
|
104
|
+
return `${headerB64}.${payloadB64}.${b64urlEncode(sig)}`;
|
|
105
|
+
}
|
|
106
|
+
export function verify(token, secret, options) {
|
|
107
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
108
|
+
throw new JsonWebTokenError("jwt must be provided");
|
|
109
|
+
}
|
|
110
|
+
if (typeof secret !== "string" || secret.length === 0) {
|
|
111
|
+
throw new JsonWebTokenError("secret must be provided");
|
|
112
|
+
}
|
|
113
|
+
const parts = token.split(".");
|
|
114
|
+
if (parts.length !== 3)
|
|
115
|
+
throw new JsonWebTokenError("jwt malformed");
|
|
116
|
+
const [headerB64, payloadB64, sigB64] = parts;
|
|
117
|
+
let header;
|
|
118
|
+
try {
|
|
119
|
+
header = JSON.parse(b64urlDecodeToBuffer(headerB64).toString("utf8"));
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
throw new JsonWebTokenError("invalid token");
|
|
123
|
+
}
|
|
124
|
+
const allowed = (options?.algorithms ?? ["HS256"]);
|
|
125
|
+
if (typeof header.alg !== "string" || !allowed.includes(header.alg)) {
|
|
126
|
+
throw new JsonWebTokenError("invalid algorithm");
|
|
127
|
+
}
|
|
128
|
+
if (header.alg !== "HS256" && header.alg !== "HS512") {
|
|
129
|
+
throw new JsonWebTokenError("invalid algorithm");
|
|
130
|
+
}
|
|
131
|
+
const expected = createHmac(hmacForAlg(header.alg), secret)
|
|
132
|
+
.update(`${headerB64}.${payloadB64}`)
|
|
133
|
+
.digest();
|
|
134
|
+
let got;
|
|
135
|
+
try {
|
|
136
|
+
got = b64urlDecodeToBuffer(sigB64);
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
throw new JsonWebTokenError("invalid signature");
|
|
140
|
+
}
|
|
141
|
+
if (got.length !== expected.length || !timingSafeEqual(got, expected)) {
|
|
142
|
+
throw new JsonWebTokenError("invalid signature");
|
|
143
|
+
}
|
|
144
|
+
let payload;
|
|
145
|
+
try {
|
|
146
|
+
payload = JSON.parse(b64urlDecodeToBuffer(payloadB64).toString("utf8"));
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
throw new JsonWebTokenError("invalid token");
|
|
150
|
+
}
|
|
151
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
152
|
+
throw new JsonWebTokenError("invalid token");
|
|
153
|
+
}
|
|
154
|
+
const clockTolerance = options?.clockTolerance ?? 0;
|
|
155
|
+
const now = Math.floor(Date.now() / 1000);
|
|
156
|
+
if (typeof payload.exp === "number" && payload.exp + clockTolerance < now) {
|
|
157
|
+
throw new TokenExpiredError("jwt expired", new Date(payload.exp * 1000));
|
|
158
|
+
}
|
|
159
|
+
if (typeof payload.nbf === "number" && payload.nbf - clockTolerance > now) {
|
|
160
|
+
throw new NotBeforeError("jwt not active", new Date(payload.nbf * 1000));
|
|
161
|
+
}
|
|
162
|
+
if (options?.issuer !== undefined && payload.iss !== options.issuer) {
|
|
163
|
+
throw new JsonWebTokenError(`jwt issuer invalid. expected: ${options.issuer}`);
|
|
164
|
+
}
|
|
165
|
+
if (options?.audience !== undefined) {
|
|
166
|
+
const wantArr = Array.isArray(options.audience) ? options.audience : [options.audience];
|
|
167
|
+
const haveArr = Array.isArray(payload.aud)
|
|
168
|
+
? payload.aud
|
|
169
|
+
: payload.aud !== undefined
|
|
170
|
+
? [payload.aud]
|
|
171
|
+
: [];
|
|
172
|
+
if (!wantArr.some((w) => haveArr.includes(w))) {
|
|
173
|
+
throw new JsonWebTokenError("jwt audience invalid");
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return payload;
|
|
177
|
+
}
|
|
178
|
+
export function decode(token) {
|
|
179
|
+
if (typeof token !== "string")
|
|
180
|
+
return null;
|
|
181
|
+
const parts = token.split(".");
|
|
182
|
+
if (parts.length !== 3)
|
|
183
|
+
return null;
|
|
184
|
+
try {
|
|
185
|
+
const decoded = JSON.parse(b64urlDecodeToBuffer(parts[1]).toString("utf8"));
|
|
186
|
+
if (decoded === null || typeof decoded !== "object" || Array.isArray(decoded))
|
|
187
|
+
return null;
|
|
188
|
+
return decoded;
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const jwt = { sign, verify, decode };
|
|
195
|
+
export default jwt;
|
|
196
|
+
//# sourceMappingURL=jwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/lib/jwt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR request context primitive — capability `functions-sdk-auth-model`.
|
|
3
|
+
*
|
|
4
|
+
* The SSR Lambda runtime establishes this context via `als.run(...)`
|
|
5
|
+
* BEFORE importing or executing the Astro server bundle (or any other
|
|
6
|
+
* user-supplied code). SDK functions that need request-scoped state
|
|
7
|
+
* (`db()`, `getUser()`, `cache.*`, `assets.*`, `email.*`, `ai.*`) read
|
|
8
|
+
* from `getCurrentContext()` rather than requiring explicit context
|
|
9
|
+
* parameters at the call site.
|
|
10
|
+
*
|
|
11
|
+
* The `active` flag exists because Node's AsyncLocalStorage propagates
|
|
12
|
+
* into timers, microtasks, and unawaited promises created inside
|
|
13
|
+
* `als.run()`. Without an explicit flag, a `setTimeout(() => db()..., 60_000)`
|
|
14
|
+
* scheduled inside a handler would, when the timer fires later, still
|
|
15
|
+
* observe an `als.getStore()` pointing at the (now-completed) request —
|
|
16
|
+
* leading to stale or incorrect SDK behavior. The SSR runtime sets
|
|
17
|
+
* `active.value = false` IMMEDIATELY after the response body is fully
|
|
18
|
+
* materialized; SDK functions check the flag and throw
|
|
19
|
+
* `R402_SDK_OUTSIDE_REQUEST_CONTEXT` when it's false.
|
|
20
|
+
*
|
|
21
|
+
* Likewise `cacheBypassTainted.value` is set to `true` by `getUser()`
|
|
22
|
+
* and payment-primitive SDK calls during render; the SSR runtime returns
|
|
23
|
+
* its final value to the gateway in the Lambda response metadata envelope
|
|
24
|
+
* (NOT via in-process ALS — the gateway runs in a different process).
|
|
25
|
+
*
|
|
26
|
+
* @see openspec/changes/astro-ssr-runtime/specs/functions-sdk-auth-model/spec.md
|
|
27
|
+
* @see openspec/changes/astro-ssr-runtime/specs/routed-http-functions/spec.md
|
|
28
|
+
*/
|
|
29
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
30
|
+
/** The shape stored in AsyncLocalStorage. See the spec referenced above
|
|
31
|
+
* for the canonical definition. */
|
|
32
|
+
export interface RunRequestContext {
|
|
33
|
+
/** Unique per-request id; matches `x-run402-request-id`. */
|
|
34
|
+
requestId: string;
|
|
35
|
+
projectId: string;
|
|
36
|
+
releaseId: string;
|
|
37
|
+
/** v1.49-negotiated locale string. `null` when the active release has
|
|
38
|
+
* no i18n slice. */
|
|
39
|
+
locale: string | null;
|
|
40
|
+
/** Echoed verbatim from the active release's `i18n.defaultLocale`,
|
|
41
|
+
* `null` when the release has no i18n slice. */
|
|
42
|
+
defaultLocale: string | null;
|
|
43
|
+
/** Validated host from the routed-function envelope — NOT the raw
|
|
44
|
+
* `Host` header. Cache-key host comes from here. */
|
|
45
|
+
host: string;
|
|
46
|
+
/** Request information SDK functions need (cookies for `getUser()`,
|
|
47
|
+
* url for invalidate path-form, etc.). Body is intentionally absent
|
|
48
|
+
* — user code reads body via the standard Web Request API passed to
|
|
49
|
+
* the handler. */
|
|
50
|
+
request: {
|
|
51
|
+
method: string;
|
|
52
|
+
url: string;
|
|
53
|
+
headers: Record<string, string | string[] | undefined>;
|
|
54
|
+
};
|
|
55
|
+
/** Mutable ref: SDK functions that read request-scoped auth or invoke
|
|
56
|
+
* payment primitives set `value = true`. The SSR Lambda runtime
|
|
57
|
+
* returns the final value to the gateway in the response metadata
|
|
58
|
+
* envelope. */
|
|
59
|
+
cacheBypassTainted: {
|
|
60
|
+
value: boolean;
|
|
61
|
+
};
|
|
62
|
+
/** Mutable ref: SSR runtime sets `value = false` after the response
|
|
63
|
+
* body has been fully materialized. SDK functions check this AND
|
|
64
|
+
* the store presence; either being false produces
|
|
65
|
+
* `R402_SDK_OUTSIDE_REQUEST_CONTEXT`. */
|
|
66
|
+
active: {
|
|
67
|
+
value: boolean;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** The shared ALS instance. Modules in @run402/functions read from
|
|
71
|
+
* this; the SSR Lambda runtime (in @run402/astro) writes to it. */
|
|
72
|
+
export declare const als: AsyncLocalStorage<RunRequestContext>;
|
|
73
|
+
/**
|
|
74
|
+
* Read the current request context, or `undefined` if no SSR request
|
|
75
|
+
* is in flight. SDK functions check both this AND `active.value` to
|
|
76
|
+
* decide whether to honor the call.
|
|
77
|
+
*/
|
|
78
|
+
export declare function getCurrentContext(): RunRequestContext | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Establish a request context and run a callback inside it. The SSR
|
|
81
|
+
* Lambda runtime calls this exactly once per invocation, wrapping the
|
|
82
|
+
* full `App.render(request)` + body-materialization sequence.
|
|
83
|
+
*
|
|
84
|
+
* The `active` flag is set to `true` initially; the caller (the SSR
|
|
85
|
+
* runtime) flips it to `false` after the response body is materialized.
|
|
86
|
+
* Don't call this from user code — it's the runtime's primitive.
|
|
87
|
+
*/
|
|
88
|
+
export declare function runWithContext<T>(context: Omit<RunRequestContext, "cacheBypassTainted" | "active"> & Partial<Pick<RunRequestContext, "cacheBypassTainted" | "active">>, callback: () => Promise<T> | T): Promise<T> | T;
|
|
89
|
+
/**
|
|
90
|
+
* Throw a structured `R402_SDK_OUTSIDE_REQUEST_CONTEXT` error. Used by
|
|
91
|
+
* SDK functions when they're invoked with no ALS store OR while the
|
|
92
|
+
* context has been marked inactive.
|
|
93
|
+
*
|
|
94
|
+
* Per the api-error-envelope spec, the thrown error carries:
|
|
95
|
+
* - `code: 'R402_SDK_OUTSIDE_REQUEST_CONTEXT'`
|
|
96
|
+
* - `message`: names the SDK function and the cause
|
|
97
|
+
* - `suggestedFix`: recommends moving the call inside a handler OR
|
|
98
|
+
* not scheduling background work that outlives the response
|
|
99
|
+
* - `docs`: `https://docs.run402.com/sdk/errors#outside-request-context`
|
|
100
|
+
*/
|
|
101
|
+
export declare class Run402OutsideRequestContextError extends Error {
|
|
102
|
+
readonly code = "R402_SDK_OUTSIDE_REQUEST_CONTEXT";
|
|
103
|
+
readonly docs = "https://docs.run402.com/sdk/errors#outside-request-context";
|
|
104
|
+
readonly suggestedFix: string;
|
|
105
|
+
readonly sdkFunction: string;
|
|
106
|
+
readonly cause: "no_context" | "context_inactive";
|
|
107
|
+
constructor(sdkFunction: string, cause: "no_context" | "context_inactive");
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Assert that a request context is active. Returns the context on
|
|
111
|
+
* success; throws `Run402OutsideRequestContextError` on failure.
|
|
112
|
+
*
|
|
113
|
+
* SDK functions call this as the first line, e.g.:
|
|
114
|
+
*
|
|
115
|
+
* const ctx = requireActiveContext("db");
|
|
116
|
+
* // use ctx.projectId, ctx.request.headers, etc.
|
|
117
|
+
*/
|
|
118
|
+
export declare function requireActiveContext(sdkFunction: string): RunRequestContext;
|
|
119
|
+
/**
|
|
120
|
+
* Flip the cache-bypass taint flag on the current context. Called by
|
|
121
|
+
* `getUser()` and payment-primitive SDK calls to signal that the
|
|
122
|
+
* rendered response depends on request-scoped auth state and therefore
|
|
123
|
+
* MUST NOT be cached publicly.
|
|
124
|
+
*
|
|
125
|
+
* No-op if there is no active context (rather than throwing — the taint
|
|
126
|
+
* is moot when there's no cache layer to inform).
|
|
127
|
+
*/
|
|
128
|
+
export declare function taintCacheBypass(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Canonical registry of SDK functions that are "payment primitives" for
|
|
131
|
+
* cache-taint purposes. Calling any of these inside an active request
|
|
132
|
+
* context MUST flip `cacheBypassTainted.value = true`. The set is
|
|
133
|
+
* defined here so the spec, runtime, and docs share one source of truth.
|
|
134
|
+
*
|
|
135
|
+
* To add a new payment primitive: append to this set AND ensure the
|
|
136
|
+
* function's implementation calls `taintCacheBypass()` on every entry.
|
|
137
|
+
*
|
|
138
|
+
* @see openspec/changes/astro-ssr-runtime/specs/functions-sdk-auth-model/spec.md
|
|
139
|
+
*/
|
|
140
|
+
export declare const PAYMENT_PRIMITIVES: ReadonlySet<string>;
|
|
141
|
+
/**
|
|
142
|
+
* Helper for payment-primitive implementations. Wraps the body in a
|
|
143
|
+
* taint-on-entry call so the registry contract is enforced at the
|
|
144
|
+
* SDK layer rather than relying on each implementation to remember.
|
|
145
|
+
*
|
|
146
|
+
* Example:
|
|
147
|
+
* export const requirePayment = withPaymentTaint("payments.require", async (opts) => {
|
|
148
|
+
* // ... actual implementation
|
|
149
|
+
* });
|
|
150
|
+
*/
|
|
151
|
+
export declare function withPaymentTaint<TArgs extends unknown[], TReturn>(name: string, impl: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
|
|
152
|
+
//# sourceMappingURL=runtime-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-context.d.ts","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD;oCACoC;AACpC,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB;yBACqB;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;qDACiD;IACjD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;yDACqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb;;;uBAGmB;IACnB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;KACxD,CAAC;IACF;;;oBAGgB;IAChB,kBAAkB,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IACvC;;;8CAG0C;IAC1C,MAAM,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;CAC5B;AAED;oEACoE;AACpE,eAAO,MAAM,GAAG,sCAA6C,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,GAAG,SAAS,CAEjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,GAAG,QAAQ,CAAC,CAAC,EACrI,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAC7B,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAOhB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,sCAAsC;IACnD,QAAQ,CAAC,IAAI,gEAAgE;IAC7E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,kBAAkB,CAAC;gBAEtC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,kBAAkB;CAc1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,CAS3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAUjD,CAAC;AAEH;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,OAAO,EAAE,EAAE,OAAO,EAC/D,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,GAChC,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAe7B"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR request context primitive — capability `functions-sdk-auth-model`.
|
|
3
|
+
*
|
|
4
|
+
* The SSR Lambda runtime establishes this context via `als.run(...)`
|
|
5
|
+
* BEFORE importing or executing the Astro server bundle (or any other
|
|
6
|
+
* user-supplied code). SDK functions that need request-scoped state
|
|
7
|
+
* (`db()`, `getUser()`, `cache.*`, `assets.*`, `email.*`, `ai.*`) read
|
|
8
|
+
* from `getCurrentContext()` rather than requiring explicit context
|
|
9
|
+
* parameters at the call site.
|
|
10
|
+
*
|
|
11
|
+
* The `active` flag exists because Node's AsyncLocalStorage propagates
|
|
12
|
+
* into timers, microtasks, and unawaited promises created inside
|
|
13
|
+
* `als.run()`. Without an explicit flag, a `setTimeout(() => db()..., 60_000)`
|
|
14
|
+
* scheduled inside a handler would, when the timer fires later, still
|
|
15
|
+
* observe an `als.getStore()` pointing at the (now-completed) request —
|
|
16
|
+
* leading to stale or incorrect SDK behavior. The SSR runtime sets
|
|
17
|
+
* `active.value = false` IMMEDIATELY after the response body is fully
|
|
18
|
+
* materialized; SDK functions check the flag and throw
|
|
19
|
+
* `R402_SDK_OUTSIDE_REQUEST_CONTEXT` when it's false.
|
|
20
|
+
*
|
|
21
|
+
* Likewise `cacheBypassTainted.value` is set to `true` by `getUser()`
|
|
22
|
+
* and payment-primitive SDK calls during render; the SSR runtime returns
|
|
23
|
+
* its final value to the gateway in the Lambda response metadata envelope
|
|
24
|
+
* (NOT via in-process ALS — the gateway runs in a different process).
|
|
25
|
+
*
|
|
26
|
+
* @see openspec/changes/astro-ssr-runtime/specs/functions-sdk-auth-model/spec.md
|
|
27
|
+
* @see openspec/changes/astro-ssr-runtime/specs/routed-http-functions/spec.md
|
|
28
|
+
*/
|
|
29
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
30
|
+
/** The shared ALS instance. Modules in @run402/functions read from
|
|
31
|
+
* this; the SSR Lambda runtime (in @run402/astro) writes to it. */
|
|
32
|
+
export const als = new AsyncLocalStorage();
|
|
33
|
+
/**
|
|
34
|
+
* Read the current request context, or `undefined` if no SSR request
|
|
35
|
+
* is in flight. SDK functions check both this AND `active.value` to
|
|
36
|
+
* decide whether to honor the call.
|
|
37
|
+
*/
|
|
38
|
+
export function getCurrentContext() {
|
|
39
|
+
return als.getStore();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Establish a request context and run a callback inside it. The SSR
|
|
43
|
+
* Lambda runtime calls this exactly once per invocation, wrapping the
|
|
44
|
+
* full `App.render(request)` + body-materialization sequence.
|
|
45
|
+
*
|
|
46
|
+
* The `active` flag is set to `true` initially; the caller (the SSR
|
|
47
|
+
* runtime) flips it to `false` after the response body is materialized.
|
|
48
|
+
* Don't call this from user code — it's the runtime's primitive.
|
|
49
|
+
*/
|
|
50
|
+
export function runWithContext(context, callback) {
|
|
51
|
+
const full = {
|
|
52
|
+
...context,
|
|
53
|
+
cacheBypassTainted: context.cacheBypassTainted ?? { value: false },
|
|
54
|
+
active: context.active ?? { value: true },
|
|
55
|
+
};
|
|
56
|
+
return als.run(full, callback);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Throw a structured `R402_SDK_OUTSIDE_REQUEST_CONTEXT` error. Used by
|
|
60
|
+
* SDK functions when they're invoked with no ALS store OR while the
|
|
61
|
+
* context has been marked inactive.
|
|
62
|
+
*
|
|
63
|
+
* Per the api-error-envelope spec, the thrown error carries:
|
|
64
|
+
* - `code: 'R402_SDK_OUTSIDE_REQUEST_CONTEXT'`
|
|
65
|
+
* - `message`: names the SDK function and the cause
|
|
66
|
+
* - `suggestedFix`: recommends moving the call inside a handler OR
|
|
67
|
+
* not scheduling background work that outlives the response
|
|
68
|
+
* - `docs`: `https://docs.run402.com/sdk/errors#outside-request-context`
|
|
69
|
+
*/
|
|
70
|
+
export class Run402OutsideRequestContextError extends Error {
|
|
71
|
+
code = "R402_SDK_OUTSIDE_REQUEST_CONTEXT";
|
|
72
|
+
docs = "https://docs.run402.com/sdk/errors#outside-request-context";
|
|
73
|
+
suggestedFix;
|
|
74
|
+
sdkFunction;
|
|
75
|
+
cause;
|
|
76
|
+
constructor(sdkFunction, cause) {
|
|
77
|
+
const causeMsg = cause === "no_context"
|
|
78
|
+
? "no active request context (called from module scope or outside a handler)"
|
|
79
|
+
: "request context marked inactive (called from a timer or unawaited promise after response completion)";
|
|
80
|
+
super(`${sdkFunction}: ${causeMsg}`);
|
|
81
|
+
this.name = "Run402OutsideRequestContextError";
|
|
82
|
+
this.sdkFunction = sdkFunction;
|
|
83
|
+
this.cause = cause;
|
|
84
|
+
this.suggestedFix =
|
|
85
|
+
cause === "no_context"
|
|
86
|
+
? `Move the ${sdkFunction} call inside an HTTP request handler or Astro frontmatter. SDK functions cannot resolve project context outside an active request.`
|
|
87
|
+
: `The request that called ${sdkFunction} has already returned. Don't schedule SDK calls in setTimeout / setInterval / unawaited promises that outlive the handler.`;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Assert that a request context is active. Returns the context on
|
|
92
|
+
* success; throws `Run402OutsideRequestContextError` on failure.
|
|
93
|
+
*
|
|
94
|
+
* SDK functions call this as the first line, e.g.:
|
|
95
|
+
*
|
|
96
|
+
* const ctx = requireActiveContext("db");
|
|
97
|
+
* // use ctx.projectId, ctx.request.headers, etc.
|
|
98
|
+
*/
|
|
99
|
+
export function requireActiveContext(sdkFunction) {
|
|
100
|
+
const ctx = als.getStore();
|
|
101
|
+
if (ctx === undefined) {
|
|
102
|
+
throw new Run402OutsideRequestContextError(sdkFunction, "no_context");
|
|
103
|
+
}
|
|
104
|
+
if (!ctx.active.value) {
|
|
105
|
+
throw new Run402OutsideRequestContextError(sdkFunction, "context_inactive");
|
|
106
|
+
}
|
|
107
|
+
return ctx;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Flip the cache-bypass taint flag on the current context. Called by
|
|
111
|
+
* `getUser()` and payment-primitive SDK calls to signal that the
|
|
112
|
+
* rendered response depends on request-scoped auth state and therefore
|
|
113
|
+
* MUST NOT be cached publicly.
|
|
114
|
+
*
|
|
115
|
+
* No-op if there is no active context (rather than throwing — the taint
|
|
116
|
+
* is moot when there's no cache layer to inform).
|
|
117
|
+
*/
|
|
118
|
+
export function taintCacheBypass() {
|
|
119
|
+
const ctx = als.getStore();
|
|
120
|
+
if (ctx !== undefined) {
|
|
121
|
+
ctx.cacheBypassTainted.value = true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Canonical registry of SDK functions that are "payment primitives" for
|
|
126
|
+
* cache-taint purposes. Calling any of these inside an active request
|
|
127
|
+
* context MUST flip `cacheBypassTainted.value = true`. The set is
|
|
128
|
+
* defined here so the spec, runtime, and docs share one source of truth.
|
|
129
|
+
*
|
|
130
|
+
* To add a new payment primitive: append to this set AND ensure the
|
|
131
|
+
* function's implementation calls `taintCacheBypass()` on every entry.
|
|
132
|
+
*
|
|
133
|
+
* @see openspec/changes/astro-ssr-runtime/specs/functions-sdk-auth-model/spec.md
|
|
134
|
+
*/
|
|
135
|
+
export const PAYMENT_PRIMITIVES = new Set([
|
|
136
|
+
// None implemented yet — the registry exists so the contract is
|
|
137
|
+
// explicit and discoverable. Payment-primitive SDK functions added
|
|
138
|
+
// in future changes (per Run402 x402/MPP roadmap) will register here
|
|
139
|
+
// as they land.
|
|
140
|
+
// Example future entries (commented to keep the set actually empty
|
|
141
|
+
// until the helpers ship):
|
|
142
|
+
// "payments.require",
|
|
143
|
+
// "payments.gate",
|
|
144
|
+
// "payments.fulfill",
|
|
145
|
+
]);
|
|
146
|
+
/**
|
|
147
|
+
* Helper for payment-primitive implementations. Wraps the body in a
|
|
148
|
+
* taint-on-entry call so the registry contract is enforced at the
|
|
149
|
+
* SDK layer rather than relying on each implementation to remember.
|
|
150
|
+
*
|
|
151
|
+
* Example:
|
|
152
|
+
* export const requirePayment = withPaymentTaint("payments.require", async (opts) => {
|
|
153
|
+
* // ... actual implementation
|
|
154
|
+
* });
|
|
155
|
+
*/
|
|
156
|
+
export function withPaymentTaint(name, impl) {
|
|
157
|
+
if (!PAYMENT_PRIMITIVES.has(name)) {
|
|
158
|
+
// Doesn't throw — adding a new primitive is a code change and the
|
|
159
|
+
// dev sees this on first invocation. Throwing would block legitimate
|
|
160
|
+
// experimentation. But emit a warning so the registry stays correct.
|
|
161
|
+
// eslint-disable-next-line no-console
|
|
162
|
+
console.warn(`[run402] withPaymentTaint("${name}") called but "${name}" is not in PAYMENT_PRIMITIVES. ` +
|
|
163
|
+
`Add it to packages/functions/src/runtime-context.ts to keep the cache-taint registry consistent.`);
|
|
164
|
+
}
|
|
165
|
+
return (...args) => {
|
|
166
|
+
taintCacheBypass();
|
|
167
|
+
return impl(...args);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=runtime-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"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"}
|