@run402/functions 2.9.0 → 3.0.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/errors.d.ts +89 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +170 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/index.d.ts +98 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +453 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/types.d.ts +58 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +13 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/url-validation.d.ts +31 -0
- package/dist/auth/url-validation.d.ts.map +1 -0
- package/dist/auth/url-validation.js +83 -0
- package/dist/auth/url-validation.js.map +1 -0
- package/dist/auth.d.ts +25 -50
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +34 -103
- package/dist/auth.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +40 -0
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/actor-context-verify.d.ts +95 -0
- package/dist/lib/actor-context-verify.d.ts.map +1 -0
- package/dist/lib/actor-context-verify.js +200 -0
- package/dist/lib/actor-context-verify.js.map +1 -0
- package/dist/runtime-context.d.ts +14 -1
- package/dist/runtime-context.d.ts.map +1 -1
- package/dist/runtime-context.js +60 -0
- package/dist/runtime-context.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK runtime verifier for the gateway-signed actor-context envelope.
|
|
3
|
+
*
|
|
4
|
+
* Why this lives in `packages/functions/src/lib/` (vendored shape):
|
|
5
|
+
* - `@run402/functions` is published independently; it must NOT depend
|
|
6
|
+
* on `@run402/gateway` types or runtime.
|
|
7
|
+
* - The verifier is small, deterministic, and security-critical — easier
|
|
8
|
+
* to audit when it lives next to the consumer.
|
|
9
|
+
* - Matches the convention used for `jwt.ts` (vendored upstream copy of
|
|
10
|
+
* the verifier we trust).
|
|
11
|
+
*
|
|
12
|
+
* Contract — the encoded envelope is `base64url(canonical_json) + "." +
|
|
13
|
+
* base64url(hmac_sha256)`. Canonical JSON has a fixed key order; the
|
|
14
|
+
* verifier doesn't re-canonicalise, it just rehmac's the body bytes that
|
|
15
|
+
* were base64-decoded. (Trying to re-derive canonical JSON from the parsed
|
|
16
|
+
* object would re-introduce key-order brittleness; verify the bytes you
|
|
17
|
+
* received, parse only to read fields.)
|
|
18
|
+
*
|
|
19
|
+
* Lookup of `actor_context_signing_key[kid]`:
|
|
20
|
+
* 1. `ACTOR_CONTEXT_SIGNING_KEY_MAP_JSON` env (`{kid: base64}` JSON).
|
|
21
|
+
* 2. `ACTOR_CONTEXT_SIGNING_KEY_<KID_UPPER>` env (one var per kid).
|
|
22
|
+
* 3. Test injection via `_setActorContextKeyMapForTest` on this module.
|
|
23
|
+
*
|
|
24
|
+
* Verification failure modes (mirrors the gateway side):
|
|
25
|
+
* - "malformed" — encoded shape rejected before parse
|
|
26
|
+
* - "unknown_kid" — envelope's kid not in the verifier map
|
|
27
|
+
* - "bad_signature" — HMAC mismatch
|
|
28
|
+
* - "iss_mismatch" — envelope.iss !== "run402-gateway"
|
|
29
|
+
* - "aud_mismatch" — envelope.aud !== "run402-functions-runtime"
|
|
30
|
+
* - "expired" — envelope.exp <= now
|
|
31
|
+
* - "lifetime_too_long" — envelope.exp - envelope.iat > 60s
|
|
32
|
+
* - "project_id_mismatch" — envelope.project_id !== request's
|
|
33
|
+
* - "request_id_mismatch" — envelope.request_id !== request's
|
|
34
|
+
* - "method_mismatch" — different HTTP method
|
|
35
|
+
* - "host_mismatch" — different host (after default-port normalise)
|
|
36
|
+
* - "path_mismatch" — different path (compared by sha256)
|
|
37
|
+
* - "version_mismatch" — schema version not what we compiled
|
|
38
|
+
*
|
|
39
|
+
* On ANY failure the SDK runtime treats the request as anonymous AND
|
|
40
|
+
* logs `R402_AUTH_ACTOR_HEADER_SPOOF` so spoofs / replays are visible
|
|
41
|
+
* in observability.
|
|
42
|
+
*
|
|
43
|
+
* @see openspec/changes/auth-aware-ssr/specs/routed-http-functions/spec.md
|
|
44
|
+
*/
|
|
45
|
+
import crypto from "node:crypto";
|
|
46
|
+
export const ACTOR_CONTEXT_ENVELOPE_VERSION = 1;
|
|
47
|
+
export const ACTOR_CONTEXT_ENVELOPE_ISS = "run402-gateway";
|
|
48
|
+
export const ACTOR_CONTEXT_ENVELOPE_AUD = "run402-functions-runtime";
|
|
49
|
+
export const ACTOR_CONTEXT_MAX_LIFETIME_SEC = 60;
|
|
50
|
+
/** Inbound header carrying the encoded envelope. The runtime reads from
|
|
51
|
+
* the request headers in `RunRequestContext.request.headers`. */
|
|
52
|
+
export const ACTOR_CONTEXT_HEADER = "x-run402-actor-context";
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Key store (env-loaded, test-injectable)
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
const KEY_MIN_BYTES = 32;
|
|
57
|
+
let keyMap = null;
|
|
58
|
+
function loadKeyMap() {
|
|
59
|
+
if (keyMap)
|
|
60
|
+
return keyMap;
|
|
61
|
+
const map = new Map();
|
|
62
|
+
const mapJson = process.env.ACTOR_CONTEXT_SIGNING_KEY_MAP_JSON;
|
|
63
|
+
if (mapJson) {
|
|
64
|
+
let parsed;
|
|
65
|
+
try {
|
|
66
|
+
parsed = JSON.parse(mapJson);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
throw new Error(`ACTOR_CONTEXT_SIGNING_KEY_MAP_JSON is not valid JSON: ${err.message}`);
|
|
70
|
+
}
|
|
71
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
72
|
+
throw new Error("ACTOR_CONTEXT_SIGNING_KEY_MAP_JSON must be an object {kid: base64}");
|
|
73
|
+
}
|
|
74
|
+
for (const [kid, b64] of Object.entries(parsed)) {
|
|
75
|
+
if (typeof b64 !== "string")
|
|
76
|
+
continue;
|
|
77
|
+
const buf = Buffer.from(b64, "base64");
|
|
78
|
+
if (buf.length >= KEY_MIN_BYTES)
|
|
79
|
+
map.set(kid, buf);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const [envName, envValue] of Object.entries(process.env)) {
|
|
83
|
+
const match = envName.match(/^ACTOR_CONTEXT_SIGNING_KEY_([A-Z0-9_-]+)$/);
|
|
84
|
+
if (!match)
|
|
85
|
+
continue;
|
|
86
|
+
if (envName === "ACTOR_CONTEXT_SIGNING_KEY_CURRENT_KID" ||
|
|
87
|
+
envName === "ACTOR_CONTEXT_SIGNING_KEY_MAP_JSON") {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (typeof envValue !== "string" || envValue.length === 0)
|
|
91
|
+
continue;
|
|
92
|
+
const kid = match[1].toLowerCase().replace(/_/g, "-");
|
|
93
|
+
if (map.has(kid))
|
|
94
|
+
continue;
|
|
95
|
+
const buf = Buffer.from(envValue, "base64");
|
|
96
|
+
if (buf.length >= KEY_MIN_BYTES)
|
|
97
|
+
map.set(kid, buf);
|
|
98
|
+
}
|
|
99
|
+
keyMap = map;
|
|
100
|
+
return map;
|
|
101
|
+
}
|
|
102
|
+
/** Test injection. NEVER call from production code. */
|
|
103
|
+
export function _setActorContextKeyMapForTest(map) {
|
|
104
|
+
if (map === null) {
|
|
105
|
+
keyMap = null;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const m = new Map();
|
|
109
|
+
for (const [kid, value] of Object.entries(map)) {
|
|
110
|
+
const buf = Buffer.isBuffer(value) ? value : Buffer.from(value, "base64");
|
|
111
|
+
if (buf.length < KEY_MIN_BYTES) {
|
|
112
|
+
throw new Error(`Actor-context key for kid "${kid}" is too short`);
|
|
113
|
+
}
|
|
114
|
+
m.set(kid, buf);
|
|
115
|
+
}
|
|
116
|
+
keyMap = m;
|
|
117
|
+
}
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Verifier
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
export function verifyActorContextEnvelope(encoded, ctx) {
|
|
122
|
+
if (typeof encoded !== "string" || encoded.length === 0) {
|
|
123
|
+
return { ok: false, reason: "malformed" };
|
|
124
|
+
}
|
|
125
|
+
const dot = encoded.indexOf(".");
|
|
126
|
+
if (dot <= 0 || dot === encoded.length - 1) {
|
|
127
|
+
return { ok: false, reason: "malformed" };
|
|
128
|
+
}
|
|
129
|
+
const bodyB64 = encoded.slice(0, dot);
|
|
130
|
+
const sigB64 = encoded.slice(dot + 1);
|
|
131
|
+
if (!/^[A-Za-z0-9_-]+$/.test(bodyB64) || !/^[A-Za-z0-9_-]+$/.test(sigB64)) {
|
|
132
|
+
return { ok: false, reason: "malformed" };
|
|
133
|
+
}
|
|
134
|
+
let bodyBuf;
|
|
135
|
+
let envelope;
|
|
136
|
+
try {
|
|
137
|
+
bodyBuf = Buffer.from(bodyB64, "base64url");
|
|
138
|
+
envelope = JSON.parse(bodyBuf.toString("utf8"));
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return { ok: false, reason: "malformed" };
|
|
142
|
+
}
|
|
143
|
+
if (!envelope || typeof envelope !== "object") {
|
|
144
|
+
return { ok: false, reason: "malformed" };
|
|
145
|
+
}
|
|
146
|
+
if (envelope.v !== ACTOR_CONTEXT_ENVELOPE_VERSION) {
|
|
147
|
+
return { ok: false, reason: "version_mismatch" };
|
|
148
|
+
}
|
|
149
|
+
if (typeof envelope.kid !== "string")
|
|
150
|
+
return { ok: false, reason: "malformed" };
|
|
151
|
+
const key = loadKeyMap().get(envelope.kid);
|
|
152
|
+
if (!key)
|
|
153
|
+
return { ok: false, reason: "unknown_kid" };
|
|
154
|
+
const sigBuf = Buffer.from(sigB64, "base64url");
|
|
155
|
+
const expectedSig = crypto.createHmac("sha256", key).update(bodyBuf).digest();
|
|
156
|
+
if (sigBuf.length !== expectedSig.length) {
|
|
157
|
+
return { ok: false, reason: "bad_signature" };
|
|
158
|
+
}
|
|
159
|
+
if (!crypto.timingSafeEqual(sigBuf, expectedSig)) {
|
|
160
|
+
return { ok: false, reason: "bad_signature" };
|
|
161
|
+
}
|
|
162
|
+
if (envelope.iss !== ACTOR_CONTEXT_ENVELOPE_ISS) {
|
|
163
|
+
return { ok: false, reason: "iss_mismatch" };
|
|
164
|
+
}
|
|
165
|
+
if (envelope.aud !== ACTOR_CONTEXT_ENVELOPE_AUD) {
|
|
166
|
+
return { ok: false, reason: "aud_mismatch" };
|
|
167
|
+
}
|
|
168
|
+
if (typeof envelope.iat !== "number" || typeof envelope.exp !== "number") {
|
|
169
|
+
return { ok: false, reason: "malformed" };
|
|
170
|
+
}
|
|
171
|
+
if (envelope.exp - envelope.iat > ACTOR_CONTEXT_MAX_LIFETIME_SEC) {
|
|
172
|
+
return { ok: false, reason: "lifetime_too_long" };
|
|
173
|
+
}
|
|
174
|
+
const nowSec = Math.floor((ctx.now ?? new Date()).getTime() / 1000);
|
|
175
|
+
if (envelope.exp <= nowSec)
|
|
176
|
+
return { ok: false, reason: "expired" };
|
|
177
|
+
if (envelope.project_id !== ctx.projectId) {
|
|
178
|
+
return { ok: false, reason: "project_id_mismatch" };
|
|
179
|
+
}
|
|
180
|
+
if (envelope.request_id !== ctx.requestId) {
|
|
181
|
+
return { ok: false, reason: "request_id_mismatch" };
|
|
182
|
+
}
|
|
183
|
+
if (envelope.method !== ctx.method.toUpperCase()) {
|
|
184
|
+
return { ok: false, reason: "method_mismatch" };
|
|
185
|
+
}
|
|
186
|
+
if (envelope.host !== normaliseHost(ctx.host)) {
|
|
187
|
+
return { ok: false, reason: "host_mismatch" };
|
|
188
|
+
}
|
|
189
|
+
if (envelope.path_hash !== sha256Hex(ctx.path)) {
|
|
190
|
+
return { ok: false, reason: "path_mismatch" };
|
|
191
|
+
}
|
|
192
|
+
return { ok: true, envelope };
|
|
193
|
+
}
|
|
194
|
+
function normaliseHost(host) {
|
|
195
|
+
return host.toLowerCase().replace(/:80$/, "").replace(/:443$/, "");
|
|
196
|
+
}
|
|
197
|
+
function sha256Hex(s) {
|
|
198
|
+
return crypto.createHash("sha256").update(s, "utf8").digest("hex");
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=actor-context-verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor-context-verify.js","sourceRoot":"","sources":["../../src/lib/actor-context-verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,15 @@
|
|
|
27
27
|
* @see openspec/changes/astro-ssr-runtime/specs/routed-http-functions/spec.md
|
|
28
28
|
*/
|
|
29
29
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
30
|
+
import { type VerifiedActorPayload } from "./lib/actor-context-verify.js";
|
|
31
|
+
/** Capability `auth-aware-ssr`: the verified actor payload the SDK
|
|
32
|
+
* exposes via `auth.user()` etc. Populated by `runWithContext` after
|
|
33
|
+
* it verifies the inbound actor-context envelope. `null` when the
|
|
34
|
+
* request is anonymous OR when verification failed (defense in depth:
|
|
35
|
+
* forged envelopes never surface as a non-null actor). */
|
|
36
|
+
export type ActorContext = VerifiedActorPayload & {
|
|
37
|
+
sessionId: string;
|
|
38
|
+
};
|
|
30
39
|
/** The shape stored in AsyncLocalStorage. See the spec referenced above
|
|
31
40
|
* for the canonical definition. */
|
|
32
41
|
export interface RunRequestContext {
|
|
@@ -52,6 +61,10 @@ export interface RunRequestContext {
|
|
|
52
61
|
url: string;
|
|
53
62
|
headers: Record<string, string | string[] | undefined>;
|
|
54
63
|
};
|
|
64
|
+
/** Capability `auth-aware-ssr`: actor populated from the verified
|
|
65
|
+
* gateway-signed envelope. The SDK's `auth.user()` returns this
|
|
66
|
+
* verbatim; consumer code never sees the raw envelope. */
|
|
67
|
+
actor: ActorContext | null;
|
|
55
68
|
/** Mutable ref: SDK functions that read request-scoped auth or invoke
|
|
56
69
|
* payment primitives set `value = true`. The SSR Lambda runtime
|
|
57
70
|
* returns the final value to the gateway in the response metadata
|
|
@@ -85,7 +98,7 @@ export declare function getCurrentContext(): RunRequestContext | undefined;
|
|
|
85
98
|
* runtime) flips it to `false` after the response body is materialized.
|
|
86
99
|
* Don't call this from user code — it's the runtime's primitive.
|
|
87
100
|
*/
|
|
88
|
-
export declare function runWithContext<T>(context: Omit<RunRequestContext, "cacheBypassTainted" | "active"> & Partial<Pick<RunRequestContext, "cacheBypassTainted" | "active">>, callback: () => Promise<T> | T): Promise<T> | T;
|
|
101
|
+
export declare function runWithContext<T>(context: Omit<RunRequestContext, "cacheBypassTainted" | "active" | "actor"> & Partial<Pick<RunRequestContext, "cacheBypassTainted" | "active" | "actor">>, callback: () => Promise<T> | T): Promise<T> | T;
|
|
89
102
|
/**
|
|
90
103
|
* Throw a structured `R402_SDK_OUTSIDE_REQUEST_CONTEXT` error. Used by
|
|
91
104
|
* SDK functions when they're invoked with no ALS store OR while the
|
|
@@ -1 +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;
|
|
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;AACrD,OAAO,EAGL,KAAK,oBAAoB,EAE1B,MAAM,+BAA+B,CAAC;AAEvC;;;;2DAI2D;AAC3D,MAAM,MAAM,YAAY,GAAG,oBAAoB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE;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;;+DAE2D;IAC3D,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B;;;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,GAAG,OAAO,CAAC,GACzE,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,oBAAoB,GAAG,QAAQ,GAAG,OAAO,CAAC,CAAC,EAC7E,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAC7B,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAgBhB;AA6DD;;;;;;;;;;;GAWG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,sCAAsC;IACnD,QAAQ,CAAC,IAAI,iEAAiE;IAC9E,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"}
|
package/dist/runtime-context.js
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* @see openspec/changes/astro-ssr-runtime/specs/routed-http-functions/spec.md
|
|
28
28
|
*/
|
|
29
29
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
30
|
+
import { verifyActorContextEnvelope, ACTOR_CONTEXT_HEADER, } from "./lib/actor-context-verify.js";
|
|
30
31
|
/** The shared ALS instance. Modules in @run402/functions read from
|
|
31
32
|
* this; the SSR Lambda runtime (in @run402/astro) writes to it. */
|
|
32
33
|
export const als = new AsyncLocalStorage();
|
|
@@ -48,13 +49,72 @@ export function getCurrentContext() {
|
|
|
48
49
|
* Don't call this from user code — it's the runtime's primitive.
|
|
49
50
|
*/
|
|
50
51
|
export function runWithContext(context, callback) {
|
|
52
|
+
// Resolve the actor either from the caller-provided override (tests, the
|
|
53
|
+
// SSR runtime when it has pre-verified the envelope) or by verifying the
|
|
54
|
+
// inbound actor-context header against the request bound to this context.
|
|
55
|
+
// Failure is non-fatal: the request becomes anonymous AND we log
|
|
56
|
+
// `R402_AUTH_ACTOR_HEADER_SPOOF` so spoof attempts surface in metrics.
|
|
57
|
+
const actor = context.actor !== undefined
|
|
58
|
+
? context.actor
|
|
59
|
+
: verifyEnvelopeFromRequest(context);
|
|
51
60
|
const full = {
|
|
52
61
|
...context,
|
|
62
|
+
actor,
|
|
53
63
|
cacheBypassTainted: context.cacheBypassTainted ?? { value: false },
|
|
54
64
|
active: context.active ?? { value: true },
|
|
55
65
|
};
|
|
56
66
|
return als.run(full, callback);
|
|
57
67
|
}
|
|
68
|
+
function verifyEnvelopeFromRequest(ctx) {
|
|
69
|
+
const headers = ctx.request.headers;
|
|
70
|
+
const headerValue = headers[ACTOR_CONTEXT_HEADER];
|
|
71
|
+
const encoded = Array.isArray(headerValue) ? headerValue[0] : headerValue;
|
|
72
|
+
if (!encoded || typeof encoded !== "string")
|
|
73
|
+
return null;
|
|
74
|
+
// The runtime sees `request.url` as a full path-only string from the
|
|
75
|
+
// SSR Lambda envelope (e.g. `/forum/topic-1?q=astro`). The signing side
|
|
76
|
+
// hashed the path-only URL, so we hash the same here. The query string
|
|
77
|
+
// is part of the binding so `/forum?topic=1` and `/forum?topic=2` can't
|
|
78
|
+
// accept the same envelope.
|
|
79
|
+
const path = ctx.request.url;
|
|
80
|
+
const outcome = verifyActorContextEnvelope(encoded, {
|
|
81
|
+
projectId: ctx.projectId,
|
|
82
|
+
requestId: ctx.requestId,
|
|
83
|
+
method: ctx.request.method,
|
|
84
|
+
host: ctx.host,
|
|
85
|
+
path,
|
|
86
|
+
});
|
|
87
|
+
if (!outcome.ok) {
|
|
88
|
+
logActorContextSpoof(outcome.reason, ctx.requestId);
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
id: outcome.envelope.actor.id,
|
|
93
|
+
email: outcome.envelope.actor.email,
|
|
94
|
+
emailVerified: outcome.envelope.actor.emailVerified,
|
|
95
|
+
authTime: outcome.envelope.actor.authTime,
|
|
96
|
+
amr: outcome.envelope.actor.amr,
|
|
97
|
+
amrTimes: outcome.envelope.actor.amrTimes,
|
|
98
|
+
authzVersion: outcome.envelope.actor.authzVersion,
|
|
99
|
+
// session_id is NOT in the envelope — it's gateway-internal state.
|
|
100
|
+
// For now we mint a deterministic-by-request id so downstream code
|
|
101
|
+
// has a string to hang `db()` set_config on. Once the gateway adds
|
|
102
|
+
// session_id to the envelope (planned in section 4 of the spec),
|
|
103
|
+
// populate it here from outcome.envelope.actor.sessionId.
|
|
104
|
+
sessionId: outcome.envelope.request_id,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function logActorContextSpoof(reason, requestId) {
|
|
108
|
+
// Structured one-line log so observability can alert on rate. The
|
|
109
|
+
// SDK runs in Lambda; CloudWatch picks this up.
|
|
110
|
+
// eslint-disable-next-line no-console
|
|
111
|
+
console.warn(JSON.stringify({
|
|
112
|
+
level: "warn",
|
|
113
|
+
event: "R402_AUTH_ACTOR_HEADER_SPOOF",
|
|
114
|
+
reason,
|
|
115
|
+
request_id: requestId,
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
58
118
|
/**
|
|
59
119
|
* Throw a structured `R402_SDK_OUTSIDE_REQUEST_CONTEXT` error. Used by
|
|
60
120
|
* SDK functions when they're invoked with no ALS store OR while the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@run402/functions",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "In-function helper library for Run402 serverless functions — db, adminDb, getUser, email, ai, assets, verifyWebhook. Auto-bundled into deployed functions; also installable for local TypeScript autocomplete.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|