@patchstack/connect 0.3.16 → 0.3.17

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/protect/runtime.js","../src/protect/engine/client.js","../src/protect/engine/request.js","../src/protect/engine/normalizer.js","../src/protect/engine/engine.js","../src/protect/engine/pulse-client.js","../src/protect/engine/fetch.js","../src/protect/engine/node.js","../src/protect/egress.js","../src/protect/defaults.js","../src/protect/supabase-guard.js"],"sourcesContent":["// @patchstack/protect — \"Protect = respond\".\n//\n// One entry point that composes the node-waf engine + adapters with:\n// - a rule source: an explicit bundle, or fetched from the Patchstack API (token),\n// with a disk cache so the engine keeps working on last-known-good if the API is down\n// - execution modes: 'dry-run' (detect + log, never block — the safe onramp) and\n// 'block' (enforce). Default is 'dry-run'.\n// - fail-open everywhere: a rule/engine error never blocks (or crashes) a request.\n//\n// Runtime guards: .express(), .node(), .fetch(handler) / .fetchGuard() — same policy,\n// every runtime an AI builder deploys to.\n// Vendored node-waf engine (this package is self-contained — no @patchstack/node-waf dep).\nimport { RuleEngine, PatchstackRuleClient } from './engine/index.js';\nimport { PulseRuleClient } from './engine/pulse-client.js';\nimport { fromFetchRequest } from './engine/fetch.js';\nimport { fromNodeRequest } from './engine/node.js';\nimport { installEgressGuard } from './egress.js';\nimport { DEFAULT_RESPONSE_RULES, DEFAULT_EGRESS_RULES } from './defaults.js';\nimport { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\n// Supabase-tunnel guard for AI-builder apps (Lovable / TanStack Start + Supabase).\nexport { createSupabaseGuard, GUARD_PATH } from './supabase-guard.js';\n\n// Per-site live rule client (Pulse). Re-exported for callers/tests that want to use it directly.\nexport { PulseRuleClient };\n\n// Server-function guard. Modern Lovable apps mutate data through TanStack server functions\n// (browser → server fn → server-side Supabase client), which bypass the browser-side tunnel the\n// Supabase guard relies on. This inspects the decoded server-fn call args against the SAME policy\n// by feeding them through fetchGuard (the args become the request body, so the engine resolves\n// `post.<field>` exactly as it does for a tunneled Supabase insert). Returns a block receipt\n// { rule?, message } to throw on, or null to allow (also null in dry-run — the detection is still\n// recorded by fetchGuard). Fail-open on any error.\nexport function createServerFnGuard({ protection }) {\n const guard = protection.fetchGuard();\n return async (data) => {\n let res;\n try {\n const req = new Request('https://patchstack.local/_serverfn', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(data ?? {}),\n });\n res = await guard(req);\n } catch {\n return null; // fail open\n }\n if (!res) return null; // allowed (or dry-run)\n let body = {};\n try {\n body = await res.clone().json();\n } catch {\n /* non-JSON block response */\n }\n return { rule: body.rule, message: body.message || 'Blocked by Patchstack' };\n };\n}\n\nexport async function createProtection(options = {}) {\n const mode = options.mode === 'block' ? 'block' : 'dry-run';\n const onError = options.onError;\n const onDetect = options.onDetect ?? defaultOnDetect;\n\n const bundle = await resolveRules(options);\n const incoming = bundle.firewall ?? [];\n\n // Split the delivered ruleset by phase (default \"request\"), merging phase defaults +\n // per-call overrides. Detection is fully rule-driven — nothing hardcoded.\n const requestRules = byPhase(incoming, 'request');\n const responseRules = [...(options.responseRules ?? DEFAULT_RESPONSE_RULES), ...byPhase(incoming, 'response')];\n const egressRules = [...(options.egressRules ?? DEFAULT_EGRESS_RULES), ...byPhase(incoming, 'egress')];\n\n const engine = new RuleEngine({\n firewall: requestRules,\n whitelists: bundle.whitelists,\n whitelist_keys: bundle.whitelist_keys,\n onError\n });\n // One engine per response rule so we can find ALL matches (to redact each). `action:\n // \"redact\"` masks the offending span(s); anything else withholds the whole response.\n const responseRuleSet = responseRules.map((rule) => ({\n rule,\n engine: new RuleEngine({ firewall: [rule], onError }),\n redactors: rule.action === 'redact' ? extractRedactors(rule) : null\n }));\n const egressEngine = new RuleEngine({ firewall: egressRules, onError });\n const maskFn =\n typeof options.maskWith === 'function'\n ? options.maskWith\n : () => (typeof options.maskWith === 'string' ? options.maskWith : '[REDACTED]');\n\n // Given a request/egress result, enforce (block mode) or just record (dry-run).\n const decide = (phase, result, block, allow) => {\n if (!result || !result.blocked) return allow();\n onDetect({ phase, mode, category: result.rule?.category, rule: result.rule, message: result.message });\n return mode === 'block' ? block() : allow();\n };\n\n // Response phase core: screen a text body → { verdict: 'pass'|'block'|'redact', body? }.\n // redact masks matched spans; block withholds; block wins over redact. Enforcement only in\n // block mode (dry-run records via onDetect but returns 'pass').\n const isTextCT = (ct) => {\n ct = (ct || '').toLowerCase();\n return ct === '' || /(json|text|xml|html|javascript|csv|yaml|x-www-form-urlencoded)/.test(ct);\n };\n const screenText = (text, meta) => {\n let blockRule = null;\n const redactions = [];\n for (const { rule, engine: re, redactors } of responseRuleSet) {\n let result;\n try {\n result = re.evaluate({ _response: { ...meta, body: text } });\n } catch (err) {\n onError?.(err);\n continue;\n }\n if (!result.blocked) continue;\n onDetect({ phase: 'response', mode, category: rule.category, rule, message: result.message });\n if (mode !== 'block') continue; // dry-run: observe only\n if (redactors && redactors.length) redactions.push({ rule, redactors });\n else if (!blockRule) blockRule = rule;\n }\n if (mode !== 'block' || (!blockRule && !redactions.length)) return { verdict: 'pass' };\n if (blockRule) return { verdict: 'block' };\n let body = text;\n for (const { rule, redactors } of redactions) body = applyRedactors(body, redactors, maskFn(rule.category));\n return { verdict: 'redact', body };\n };\n\n // Screen a fetch Response (used by .fetch() and — via protection.screenResponse — the Supabase guard).\n const screenResp = async (response) => {\n const text = await readTextResponse(response);\n if (text == null) return response;\n const r = screenText(text, { status: response.status, headers: headerObject(response.headers) });\n if (r.verdict === 'block') return leakResponse();\n if (r.verdict === 'redact') return rebuildResponse(response, r.body);\n return response;\n };\n\n // Wrap a Node ServerResponse so its (buffered, text) body is screened before it's sent.\n // Opt-in (buffering can delay a streamed response); over 512 KiB it stops buffering and\n // passes through unscanned.\n const wrapNodeResponse = (res) => {\n const origWrite = res.write.bind(res);\n const origEnd = res.end.bind(res);\n const chunks = [];\n let size = 0;\n let overflow = false;\n const MAX = 512 * 1024;\n const collect = (chunk, enc) => {\n if (chunk == null) return;\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, typeof enc === 'string' ? enc : 'utf8');\n size += buf.length;\n if (size > MAX) { overflow = true; return; }\n chunks.push(buf);\n };\n res.write = function (chunk, enc, cb) {\n if (overflow) return origWrite(chunk, enc, cb);\n collect(chunk, enc);\n if (typeof enc === 'function') enc();\n else if (typeof cb === 'function') cb();\n return true;\n };\n res.end = function (chunk, enc, cb) {\n if (typeof chunk === 'function') { cb = chunk; chunk = undefined; enc = undefined; }\n else if (typeof enc === 'function') { cb = enc; enc = undefined; }\n if (overflow) { if (chunk != null) origWrite(chunk, enc); return origEnd(cb); }\n collect(chunk, enc);\n const text = Buffer.concat(chunks).toString('utf8');\n let ct = res.getHeader ? res.getHeader('content-type') : undefined;\n if (Array.isArray(ct)) ct = ct[0];\n if (!isTextCT(ct)) { for (const c of chunks) origWrite(c); return origEnd(cb); }\n let r;\n try {\n r = screenText(text, { status: res.statusCode, headers: {} });\n } catch (err) {\n onError?.(err);\n for (const c of chunks) origWrite(c);\n return origEnd(cb);\n }\n if (r.verdict === 'block') {\n res.statusCode = 500;\n try { res.setHeader('content-type', 'application/json'); } catch { /* headers sent */ }\n return origEnd(JSON.stringify({ error: 'Response withheld by Patchstack (sensitive data detected)' }), cb);\n }\n if (r.verdict === 'redact') {\n try { res.removeHeader && res.removeHeader('content-length'); } catch { /* ignore */ }\n return origEnd(r.body, cb);\n }\n for (const c of chunks) origWrite(c);\n return origEnd(cb);\n };\n };\n\n // Egress phase: is this outbound call blocked? (records detection either way)\n const allow = new Set((options.allowHosts ?? []).map((h) => String(h).toLowerCase()));\n const egressShouldBlock = (url, host, method) => {\n if (host && allow.has(host.toLowerCase())) return false;\n let result;\n try {\n result = egressEngine.evaluate({ _egress: { url, host, method } });\n } catch (err) {\n onError?.(err);\n return false;\n }\n if (!result.blocked) return false;\n onDetect({ phase: 'egress', mode, category: result.rule?.category, rule: result.rule, message: result.message });\n return mode === 'block';\n };\n\n const protection = {\n mode,\n rules: { request: requestRules, response: responseRules, egress: egressRules },\n\n // Screen a fetch Response through the response-phase rules (redact/block). Used by\n // .fetch(), and by the Supabase guard on its forwarded upstream response.\n screenResponse: (response) => screenResp(response),\n\n // (request) => Response | null (null = allow, caller proceeds). Request phase only.\n fetchGuard() {\n return async (request) => {\n let result;\n try {\n result = engine.evaluate(await fromFetchRequest(request));\n } catch (err) {\n onError?.(err);\n return null; // fail open\n }\n return decide('request', result, () => blockResponse(result), () => null);\n };\n },\n\n // Wrap a fetch handler: screens the request, then the response (redact/block).\n fetch(handler) {\n const guard = protection.fetchGuard();\n return async (request, ...rest) => {\n const blocked = await guard(request);\n if (blocked) return blocked;\n const response = await handler(request, ...rest);\n return screenResp(response);\n };\n },\n\n // Express middleware (request phase; expects express-parsed req.query/req.body).\n // Pass { screenResponses: true } to also screen the outgoing response (buffers it).\n express(exprOptions = {}) {\n return (req, res, next) => {\n let result;\n try {\n result = engine.evaluate(req);\n } catch (err) {\n onError?.(err);\n if (exprOptions.screenResponses) wrapNodeResponse(res);\n return next();\n }\n decide(\n 'request',\n result,\n () => res.status(403).json(blockBody(result)),\n () => {\n if (exprOptions.screenResponses) wrapNodeResponse(res);\n next();\n },\n );\n };\n },\n\n // Node / Connect middleware — buffers the body itself (request phase).\n // Pass { screenResponses: true } to also screen the outgoing response (buffers it).\n node(nodeOptions = {}) {\n const maxBytes = nodeOptions.maxBodyBytes ?? 1024 * 1024;\n return (req, res, next) => {\n const chunks = [];\n let size = 0;\n let overflow = false;\n req.on('data', (chunk) => {\n size += chunk.length;\n if (size > maxBytes) {\n overflow = true;\n return;\n }\n chunks.push(chunk);\n });\n req.on('error', (err) => {\n onError?.(err);\n next();\n });\n req.on('end', () => {\n const rawBody = overflow ? '' : Buffer.concat(chunks).toString('utf8');\n let shaped;\n let result;\n try {\n shaped = fromNodeRequest(req, rawBody);\n result = engine.evaluate(shaped);\n } catch (err) {\n onError?.(err);\n return next();\n }\n decide(\n 'request',\n result,\n () => {\n res.statusCode = 403;\n res.setHeader('content-type', 'application/json');\n res.end(JSON.stringify(blockBody(result)));\n },\n () => {\n // This guard consumed the request stream to screen it; re-expose the parsed\n // body so a downstream handler (without its own body-parser) can read it.\n if (req.body === undefined) req.body = shaped.body;\n if (nodeOptions.screenResponses) wrapNodeResponse(res);\n next();\n },\n );\n });\n };\n },\n };\n\n // Egress interception is opt-in (it wraps the global fetch).\n if (options.egress) {\n protection.uninstallEgress = installEgressGuard({ shouldBlock: egressShouldBlock, onBlock: options.onEgressBlock });\n }\n\n return protection;\n}\n\n// --- phase / response helpers -------------------------------------------\n\nfunction byPhase(rules, phase) {\n return (rules ?? []).filter((r) => (r.phase ?? 'request') === phase);\n}\n\nasync function readTextResponse(response) {\n if (!response || typeof response.clone !== 'function') return null;\n const ct = (response.headers?.get?.('content-type') || '').toLowerCase();\n const isText = ct === '' || /(json|text|xml|html|javascript|csv|yaml|x-www-form-urlencoded)/.test(ct);\n if (!isText) return null;\n const len = Number(response.headers?.get?.('content-length') || 0);\n if (len && len > 512 * 1024) return null;\n try {\n const text = await response.clone().text();\n return text.length > 512 * 1024 ? null : text;\n } catch {\n return null;\n }\n}\n\nfunction headerObject(headers) {\n const out = {};\n headers?.forEach?.((v, k) => { out[k.toLowerCase()] = v; });\n return out;\n}\n\n// Derive redaction targets from a rule's own conditions: regex → mask every match;\n// contains/stripos → mask the literal. (Other match types can't identify a span → the\n// rule falls back to block.)\nfunction extractRedactors(rule) {\n const out = [];\n const walk = (conds) => {\n for (const c of conds ?? []) {\n if (Array.isArray(c.rules)) walk(c.rules);\n const m = c.match;\n if (!m) continue;\n if (m.type === 'regex' && typeof m.value === 'string') {\n const parsed = m.value.match(/^\\/(.+)\\/([a-z]*)$/is);\n if (parsed) {\n const flags = parsed[2].includes('g') ? parsed[2] : parsed[2] + 'g';\n try {\n out.push({ re: new RegExp(parsed[1], flags) });\n } catch {\n /* skip invalid */\n }\n }\n } else if ((m.type === 'contains' || m.type === 'stripos') && m.value != null) {\n out.push({ literal: String(m.value) });\n }\n }\n };\n walk(rule.rule_v2);\n return out;\n}\n\nfunction applyRedactors(body, redactors, mask) {\n let out = body;\n for (const r of redactors) {\n if (r.re) out = out.replace(r.re, mask);\n else if (r.literal) out = out.split(r.literal).join(mask);\n }\n return out;\n}\n\nfunction rebuildResponse(response, body) {\n const headers = new Headers(response.headers);\n headers.delete('content-length'); // body length changed after redaction\n return new Response(body, { status: response.status, statusText: response.statusText, headers });\n}\n\nfunction leakResponse() {\n return new Response(JSON.stringify({ error: 'Response withheld by Patchstack (sensitive data detected)' }), {\n status: 500,\n headers: { 'content-type': 'application/json' }\n });\n}\n\n// --- rule source --------------------------------------------------------\n\nasync function resolveRules(options) {\n if (options.siteUuid) {\n const client = new PulseRuleClient({ siteUuid: options.siteUuid, baseUrl: options.pulseRulesUrl });\n const res = await client.getRules();\n if (res.success) {\n const bundle = normalizeBundle(res);\n cacheWrite(options.cacheDir, bundle);\n return bundle;\n }\n const cached = cacheRead(options.cacheDir);\n if (cached) {\n options.onError?.(new Error(`pulse rule fetch failed (${res.error}); using cached bundle`));\n return normalizeBundle(cached);\n }\n if (options.rules) {\n options.onError?.(new Error(`pulse rule fetch failed (${res.error}); using bundled fallback`));\n return normalizeBundle(options.rules);\n }\n options.onError?.(new Error(`pulse rule fetch failed (${res.error}); no cache — running with no rules`));\n return emptyBundle();\n }\n\n if (options.token) {\n const client = new PatchstackRuleClient({ token: options.token, baseUrl: options.baseUrl });\n const res = await client.getRules();\n if (res.success) {\n const bundle = normalizeBundle(res);\n cacheWrite(options.cacheDir, bundle);\n return bundle;\n }\n const cached = cacheRead(options.cacheDir);\n if (cached) {\n options.onError?.(new Error(`rule fetch failed (${res.error}); using cached bundle`));\n return normalizeBundle(cached);\n }\n options.onError?.(new Error(`rule fetch failed (${res.error}); no cache — running with no rules`));\n return emptyBundle();\n }\n\n if (options.rules) {\n return normalizeBundle(options.rules);\n }\n\n return emptyBundle();\n}\n\nfunction normalizeBundle(b) {\n return {\n firewall: Array.isArray(b.firewall) ? b.firewall : [],\n whitelists: Array.isArray(b.whitelists) ? b.whitelists : [],\n whitelist_keys: b.whitelist_keys ?? {},\n };\n}\n\nfunction emptyBundle() {\n return { firewall: [], whitelists: [], whitelist_keys: {} };\n}\n\nfunction cachePath(dir) {\n return join(dir, 'patchstack-rules.json');\n}\n\nfunction cacheWrite(dir, bundle) {\n if (!dir) return;\n try {\n mkdirSync(dir, { recursive: true });\n writeFileSync(cachePath(dir), JSON.stringify(bundle));\n } catch {\n /* cache is best-effort */\n }\n}\n\nfunction cacheRead(dir) {\n if (!dir) return null;\n try {\n return JSON.parse(readFileSync(cachePath(dir), 'utf8'));\n } catch {\n return null;\n }\n}\n\n// --- responses ----------------------------------------------------------\n\nfunction blockBody(result) {\n return {\n error: 'Blocked by Patchstack',\n rule: result.rule?.id,\n message: result.message,\n };\n}\n\nfunction blockResponse(result) {\n return new Response(JSON.stringify(blockBody(result)), {\n status: 403,\n headers: { 'content-type': 'application/json' },\n });\n}\n\nfunction defaultOnDetect({ phase, mode, category, rule, message }) {\n const tag = mode === 'block' ? 'BLOCK' : 'DETECT (dry-run)';\n console.warn(`[patchstack] ${tag} phase=${phase ?? 'request'} category=${category ?? '?'} rule=${rule?.id ?? '?'} ${message ?? ''}`.trim());\n}\n","const DEFAULT_BASE_URL = 'https://api.patchstack.com';\nconst DEFAULT_CACHE_TTL = 300_000;\n\nexport class PatchstackRuleClient {\n #token;\n #baseUrl;\n #cacheTtl;\n #cache = null;\n #cacheTime = null;\n\n constructor({ token, baseUrl, cacheTtl } = {}) {\n this.#token = token ?? process.env.PATCHSTACK_WAF_TOKEN;\n this.#baseUrl = baseUrl ?? process.env.PATCHSTACK_WAF_API_URL ?? DEFAULT_BASE_URL;\n this.#cacheTtl = cacheTtl ?? DEFAULT_CACHE_TTL;\n\n if (!this.#token) {\n throw new Error('Patchstack WAF token is required. Pass { token } or set PATCHSTACK_WAF_TOKEN env var.');\n }\n }\n\n async getRules() {\n const now = Date.now();\n\n if (this.#cache && this.#cacheTime && (now - this.#cacheTime) < this.#cacheTtl) {\n return this.#cache;\n }\n\n const url = `${this.#baseUrl}/api/get-rules/3`;\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.#token}`,\n 'LicenseID': '1' // Hard-coded, is never actually used but needed by the API\n },\n body: JSON.stringify({}),\n signal: AbortSignal.timeout(30_000)\n });\n\n if (!response.ok) {\n return {\n success: false,\n error: `API returned ${response.status}: ${response.statusText}`,\n firewall: [],\n whitelists: [],\n whitelist_keys: {}\n };\n }\n\n const data = await response.json();\n\n const result = {\n success: true,\n firewall: Array.isArray(data.firewall) ? data.firewall : [],\n whitelists: Array.isArray(data.whitelists) ? data.whitelists : [],\n whitelist_keys: data.whitelist_keys ?? {}\n };\n\n this.#cache = result;\n this.#cacheTime = now;\n\n return result;\n } catch (err) {\n return {\n success: false,\n error: err.name === 'TimeoutError'\n ? 'Request timed out'\n : err.message,\n firewall: [],\n whitelists: [],\n whitelist_keys: {}\n };\n }\n }\n\n clearCache() {\n this.#cache = null;\n this.#cacheTime = null;\n }\n}\n","// WinterCG-safe base64 decode: use Buffer on Node, fall back to atob/TextDecoder on\n// edge runtimes (Cloudflare Workers, Deno, Bun) where Buffer may be absent. Keeps the\n// engine hot path free of Node-only APIs (per the ADR engine-language decision).\nfunction base64DecodeUtf8(value) {\n const str = String(value);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'base64').toString('utf-8');\n }\n const binary = atob(str);\n const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\nexport class RequestResolver {\n #req;\n #cookies;\n\n constructor(req) {\n this.#req = req;\n this.#cookies = null;\n }\n\n resolve(parameter) {\n if (!parameter || parameter === 'false') {\n return [null];\n }\n\n if (parameter === 'rules') {\n return [null];\n }\n\n if (parameter === 'raw') {\n return this.#resolveRaw();\n }\n\n if (parameter === 'all') {\n return this.#resolveAll();\n }\n\n const dotIndex = parameter.indexOf('.');\n if (dotIndex === -1) {\n return [];\n }\n\n const source = parameter.substring(0, dotIndex);\n const key = parameter.substring(dotIndex + 1);\n\n switch (source) {\n case 'get':\n return this.#resolveGet(key);\n case 'post':\n return this.#resolvePost(key);\n case 'request':\n return this.#resolveRequest(key);\n case 'cookie':\n return this.#resolveCookie(key);\n case 'server':\n return this.#resolveServer(key);\n case 'files':\n return this.#resolveFiles(key);\n case 'response':\n return this.#resolveResponse(key);\n case 'egress':\n return this.#resolveEgress(key);\n default:\n return [];\n }\n }\n\n // Response-phase sources (req._response = { status, headers, body }). Lets rules inspect\n // what the app is about to SEND — e.g. a leaked secret in the body — regardless of route.\n #resolveResponse(key) {\n const resp = this.#req._response;\n if (!resp) {\n return [];\n }\n if (key === 'status') {\n return resp.status !== undefined ? [String(resp.status)] : [];\n }\n if (key === 'body') {\n return resp.body != null && resp.body !== '' ? [resp.body] : [];\n }\n if (key === 'headers') {\n const headers = resp.headers ?? {};\n return [Object.entries(headers).map(([k, v]) => `${k}: ${v}`).join('\\n')];\n }\n if (key.startsWith('header.')) {\n const name = key.slice('header.'.length).toLowerCase();\n const value = (resp.headers ?? {})[name];\n return value !== undefined ? [value] : [];\n }\n return [];\n }\n\n // Egress-phase sources (req._egress = { url, host, method }). Lets rules inspect an\n // OUTBOUND request the app is about to make — SSRF at the egress boundary.\n #resolveEgress(key) {\n const eg = this.#req._egress;\n if (!eg) {\n return [];\n }\n if (key === 'url') return eg.url ? [eg.url] : [];\n if (key === 'host') return eg.host ? [eg.host] : [];\n if (key === 'method') return eg.method ? [eg.method] : [];\n return [];\n }\n\n applyMutations(mutations, value) {\n if (!mutations || !Array.isArray(mutations)) {\n return value;\n }\n\n let result = value;\n\n for (const mutation of mutations) {\n result = this.#applyMutation(mutation, result);\n }\n\n return result;\n }\n\n #applyMutation(mutation, value) {\n if (value === null || value === undefined) {\n return value;\n }\n\n switch (mutation) {\n case 'base64_decode':\n try {\n return base64DecodeUtf8(value);\n } catch {\n return value;\n }\n\n case 'json_decode':\n try {\n return JSON.parse(String(value));\n } catch {\n return value;\n }\n\n case 'json_encode':\n try {\n return JSON.stringify(value);\n } catch {\n return value;\n }\n\n case 'urldecode':\n try {\n return decodeURIComponent(String(value));\n } catch {\n return value;\n }\n\n case 'intval':\n return parseInt(String(value), 10) || 0;\n\n case 'getArrayValues':\n if (typeof value === 'object' && value !== null) {\n return Object.values(value);\n }\n return value;\n\n default:\n return value;\n }\n }\n\n #resolveGet(key) {\n const query = this.#req.query ?? {};\n\n if (key.endsWith('*')) {\n return this.#resolveWildcard(query, key);\n }\n\n const value = this.#getNestedValue(query, key);\n return value !== undefined ? [value] : [];\n }\n\n #resolvePost(key) {\n const body = this.#req.body ?? {};\n\n if (key.endsWith('*')) {\n return this.#resolveWildcard(body, key);\n }\n\n const value = this.#getNestedValue(body, key);\n return value !== undefined ? [value] : [];\n }\n\n #resolveRequest(key) {\n const query = this.#req.query ?? {};\n const body = this.#req.body ?? {};\n const cookies = this.#parseCookies();\n\n if (key.endsWith('*')) {\n return [\n ...this.#resolveWildcard(query, key),\n ...this.#resolveWildcard(body, key),\n ...this.#resolveWildcard(cookies, key)\n ];\n }\n\n const value = this.#getNestedValue(query, key)\n ?? this.#getNestedValue(body, key)\n ?? cookies[key];\n\n return value !== undefined ? [value] : [];\n }\n\n #resolveCookie(key) {\n const cookies = this.#parseCookies();\n\n if (key.endsWith('*')) {\n return this.#resolveWildcard(cookies, key);\n }\n\n const value = cookies[key];\n return value !== undefined ? [value] : [];\n }\n\n #resolveServer(key) {\n const req = this.#req;\n\n switch (key) {\n case 'REQUEST_URI':\n return [req.originalUrl ?? req.url ?? '/'];\n case 'REQUEST_METHOD':\n return [req.method ?? 'GET'];\n case 'HTTP_USER_AGENT':\n return req.headers?.['user-agent'] ? [req.headers['user-agent']] : [];\n case 'HTTP_REFERER':\n return req.headers?.referer ? [req.headers.referer] : [];\n case 'HTTP_HOST':\n return req.headers?.host ? [req.headers.host] : [];\n case 'REMOTE_ADDR':\n case 'ip':\n return [req.ip ?? req.socket?.remoteAddress ?? ''];\n case 'CONTENT_TYPE':\n return req.headers?.['content-type'] ? [req.headers['content-type']] : [];\n case 'CONTENT_LENGTH':\n return req.headers?.['content-length'] ? [req.headers['content-length']] : [];\n default: {\n if (key.startsWith('HTTP_')) {\n const headerName = key.substring(5).toLowerCase().replace(/_/g, '-');\n return req.headers?.[headerName] ? [req.headers[headerName]] : [];\n }\n return [];\n }\n }\n }\n\n #resolveFiles(key) {\n const files = this.#req.files;\n if (!files) {\n return [];\n }\n\n if (key.endsWith('*')) {\n return this.#resolveWildcard(files, key);\n }\n\n const value = files[key];\n return value !== undefined ? [value] : [];\n }\n\n #resolveRaw() {\n // Use pre-captured raw body if available (set by normalizeRequest).\n // For string bodies, the original text is preserved verbatim.\n // For pre-parsed objects, serializeForRawDetection uses Object.getOwnPropertyNames()\n // to include __proto__ own-property keys that JSON.stringify() would silently drop.\n if (typeof this.#req._rawBody === 'string') {\n return this.#req._rawBody ? [this.#req._rawBody] : [];\n }\n\n const body = this.#req.body;\n\n if (body === undefined || body === null) {\n return [];\n }\n\n if (typeof body === 'string') {\n return [body];\n }\n\n try {\n return [JSON.stringify(body)];\n } catch {\n return [String(body)];\n }\n }\n\n #resolveAll() {\n const parts = [];\n\n const uri = this.#req.originalUrl ?? this.#req.url ?? '/';\n parts.push(uri);\n\n const queryString = uri.includes('?') ? uri.split('?')[1] : '';\n if (queryString) {\n parts.push(queryString);\n }\n\n const body = this.#req.body;\n if (body) {\n parts.push(typeof body === 'string' ? body : JSON.stringify(body));\n }\n\n const headers = this.#req.headers ?? {};\n const excludedHeaders = new Set([\n 'host', 'connection', 'cache-control', 'accept', 'accept-encoding',\n 'accept-language', 'priority', 'sec-ch-ua', 'sec-ch-ua-mobile',\n 'sec-ch-ua-platform', 'sec-fetch-dest', 'sec-fetch-mode',\n 'sec-fetch-site', 'sec-fetch-user', 'upgrade-insecure-requests'\n ]);\n\n for (const [name, value] of Object.entries(headers)) {\n if (!excludedHeaders.has(name)) {\n parts.push(`${name}: ${value}`);\n }\n }\n\n const cookies = this.#parseCookies();\n const cookieStr = Object.entries(cookies).map(([k, v]) => `${k}=${v}`).join('; ');\n if (cookieStr) {\n parts.push(cookieStr);\n }\n\n return [parts.join(' ')];\n }\n\n #resolveWildcard(obj, pattern) {\n if (typeof obj !== 'object' || obj === null) {\n return [];\n }\n\n const prefix = pattern.slice(0, -1);\n const values = [];\n\n for (const [key, value] of Object.entries(obj)) {\n if (key.startsWith(prefix)) {\n values.push(value);\n }\n }\n\n return values;\n }\n\n #getNestedValue(obj, key) {\n if (typeof obj !== 'object' || obj === null) {\n return undefined;\n }\n\n if (key in obj) {\n return obj[key];\n }\n\n const parts = key.split('.');\n let current = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n current = current[part];\n }\n\n return current;\n }\n\n #parseCookies() {\n if (this.#cookies !== null) {\n return this.#cookies;\n }\n\n if (this.#req.cookies) {\n this.#cookies = this.#req.cookies;\n return this.#cookies;\n }\n\n const header = this.#req.headers?.cookie;\n if (!header) {\n this.#cookies = {};\n return this.#cookies;\n }\n\n const cookies = {};\n\n for (const pair of header.split(';')) {\n const eqIndex = pair.indexOf('=');\n if (eqIndex === -1) {\n continue;\n }\n const name = pair.substring(0, eqIndex).trim();\n const value = pair.substring(eqIndex + 1).trim();\n cookies[name] = value;\n }\n\n this.#cookies = cookies;\n return this.#cookies;\n }\n}\n","/**\n * Request Normalization Pipeline\n *\n * Normalizes request data to prevent encoding-based bypass attacks.\n * This module handles URL encoding, HTML entities, SQL comments, and other\n * obfuscation techniques that attackers use to evade pattern matching.\n */\n\nconst HTML_ENTITIES = {\n '&amp;': '&',\n '&lt;': '<',\n '&gt;': '>',\n '&quot;': '\"',\n '&#39;': \"'\",\n '&apos;': \"'\",\n '&nbsp;': ' ',\n '&#x27;': \"'\",\n '&#x22;': '\"',\n '&#x3C;': '<',\n '&#x3E;': '>',\n '&#x26;': '&',\n '&#34;': '\"',\n '&#60;': '<',\n '&#62;': '>',\n '&#38;': '&'\n};\n\nconst MAX_DECODE_ITERATIONS = 5;\n\nexport function normalize(value, options = {}) {\n if (typeof value !== 'string') {\n return value;\n }\n\n const opts = {\n urlDecode: true,\n htmlDecode: true,\n sqlComments: true,\n nullBytes: true,\n whitespace: true,\n ...options\n };\n\n let result = value;\n\n if (opts.nullBytes) {\n result = removeNullBytes(result);\n }\n\n if (opts.urlDecode) {\n result = urlDecode(result);\n }\n\n if (opts.htmlDecode) {\n result = htmlEntityDecode(result);\n }\n\n if (opts.sqlComments) {\n result = removeSqlComments(result);\n }\n\n if (opts.whitespace) {\n result = normalizeWhitespace(result);\n }\n\n return result;\n}\n\nexport function urlDecode(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value;\n let previous = '';\n let iterations = 0;\n\n while (result !== previous && iterations < MAX_DECODE_ITERATIONS) {\n previous = result;\n iterations++;\n\n try {\n result = decodeURIComponent(result);\n } catch {\n result = safeUrlDecode(result);\n break;\n }\n }\n\n return result;\n}\n\nfunction safeUrlDecode(value) {\n return value.replace(/%([0-9A-Fa-f]{2})/g, (match, hex) => {\n try {\n return String.fromCharCode(parseInt(hex, 16));\n } catch {\n return match;\n }\n });\n}\n\nexport function htmlEntityDecode(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value;\n\n for (const [entity, char] of Object.entries(HTML_ENTITIES)) {\n result = result.split(entity).join(char);\n }\n\n result = result.replace(/&#(\\d+);/g, (match, code) => {\n const num = parseInt(code, 10);\n return num > 0 && num < 65536 ? String.fromCharCode(num) : match;\n });\n\n result = result.replace(/&#x([0-9A-Fa-f]+);/g, (match, hex) => {\n const num = parseInt(hex, 16);\n return num > 0 && num < 65536 ? String.fromCharCode(num) : match;\n });\n\n return result;\n}\n\nexport function removeSqlComments(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value;\n\n result = result.replace(/\\/\\*[\\s\\S]*?\\*\\//g, ' ');\n result = result.replace(/\\/\\*![\\s\\S]*?\\*\\//g, ' ');\n result = result.replace(/--[^\\r\\n]*/g, '');\n result = result.replace(/#[^\\r\\n]*/g, '');\n\n return result;\n}\n\nexport function removeNullBytes(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value.replace(/\\x00/g, '');\n\n result = result.replace(/[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/g, '');\n\n return result;\n}\n\nexport function normalizeWhitespace(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value.replace(/[\\t\\r\\n\\f\\v]+/g, ' ');\n\n result = result.replace(/ {2,}/g, ' ');\n\n return result;\n}\n\nfunction serializeForRawDetection(body, visited = new Set(), isRoot = true) {\n if (body === null || body === undefined) {\n return isRoot ? '' : 'null';\n }\n\n if (typeof body === 'string') {\n return isRoot ? body : JSON.stringify(body);\n }\n\n if (typeof body !== 'object') {\n return String(body);\n }\n\n if (visited.has(body)) {\n return '[Circular]';\n }\n visited.add(body);\n\n if (Array.isArray(body)) {\n const items = body.map(item => serializeForRawDetection(item, visited, false));\n return '[' + items.join(',') + ']';\n }\n\n // Object.getOwnPropertyNames includes non-enumerable own properties, so a __proto__ key\n // set via Object.defineProperty (as modern JSON.parse may do) is included in the output.\n const keys = Object.getOwnPropertyNames(body);\n const parts = keys.map(key => {\n const val = serializeForRawDetection(body[key], visited, false);\n return JSON.stringify(key) + ':' + val;\n });\n\n return '{' + parts.join(',') + '}';\n}\n\nexport function normalizeRequest(req, options = {}) {\n // Prefer a caller-provided verbatim body string (set by the fetch/node adapters):\n // it preserves literal keys like `__proto__` that JSON.stringify drops, which is\n // what makes prototype-pollution rules on `raw` robust. Fall back to a\n // reconstruction from the parsed body (the Express path, which has no raw text).\n const rawBody = typeof req._rawBody === 'string'\n ? req._rawBody\n : serializeForRawDetection(req.body ?? null);\n\n return {\n query: normalizeObject(req.query || {}, options),\n body: normalizeObject(req.body || {}, options),\n headers: normalizeObject(req.headers || {}, options),\n url: normalize(req.url || '', options),\n originalUrl: normalize(req.originalUrl || req.url || '', options),\n _rawBody: rawBody\n };\n}\n\nexport function normalizeObject(value, options = {}) {\n if (typeof value === 'string') {\n return normalize(value, options);\n }\n\n if (Array.isArray(value)) {\n return value.map(item => normalizeObject(item, options));\n }\n\n if (typeof value === 'object' && value !== null) {\n const result = {};\n\n for (const [key, val] of Object.entries(value)) {\n result[key] = normalizeObject(val, options);\n }\n\n return result;\n }\n\n return value;\n}\n\nexport function createMatchVariants(value) {\n if (typeof value !== 'string') {\n return [value];\n }\n\n const variants = new Set();\n\n variants.add(value);\n\n const urlDecoded = urlDecode(value);\n variants.add(urlDecoded);\n\n const htmlDecoded = htmlEntityDecode(value);\n variants.add(htmlDecoded);\n\n const bothDecoded = htmlEntityDecode(urlDecoded);\n variants.add(bothDecoded);\n\n const normalized = normalize(value);\n variants.add(normalized);\n\n variants.add(value.toLowerCase());\n variants.add(normalized.toLowerCase());\n\n return Array.from(variants);\n}\n\nexport const _testExports = {\n safeUrlDecode,\n serializeForRawDetection,\n HTML_ENTITIES,\n MAX_DECODE_ITERATIONS\n};\n","import { RequestResolver } from './request.js';\nimport { normalizeRequest } from './normalizer.js';\n\nconst REDOS_PATTERNS = [\n /\\(\\w\\+\\)\\+/,\n /\\(\\w\\*\\)\\+/,\n /\\(\\w\\+\\)\\*/,\n /\\(\\w\\*\\)\\*/,\n /\\(\\w\\|\\w\\)\\+/\n];\n\nfunction safeRegExp(pattern) {\n if (!pattern) {\n return null;\n }\n\n for (const dangerous of REDOS_PATTERNS) {\n if (dangerous.test(pattern)) {\n return null;\n }\n }\n\n const match = pattern.match(/^\\/(.+?)\\/([gimsuy]*)$/s);\n if (!match) {\n return null;\n }\n\n try {\n return new RegExp(match[1], match[2]);\n } catch {\n return null;\n }\n}\n\n// ctype_*/is_numeric compare their character-class result to the rule's expected\n// `value`. Rules are almost always written `{ \"type\": \"ctype_digit\", \"value\": false }`\n// meaning \"flag when NOT of this class\" — so the result must be compared to matchVal,\n// not returned raw. Empty/absent values never match (mirrors engine-php's `$value != ''`\n// guard), otherwise every missing parameter false-positives a `value:false` rule.\n// When `value` is not a boolean (null/omitted) the legacy default of `true` is used, so\n// existing rules that relied on the raw class check are unaffected.\nfunction ctypeResult(strValue, isClass, matchVal) {\n if (strValue === '') {\n return false;\n }\n const expected = typeof matchVal === 'boolean' ? matchVal : true;\n return isClass === expected;\n}\n\n// array_key_value: navigate `match.key` (a dot-path, or an array of paths) inside the\n// decoded value and run the nested `match.match` against whatever it finds. Mirrors\n// engine-php's recursive array_key_value handling.\nfunction arrayKeyValue(value, matchObj) {\n if (!matchObj || !matchObj.match || value === null || typeof value !== 'object') {\n return false;\n }\n const keys = Array.isArray(matchObj.key) ? matchObj.key : [matchObj.key];\n const sub = matchObj.match;\n\n for (const key of keys) {\n let node = value;\n for (const part of String(key).split('.')) {\n if (node === null || typeof node !== 'object') {\n node = undefined;\n break;\n }\n node = node[part];\n }\n if (node === undefined) {\n continue;\n }\n const candidates = Array.isArray(node) ? node : [node];\n for (const candidate of candidates) {\n if (matchValue(sub.type, candidate, sub.value, sub)) {\n return true;\n }\n }\n }\n return false;\n}\n\n// Report an unknown/removed match type once, so a rule referencing it is not silently\n// unenforced (ADR: \"unknown match type → skipped and logged, never silently passed\").\nconst warnedMatchTypes = new Set();\nfunction warnUnsupportedMatchType(type) {\n if (type == null || warnedMatchTypes.has(type)) {\n return;\n }\n warnedMatchTypes.add(type);\n console.warn(\n `[patchstack] Unsupported rule_v2 match type \"${type}\" — condition treated as no-match. ` +\n `Rules relying on it are not enforced by this engine.`\n );\n}\n\n// Internal / private / loopback / link-local / cloud-metadata host check, used by the\n// `internal_host` match type for SSRF egress rules. Handles IPv4 (incl. IPv4-mapped IPv6),\n// IPv6 loopback/link-local/unique-local, and localhost / *.local / GCP metadata names.\nfunction isInternalHost(hostname) {\n if (!hostname) return false;\n const host = String(hostname).toLowerCase().replace(/^\\[|\\]$/g, '');\n\n if (host === 'localhost' || host.endsWith('.localhost') || host.endsWith('.local')) return true;\n if (host === 'metadata.google.internal') return true;\n if (host === '::1' || host === '::') return true;\n if (host.startsWith('fe80:') || host.startsWith('fc') || host.startsWith('fd')) return true;\n\n const v4 = host.match(/(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n if (v4) {\n const a = Number(v4[1]);\n const b = Number(v4[2]);\n if (a === 127 || a === 10 || a === 0) return true; // loopback / private / this-host\n if (a === 169 && b === 254) return true; // link-local incl. 169.254.169.254 metadata\n if (a === 172 && b >= 16 && b <= 31) return true; // 172.16.0.0/12\n if (a === 192 && b === 168) return true; // 192.168.0.0/16\n }\n return false;\n}\n\n// `matchObj` is the full match object; needed by types that read sibling fields\n// (array_key_value reads `key`/`match`). Optional so direct callers/tests can keep\n// using the (type, value, matchVal) signature.\nfunction matchValue(type, value, matchVal, matchObj) {\n if (value === null || value === undefined) {\n if (type === 'isset') {\n return false;\n }\n return false;\n }\n\n const strValue = typeof value === 'string' ? value : String(value);\n\n switch (type) {\n case 'equals':\n return strValue == matchVal;\n\n case 'equals_strict':\n return strValue === matchVal;\n\n case 'contains':\n // engine-php exposes `stripos` as an alias of `contains`.\n case 'stripos': {\n const lower = strValue.toLowerCase();\n const target = String(matchVal).toLowerCase();\n return lower.includes(target);\n }\n\n case 'not_contains': {\n const lower = strValue.toLowerCase();\n const target = String(matchVal).toLowerCase();\n return !lower.includes(target);\n }\n\n case 'regex': {\n const regex = safeRegExp(matchVal);\n if (!regex) {\n return false;\n }\n return regex.test(strValue);\n }\n\n case 'more_than':\n return Number(strValue) > Number(matchVal);\n\n case 'less_than':\n return Number(strValue) < Number(matchVal);\n\n case 'ctype_digit':\n return ctypeResult(strValue, /^\\d+$/.test(strValue), matchVal);\n\n case 'ctype_alnum':\n return ctypeResult(strValue, /^[\\w$\\u0080-\\uFFFF]+$/.test(strValue), matchVal);\n\n case 'is_numeric':\n return ctypeResult(strValue, !isNaN(strValue) && strValue.trim() !== '', matchVal);\n\n case 'isset':\n return true;\n\n case 'in_array': {\n const arr = Array.isArray(matchVal) ? matchVal : [matchVal];\n return arr.includes(strValue);\n }\n\n case 'not_in_array': {\n const arr = Array.isArray(matchVal) ? matchVal : [matchVal];\n return !arr.includes(strValue);\n }\n\n case 'array_in_array': {\n if (!Array.isArray(value) || !Array.isArray(matchVal)) {\n return false;\n }\n return value.some(v => matchVal.includes(v));\n }\n\n case 'hostname': {\n try {\n const url = new URL(strValue);\n return url.hostname === matchVal;\n } catch {\n return false;\n }\n }\n\n case 'internal_host':\n // SSRF egress: private / loopback / link-local / cloud-metadata destinations.\n return isInternalHost(strValue);\n\n case 'quotes':\n // engine-php exposes `inline_js_xss` as an alias of `quotes`.\n case 'inline_js_xss':\n return /['\"]/.test(strValue);\n\n case 'inline_xss':\n // Attribute-breakout heuristic: a quote AND a `>` or `=` (matches engine-php).\n return /['\"]/.test(strValue) && /[>=]/.test(strValue);\n\n case 'ctype_special': {\n // engine-php strips space, `_`, `-`, `,` then applies the alnum/unicode check,\n // and compares the result to `value` (usually false = \"flag when NOT clean\").\n const stripped = strValue.replace(/[ _\\-,]/g, '');\n return ctypeResult(strValue, /^[\\w$€-￿]*$/.test(stripped), matchVal);\n }\n\n case 'array_key_value':\n // Navigate `match.key` (dot-path, or array of paths) inside the decoded value and\n // run the nested `match.match` against it — e.g. a json_decode'd body where a\n // specific key must hold a specific value.\n return arrayKeyValue(value, matchObj);\n\n // file_contains (uploaded-file content scanning) is NOT WordPress-specific, but is\n // not yet implemented in the JS engine (needs multipart body access). Kept as an\n // explicit, documented no-match rather than silently hitting `default`.\n case 'file_contains':\n return false;\n\n // WordPress-only match types (current_user_cannot, general_xss, getShortcodeAtts,\n // getBlockAtts) have been removed: they depend on WP capabilities, wp_kses_post, and\n // the shortcode/block parsers, and have no meaning in a JS app. They now fall through\n // here and are reported once instead of pretending to be a no-match.\n default:\n warnUnsupportedMatchType(type);\n return false;\n }\n}\n\nexport class RuleEngine {\n #rules;\n #whitelists;\n #whitelistKeys;\n #onError;\n #reportedErrors = new Set();\n\n constructor({ firewall = [], whitelists = [], whitelist_keys = {}, onError } = {}) {\n this.#rules = firewall;\n this.#whitelists = whitelists;\n this.#whitelistKeys = whitelist_keys;\n this.#onError = onError;\n }\n\n // A mitigation engine must never take down the app it protects: any error while\n // evaluating a rule is reported and the request is allowed through (fail open). A\n // malformed rule is skipped without aborting the rest of the ruleset.\n #reportError(err) {\n if (this.#onError) {\n this.#onError(err);\n return;\n }\n // Default: log once per distinct message so a persistently-broken rule doesn't\n // spam per request (never silently swallow — hosts can pass `onError` for structured logging).\n const key = err && err.message ? err.message : String(err);\n if (this.#reportedErrors.has(key)) {\n return;\n }\n this.#reportedErrors.add(key);\n console.error('[patchstack] rule evaluation error (rule skipped, request allowed):', err);\n }\n\n evaluate(req) {\n let normalizedReq;\n let resolver;\n try {\n normalizedReq = { ...req, ...normalizeRequest(req) };\n resolver = new RequestResolver(normalizedReq);\n } catch (err) {\n this.#reportError(err);\n return { blocked: false, rule: null, message: null }; // fail open\n }\n\n for (const rule of this.#rules) {\n try {\n const conditions = rule.rule_v2;\n\n if (!Array.isArray(conditions) || conditions.length === 0) {\n continue;\n }\n\n if (this.#evaluateRule(conditions, resolver)) {\n if (this.#isWhitelisted(normalizedReq, rule)) {\n continue;\n }\n\n return {\n blocked: true,\n rule,\n message: rule.message ?? `Blocked by Patchstack WAF rule: ${rule.title ?? rule.id}`\n };\n }\n } catch (err) {\n // Skip this rule and keep evaluating the rest — one bad rule never blocks a\n // request nor shadows the rules after it.\n this.#reportError(err);\n }\n }\n\n return { blocked: false, rule: null, message: null };\n }\n\n #evaluateRule(conditions, resolver) {\n const inclusiveConditions = conditions.filter(c => c.inclusive);\n const nonInclusiveConditions = conditions.filter(c => !c.inclusive);\n\n if (inclusiveConditions.length > 0) {\n let inclusiveHits = 0;\n\n for (const condition of inclusiveConditions) {\n if (this.#evaluateCondition(condition, resolver)) {\n inclusiveHits++;\n }\n }\n\n if (inclusiveHits === inclusiveConditions.length) {\n return true;\n }\n }\n\n for (const condition of nonInclusiveConditions) {\n if (this.#evaluateCondition(condition, resolver)) {\n return true;\n }\n }\n\n return false;\n }\n\n #evaluateCondition(condition, resolver) {\n const { parameter, match, mutations } = condition;\n\n if (parameter === 'rules' && Array.isArray(condition.rules)) {\n return this.#evaluateRule(condition.rules, resolver);\n }\n\n // `parameter` may be an array (e.g. [\"get.action\",\"post.action\"]) — the rule_v2 format\n // uses these pervasively to mean \"any of these sources\". Resolve each and OR the\n // candidate values together. (A bare string resolves as a single source.)\n const params = Array.isArray(parameter) ? parameter : [parameter];\n const values = params.flatMap((p) => resolver.resolve(p));\n\n if (values.length === 0) {\n return false;\n }\n\n for (let value of values) {\n if (mutations) {\n value = resolver.applyMutations(mutations, value);\n }\n\n // array_key_value inspects the object as a whole (it navigates a key path),\n // so it must not go through the per-value object iteration below.\n if (match.type === 'array_key_value') {\n if (matchValue(match.type, value, match.value, match)) {\n return true;\n }\n continue;\n }\n\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n for (const v of Object.values(value)) {\n if (matchValue(match.type, v, match.value, match)) {\n return true;\n }\n }\n continue;\n }\n\n if (matchValue(match.type, value, match.value, match)) {\n return true;\n }\n }\n\n return false;\n }\n\n #isWhitelisted(req, rule) {\n if (!this.#whitelists || this.#whitelists.length === 0) {\n return false;\n }\n\n for (const whitelist of this.#whitelists) {\n if (!Array.isArray(whitelist.rule_v2)) {\n continue;\n }\n\n if (whitelist.rule_id && whitelist.rule_id !== rule.id) {\n continue;\n }\n\n const resolver = new RequestResolver(req);\n if (this.#evaluateRule(whitelist.rule_v2, resolver)) {\n return true;\n }\n }\n\n return false;\n }\n}\n\nexport const _testExports = { matchValue, safeRegExp, isInternalHost };\n","const DEFAULT_BASE_URL = 'https://api.patchstack.com/monitor/pulse';\nconst DEFAULT_CACHE_TTL = 300_000;\n\n// Per-site rules client for Pulse (npm/JS) apps. Public endpoint — the site UUID is the only\n// credential, passed in the path. Fail-open: any error returns success:false + empty rules so\n// createProtection falls back to the disk cache or the bundled rules.\nexport class PulseRuleClient {\n #siteUuid;\n #baseUrl;\n #cacheTtl;\n #cache = null;\n #cacheTime = null;\n\n constructor({ siteUuid, baseUrl, cacheTtl } = {}) {\n this.#siteUuid = siteUuid ?? process.env.PATCHSTACK_SITE_UUID;\n this.#baseUrl = baseUrl ?? process.env.PATCHSTACK_PULSE_RULES_URL ?? DEFAULT_BASE_URL;\n this.#cacheTtl = cacheTtl ?? DEFAULT_CACHE_TTL;\n if (!this.#siteUuid) {\n throw new Error('Patchstack site UUID is required. Pass { siteUuid } or set PATCHSTACK_SITE_UUID.');\n }\n }\n\n async getRules() {\n const now = Date.now();\n if (this.#cache && this.#cacheTime && now - this.#cacheTime < this.#cacheTtl) {\n return this.#cache;\n }\n const url = `${this.#baseUrl}/rules/${encodeURIComponent(this.#siteUuid)}`;\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n signal: AbortSignal.timeout(30_000),\n });\n if (!response.ok) {\n return { success: false, error: `API returned ${response.status}`, firewall: [], whitelists: [], whitelist_keys: {} };\n }\n const data = await response.json();\n const result = {\n success: true,\n firewall: Array.isArray(data.firewall) ? data.firewall : [],\n whitelists: Array.isArray(data.whitelists) ? data.whitelists : [],\n whitelist_keys: data.whitelist_keys ?? {},\n };\n this.#cache = result;\n this.#cacheTime = now;\n return result;\n } catch (err) {\n return {\n success: false,\n error: err.name === 'TimeoutError' ? 'Request timed out' : err.message,\n firewall: [], whitelists: [], whitelist_keys: {},\n };\n }\n }\n\n clearCache() {\n this.#cache = null;\n this.#cacheTime = null;\n }\n}\n","// Web Fetch adapter — runs the node-waf engine on any runtime where a request is a\n// WHATWG `Request` and a handler returns a `Response`: Cloudflare Workers, Bun, Deno,\n// Hono, Next.js edge, and TanStack Start's `server.ts`. This is the surface AI-builder\n// apps actually deploy to, and where require-based instrumentation can't reach.\n//\n// The engine already consumes a runtime-neutral request shape; this adapter builds that\n// shape from a `Request`, so no engine changes are needed beyond keeping the hot path\n// free of Node-only APIs.\nimport { RuleEngine } from './engine.js';\n\n// Build the engine's request shape from a WHATWG Request. The body is read from a\n// CLONE so the downstream handler still receives an intact request.\nexport async function fromFetchRequest(request) {\n const url = new URL(request.url);\n const method = (request.method || 'GET').toUpperCase();\n\n const headers = {};\n request.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n\n const query = {};\n for (const [key, value] of url.searchParams) {\n if (key in query) {\n query[key] = Array.isArray(query[key]) ? [...query[key], value] : [query[key], value];\n } else {\n query[key] = value;\n }\n }\n\n let rawBody = '';\n if (method !== 'GET' && method !== 'HEAD') {\n try {\n rawBody = await request.clone().text();\n } catch {\n rawBody = '';\n }\n }\n\n const contentType = headers['content-type'] || '';\n let body = {};\n if (rawBody) {\n if (contentType.includes('application/json')) {\n try {\n body = JSON.parse(rawBody);\n } catch {\n body = {};\n }\n } else if (contentType.includes('application/x-www-form-urlencoded')) {\n body = {};\n for (const [k, v] of new URLSearchParams(rawBody)) {\n body[k] = k in body ? [].concat(body[k], v) : v;\n }\n }\n }\n\n const uri = url.pathname + url.search;\n const forwarded =\n headers['cf-connecting-ip'] || headers['x-forwarded-for'] || headers['x-real-ip'] || '';\n\n return {\n method,\n url: uri,\n originalUrl: uri,\n query,\n body,\n headers,\n ip: forwarded.split(',')[0].trim(),\n cookies: parseCookies(headers.cookie),\n // Verbatim body text: preserves literal keys (e.g. `__proto__`) that JSON.stringify\n // drops, so prototype-pollution rules on `raw` are robust.\n _rawBody: rawBody\n };\n}\n\nfunction parseCookies(header) {\n const cookies = {};\n if (!header) {\n return cookies;\n }\n for (const pair of header.split(';')) {\n const idx = pair.indexOf('=');\n if (idx === -1) {\n continue;\n }\n cookies[pair.slice(0, idx).trim()] = pair.slice(idx + 1).trim();\n }\n return cookies;\n}\n\nfunction defaultBlockResponse(result) {\n return new Response(\n JSON.stringify({\n error: 'Blocked by Patchstack WAF',\n message: result.message,\n timestamp: new Date().toISOString()\n }),\n { status: 403, headers: { 'content-type': 'application/json' } }\n );\n}\n\n/**\n * Returns a guard `(request) => Promise<Response|null>`. A `Response` means blocked;\n * `null` means allowed — the caller should proceed to its handler. Accepts either a\n * rules bundle (`{ firewall, whitelists, whitelist_keys }`) or a `RuleEngine` instance.\n * Fails open: a rule that throws never blocks the request.\n */\nexport function createFetchMiddleware(rulesData, options = {}) {\n const engine =\n rulesData && typeof rulesData.evaluate === 'function'\n ? rulesData\n : new RuleEngine(rulesData);\n\n const guard = async (request) => {\n const req = await fromFetchRequest(request);\n\n let result;\n try {\n result = engine.evaluate(req);\n } catch (err) {\n if (options.onError) {\n options.onError(err);\n }\n return null; // fail open\n }\n\n if (result.blocked) {\n if (options.onBlock) {\n options.onBlock({\n rule: result.rule,\n message: result.message,\n request: { method: req.method, url: req.url, ip: req.ip }\n });\n }\n return (options.response || defaultBlockResponse)(result);\n }\n\n return null;\n };\n\n guard.engine = engine;\n return guard;\n}\n\n/**\n * Wrap a fetch handler so every request is screened first. One-line hook:\n * export default { fetch: wrapFetchHandler(app.fetch, rulesData) }\n */\nexport function wrapFetchHandler(handler, rulesData, options = {}) {\n const guard = createFetchMiddleware(rulesData, options);\n const wrapped = async (request, ...rest) => {\n const blocked = await guard(request);\n return blocked ?? handler(request, ...rest);\n };\n wrapped.engine = guard.engine;\n return wrapped;\n}\n","// Raw Node.js / Connect adapter — for traditional Node servers where the request is a\n// `http.IncomingMessage` and the body is NOT already parsed (plain `http`, Connect,\n// Express without a body-parser, Fastify via its Node req). It buffers the body once,\n// builds the engine's request shape, and blocks or calls `next()`.\n//\n// This complements the Express `createMiddleware` (which assumes `req.body`/`req.query`\n// are already populated) and the Web-Fetch adapter (Workers/edge). Mount it FIRST, before\n// any body-parser — it consumes the stream and exposes the parsed body as `req.body`.\nimport { RuleEngine } from './engine.js';\n\n// Build the engine's request shape from a Node IncomingMessage + its raw body text.\nexport function fromNodeRequest(req, rawBody = '') {\n const method = (req.method || 'GET').toUpperCase();\n\n const headers = {};\n for (const [key, value] of Object.entries(req.headers || {})) {\n headers[key.toLowerCase()] = Array.isArray(value) ? value.join(', ') : value;\n }\n\n const host = headers.host || 'localhost';\n const url = new URL(req.url || '/', `http://${host}`);\n\n const query = {};\n for (const [key, value] of url.searchParams) {\n if (key in query) {\n query[key] = Array.isArray(query[key]) ? [...query[key], value] : [query[key], value];\n } else {\n query[key] = value;\n }\n }\n\n const contentType = headers['content-type'] || '';\n let body = {};\n if (rawBody) {\n if (contentType.includes('application/json')) {\n try {\n body = JSON.parse(rawBody);\n } catch {\n body = {};\n }\n } else if (contentType.includes('application/x-www-form-urlencoded')) {\n body = {};\n for (const [k, v] of new URLSearchParams(rawBody)) {\n body[k] = k in body ? [].concat(body[k], v) : v;\n }\n }\n }\n\n const uri = url.pathname + url.search;\n const forwarded =\n headers['cf-connecting-ip'] || headers['x-forwarded-for'] || headers['x-real-ip'] || '';\n\n return {\n method,\n url: uri,\n originalUrl: uri,\n query,\n body,\n headers,\n ip: forwarded.split(',')[0].trim() || (req.socket && req.socket.remoteAddress) || '',\n cookies: parseCookies(headers.cookie),\n // Verbatim body text: preserves literal keys (e.g. `__proto__`) that JSON.stringify drops.\n _rawBody: rawBody\n };\n}\n\nfunction parseCookies(header) {\n const cookies = {};\n if (!header) {\n return cookies;\n }\n for (const pair of header.split(';')) {\n const idx = pair.indexOf('=');\n if (idx === -1) {\n continue;\n }\n cookies[pair.slice(0, idx).trim()] = pair.slice(idx + 1).trim();\n }\n return cookies;\n}\n\nfunction defaultBlock(res, result) {\n res.statusCode = 403;\n res.setHeader('content-type', 'application/json');\n res.end(\n JSON.stringify({\n error: 'Blocked by Patchstack WAF',\n message: result.message,\n timestamp: new Date().toISOString()\n })\n );\n}\n\n/**\n * Connect/Express-style middleware `(req, res, next)` that buffers the body itself.\n * Accepts a `RuleEngine` instance or a `{ firewall, whitelists, whitelist_keys }` bundle.\n * Fails open: an engine error (or oversized body) never blocks the request.\n * Options: `{ maxBodyBytes = 1MiB, onBlock, onError, response }`.\n */\nexport function createNodeMiddleware(rulesData, options = {}) {\n const engine =\n rulesData && typeof rulesData.evaluate === 'function' ? rulesData : new RuleEngine(rulesData);\n const maxBytes = options.maxBodyBytes ?? 1024 * 1024;\n\n return function guard(req, res, next) {\n const chunks = [];\n let size = 0;\n let overflow = false;\n\n req.on('data', (chunk) => {\n size += chunk.length;\n if (size > maxBytes) {\n overflow = true;\n return;\n }\n chunks.push(chunk);\n });\n\n req.on('error', (err) => next(err));\n\n req.on('end', () => {\n const rawBody = overflow ? '' : Buffer.concat(chunks).toString('utf8');\n const shaped = fromNodeRequest(req, rawBody);\n\n let result;\n try {\n result = engine.evaluate(shaped);\n } catch (err) {\n if (options.onError) {\n options.onError(err);\n }\n return next(); // fail open\n }\n\n if (result.blocked) {\n if (options.onBlock) {\n options.onBlock({\n rule: result.rule,\n message: result.message,\n request: { method: shaped.method, url: shaped.url, ip: shaped.ip }\n });\n }\n return (options.response || defaultBlock)(res, result);\n }\n\n // Expose the parsed body downstream so a body-parser isn't also required.\n req.body = shaped.body;\n next();\n });\n };\n}\n","// Egress guard MECHANISM only. Wraps the global `fetch` so the app's outbound requests\n// can be screened; the block DECISION is delegated to a caller-supplied `shouldBlock`\n// predicate (which the runtime builds from egress-phase rules — see defaults.js).\n// No policy is hardcoded here: what counts as \"internal\"/disallowed lives in rules.\n// WinterCG — works on Node 18+, Cloudflare Workers, Bun, Deno.\n\n/**\n * @param {{ shouldBlock: (url:string, host:string|null, method:string)=>boolean,\n * onBlock?: (info:{url:string,host:string|null,method:string})=>void }} opts\n * @returns {() => void} uninstall (restores the original fetch)\n */\nexport function installEgressGuard({ shouldBlock, onBlock } = {}) {\n const original = globalThis.fetch;\n if (typeof original !== 'function' || original.__patchstackGuarded || typeof shouldBlock !== 'function') {\n return () => {};\n }\n\n const guarded = async (input, init) => {\n const url = typeof input === 'string' ? input : (input && input.url) || String(input);\n let host = null;\n try {\n host = new URL(url).hostname;\n } catch {\n host = null;\n }\n const method = (init && init.method) || (input && input.method) || 'GET';\n\n if (shouldBlock(url, host, method)) {\n onBlock?.({ url, host, method });\n throw new Error(`Patchstack blocked an outbound request to a disallowed address: ${host ?? url}`);\n }\n return original(input, init);\n };\n\n guarded.__patchstackGuarded = true;\n globalThis.fetch = guarded;\n\n return () => {\n if (globalThis.fetch === guarded) {\n globalThis.fetch = original;\n }\n };\n}\n","// Default response- and egress-phase rule bundles, as JS constants (not JSON files) so\n// tsup bundles them into dist/protect.js without a copy step. These are just rules —\n// override per app via createProtection({ responseRules, egressRules }) or extend by\n// adding phase-tagged rules to the delivered bundle. Patterns are high-precision\n// (low false positive): structural markers a real secret has and normal content doesn't.\n\n// Response phase — secret / info exposure. Default action `redact` masks only the\n// offending span and still serves the page (a legit response that leaks one key gets\n// that key masked, not withheld). Use `action: \"block\"` to withhold the whole response.\nexport const DEFAULT_RESPONSE_RULES = [\n {\n id: 'resp-private-key',\n title: 'Private key in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/' } }]\n },\n {\n id: 'resp-aws-access-key',\n title: 'AWS access key id in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\\\b/' } }]\n },\n {\n id: 'resp-gcp-api-key',\n title: 'Google API key in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\bAIza[0-9A-Za-z_-]{35}\\\\b/' } }]\n },\n {\n id: 'resp-jwt',\n title: 'JWT in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\beyJ[A-Za-z0-9_-]{8,}\\\\.eyJ[A-Za-z0-9_-]{8,}\\\\.[A-Za-z0-9_-]{8,}\\\\b/' } }]\n },\n {\n id: 'resp-db-connection-string',\n title: 'Database connection string with credentials in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\b(?:mongodb(?:\\\\+srv)?|postgres(?:ql)?|mysql|redis|amqps?):\\\\/\\\\/[^\\\\s:@\\\\/]+:[^\\\\s:@\\\\/]+@/i' } }]\n },\n {\n id: 'resp-stack-trace',\n title: 'Node stack trace leaking in response body',\n phase: 'response',\n category: 'info-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\n\\\\s+at\\\\s+.+\\\\(.+:\\\\d+:\\\\d+\\\\)/' } }]\n }\n];\n\n// Egress phase — SSRF: block the app's outbound calls to internal / metadata addresses.\nexport const DEFAULT_EGRESS_RULES = [\n {\n id: 'egress-internal-address',\n title: 'Outbound request to an internal / metadata address (SSRF)',\n phase: 'egress',\n category: 'ssrf',\n rule_v2: [{ parameter: 'egress.host', match: { type: 'internal_host' } }]\n }\n];\n","// Supabase-tunnel guard for AI-builder apps (Lovable / TanStack Start + Supabase).\n//\n// The vibe-coded app's browser talks straight to Supabase, bypassing the app's own server —\n// so a normal in-app WAF never sees the data traffic. The installer patches the generated\n// Supabase client to tunnel every call through this guard (running in the app's own server /\n// Worker). The guard runs the Patchstack protection policy on the tunneled request, then\n// forwards it to Supabase — pinned to the app's own project so it can't be turned into an\n// open proxy (SSRF).\n//\n// The heavy lifting (rule evaluation, dry-run/block, fail-open) is `protection.fetchGuard()`\n// from `createProtection` — this module is just the Supabase-specific tunnel around it.\n\nexport const GUARD_PATH = '/_patchstack/guard';\n\n// Headers we must not copy verbatim when re-emitting the upstream response.\nconst HOP_BY_HOP = new Set(['content-encoding', 'content-length', 'transfer-encoding', 'connection']);\n\n/**\n * @param {object} opts\n * @param {{ fetchGuard: () => (req: Request) => Promise<Response|null> }} opts.protection a createProtection() result\n * @param {string|undefined} opts.supabaseUrl the app's Supabase project URL (server-side env) — the only allowed forward target\n * @param {typeof fetch} [opts.fetchImpl] injectable fetch (tests)\n * @returns {(request: Request) => Promise<Response>}\n */\nexport function createSupabaseGuard({ protection, supabaseUrl, fetchImpl = fetch }) {\n const guard = protection.fetchGuard();\n const allowedOrigin = supabaseUrl ? new URL(supabaseUrl).origin : null;\n\n return async function handleGuardRequest(request) {\n const target = request.headers.get('x-ps-target');\n if (!target) return new Response('patchstack: missing x-ps-target', { status: 400 });\n\n let targetUrl;\n try {\n targetUrl = new URL(target);\n } catch {\n return new Response('patchstack: invalid target', { status: 400 });\n }\n\n // SSRF pin: only ever forward to the app's own Supabase project (origin from server-side\n // env, never the client-supplied header). Anything else — internal hosts, cloud metadata,\n // a different scheme — is rejected before any outbound request.\n if (!allowedOrigin || targetUrl.protocol !== 'https:' || targetUrl.origin !== allowedOrigin) {\n return new Response('patchstack: target not allowed', { status: 403 });\n }\n\n const hasBody = request.method !== 'GET' && request.method !== 'HEAD';\n const bodyText = hasBody ? await request.text() : '';\n\n // Evaluate the tunneled call against the policy. fetchGuard returns a 403 Response when it\n // blocks (block mode + match), or null to allow (allow, or dry-run — it records via onDetect).\n const evalReq = new Request(targetUrl.toString(), {\n method: request.method,\n headers: request.headers,\n body: hasBody ? bodyText : undefined,\n });\n const blocked = await guard(evalReq);\n if (blocked) return blocked;\n\n // Allowed → forward to Supabase, server-side.\n const forwardHeaders = new Headers(request.headers);\n forwardHeaders.delete('x-ps-target');\n forwardHeaders.delete('host');\n const upstream = await fetchImpl(targetUrl.toString(), {\n method: request.method,\n headers: forwardHeaders,\n body: hasBody ? bodyText : undefined,\n redirect: 'manual',\n });\n\n const outHeaders = new Headers();\n upstream.headers.forEach((value, key) => {\n if (!HOP_BY_HOP.has(key.toLowerCase())) outHeaders.set(key, value);\n });\n const buf = await upstream.arrayBuffer();\n const forwarded = new Response(buf, { status: upstream.status, statusText: upstream.statusText, headers: outHeaders });\n\n // Response phase: screen what Supabase returned (query results can leak secrets/PII) —\n // redact the offending spans / withhold, per the response rules. Fail-open if unavailable.\n return protection.screenResponse ? protection.screenResponse(forwarded) : forwarded;\n };\n}\n"],"mappings":"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","names":["DEFAULT_BASE_URL","DEFAULT_CACHE_TTL","parseCookies","allow"]}
1
+ {"version":3,"sources":["../src/protect/runtime.js","../src/protect/engine/client.js","../src/protect/engine/request.js","../src/protect/engine/normalizer.js","../src/protect/engine/engine.js","../src/protect/engine/pulse-client.js","../src/protect/engine/fetch.js","../src/protect/engine/node.js","../src/protect/egress.js","../src/protect/defaults.js","../src/protect/block-page.js","../src/protect/supabase-guard.js"],"sourcesContent":["// @patchstack/protect — \"Protect = respond\".\n//\n// One entry point that composes the node-waf engine + adapters with:\n// - a rule source: an explicit bundle, or fetched from the Patchstack API (token),\n// with a disk cache so the engine keeps working on last-known-good if the API is down\n// - execution modes: 'dry-run' (detect + log, never block — the safe onramp) and\n// 'block' (enforce). Default is 'dry-run'.\n// - fail-open everywhere: a rule/engine error never blocks (or crashes) a request.\n//\n// Runtime guards: .express(), .node(), .fetch(handler) / .fetchGuard() — same policy,\n// every runtime an AI builder deploys to.\n// Vendored node-waf engine (this package is self-contained — no @patchstack/node-waf dep).\nimport { RuleEngine, PatchstackRuleClient } from './engine/index.js';\nimport { PulseRuleClient } from './engine/pulse-client.js';\nimport { fromFetchRequest } from './engine/fetch.js';\nimport { fromNodeRequest } from './engine/node.js';\nimport { installEgressGuard } from './egress.js';\nimport { DEFAULT_RESPONSE_RULES, DEFAULT_EGRESS_RULES } from './defaults.js';\nimport { renderBlockPage } from './block-page.js';\nimport { readFileSync, writeFileSync, mkdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\n// Supabase-tunnel guard for AI-builder apps (Lovable / TanStack Start + Supabase).\nexport { createSupabaseGuard, GUARD_PATH } from './supabase-guard.js';\n\n// Per-site live rule client (Pulse). Re-exported for callers/tests that want to use it directly.\nexport { PulseRuleClient };\n\n// Server-function guard. Modern Lovable apps mutate data through TanStack server functions\n// (browser → server fn → server-side Supabase client), which bypass the browser-side tunnel the\n// Supabase guard relies on. This inspects the decoded server-fn call args against the SAME policy\n// by feeding them through fetchGuard (the args become the request body, so the engine resolves\n// `post.<field>` exactly as it does for a tunneled Supabase insert). Returns a block receipt\n// { rule?, message } to throw on, or null to allow (also null in dry-run — the detection is still\n// recorded by fetchGuard). Fail-open on any error.\nexport function createServerFnGuard({ protection }) {\n const guard = protection.fetchGuard();\n return async (data) => {\n let res;\n try {\n const req = new Request('https://patchstack.local/_serverfn', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(data ?? {}),\n });\n res = await guard(req);\n } catch {\n return null; // fail open\n }\n if (!res) return null; // allowed (or dry-run)\n let body = {};\n try {\n body = await res.clone().json();\n } catch {\n /* non-JSON block response */\n }\n return { rule: body.rule, message: body.message || 'Blocked by Patchstack' };\n };\n}\n\nexport async function createProtection(options = {}) {\n const mode = options.mode === 'block' ? 'block' : 'dry-run';\n const onError = options.onError;\n const onDetect = options.onDetect ?? defaultOnDetect;\n\n const bundle = await resolveRules(options);\n const incoming = bundle.firewall ?? [];\n\n // Split the delivered ruleset by phase (default \"request\"), merging phase defaults +\n // per-call overrides. Detection is fully rule-driven — nothing hardcoded.\n const requestRules = byPhase(incoming, 'request');\n const responseRules = [...(options.responseRules ?? DEFAULT_RESPONSE_RULES), ...byPhase(incoming, 'response')];\n const egressRules = [...(options.egressRules ?? DEFAULT_EGRESS_RULES), ...byPhase(incoming, 'egress')];\n\n const engine = new RuleEngine({\n firewall: requestRules,\n whitelists: bundle.whitelists,\n whitelist_keys: bundle.whitelist_keys,\n onError\n });\n // One engine per response rule so we can find ALL matches (to redact each). `action:\n // \"redact\"` masks the offending span(s); anything else withholds the whole response.\n const responseRuleSet = responseRules.map((rule) => ({\n rule,\n engine: new RuleEngine({ firewall: [rule], onError }),\n redactors: rule.action === 'redact' ? extractRedactors(rule) : null\n }));\n const egressEngine = new RuleEngine({ firewall: egressRules, onError });\n const maskFn =\n typeof options.maskWith === 'function'\n ? options.maskWith\n : () => (typeof options.maskWith === 'string' ? options.maskWith : '[REDACTED]');\n\n // Given a request/egress result, enforce (block mode) or just record (dry-run).\n const decide = (phase, result, block, allow) => {\n if (!result || !result.blocked) return allow();\n onDetect({ phase, mode, category: result.rule?.category, rule: result.rule, message: result.message });\n return mode === 'block' ? block() : allow();\n };\n\n // Response phase core: screen a text body → { verdict: 'pass'|'block'|'redact', body? }.\n // redact masks matched spans; block withholds; block wins over redact. Enforcement only in\n // block mode (dry-run records via onDetect but returns 'pass').\n const isTextCT = (ct) => {\n ct = (ct || '').toLowerCase();\n return ct === '' || /(json|text|xml|html|javascript|csv|yaml|x-www-form-urlencoded)/.test(ct);\n };\n const screenText = (text, meta) => {\n let blockRule = null;\n const redactions = [];\n for (const { rule, engine: re, redactors } of responseRuleSet) {\n let result;\n try {\n result = re.evaluate({ _response: { ...meta, body: text } });\n } catch (err) {\n onError?.(err);\n continue;\n }\n if (!result.blocked) continue;\n onDetect({ phase: 'response', mode, category: rule.category, rule, message: result.message });\n if (mode !== 'block') continue; // dry-run: observe only\n if (redactors && redactors.length) redactions.push({ rule, redactors });\n else if (!blockRule) blockRule = rule;\n }\n if (mode !== 'block' || (!blockRule && !redactions.length)) return { verdict: 'pass' };\n if (blockRule) return { verdict: 'block' };\n let body = text;\n // Redact the offending spans in the body AND in every (string) header value — so a secret\n // that leaks in a header (Set-Cookie, an echoed X-Api-Key, …) is masked too, and a rule that\n // targets `response.header.*` actually strips the header rather than just detecting it.\n const headers = { ...(meta.headers || {}) };\n for (const { rule, redactors } of redactions) {\n const mask = maskFn(rule.category);\n body = applyRedactors(body, redactors, mask);\n for (const name of Object.keys(headers)) {\n const value = headers[name];\n if (typeof value === 'string') {\n headers[name] = applyRedactors(value, redactors, mask);\n } else if (Array.isArray(value)) {\n // Multi-valued headers (Set-Cookie) — redact each entry.\n headers[name] = value.map((item) => (typeof item === 'string' ? applyRedactors(item, redactors, mask) : item));\n }\n }\n }\n return { verdict: 'redact', body, headers };\n };\n\n // Screen a fetch Response (used by .fetch() and — via protection.screenResponse — the Supabase guard).\n const screenResp = async (response) => {\n const text = await readTextResponse(response);\n if (text == null) return response;\n const r = screenText(text, { status: response.status, headers: headerObject(response.headers) });\n if (r.verdict === 'block') return leakResponse();\n if (r.verdict === 'redact') return rebuildResponse(response, r.body, r.headers);\n return response;\n };\n\n // Wrap a Node ServerResponse so its (buffered, text) body is screened before it's sent.\n // Opt-in (buffering can delay a streamed response); over 512 KiB it stops buffering and\n // passes through unscanned.\n const wrapNodeResponse = (res) => {\n const origWrite = res.write.bind(res);\n const origEnd = res.end.bind(res);\n const chunks = [];\n let size = 0;\n let overflow = false;\n const MAX = 512 * 1024;\n const collect = (chunk, enc) => {\n if (chunk == null) return;\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, typeof enc === 'string' ? enc : 'utf8');\n size += buf.length;\n if (size > MAX) { overflow = true; return; }\n chunks.push(buf);\n };\n res.write = function (chunk, enc, cb) {\n if (overflow) return origWrite(chunk, enc, cb);\n collect(chunk, enc);\n if (typeof enc === 'function') enc();\n else if (typeof cb === 'function') cb();\n return true;\n };\n res.end = function (chunk, enc, cb) {\n if (typeof chunk === 'function') { cb = chunk; chunk = undefined; enc = undefined; }\n else if (typeof enc === 'function') { cb = enc; enc = undefined; }\n if (overflow) { if (chunk != null) origWrite(chunk, enc); return origEnd(cb); }\n collect(chunk, enc);\n const text = Buffer.concat(chunks).toString('utf8');\n let ct = res.getHeader ? res.getHeader('content-type') : undefined;\n if (Array.isArray(ct)) ct = ct[0];\n if (!isTextCT(ct)) { for (const c of chunks) origWrite(c); return origEnd(cb); }\n let r;\n try {\n r = screenText(text, { status: res.statusCode, headers: res.getHeaders ? res.getHeaders() : {} });\n } catch (err) {\n onError?.(err);\n for (const c of chunks) origWrite(c);\n return origEnd(cb);\n }\n if (r.verdict === 'block') {\n res.statusCode = 500;\n try { res.setHeader('content-type', 'application/json'); } catch { /* headers sent */ }\n return origEnd(JSON.stringify({ error: 'Response withheld by Patchstack (sensitive data detected)' }), cb);\n }\n if (r.verdict === 'redact') {\n try { res.removeHeader && res.removeHeader('content-length'); } catch { /* ignore */ }\n if (r.headers && res.setHeader) {\n const current = res.getHeaders ? res.getHeaders() : {};\n for (const [name, value] of Object.entries(r.headers)) {\n if (Array.isArray(value)) {\n try { res.setHeader(name, value); } catch { /* ignore invalid header */ } // Set-Cookie array\n } else if (typeof value === 'string' && current[name] !== value) {\n try { res.setHeader(name, value); } catch { /* ignore invalid header */ }\n }\n }\n }\n return origEnd(r.body, cb);\n }\n for (const c of chunks) origWrite(c);\n return origEnd(cb);\n };\n };\n\n // Egress phase: is this outbound call blocked? (records detection either way)\n const allow = new Set((options.allowHosts ?? []).map((h) => String(h).toLowerCase()));\n const egressShouldBlock = (url, host, method) => {\n if (host && allow.has(host.toLowerCase())) return false;\n let result;\n try {\n result = egressEngine.evaluate({ _egress: { url, host, method } });\n } catch (err) {\n onError?.(err);\n return false;\n }\n if (!result.blocked) return false;\n onDetect({ phase: 'egress', mode, category: result.rule?.category, rule: result.rule, message: result.message });\n return mode === 'block';\n };\n\n const protection = {\n mode,\n rules: { request: requestRules, response: responseRules, egress: egressRules },\n\n // Screen a fetch Response through the response-phase rules (redact/block). Used by\n // .fetch(), and by the Supabase guard on its forwarded upstream response.\n screenResponse: (response) => screenResp(response),\n\n // (request) => Response | null (null = allow, caller proceeds). Request phase only.\n fetchGuard() {\n return async (request) => {\n let result;\n try {\n result = engine.evaluate(await fromFetchRequest(request));\n } catch (err) {\n onError?.(err);\n return null; // fail open\n }\n return decide('request', result, () => blockResponse(result, request), () => null);\n };\n },\n\n // Wrap a fetch handler: screens the request, then the response (redact/block).\n fetch(handler) {\n const guard = protection.fetchGuard();\n return async (request, ...rest) => {\n const blocked = await guard(request);\n if (blocked) return blocked;\n const response = await handler(request, ...rest);\n return screenResp(response);\n };\n },\n\n // Express middleware (request phase; expects express-parsed req.query/req.body).\n // Pass { screenResponses: true } to also screen the outgoing response (buffers it).\n express(exprOptions = {}) {\n return (req, res, next) => {\n let result;\n try {\n result = engine.evaluate(req);\n } catch (err) {\n onError?.(err);\n if (exprOptions.screenResponses) wrapNodeResponse(res);\n return next();\n }\n decide(\n 'request',\n result,\n () => {\n if (isDocumentNavigation((n) => req.headers?.[n])) {\n res.status(403).type('html').send(renderBlockPage({ url: req.originalUrl || req.url || '/', code: result?.rule?.id }));\n } else {\n res.status(403).json(blockBody(result));\n }\n },\n () => {\n if (exprOptions.screenResponses) wrapNodeResponse(res);\n next();\n },\n );\n };\n },\n\n // Node / Connect middleware — buffers the body itself (request phase).\n // Pass { screenResponses: true } to also screen the outgoing response (buffers it).\n node(nodeOptions = {}) {\n const maxBytes = nodeOptions.maxBodyBytes ?? 1024 * 1024;\n return (req, res, next) => {\n const chunks = [];\n let size = 0;\n let overflow = false;\n req.on('data', (chunk) => {\n size += chunk.length;\n if (size > maxBytes) {\n overflow = true;\n return;\n }\n chunks.push(chunk);\n });\n req.on('error', (err) => {\n onError?.(err);\n next();\n });\n req.on('end', () => {\n const rawBody = overflow ? '' : Buffer.concat(chunks).toString('utf8');\n let shaped;\n let result;\n try {\n shaped = fromNodeRequest(req, rawBody);\n result = engine.evaluate(shaped);\n } catch (err) {\n onError?.(err);\n return next();\n }\n decide(\n 'request',\n result,\n () => {\n res.statusCode = 403;\n if (isDocumentNavigation((n) => req.headers?.[n])) {\n res.setHeader('content-type', 'text/html; charset=utf-8');\n res.end(renderBlockPage({ url: req.url || '/', code: result?.rule?.id }));\n } else {\n res.setHeader('content-type', 'application/json');\n res.end(JSON.stringify(blockBody(result)));\n }\n },\n () => {\n // This guard consumed the request stream to screen it; re-expose the parsed\n // body so a downstream handler (without its own body-parser) can read it.\n if (req.body === undefined) req.body = shaped.body;\n if (nodeOptions.screenResponses) wrapNodeResponse(res);\n next();\n },\n );\n });\n };\n },\n };\n\n // Egress interception is opt-in (it wraps the global fetch, and node:http/https on Node).\n if (options.egress) {\n protection.uninstallEgress = await installEgressGuard({ shouldBlock: egressShouldBlock, onBlock: options.onEgressBlock });\n }\n\n return protection;\n}\n\n// --- phase / response helpers -------------------------------------------\n\nfunction byPhase(rules, phase) {\n return (rules ?? []).filter((r) => (r.phase ?? 'request') === phase);\n}\n\nasync function readTextResponse(response) {\n if (!response || typeof response.clone !== 'function') return null;\n const ct = (response.headers?.get?.('content-type') || '').toLowerCase();\n const isText = ct === '' || /(json|text|xml|html|javascript|csv|yaml|x-www-form-urlencoded)/.test(ct);\n if (!isText) return null;\n const len = Number(response.headers?.get?.('content-length') || 0);\n if (len && len > 512 * 1024) return null;\n try {\n const text = await response.clone().text();\n return text.length > 512 * 1024 ? null : text;\n } catch {\n return null;\n }\n}\n\nfunction headerObject(headers) {\n const out = {};\n headers?.forEach?.((v, k) => { out[k.toLowerCase()] = v; });\n // Set-Cookie is multi-valued; forEach collapses it. Recover the individual cookies so each can\n // be screened (and re-emitted) separately.\n const setCookies = headers?.getSetCookie?.();\n if (setCookies && setCookies.length) out['set-cookie'] = setCookies;\n return out;\n}\n\n// Derive redaction targets from a rule's own conditions: regex → mask every match;\n// contains/stripos → mask the literal. (Other match types can't identify a span → the\n// rule falls back to block.)\nfunction extractRedactors(rule) {\n const out = [];\n const walk = (conds) => {\n for (const c of conds ?? []) {\n if (Array.isArray(c.rules)) walk(c.rules);\n const m = c.match;\n if (!m) continue;\n if (m.type === 'regex' && typeof m.value === 'string') {\n const parsed = m.value.match(/^\\/(.+)\\/([a-z]*)$/is);\n if (parsed) {\n const flags = parsed[2].includes('g') ? parsed[2] : parsed[2] + 'g';\n try {\n out.push({ re: new RegExp(parsed[1], flags) });\n } catch {\n /* skip invalid */\n }\n }\n } else if ((m.type === 'contains' || m.type === 'stripos') && m.value != null) {\n out.push({ literal: String(m.value) });\n }\n }\n };\n walk(rule.rule_v2);\n return out;\n}\n\nfunction applyRedactors(body, redactors, mask) {\n let out = body;\n for (const r of redactors) {\n if (r.re) out = out.replace(r.re, mask);\n else if (r.literal) out = out.split(r.literal).join(mask);\n }\n return out;\n}\n\nfunction rebuildResponse(response, body, redactedHeaders) {\n const headers = new Headers(response.headers);\n headers.delete('content-length'); // body length changed after redaction\n if (redactedHeaders) {\n for (const [name, value] of Object.entries(redactedHeaders)) {\n if (typeof value === 'string') {\n if (headers.get(name) !== value) {\n try { headers.set(name, value); } catch { /* invalid header name — skip */ }\n }\n } else if (Array.isArray(value)) {\n // Re-emit each (possibly redacted) Set-Cookie separately (Headers collapses them otherwise).\n try {\n headers.delete(name);\n for (const item of value) headers.append(name, String(item));\n } catch { /* skip */ }\n }\n }\n }\n return new Response(body, { status: response.status, statusText: response.statusText, headers });\n}\n\nfunction leakResponse() {\n return new Response(JSON.stringify({ error: 'Response withheld by Patchstack (sensitive data detected)' }), {\n status: 500,\n headers: { 'content-type': 'application/json' }\n });\n}\n\n// --- rule source --------------------------------------------------------\n\nasync function resolveRules(options) {\n const cache = makeCache(options);\n\n if (options.siteUuid) {\n const prior = await cache.read(); // { bundle, etag } | null\n const client = new PulseRuleClient({ siteUuid: options.siteUuid, baseUrl: options.pulseRulesUrl, etag: prior?.etag });\n const res = await client.getRules();\n if (res.success && res.notModified && prior?.bundle) return normalizeBundle(prior.bundle);\n if (res.success && !res.notModified) {\n const bundle = normalizeBundle(res);\n await cache.write({ bundle, etag: res.etag ?? null });\n return bundle;\n }\n if (prior?.bundle) {\n options.onError?.(new Error(`pulse rule fetch failed (${res.error ?? 'no usable response'}); using cached bundle`));\n return normalizeBundle(prior.bundle);\n }\n if (options.rules) {\n options.onError?.(new Error(`pulse rule fetch failed (${res.error ?? 'no usable response'}); using bundled fallback`));\n return normalizeBundle(options.rules);\n }\n options.onError?.(new Error(`pulse rule fetch failed (${res.error ?? 'no usable response'}); no cache — running with no rules`));\n return emptyBundle();\n }\n\n if (options.token) {\n const prior = await cache.read();\n const client = new PatchstackRuleClient({ token: options.token, baseUrl: options.baseUrl, etag: prior?.etag });\n const res = await client.getRules();\n if (res.success && res.notModified && prior?.bundle) return normalizeBundle(prior.bundle);\n if (res.success && !res.notModified) {\n const bundle = normalizeBundle(res);\n await cache.write({ bundle, etag: res.etag ?? null });\n return bundle;\n }\n if (prior?.bundle) {\n options.onError?.(new Error(`rule fetch failed (${res.error ?? 'no usable response'}); using cached bundle`));\n return normalizeBundle(prior.bundle);\n }\n options.onError?.(new Error(`rule fetch failed (${res.error ?? 'no usable response'}); no cache — running with no rules`));\n return emptyBundle();\n }\n\n if (options.rules) {\n return normalizeBundle(options.rules);\n }\n\n return emptyBundle();\n}\n\nfunction normalizeBundle(b) {\n return {\n firewall: Array.isArray(b.firewall) ? b.firewall : [],\n whitelists: Array.isArray(b.whitelists) ? b.whitelists : [],\n whitelist_keys: b.whitelist_keys ?? {},\n };\n}\n\nfunction emptyBundle() {\n return { firewall: [], whitelists: [], whitelist_keys: {} };\n}\n\n// The cache stores an envelope { bundle, etag } so a restart can revalidate with If-None-Match. A\n// pluggable adapter (options.ruleCache) lets runtimes without a filesystem (Workers/Deno) persist\n// last-known-good in their own store; the default is a disk cache under options.cacheDir. Both\n// paths are best-effort — a read/write error yields no cache rather than throwing.\nfunction makeCache(options) {\n const adapter = options.ruleCache;\n if (adapter && typeof adapter.read === 'function' && typeof adapter.write === 'function') {\n return {\n read: async () => {\n try {\n return toEnvelope(await adapter.read());\n } catch {\n return null;\n }\n },\n write: async (env) => {\n try {\n await adapter.write(env);\n } catch {\n /* best-effort */\n }\n },\n };\n }\n const dir = options.cacheDir;\n return {\n read: async () => cacheRead(dir),\n write: async (env) => cacheWrite(dir, env),\n };\n}\n\nfunction cachePath(dir) {\n return join(dir, 'patchstack-rules.json');\n}\n\nfunction cacheWrite(dir, env) {\n if (!dir) return;\n try {\n mkdirSync(dir, { recursive: true });\n writeFileSync(cachePath(dir), JSON.stringify(env));\n } catch {\n /* cache is best-effort */\n }\n}\n\nfunction cacheRead(dir) {\n if (!dir) return null;\n try {\n return toEnvelope(JSON.parse(readFileSync(cachePath(dir), 'utf8')));\n } catch {\n return null;\n }\n}\n\n// Accept the current { bundle, etag } envelope and a legacy bare bundle (pre-envelope cache files).\nfunction toEnvelope(value) {\n if (!value || typeof value !== 'object') return null;\n if (value.bundle && typeof value.bundle === 'object') {\n return { bundle: value.bundle, etag: value.etag ?? null };\n }\n if (Array.isArray(value.firewall) || Array.isArray(value.whitelists)) {\n return { bundle: value, etag: null }; // legacy bare-bundle cache file\n }\n return null;\n}\n\n// --- responses ----------------------------------------------------------\n\n// Client-facing block text — deliberately generic: no WAF narrative, no rule title. The reason\n// detail stays in the server-side log via onDetect.\nconst BLOCK_MESSAGE = 'This request has been blocked by Patchstack.';\n\nfunction blockBody(result) {\n // Human text is masked (no WAF narrative, no rule title). The opaque rule id stays for machine\n // consumers (server-fn receipts, support reference); full rule detail lives in the server log.\n return { error: BLOCK_MESSAGE, message: BLOCK_MESSAGE, rule: result?.rule?.id };\n}\n\n// A top-level document navigation (vs an XHR/fetch)? Browsers set Sec-Fetch-Dest on navigations;\n// fall back to the Accept header. Governs whether a block returns the HTML page or JSON.\nfunction isDocumentNavigation(getHeader) {\n const dest = getHeader('sec-fetch-dest');\n if (dest) return dest === 'document';\n return (getHeader('accept') || '').includes('text/html');\n}\n\n// Request-phase block. Serves the branded HTML \"Access Denied\" page to a browser navigation, and\n// masked JSON to XHR/fetch/programmatic clients.\nfunction blockResponse(result, request) {\n if (request && isDocumentNavigation((n) => request.headers.get(n))) {\n return new Response(renderBlockPage({ url: request.url, code: result?.rule?.id }), {\n status: 403,\n headers: { 'content-type': 'text/html; charset=utf-8' },\n });\n }\n return new Response(JSON.stringify(blockBody(result)), {\n status: 403,\n headers: { 'content-type': 'application/json' },\n });\n}\n\nfunction defaultOnDetect({ phase, mode, category, rule, message }) {\n const tag = mode === 'block' ? 'BLOCK' : 'DETECT (dry-run)';\n console.warn(`[patchstack] ${tag} phase=${phase ?? 'request'} category=${category ?? '?'} rule=${rule?.id ?? '?'} ${message ?? ''}`.trim());\n}\n","const DEFAULT_BASE_URL = 'https://api.patchstack.com';\nconst DEFAULT_CACHE_TTL = 300_000;\n// Randomly shorten the effective TTL by up to this fraction so many long-lived clients don't all\n// revalidate on the same tick (spreads load against the rules API).\nconst JITTER_FRACTION = 0.1;\n\n// Token-authenticated rules client. Conditional fetch (If-None-Match / 304) and the persisted\n// `etag` mirror PulseRuleClient; both are a no-op until the API emits an ETag and honors the\n// conditional request — with no ETag in the response the client behaves as before (full fetch).\nexport class PatchstackRuleClient {\n #token;\n #baseUrl;\n #cacheTtl;\n #cache = null;\n #cacheTime = null;\n #ttlEffective = 0;\n #etag;\n\n constructor({ token, baseUrl, cacheTtl, etag } = {}) {\n this.#token = token ?? process.env.PATCHSTACK_WAF_TOKEN;\n this.#baseUrl = baseUrl ?? process.env.PATCHSTACK_WAF_API_URL ?? DEFAULT_BASE_URL;\n this.#cacheTtl = cacheTtl ?? DEFAULT_CACHE_TTL;\n this.#etag = etag ?? null;\n\n if (!this.#token) {\n throw new Error('Patchstack WAF token is required. Pass { token } or set PATCHSTACK_WAF_TOKEN env var.');\n }\n }\n\n async getRules() {\n const now = Date.now();\n\n if (this.#cache && this.#cacheTime !== null && (now - this.#cacheTime) < this.#ttlEffective) {\n return this.#cache;\n }\n\n const url = `${this.#baseUrl}/api/get-rules/3`;\n\n try {\n const headers = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.#token}`,\n 'LicenseID': '1' // Hard-coded, is never actually used but needed by the API\n };\n if (this.#etag) headers['If-None-Match'] = this.#etag;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({}),\n signal: AbortSignal.timeout(30_000)\n });\n\n if (response.status === 304) {\n this.#touch(now); // revalidated — reset the clock (fresh jitter)\n return this.#cache ?? { success: true, notModified: true, etag: this.#etag, firewall: [], whitelists: [], whitelist_keys: {} };\n }\n\n if (!response.ok) {\n return {\n success: false,\n error: `API returned ${response.status}: ${response.statusText}`,\n firewall: [],\n whitelists: [],\n whitelist_keys: {}\n };\n }\n\n const data = await response.json();\n\n const result = {\n success: true,\n notModified: false,\n etag: response.headers?.get?.('etag') ?? null,\n firewall: Array.isArray(data.firewall) ? data.firewall : [],\n whitelists: Array.isArray(data.whitelists) ? data.whitelists : [],\n whitelist_keys: data.whitelist_keys ?? {}\n };\n\n this.#cache = result;\n this.#etag = result.etag;\n this.#touch(now);\n\n return result;\n } catch (err) {\n return {\n success: false,\n error: err.name === 'TimeoutError'\n ? 'Request timed out'\n : err.message,\n firewall: [],\n whitelists: [],\n whitelist_keys: {}\n };\n }\n }\n\n #touch(now) {\n this.#cacheTime = now;\n this.#ttlEffective = this.#cacheTtl - Math.floor(Math.random() * this.#cacheTtl * JITTER_FRACTION);\n }\n\n clearCache() {\n this.#cache = null;\n this.#cacheTime = null;\n this.#etag = null;\n }\n}\n","// WinterCG-safe base64 decode: use Buffer on Node, fall back to atob/TextDecoder on\n// edge runtimes (Cloudflare Workers, Deno, Bun) where Buffer may be absent. Keeps the\n// engine hot path free of Node-only APIs (per the ADR engine-language decision).\nfunction base64DecodeUtf8(value) {\n const str = String(value);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'base64').toString('utf-8');\n }\n const binary = atob(str);\n const bytes = Uint8Array.from(binary, (c) => c.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\nexport class RequestResolver {\n #req;\n #cookies;\n\n constructor(req) {\n this.#req = req;\n this.#cookies = null;\n }\n\n resolve(parameter) {\n if (!parameter || parameter === 'false') {\n return [null];\n }\n\n if (parameter === 'rules') {\n return [null];\n }\n\n if (parameter === 'raw') {\n return this.#resolveRaw();\n }\n\n if (parameter === 'all') {\n return this.#resolveAll();\n }\n\n const dotIndex = parameter.indexOf('.');\n if (dotIndex === -1) {\n return [];\n }\n\n const source = parameter.substring(0, dotIndex);\n const key = parameter.substring(dotIndex + 1);\n\n switch (source) {\n case 'get':\n return this.#resolveGet(key);\n case 'post':\n return this.#resolvePost(key);\n case 'request':\n return this.#resolveRequest(key);\n case 'cookie':\n return this.#resolveCookie(key);\n case 'server':\n return this.#resolveServer(key);\n case 'files':\n return this.#resolveFiles(key);\n case 'response':\n return this.#resolveResponse(key);\n case 'egress':\n return this.#resolveEgress(key);\n default:\n return [];\n }\n }\n\n // Response-phase sources (req._response = { status, headers, body }). Lets rules inspect\n // what the app is about to SEND — e.g. a leaked secret in the body — regardless of route.\n #resolveResponse(key) {\n const resp = this.#req._response;\n if (!resp) {\n return [];\n }\n if (key === 'status') {\n return resp.status !== undefined ? [String(resp.status)] : [];\n }\n if (key === 'body') {\n return resp.body != null && resp.body !== '' ? [resp.body] : [];\n }\n if (key === 'headers') {\n const headers = resp.headers ?? {};\n return [Object.entries(headers).map(([k, v]) => `${k}: ${v}`).join('\\n')];\n }\n if (key.startsWith('header.')) {\n const name = key.slice('header.'.length).toLowerCase();\n const value = (resp.headers ?? {})[name];\n return value !== undefined ? [value] : [];\n }\n return [];\n }\n\n // Egress-phase sources (req._egress = { url, host, method }). Lets rules inspect an\n // OUTBOUND request the app is about to make — SSRF at the egress boundary.\n #resolveEgress(key) {\n const eg = this.#req._egress;\n if (!eg) {\n return [];\n }\n if (key === 'url') return eg.url ? [eg.url] : [];\n if (key === 'host') return eg.host ? [eg.host] : [];\n if (key === 'method') return eg.method ? [eg.method] : [];\n return [];\n }\n\n applyMutations(mutations, value) {\n if (!mutations || !Array.isArray(mutations)) {\n return value;\n }\n\n let result = value;\n\n for (const mutation of mutations) {\n result = this.#applyMutation(mutation, result);\n }\n\n return result;\n }\n\n #applyMutation(mutation, value) {\n if (value === null || value === undefined) {\n return value;\n }\n\n switch (mutation) {\n case 'base64_decode':\n try {\n return base64DecodeUtf8(value);\n } catch {\n return value;\n }\n\n case 'json_decode':\n try {\n return JSON.parse(String(value));\n } catch {\n return value;\n }\n\n case 'json_encode':\n try {\n return JSON.stringify(value);\n } catch {\n return value;\n }\n\n case 'urldecode':\n try {\n return decodeURIComponent(String(value));\n } catch {\n return value;\n }\n\n case 'intval':\n return parseInt(String(value), 10) || 0;\n\n case 'getArrayValues':\n if (typeof value === 'object' && value !== null) {\n return Object.values(value);\n }\n return value;\n\n default:\n return value;\n }\n }\n\n #resolveGet(key) {\n const query = this.#req.query ?? {};\n\n if (key.endsWith('*')) {\n return this.#resolveWildcard(query, key);\n }\n\n const value = this.#getNestedValue(query, key);\n return value !== undefined ? [value] : [];\n }\n\n #resolvePost(key) {\n const body = this.#req.body ?? {};\n\n if (key.endsWith('*')) {\n return this.#resolveWildcard(body, key);\n }\n\n const value = this.#getNestedValue(body, key);\n return value !== undefined ? [value] : [];\n }\n\n #resolveRequest(key) {\n const query = this.#req.query ?? {};\n const body = this.#req.body ?? {};\n const cookies = this.#parseCookies();\n\n if (key.endsWith('*')) {\n return [\n ...this.#resolveWildcard(query, key),\n ...this.#resolveWildcard(body, key),\n ...this.#resolveWildcard(cookies, key)\n ];\n }\n\n const value = this.#getNestedValue(query, key)\n ?? this.#getNestedValue(body, key)\n ?? cookies[key];\n\n return value !== undefined ? [value] : [];\n }\n\n #resolveCookie(key) {\n const cookies = this.#parseCookies();\n\n if (key.endsWith('*')) {\n return this.#resolveWildcard(cookies, key);\n }\n\n const value = cookies[key];\n return value !== undefined ? [value] : [];\n }\n\n #resolveServer(key) {\n const req = this.#req;\n\n switch (key) {\n case 'REQUEST_URI':\n return [req.originalUrl ?? req.url ?? '/'];\n case 'REQUEST_METHOD':\n return [req.method ?? 'GET'];\n case 'HTTP_USER_AGENT':\n return req.headers?.['user-agent'] ? [req.headers['user-agent']] : [];\n case 'HTTP_REFERER':\n return req.headers?.referer ? [req.headers.referer] : [];\n case 'HTTP_HOST':\n return req.headers?.host ? [req.headers.host] : [];\n case 'REMOTE_ADDR':\n case 'ip':\n return [req.ip ?? req.socket?.remoteAddress ?? ''];\n case 'CONTENT_TYPE':\n return req.headers?.['content-type'] ? [req.headers['content-type']] : [];\n case 'CONTENT_LENGTH':\n return req.headers?.['content-length'] ? [req.headers['content-length']] : [];\n default: {\n if (key.startsWith('HTTP_')) {\n const headerName = key.substring(5).toLowerCase().replace(/_/g, '-');\n return req.headers?.[headerName] ? [req.headers[headerName]] : [];\n }\n return [];\n }\n }\n }\n\n #resolveFiles(key) {\n const files = this.#req.files;\n if (!files) {\n return [];\n }\n\n if (key.endsWith('*')) {\n return this.#resolveWildcard(files, key);\n }\n\n const value = files[key];\n return value !== undefined ? [value] : [];\n }\n\n #resolveRaw() {\n // Use pre-captured raw body if available (set by normalizeRequest).\n // For string bodies, the original text is preserved verbatim.\n // For pre-parsed objects, serializeForRawDetection uses Object.getOwnPropertyNames()\n // to include __proto__ own-property keys that JSON.stringify() would silently drop.\n if (typeof this.#req._rawBody === 'string') {\n return this.#req._rawBody ? [this.#req._rawBody] : [];\n }\n\n const body = this.#req.body;\n\n if (body === undefined || body === null) {\n return [];\n }\n\n if (typeof body === 'string') {\n return [body];\n }\n\n try {\n return [JSON.stringify(body)];\n } catch {\n return [String(body)];\n }\n }\n\n #resolveAll() {\n const parts = [];\n\n const uri = this.#req.originalUrl ?? this.#req.url ?? '/';\n parts.push(uri);\n\n const queryString = uri.includes('?') ? uri.split('?')[1] : '';\n if (queryString) {\n parts.push(queryString);\n }\n\n const body = this.#req.body;\n if (body) {\n parts.push(typeof body === 'string' ? body : JSON.stringify(body));\n }\n\n const headers = this.#req.headers ?? {};\n const excludedHeaders = new Set([\n 'host', 'connection', 'cache-control', 'accept', 'accept-encoding',\n 'accept-language', 'priority', 'sec-ch-ua', 'sec-ch-ua-mobile',\n 'sec-ch-ua-platform', 'sec-fetch-dest', 'sec-fetch-mode',\n 'sec-fetch-site', 'sec-fetch-user', 'upgrade-insecure-requests'\n ]);\n\n for (const [name, value] of Object.entries(headers)) {\n if (!excludedHeaders.has(name)) {\n parts.push(`${name}: ${value}`);\n }\n }\n\n const cookies = this.#parseCookies();\n const cookieStr = Object.entries(cookies).map(([k, v]) => `${k}=${v}`).join('; ');\n if (cookieStr) {\n parts.push(cookieStr);\n }\n\n return [parts.join(' ')];\n }\n\n #resolveWildcard(obj, pattern) {\n if (typeof obj !== 'object' || obj === null) {\n return [];\n }\n\n const prefix = pattern.slice(0, -1);\n const values = [];\n\n for (const [key, value] of Object.entries(obj)) {\n if (key.startsWith(prefix)) {\n values.push(value);\n }\n }\n\n return values;\n }\n\n #getNestedValue(obj, key) {\n if (typeof obj !== 'object' || obj === null) {\n return undefined;\n }\n\n if (key in obj) {\n return obj[key];\n }\n\n const parts = key.split('.');\n let current = obj;\n\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n current = current[part];\n }\n\n return current;\n }\n\n #parseCookies() {\n if (this.#cookies !== null) {\n return this.#cookies;\n }\n\n if (this.#req.cookies) {\n this.#cookies = this.#req.cookies;\n return this.#cookies;\n }\n\n const header = this.#req.headers?.cookie;\n if (!header) {\n this.#cookies = {};\n return this.#cookies;\n }\n\n const cookies = {};\n\n for (const pair of header.split(';')) {\n const eqIndex = pair.indexOf('=');\n if (eqIndex === -1) {\n continue;\n }\n const name = pair.substring(0, eqIndex).trim();\n const value = pair.substring(eqIndex + 1).trim();\n cookies[name] = value;\n }\n\n this.#cookies = cookies;\n return this.#cookies;\n }\n}\n","/**\n * Request Normalization Pipeline\n *\n * Normalizes request data to prevent encoding-based bypass attacks.\n * This module handles URL encoding, HTML entities, SQL comments, and other\n * obfuscation techniques that attackers use to evade pattern matching.\n */\n\nconst HTML_ENTITIES = {\n '&amp;': '&',\n '&lt;': '<',\n '&gt;': '>',\n '&quot;': '\"',\n '&#39;': \"'\",\n '&apos;': \"'\",\n '&nbsp;': ' ',\n '&#x27;': \"'\",\n '&#x22;': '\"',\n '&#x3C;': '<',\n '&#x3E;': '>',\n '&#x26;': '&',\n '&#34;': '\"',\n '&#60;': '<',\n '&#62;': '>',\n '&#38;': '&'\n};\n\nconst MAX_DECODE_ITERATIONS = 5;\n\nexport function normalize(value, options = {}) {\n if (typeof value !== 'string') {\n return value;\n }\n\n const opts = {\n urlDecode: true,\n htmlDecode: true,\n sqlComments: true,\n nullBytes: true,\n whitespace: true,\n ...options\n };\n\n let result = value;\n\n if (opts.nullBytes) {\n result = removeNullBytes(result);\n }\n\n if (opts.urlDecode) {\n result = urlDecode(result);\n }\n\n if (opts.htmlDecode) {\n result = htmlEntityDecode(result);\n }\n\n if (opts.sqlComments) {\n result = removeSqlComments(result);\n }\n\n if (opts.whitespace) {\n result = normalizeWhitespace(result);\n }\n\n return result;\n}\n\nexport function urlDecode(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value;\n let previous = '';\n let iterations = 0;\n\n while (result !== previous && iterations < MAX_DECODE_ITERATIONS) {\n previous = result;\n iterations++;\n\n try {\n result = decodeURIComponent(result);\n } catch {\n result = safeUrlDecode(result);\n break;\n }\n }\n\n return result;\n}\n\nfunction safeUrlDecode(value) {\n return value.replace(/%([0-9A-Fa-f]{2})/g, (match, hex) => {\n try {\n return String.fromCharCode(parseInt(hex, 16));\n } catch {\n return match;\n }\n });\n}\n\nexport function htmlEntityDecode(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value;\n\n for (const [entity, char] of Object.entries(HTML_ENTITIES)) {\n result = result.split(entity).join(char);\n }\n\n result = result.replace(/&#(\\d+);/g, (match, code) => {\n const num = parseInt(code, 10);\n return num > 0 && num < 65536 ? String.fromCharCode(num) : match;\n });\n\n result = result.replace(/&#x([0-9A-Fa-f]+);/g, (match, hex) => {\n const num = parseInt(hex, 16);\n return num > 0 && num < 65536 ? String.fromCharCode(num) : match;\n });\n\n return result;\n}\n\nexport function removeSqlComments(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value;\n\n result = result.replace(/\\/\\*[\\s\\S]*?\\*\\//g, ' ');\n result = result.replace(/\\/\\*![\\s\\S]*?\\*\\//g, ' ');\n result = result.replace(/--[^\\r\\n]*/g, '');\n result = result.replace(/#[^\\r\\n]*/g, '');\n\n return result;\n}\n\nexport function removeNullBytes(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value.replace(/\\x00/g, '');\n\n result = result.replace(/[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/g, '');\n\n return result;\n}\n\nexport function normalizeWhitespace(value) {\n if (typeof value !== 'string') {\n return value;\n }\n\n let result = value.replace(/[\\t\\r\\n\\f\\v]+/g, ' ');\n\n result = result.replace(/ {2,}/g, ' ');\n\n return result;\n}\n\nfunction serializeForRawDetection(body, visited = new Set(), isRoot = true) {\n if (body === null || body === undefined) {\n return isRoot ? '' : 'null';\n }\n\n if (typeof body === 'string') {\n return isRoot ? body : JSON.stringify(body);\n }\n\n if (typeof body !== 'object') {\n return String(body);\n }\n\n if (visited.has(body)) {\n return '[Circular]';\n }\n visited.add(body);\n\n if (Array.isArray(body)) {\n const items = body.map(item => serializeForRawDetection(item, visited, false));\n return '[' + items.join(',') + ']';\n }\n\n // Object.getOwnPropertyNames includes non-enumerable own properties, so a __proto__ key\n // set via Object.defineProperty (as modern JSON.parse may do) is included in the output.\n const keys = Object.getOwnPropertyNames(body);\n const parts = keys.map(key => {\n const val = serializeForRawDetection(body[key], visited, false);\n return JSON.stringify(key) + ':' + val;\n });\n\n return '{' + parts.join(',') + '}';\n}\n\nexport function normalizeRequest(req, options = {}) {\n // Prefer a caller-provided verbatim body string (set by the fetch/node adapters):\n // it preserves literal keys like `__proto__` that JSON.stringify drops, which is\n // what makes prototype-pollution rules on `raw` robust. Fall back to a\n // reconstruction from the parsed body (the Express path, which has no raw text).\n const rawBody = typeof req._rawBody === 'string'\n ? req._rawBody\n : serializeForRawDetection(req.body ?? null);\n\n return {\n query: normalizeObject(req.query || {}, options),\n body: normalizeObject(req.body || {}, options),\n headers: normalizeObject(req.headers || {}, options),\n url: normalize(req.url || '', options),\n originalUrl: normalize(req.originalUrl || req.url || '', options),\n _rawBody: rawBody\n };\n}\n\nexport function normalizeObject(value, options = {}) {\n if (typeof value === 'string') {\n return normalize(value, options);\n }\n\n if (Array.isArray(value)) {\n return value.map(item => normalizeObject(item, options));\n }\n\n if (typeof value === 'object' && value !== null) {\n const result = {};\n\n for (const [key, val] of Object.entries(value)) {\n result[key] = normalizeObject(val, options);\n }\n\n return result;\n }\n\n return value;\n}\n\nexport function createMatchVariants(value) {\n if (typeof value !== 'string') {\n return [value];\n }\n\n const variants = new Set();\n\n variants.add(value);\n\n const urlDecoded = urlDecode(value);\n variants.add(urlDecoded);\n\n const htmlDecoded = htmlEntityDecode(value);\n variants.add(htmlDecoded);\n\n const bothDecoded = htmlEntityDecode(urlDecoded);\n variants.add(bothDecoded);\n\n const normalized = normalize(value);\n variants.add(normalized);\n\n variants.add(value.toLowerCase());\n variants.add(normalized.toLowerCase());\n\n return Array.from(variants);\n}\n\nexport const _testExports = {\n safeUrlDecode,\n serializeForRawDetection,\n HTML_ENTITIES,\n MAX_DECODE_ITERATIONS\n};\n","import { RequestResolver } from './request.js';\nimport { normalizeRequest } from './normalizer.js';\n\nconst REDOS_PATTERNS = [\n /\\(\\w\\+\\)\\+/,\n /\\(\\w\\*\\)\\+/,\n /\\(\\w\\+\\)\\*/,\n /\\(\\w\\*\\)\\*/,\n /\\(\\w\\|\\w\\)\\+/\n];\n\nfunction safeRegExp(pattern) {\n if (!pattern) {\n return null;\n }\n\n for (const dangerous of REDOS_PATTERNS) {\n if (dangerous.test(pattern)) {\n return null;\n }\n }\n\n const match = pattern.match(/^\\/(.+?)\\/([gimsuy]*)$/s);\n if (!match) {\n return null;\n }\n\n try {\n return new RegExp(match[1], match[2]);\n } catch {\n return null;\n }\n}\n\n// ctype_*/is_numeric compare their character-class result to the rule's expected\n// `value`. Rules are almost always written `{ \"type\": \"ctype_digit\", \"value\": false }`\n// meaning \"flag when NOT of this class\" — so the result must be compared to matchVal,\n// not returned raw. Empty/absent values never match (mirrors engine-php's `$value != ''`\n// guard), otherwise every missing parameter false-positives a `value:false` rule.\n// When `value` is not a boolean (null/omitted) the legacy default of `true` is used, so\n// existing rules that relied on the raw class check are unaffected.\nfunction ctypeResult(strValue, isClass, matchVal) {\n if (strValue === '') {\n return false;\n }\n const expected = typeof matchVal === 'boolean' ? matchVal : true;\n return isClass === expected;\n}\n\n// array_key_value: navigate `match.key` (a dot-path, or an array of paths) inside the\n// decoded value and run the nested `match.match` against whatever it finds. Mirrors\n// engine-php's recursive array_key_value handling.\nfunction arrayKeyValue(value, matchObj) {\n if (!matchObj || !matchObj.match || value === null || typeof value !== 'object') {\n return false;\n }\n const keys = Array.isArray(matchObj.key) ? matchObj.key : [matchObj.key];\n const sub = matchObj.match;\n\n for (const key of keys) {\n let node = value;\n for (const part of String(key).split('.')) {\n if (node === null || typeof node !== 'object') {\n node = undefined;\n break;\n }\n node = node[part];\n }\n if (node === undefined) {\n continue;\n }\n const candidates = Array.isArray(node) ? node : [node];\n for (const candidate of candidates) {\n if (matchValue(sub.type, candidate, sub.value, sub)) {\n return true;\n }\n }\n }\n return false;\n}\n\n// Report an unknown/removed match type once, so a rule referencing it is not silently\n// unenforced (ADR: \"unknown match type → skipped and logged, never silently passed\").\nconst warnedMatchTypes = new Set();\nfunction warnUnsupportedMatchType(type) {\n if (type == null || warnedMatchTypes.has(type)) {\n return;\n }\n warnedMatchTypes.add(type);\n console.warn(\n `[patchstack] Unsupported rule_v2 match type \"${type}\" — condition treated as no-match. ` +\n `Rules relying on it are not enforced by this engine.`\n );\n}\n\n// Internal / private / loopback / link-local / cloud-metadata host check, used by the\n// `internal_host` match type for SSRF egress rules. Handles IPv4 (incl. IPv4-mapped IPv6),\n// IPv6 loopback/link-local/unique-local, and localhost / *.local / GCP metadata names.\nfunction isInternalHost(hostname) {\n if (!hostname) return false;\n const host = String(hostname).toLowerCase().replace(/^\\[|\\]$/g, '');\n\n if (host === 'localhost' || host.endsWith('.localhost') || host.endsWith('.local')) return true;\n if (host === 'metadata.google.internal') return true;\n if (host === '::1' || host === '::') return true;\n if (host.startsWith('fe80:') || host.startsWith('fc') || host.startsWith('fd')) return true;\n\n const v4 = host.match(/(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/);\n if (v4) {\n const a = Number(v4[1]);\n const b = Number(v4[2]);\n if (a === 127 || a === 10 || a === 0) return true; // loopback / private / this-host\n if (a === 169 && b === 254) return true; // link-local incl. 169.254.169.254 metadata\n if (a === 172 && b >= 16 && b <= 31) return true; // 172.16.0.0/12\n if (a === 192 && b === 168) return true; // 192.168.0.0/16\n }\n return false;\n}\n\n// `matchObj` is the full match object; needed by types that read sibling fields\n// (array_key_value reads `key`/`match`). Optional so direct callers/tests can keep\n// using the (type, value, matchVal) signature.\nfunction matchValue(type, value, matchVal, matchObj) {\n if (value === null || value === undefined) {\n if (type === 'isset') {\n return false;\n }\n return false;\n }\n\n const strValue = typeof value === 'string' ? value : String(value);\n\n switch (type) {\n case 'equals':\n return strValue == matchVal;\n\n case 'equals_strict':\n return strValue === matchVal;\n\n case 'contains':\n // engine-php exposes `stripos` as an alias of `contains`.\n case 'stripos': {\n const lower = strValue.toLowerCase();\n const target = String(matchVal).toLowerCase();\n return lower.includes(target);\n }\n\n case 'not_contains': {\n const lower = strValue.toLowerCase();\n const target = String(matchVal).toLowerCase();\n return !lower.includes(target);\n }\n\n case 'regex': {\n const regex = safeRegExp(matchVal);\n if (!regex) {\n return false;\n }\n return regex.test(strValue);\n }\n\n case 'more_than':\n return Number(strValue) > Number(matchVal);\n\n case 'less_than':\n return Number(strValue) < Number(matchVal);\n\n case 'ctype_digit':\n return ctypeResult(strValue, /^\\d+$/.test(strValue), matchVal);\n\n case 'ctype_alnum':\n return ctypeResult(strValue, /^[\\w$\\u0080-\\uFFFF]+$/.test(strValue), matchVal);\n\n case 'is_numeric':\n return ctypeResult(strValue, !isNaN(strValue) && strValue.trim() !== '', matchVal);\n\n case 'isset':\n return true;\n\n case 'in_array': {\n const arr = Array.isArray(matchVal) ? matchVal : [matchVal];\n return arr.includes(strValue);\n }\n\n case 'not_in_array': {\n const arr = Array.isArray(matchVal) ? matchVal : [matchVal];\n return !arr.includes(strValue);\n }\n\n case 'array_in_array': {\n if (!Array.isArray(value) || !Array.isArray(matchVal)) {\n return false;\n }\n return value.some(v => matchVal.includes(v));\n }\n\n case 'hostname': {\n try {\n const url = new URL(strValue);\n return url.hostname === matchVal;\n } catch {\n return false;\n }\n }\n\n case 'internal_host':\n // SSRF egress: private / loopback / link-local / cloud-metadata destinations.\n return isInternalHost(strValue);\n\n case 'quotes':\n // engine-php exposes `inline_js_xss` as an alias of `quotes`.\n case 'inline_js_xss':\n return /['\"]/.test(strValue);\n\n case 'inline_xss':\n // Attribute-breakout heuristic: a quote AND a `>` or `=` (matches engine-php).\n return /['\"]/.test(strValue) && /[>=]/.test(strValue);\n\n case 'ctype_special': {\n // engine-php strips space, `_`, `-`, `,` then applies the alnum/unicode check,\n // and compares the result to `value` (usually false = \"flag when NOT clean\").\n const stripped = strValue.replace(/[ _\\-,]/g, '');\n return ctypeResult(strValue, /^[\\w$€-￿]*$/.test(stripped), matchVal);\n }\n\n case 'array_key_value':\n // Navigate `match.key` (dot-path, or array of paths) inside the decoded value and\n // run the nested `match.match` against it — e.g. a json_decode'd body where a\n // specific key must hold a specific value.\n return arrayKeyValue(value, matchObj);\n\n // file_contains (uploaded-file content scanning) is NOT WordPress-specific, but is\n // not yet implemented in the JS engine (needs multipart body access). Kept as an\n // explicit, documented no-match rather than silently hitting `default`.\n case 'file_contains':\n return false;\n\n // WordPress-only match types (current_user_cannot, general_xss, getShortcodeAtts,\n // getBlockAtts) have been removed: they depend on WP capabilities, wp_kses_post, and\n // the shortcode/block parsers, and have no meaning in a JS app. They now fall through\n // here and are reported once instead of pretending to be a no-match.\n default:\n warnUnsupportedMatchType(type);\n return false;\n }\n}\n\nexport class RuleEngine {\n #rules;\n #whitelists;\n #whitelistKeys;\n #onError;\n #reportedErrors = new Set();\n\n constructor({ firewall = [], whitelists = [], whitelist_keys = {}, onError } = {}) {\n this.#rules = firewall;\n this.#whitelists = whitelists;\n this.#whitelistKeys = whitelist_keys;\n this.#onError = onError;\n }\n\n // A mitigation engine must never take down the app it protects: any error while\n // evaluating a rule is reported and the request is allowed through (fail open). A\n // malformed rule is skipped without aborting the rest of the ruleset.\n #reportError(err) {\n if (this.#onError) {\n this.#onError(err);\n return;\n }\n // Default: log once per distinct message so a persistently-broken rule doesn't\n // spam per request (never silently swallow — hosts can pass `onError` for structured logging).\n const key = err && err.message ? err.message : String(err);\n if (this.#reportedErrors.has(key)) {\n return;\n }\n this.#reportedErrors.add(key);\n console.error('[patchstack] rule evaluation error (rule skipped, request allowed):', err);\n }\n\n evaluate(req) {\n let normalizedReq;\n let resolver;\n try {\n normalizedReq = { ...req, ...normalizeRequest(req) };\n resolver = new RequestResolver(normalizedReq);\n } catch (err) {\n this.#reportError(err);\n return { blocked: false, rule: null, message: null }; // fail open\n }\n\n for (const rule of this.#rules) {\n try {\n const conditions = rule.rule_v2;\n\n if (!Array.isArray(conditions) || conditions.length === 0) {\n continue;\n }\n\n if (this.#evaluateRule(conditions, resolver)) {\n if (this.#isWhitelisted(normalizedReq, rule)) {\n continue;\n }\n\n return {\n blocked: true,\n rule,\n message: rule.message ?? `Blocked by Patchstack WAF rule: ${rule.title ?? rule.id}`\n };\n }\n } catch (err) {\n // Skip this rule and keep evaluating the rest — one bad rule never blocks a\n // request nor shadows the rules after it.\n this.#reportError(err);\n }\n }\n\n return { blocked: false, rule: null, message: null };\n }\n\n #evaluateRule(conditions, resolver) {\n const inclusiveConditions = conditions.filter(c => c.inclusive);\n const nonInclusiveConditions = conditions.filter(c => !c.inclusive);\n\n if (inclusiveConditions.length > 0) {\n let inclusiveHits = 0;\n\n for (const condition of inclusiveConditions) {\n if (this.#evaluateCondition(condition, resolver)) {\n inclusiveHits++;\n }\n }\n\n if (inclusiveHits === inclusiveConditions.length) {\n return true;\n }\n }\n\n for (const condition of nonInclusiveConditions) {\n if (this.#evaluateCondition(condition, resolver)) {\n return true;\n }\n }\n\n return false;\n }\n\n #evaluateCondition(condition, resolver) {\n const { parameter, match, mutations } = condition;\n\n if (parameter === 'rules' && Array.isArray(condition.rules)) {\n return this.#evaluateRule(condition.rules, resolver);\n }\n\n // `parameter` may be an array (e.g. [\"get.action\",\"post.action\"]) — the rule_v2 format\n // uses these pervasively to mean \"any of these sources\". Resolve each and OR the\n // candidate values together. (A bare string resolves as a single source.)\n const params = Array.isArray(parameter) ? parameter : [parameter];\n const values = params.flatMap((p) => resolver.resolve(p));\n\n if (values.length === 0) {\n return false;\n }\n\n for (let value of values) {\n if (mutations) {\n value = resolver.applyMutations(mutations, value);\n }\n\n // array_key_value inspects the object as a whole (it navigates a key path),\n // so it must not go through the per-value object iteration below.\n if (match.type === 'array_key_value') {\n if (matchValue(match.type, value, match.value, match)) {\n return true;\n }\n continue;\n }\n\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n for (const v of Object.values(value)) {\n if (matchValue(match.type, v, match.value, match)) {\n return true;\n }\n }\n continue;\n }\n\n if (matchValue(match.type, value, match.value, match)) {\n return true;\n }\n }\n\n return false;\n }\n\n #isWhitelisted(req, rule) {\n if (!this.#whitelists || this.#whitelists.length === 0) {\n return false;\n }\n\n for (const whitelist of this.#whitelists) {\n if (!Array.isArray(whitelist.rule_v2)) {\n continue;\n }\n\n if (whitelist.rule_id && whitelist.rule_id !== rule.id) {\n continue;\n }\n\n const resolver = new RequestResolver(req);\n if (this.#evaluateRule(whitelist.rule_v2, resolver)) {\n return true;\n }\n }\n\n return false;\n }\n}\n\nexport const _testExports = { matchValue, safeRegExp, isInternalHost };\n","const DEFAULT_BASE_URL = 'https://api.patchstack.com/monitor/pulse';\nconst DEFAULT_CACHE_TTL = 300_000;\n// Randomly shorten the effective TTL by up to this fraction so many long-lived clients don't all\n// revalidate on the same tick (spreads load / avoids a thundering herd against the rules API).\nconst JITTER_FRACTION = 0.1;\n\n// Per-site rules client for Pulse (npm/JS) apps. Public endpoint — the site UUID is the only\n// credential, passed in the path. Fail-open: any error returns success:false + empty rules so\n// createProtection falls back to the disk cache or the bundled rules.\n//\n// Conditional fetch: pass a prior `etag` (persisted with the last cached bundle) and the client\n// sends `If-None-Match`; a 304 returns `{ notModified: true }` so the caller reuses its cache\n// without re-downloading, and a 200 returns the new bundle plus its `etag` to persist. This is a\n// no-op until the rules API emits an ETag and honors If-None-Match — with no ETag in the response\n// the client simply behaves as before (a full fetch every refresh).\nexport class PulseRuleClient {\n #siteUuid;\n #baseUrl;\n #cacheTtl;\n #cache = null;\n #cacheTime = null;\n #ttlEffective = 0;\n #etag;\n\n constructor({ siteUuid, baseUrl, cacheTtl, etag } = {}) {\n this.#siteUuid = siteUuid ?? process.env.PATCHSTACK_SITE_UUID;\n this.#baseUrl = baseUrl ?? process.env.PATCHSTACK_PULSE_RULES_URL ?? DEFAULT_BASE_URL;\n this.#cacheTtl = cacheTtl ?? DEFAULT_CACHE_TTL;\n this.#etag = etag ?? null;\n if (!this.#siteUuid) {\n throw new Error('Patchstack site UUID is required. Pass { siteUuid } or set PATCHSTACK_SITE_UUID.');\n }\n }\n\n async getRules() {\n const now = Date.now();\n if (this.#cache && this.#cacheTime !== null && now - this.#cacheTime < this.#ttlEffective) {\n return this.#cache;\n }\n const url = `${this.#baseUrl}/rules/${encodeURIComponent(this.#siteUuid)}`;\n try {\n const headers = { Accept: 'application/json' };\n if (this.#etag) headers['If-None-Match'] = this.#etag;\n const response = await fetch(url, { method: 'GET', headers, signal: AbortSignal.timeout(30_000) });\n\n if (response.status === 304) {\n this.#touch(now); // revalidated — reset the clock (fresh jitter)\n return this.#cache ?? { success: true, notModified: true, etag: this.#etag, firewall: [], whitelists: [], whitelist_keys: {} };\n }\n if (!response.ok) {\n return { success: false, error: `API returned ${response.status}`, firewall: [], whitelists: [], whitelist_keys: {} };\n }\n const data = await response.json();\n const result = {\n success: true,\n notModified: false,\n etag: response.headers?.get?.('etag') ?? null,\n firewall: Array.isArray(data.firewall) ? data.firewall : [],\n whitelists: Array.isArray(data.whitelists) ? data.whitelists : [],\n whitelist_keys: data.whitelist_keys ?? {},\n };\n this.#cache = result;\n this.#etag = result.etag;\n this.#touch(now);\n return result;\n } catch (err) {\n return {\n success: false,\n error: err.name === 'TimeoutError' ? 'Request timed out' : err.message,\n firewall: [], whitelists: [], whitelist_keys: {},\n };\n }\n }\n\n #touch(now) {\n this.#cacheTime = now;\n this.#ttlEffective = this.#cacheTtl - Math.floor(Math.random() * this.#cacheTtl * JITTER_FRACTION);\n }\n\n clearCache() {\n this.#cache = null;\n this.#cacheTime = null;\n this.#etag = null;\n }\n}\n","// Web Fetch adapter — runs the node-waf engine on any runtime where a request is a\n// WHATWG `Request` and a handler returns a `Response`: Cloudflare Workers, Bun, Deno,\n// Hono, Next.js edge, and TanStack Start's `server.ts`. This is the surface AI-builder\n// apps actually deploy to, and where require-based instrumentation can't reach.\n//\n// The engine already consumes a runtime-neutral request shape; this adapter builds that\n// shape from a `Request`, so no engine changes are needed beyond keeping the hot path\n// free of Node-only APIs.\nimport { RuleEngine } from './engine.js';\n\n// Cap how much request body we buffer for inspection. A larger body is left UNSCANNED\n// (fail-open) rather than buffered into memory — matches the node adapter's maxBodyBytes.\nconst MAX_BODY_BYTES = 1024 * 1024;\n\n// Build the engine's request shape from a WHATWG Request. The body is read from a\n// CLONE so the downstream handler still receives an intact request.\nexport async function fromFetchRequest(request, options = {}) {\n const maxBodyBytes = options.maxBodyBytes ?? MAX_BODY_BYTES;\n const url = new URL(request.url);\n const method = (request.method || 'GET').toUpperCase();\n\n const headers = {};\n request.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value;\n });\n\n const query = {};\n for (const [key, value] of url.searchParams) {\n if (key in query) {\n query[key] = Array.isArray(query[key]) ? [...query[key], value] : [query[key], value];\n } else {\n query[key] = value;\n }\n }\n\n let rawBody = '';\n if (method !== 'GET' && method !== 'HEAD') {\n rawBody = await readCappedText(request, maxBodyBytes);\n }\n\n const contentType = headers['content-type'] || '';\n let body = {};\n let files;\n if (rawBody) {\n if (contentType.includes('application/json')) {\n try {\n body = JSON.parse(rawBody);\n } catch {\n body = {};\n }\n } else if (contentType.includes('application/x-www-form-urlencoded')) {\n body = {};\n for (const [k, v] of new URLSearchParams(rawBody)) {\n body[k] = k in body ? [].concat(body[k], v) : v;\n }\n } else if (contentType.includes('multipart/form-data')) {\n const boundary = /boundary=(\"?)([^\";]+)\\1/i.exec(contentType)?.[2];\n if (boundary) {\n const parsed = parseMultipart(rawBody, boundary);\n body = parsed.body;\n files = parsed.files;\n }\n }\n }\n\n const uri = url.pathname + url.search;\n const forwarded =\n headers['cf-connecting-ip'] || headers['x-forwarded-for'] || headers['x-real-ip'] || '';\n\n return {\n method,\n url: uri,\n originalUrl: uri,\n query,\n body,\n files,\n headers,\n ip: forwarded.split(',')[0].trim(),\n cookies: parseCookies(headers.cookie),\n // Verbatim body text: preserves literal keys (e.g. `__proto__`) that JSON.stringify\n // drops, so prototype-pollution rules on `raw` are robust.\n _rawBody: rawBody\n };\n}\n\n// Read a request body as text for inspection. Memory is bounded by a hard ceiling (4× the scan\n// cap): a body whose declared Content-Length exceeds it is left UNSCANNED (fail-open). Within the\n// ceiling, an oversize body is TRUNCATED to `max` and its prefix is still scanned — so a\n// front-loaded payload is caught — rather than being discarded outright. Reads a clone so the\n// downstream handler keeps an intact body. (`max` is compared in bytes against Content-Length; the\n// prefix slice is by character, which can only over-scan a multibyte body — the safe direction.)\nasync function readCappedText(request, max) {\n const ceiling = Math.max(max, max * 4);\n const declared = Number(request.headers?.get?.('content-length') || 0);\n if (declared && declared > ceiling) return '';\n let clone;\n try {\n clone = request.clone();\n } catch {\n return '';\n }\n try {\n const text = await clone.text();\n return text.length > max ? text.slice(0, max) : text;\n } catch {\n return '';\n }\n}\n\n// Minimal multipart/form-data parser: enough to expose field names + values (so `post.<field>`\n// and `raw` rules match uploads, e.g. a `__proto__` field name) and file metadata (filename via\n// `files.<field>`). We only need the textual structure, not the binary file contents.\nfunction parseMultipart(rawBody, boundary) {\n const body = {};\n const files = {};\n for (const part of rawBody.split('--' + boundary)) {\n // Tolerate both CRLF and LF-only line endings (some clients/proxies send bare \\n).\n const sep = /\\r?\\n\\r?\\n/.exec(part);\n if (!sep) continue;\n const rawHeaders = part.slice(0, sep.index);\n const disposition = /content-disposition:[^\\r\\n]*/i.exec(rawHeaders)?.[0];\n if (!disposition) continue;\n const name = /name=\"([^\"]*)\"/i.exec(disposition)?.[1];\n if (name == null) continue;\n const content = part.slice(sep.index + sep[0].length).replace(/\\r?\\n$/, '');\n const filename = /filename=\"([^\"]*)\"/i.exec(disposition)?.[1];\n if (filename !== undefined) {\n files[name] = name in files ? [].concat(files[name], filename) : filename;\n } else {\n body[name] = name in body ? [].concat(body[name], content) : content;\n }\n }\n return { body, files };\n}\n\nfunction parseCookies(header) {\n const cookies = {};\n if (!header) {\n return cookies;\n }\n for (const pair of header.split(';')) {\n const idx = pair.indexOf('=');\n if (idx === -1) {\n continue;\n }\n cookies[pair.slice(0, idx).trim()] = pair.slice(idx + 1).trim();\n }\n return cookies;\n}\n\nfunction defaultBlockResponse(result) {\n return new Response(\n JSON.stringify({\n error: 'Blocked by Patchstack WAF',\n message: result.message,\n timestamp: new Date().toISOString()\n }),\n { status: 403, headers: { 'content-type': 'application/json' } }\n );\n}\n\n/**\n * Returns a guard `(request) => Promise<Response|null>`. A `Response` means blocked;\n * `null` means allowed — the caller should proceed to its handler. Accepts either a\n * rules bundle (`{ firewall, whitelists, whitelist_keys }`) or a `RuleEngine` instance.\n * Fails open: a rule that throws never blocks the request.\n */\nexport function createFetchMiddleware(rulesData, options = {}) {\n const engine =\n rulesData && typeof rulesData.evaluate === 'function'\n ? rulesData\n : new RuleEngine(rulesData);\n\n const guard = async (request) => {\n const req = await fromFetchRequest(request);\n\n let result;\n try {\n result = engine.evaluate(req);\n } catch (err) {\n if (options.onError) {\n options.onError(err);\n }\n return null; // fail open\n }\n\n if (result.blocked) {\n if (options.onBlock) {\n options.onBlock({\n rule: result.rule,\n message: result.message,\n request: { method: req.method, url: req.url, ip: req.ip }\n });\n }\n return (options.response || defaultBlockResponse)(result);\n }\n\n return null;\n };\n\n guard.engine = engine;\n return guard;\n}\n\n/**\n * Wrap a fetch handler so every request is screened first. One-line hook:\n * export default { fetch: wrapFetchHandler(app.fetch, rulesData) }\n */\nexport function wrapFetchHandler(handler, rulesData, options = {}) {\n const guard = createFetchMiddleware(rulesData, options);\n const wrapped = async (request, ...rest) => {\n const blocked = await guard(request);\n return blocked ?? handler(request, ...rest);\n };\n wrapped.engine = guard.engine;\n return wrapped;\n}\n","// Raw Node.js / Connect adapter — for traditional Node servers where the request is a\n// `http.IncomingMessage` and the body is NOT already parsed (plain `http`, Connect,\n// Express without a body-parser, Fastify via its Node req). It buffers the body once,\n// builds the engine's request shape, and blocks or calls `next()`.\n//\n// This complements the Express `createMiddleware` (which assumes `req.body`/`req.query`\n// are already populated) and the Web-Fetch adapter (Workers/edge). Mount it FIRST, before\n// any body-parser — it consumes the stream and exposes the parsed body as `req.body`.\nimport { RuleEngine } from './engine.js';\n\n// Build the engine's request shape from a Node IncomingMessage + its raw body text.\nexport function fromNodeRequest(req, rawBody = '') {\n const method = (req.method || 'GET').toUpperCase();\n\n const headers = {};\n for (const [key, value] of Object.entries(req.headers || {})) {\n headers[key.toLowerCase()] = Array.isArray(value) ? value.join(', ') : value;\n }\n\n const host = headers.host || 'localhost';\n const url = new URL(req.url || '/', `http://${host}`);\n\n const query = {};\n for (const [key, value] of url.searchParams) {\n if (key in query) {\n query[key] = Array.isArray(query[key]) ? [...query[key], value] : [query[key], value];\n } else {\n query[key] = value;\n }\n }\n\n const contentType = headers['content-type'] || '';\n let body = {};\n if (rawBody) {\n if (contentType.includes('application/json')) {\n try {\n body = JSON.parse(rawBody);\n } catch {\n body = {};\n }\n } else if (contentType.includes('application/x-www-form-urlencoded')) {\n body = {};\n for (const [k, v] of new URLSearchParams(rawBody)) {\n body[k] = k in body ? [].concat(body[k], v) : v;\n }\n }\n }\n\n const uri = url.pathname + url.search;\n const forwarded =\n headers['cf-connecting-ip'] || headers['x-forwarded-for'] || headers['x-real-ip'] || '';\n\n return {\n method,\n url: uri,\n originalUrl: uri,\n query,\n body,\n headers,\n ip: forwarded.split(',')[0].trim() || (req.socket && req.socket.remoteAddress) || '',\n cookies: parseCookies(headers.cookie),\n // Verbatim body text: preserves literal keys (e.g. `__proto__`) that JSON.stringify drops.\n _rawBody: rawBody\n };\n}\n\nfunction parseCookies(header) {\n const cookies = {};\n if (!header) {\n return cookies;\n }\n for (const pair of header.split(';')) {\n const idx = pair.indexOf('=');\n if (idx === -1) {\n continue;\n }\n cookies[pair.slice(0, idx).trim()] = pair.slice(idx + 1).trim();\n }\n return cookies;\n}\n\nfunction defaultBlock(res, result) {\n res.statusCode = 403;\n res.setHeader('content-type', 'application/json');\n res.end(\n JSON.stringify({\n error: 'Blocked by Patchstack WAF',\n message: result.message,\n timestamp: new Date().toISOString()\n })\n );\n}\n\n/**\n * Connect/Express-style middleware `(req, res, next)` that buffers the body itself.\n * Accepts a `RuleEngine` instance or a `{ firewall, whitelists, whitelist_keys }` bundle.\n * Fails open: an engine error (or oversized body) never blocks the request.\n * Options: `{ maxBodyBytes = 1MiB, onBlock, onError, response }`.\n */\nexport function createNodeMiddleware(rulesData, options = {}) {\n const engine =\n rulesData && typeof rulesData.evaluate === 'function' ? rulesData : new RuleEngine(rulesData);\n const maxBytes = options.maxBodyBytes ?? 1024 * 1024;\n\n return function guard(req, res, next) {\n const chunks = [];\n let size = 0;\n let overflow = false;\n\n req.on('data', (chunk) => {\n size += chunk.length;\n if (size > maxBytes) {\n overflow = true;\n return;\n }\n chunks.push(chunk);\n });\n\n req.on('error', (err) => next(err));\n\n req.on('end', () => {\n const rawBody = overflow ? '' : Buffer.concat(chunks).toString('utf8');\n const shaped = fromNodeRequest(req, rawBody);\n\n let result;\n try {\n result = engine.evaluate(shaped);\n } catch (err) {\n if (options.onError) {\n options.onError(err);\n }\n return next(); // fail open\n }\n\n if (result.blocked) {\n if (options.onBlock) {\n options.onBlock({\n rule: result.rule,\n message: result.message,\n request: { method: shaped.method, url: shaped.url, ip: shaped.ip }\n });\n }\n return (options.response || defaultBlock)(res, result);\n }\n\n // Expose the parsed body downstream so a body-parser isn't also required.\n req.body = shaped.body;\n next();\n });\n };\n}\n","// Egress guard MECHANISM only. Wraps the app's outbound calls so they can be screened; the\n// block DECISION is delegated to a caller-supplied `shouldBlock` predicate (which the runtime\n// builds from egress-phase rules — see defaults.js). No policy is hardcoded here.\n// WinterCG-first: always wraps the global `fetch` (Node 18+, Workers, Bun, Deno). On Node it\n// ALSO patches `node:http`/`node:https` so outbound calls made via those modules (axios, got,\n// the raw http client, …) — which never touch `fetch` — are screened too.\n\n/**\n * @param {{ shouldBlock: (url:string, host:string|null, method:string)=>boolean,\n * onBlock?: (info:{url:string,host:string|null,method:string})=>void }} opts\n * @returns {Promise<() => void>} uninstall (restores every patched surface)\n */\nexport async function installEgressGuard({ shouldBlock, onBlock } = {}) {\n const restores = [];\n if (typeof shouldBlock !== 'function') return () => {};\n\n const block = (url, host, method) => {\n if (!shouldBlock(url, host, method)) return false;\n onBlock?.({ url, host, method });\n return true;\n };\n\n // 1. global fetch — synchronous, so it's active the instant this returns (no startup race).\n const originalFetch = globalThis.fetch;\n if (typeof originalFetch === 'function' && !originalFetch.__patchstackGuarded) {\n const guarded = async (input, init) => {\n const url = typeof input === 'string' ? input : (input && input.url) || String(input);\n let host = null;\n try {\n host = new URL(url).hostname;\n } catch {\n host = null;\n }\n const method = (init && init.method) || (input && input.method) || 'GET';\n if (block(url, host, method)) {\n throw new Error(`Patchstack blocked an outbound request to a disallowed address: ${host ?? url}`);\n }\n return originalFetch(input, init);\n };\n guarded.__patchstackGuarded = true;\n globalThis.fetch = guarded;\n restores.push(() => {\n if (globalThis.fetch === guarded) globalThis.fetch = originalFetch;\n });\n }\n\n // 2. node:http / node:https — best-effort; absent on Workers/Deno-without-node (import throws).\n for (const moduleName of ['node:http', 'node:https']) {\n try {\n const mod = await import(moduleName);\n const restore = patchHttpModule(mod.default ?? mod, block);\n if (restore) restores.push(restore);\n } catch {\n /* module not available on this runtime — skip */\n }\n }\n\n // 3. global WebSocket — ws:// / wss:// egress that never touches fetch or node:http.\n const OriginalWS = globalThis.WebSocket;\n if (typeof OriginalWS === 'function' && !OriginalWS.__patchstackGuarded) {\n const GuardedWS = new Proxy(OriginalWS, {\n construct(target, args, newTarget) {\n const url = String(args?.[0] ?? '');\n let host = null;\n try {\n host = new URL(url).hostname;\n } catch {\n host = null;\n }\n if (block(url, host, 'WEBSOCKET')) {\n throw new Error(`Patchstack blocked an outbound WebSocket to a disallowed address: ${host ?? url}`);\n }\n return Reflect.construct(target, args, newTarget);\n },\n });\n OriginalWS.__patchstackGuarded = true; // marker on the original guards against double-wrap\n globalThis.WebSocket = GuardedWS;\n restores.push(() => {\n if (globalThis.WebSocket === GuardedWS) globalThis.WebSocket = OriginalWS;\n delete OriginalWS.__patchstackGuarded;\n });\n }\n\n return () => {\n for (const restore of restores) {\n try {\n restore();\n } catch {\n /* ignore */\n }\n }\n };\n}\n\n// Wrap http(s).request/get so a blocked destination throws before the socket opens.\nfunction patchHttpModule(http, block) {\n if (!http || typeof http.request !== 'function' || http.__patchstackGuarded) return null;\n const originalRequest = http.request;\n const originalGet = http.get;\n\n const wrap = (original) =>\n function (...args) {\n const target = extractHttpTarget(args);\n if (target && block(target.url, target.host, target.method)) {\n throw new Error(`Patchstack blocked an outbound request to a disallowed address: ${target.host ?? target.url}`);\n }\n return original.apply(this, args);\n };\n\n http.request = wrap(originalRequest);\n if (typeof originalGet === 'function') http.get = wrap(originalGet);\n http.__patchstackGuarded = true;\n\n return () => {\n http.request = originalRequest;\n if (typeof originalGet === 'function') http.get = originalGet;\n delete http.__patchstackGuarded;\n };\n}\n\n// http.request accepts (url), (url, options), or (options) — with an optional trailing callback.\nfunction extractHttpTarget(args) {\n const first = args[0];\n try {\n if (typeof first === 'string' || first instanceof URL) {\n const url = new URL(String(first));\n const opts = args.find((a) => a && typeof a === 'object' && !(a instanceof URL));\n return { url: url.href, host: url.hostname, method: (opts && opts.method) || 'GET' };\n }\n if (first && typeof first === 'object') {\n const host = normalizeHost(first.hostname || first.host);\n const protocol = first.protocol || 'http:';\n const port = first.port ? `:${first.port}` : '';\n const path = first.path || '/';\n return { url: `${protocol}//${host}${port}${path}`, host, method: first.method || 'GET' };\n }\n } catch {\n /* fall through */\n }\n return null;\n}\n\n// Extract the bare host from a node http(s) options `host`/`hostname`, WITHOUT mangling IPv6.\n// `[::1]:8080` → `::1`, bare `::1`/`fe80::1` → unchanged, `example.com:443` → `example.com`.\n// (isInternalHost strips brackets and matches ::1 / fe80: / fc / fd, so this must not corrupt them.)\nfunction normalizeHost(raw) {\n const host = String(raw || '').trim();\n const bracketed = /^\\[([^\\]]+)\\]/.exec(host);\n if (bracketed) return bracketed[1];\n if ((host.match(/:/g) || []).length > 1) return host; // bare IPv6 — no host:port to split\n return host.split(':')[0];\n}\n","// Default response- and egress-phase rule bundles, as JS constants (not JSON files) so\n// tsup bundles them into dist/protect.js without a copy step. These are just rules —\n// override per app via createProtection({ responseRules, egressRules }) or extend by\n// adding phase-tagged rules to the delivered bundle. Patterns are high-precision\n// (low false positive): structural markers a real secret has and normal content doesn't.\n\n// Response phase — secret / info exposure. Default action `redact` masks only the\n// offending span and still serves the page (a legit response that leaks one key gets\n// that key masked, not withheld). Use `action: \"block\"` to withhold the whole response.\nexport const DEFAULT_RESPONSE_RULES = [\n {\n id: 'resp-private-key',\n title: 'Private key in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/' } }]\n },\n {\n id: 'resp-aws-access-key',\n title: 'AWS access key id in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\b(?:AKIA|ASIA)[0-9A-Z]{16}\\\\b/' } }]\n },\n {\n id: 'resp-gcp-api-key',\n title: 'Google API key in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\bAIza[0-9A-Za-z_-]{35}\\\\b/' } }]\n },\n {\n id: 'resp-jwt',\n title: 'JWT in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\beyJ[A-Za-z0-9_-]{8,}\\\\.eyJ[A-Za-z0-9_-]{8,}\\\\.[A-Za-z0-9_-]{8,}\\\\b/' } }]\n },\n {\n id: 'resp-db-connection-string',\n title: 'Database connection string with credentials in response body',\n phase: 'response',\n category: 'secret-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\b(?:mongodb(?:\\\\+srv)?|postgres(?:ql)?|mysql|redis|amqps?):\\\\/\\\\/[^\\\\s:@\\\\/]+:[^\\\\s:@\\\\/]+@/i' } }]\n },\n {\n id: 'resp-stack-trace',\n title: 'Node stack trace leaking in response body',\n phase: 'response',\n category: 'info-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/\\\\n\\\\s+at\\\\s+.+\\\\(.+:\\\\d+:\\\\d+\\\\)/' } }]\n },\n {\n id: 'resp-sql-error',\n title: 'SQL / ORM error disclosure in response body',\n phase: 'response',\n category: 'info-exposure',\n action: 'redact',\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/(SQLSTATE\\\\[[0-9A-Z]+\\\\]|SequelizeDatabaseError|ER_[A-Z_]+|ORA-\\\\d{5}|PG::[A-Za-z]+Error|SQLITE_ERROR|You have an error in your SQL syntax)/i' } }]\n },\n {\n id: 'resp-exception-trace',\n title: 'Backend exception / stack trace disclosure in response body',\n phase: 'response',\n category: 'info-exposure',\n action: 'redact',\n // Multi-language exception/traceback signatures a normal API response never carries:\n // Python traceback, Java \"Exception in thread\", .NET System.*Exception, JVM stack frames,\n // Go goroutine dumps. (Node `at fn (file:line:col)` frames are handled by resp-stack-trace.)\n rule_v2: [{ parameter: 'response.body', match: { type: 'regex', value: '/(Traceback \\\\(most recent call last\\\\)|Exception in thread \"|System\\\\.[A-Za-z.]+Exception|\\\\bat [\\\\w.$]+\\\\([\\\\w]+\\\\.(?:java|kt|scala|rb|py|cs):\\\\d+\\\\)|goroutine \\\\d+ \\\\[)/' } }]\n }\n];\n\n// Egress phase — SSRF: block the app's outbound calls to internal / metadata addresses.\nexport const DEFAULT_EGRESS_RULES = [\n {\n id: 'egress-internal-address',\n title: 'Outbound request to an internal / metadata address (SSRF)',\n phase: 'egress',\n category: 'ssrf',\n rule_v2: [{ parameter: 'egress.host', match: { type: 'internal_host' } }]\n }\n];\n","// Full-page \"Access Denied\" block view, ported from the Patchstack WordPress plugin's\n// sample.php. Served (instead of JSON) when a BLOCKED request is a top-level document navigation\n// rather than an XHR/fetch — so a user who browses into a blocked URL sees a branded page, while\n// programmatic clients still get JSON. Self-contained (inline CSS + base64 SVGs); exposes no WAF\n// narrative and no rule details.\n\nfunction escapeHtml(s) {\n return String(s).replace(/[&<>\"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]));\n}\n\n/** @param {{ url?: string, code?: string }} opts @returns {string} a complete HTML document */\nexport function renderBlockPage({ url = '', code = 'patchstack' } = {}) {\n const safeUrl = escapeHtml(url);\n const safeCode = escapeHtml(code || 'patchstack');\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <style type=\"text/css\">\n\t\t.access-denied,.site-url-text{letter-spacing:.01em;color:#fff}body{background:#111216}.main-container{display:flex;justify-content:center;flex-direction:column;align-items:center}.container{width:688px;height:456px;background:#1c1e22;border-radius:16px;margin-top:120px}.content{height:330px;margin:64px}.access-denied{font-family:Verdana;font-style:normal;font-weight:600;font-size:24px;line-height:32px;display:flex;align-items:center}.descp-text,.site-url{display:flex;align-items:center}.site-url{margin-top:32px;width:560px;height:64px;background:#26282c;border-radius:4px}.reason-code-text,.site-url-text{font-family:Verdana;font-style:normal;border:none;background:#26282c}.site-url-text{text-overflow: ellipsis;font-weight:400;font-size:16px;line-height:24px;margin-left:16px;width:85%}.copy-icon{width:19px;height:22px;margin-left:20px}.copy-icon:hover{cursor:pointer}.reason-code-text{font-weight:600;font-size:24px;line-height:32px;letter-spacing:.01em;color:#AFE614;margin-left:16px;width:85%}.descp-text,.return-text{font-size:16px;line-height:24px;letter-spacing:.01em;font-weight:400}.return-text:hover{color: #AFE614}.descp-text,.logoText,.return-text,.secured-text{font-family:Verdana;font-style:normal;color:#fff}.descp{margin-top:32px;width:560px}.bottom-second-containers,.bottom-text-containers{align-items:center;display:flex}.bottom-container{margin-top:40px;display:flex;width:688px}.bottom-second-containers{margin-left:auto}.arrow-vector{margin-left:20px}.return-text{text-align:center;margin-left:12.59px;text-decoration:none}.secured-text{font-weight:400;font-size:11.2px;line-height:16px;display:flex;align-items:center;letter-spacing:.02em;margin-right:8px}.logoText{font-weight:600;font-size:16px;line-height:24px;letter-spacing:.01em;flex:none;order:1;flex-grow:0}.patch-logo{width:120px}.mobile-bottom-container{margin-top:40px;width:372px;display:none}.mobile-bottom-second-containers{margin-top:64px;display:flex;margin-left:16.5px}@media only screen and (max-width:900px){.container{background:#111216;width:370px;height:auto;margin-top:0}.content{margin-left:16.5px}.descp,.site-url{width:340px}.site-url-text{font-weight:400;font-size:14.4px;line-height:20px;letter-spacing:.02em;width:80%}.copy-icon{margin-left:20px}.reason-code-text{font-size:16px;line-height:32px;letter-spacing:.02em;margin-left:16px;width:80%}.descp-text,.return-text{font-size:14.4px;line-height:20px}.descp-text{display:flex;align-items:center;letter-spacing:.02em}.bottom-container{display:none}.mobile-bottom-container{display:block}.return-text{text-align:center;letter-spacing:.01em;color:#fff;margin-left:9.73px}}\n </style>\n <title>Access Denied</title>\n</head>\n<body>\n <div class=\"main-container\">\n <div class=\"container\">\n <div class=\"content\">\n <span class=\"access-denied\">Access Denied</span>\n <div class=\"site-url\">\n <input id=\"url\" class=\"site-url-text\" type=\"text\"\n value=\"${safeUrl}\" readonly>\n <img class=\"copy-icon\" src=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkiIGhlaWdodD0iMjMiIHZpZXdCb3g9IjAgMCAxOSAyMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE0IDAuMDIzNDM3NUgwVjE2LjAyMzRIMlYyLjAyMzQ0SDE0VjAuMDIzNDM3NVpNMTkgNC4wMjM0NEg0VjIyLjAyMzRIMTlWNC4wMjM0NFpNMTcgMjAuMDIzNEg2VjYuMDIzNDRIMTdWMjAuMDIzNFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=\" alt=\"Copy Text\" onmouseover=\"hover(this);\" onmouseout=\"unhover(this);\" onclick=\"copyText(id='url')\">\n </div>\n <div class=\"site-url\">\n <input id=\"response\" class=\"reason-code-text\" type=\"text\" value=\"${safeCode}\" readonly>\n <img class=\"copy-icon\" src=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkiIGhlaWdodD0iMjMiIHZpZXdCb3g9IjAgMCAxOSAyMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE0IDAuMDIzNDM3NUgwVjE2LjAyMzRIMlYyLjAyMzQ0SDE0VjAuMDIzNDM3NVpNMTkgNC4wMjM0NEg0VjIyLjAyMzRIMTlWNC4wMjM0NFpNMTcgMjAuMDIzNEg2VjYuMDIzNDRIMTdWMjAuMDIzNFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=\" alt=\"Copy Text\" onmouseover=\"hover(this);\" onmouseout=\"unhover(this);\" onclick=\"copyText(id='response')\">\n </div>\n <div class=\"descp\">\n <span class=\"descp-text\">This request has been blocked by Patchstack. If this message persists and you are a legitimate user, contact the site administrator with the reference above.</span>\n </div>\n </div>\n </div>\n <div class=\"bottom-container\">\n <div class=\"bottom-text-containers\">\n <img class=\"arrow-vector\" src=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOCIgaGVpZ2h0PSIxMyIgdmlld0JveD0iMCAwIDggMTMiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik03LjQxIDEuNDMzNDRMNiAwLjAyMzQzNzVMMCA2LjAyMzQ0TDYgMTIuMDIzNEw3LjQxIDEwLjYxMzRMMi44MyA2LjAyMzQ0TDcuNDEgMS40MzM0NFoiIGZpbGw9IiNBRkU2MTQiLz4KPC9zdmc+Cg==\" alt=\"Arrow Left\">\n <a href=\"/\" class=\"return-text\">Return to homepage</a>\n </div>\n <div class=\"bottom-second-containers\">\n <span class=\"secured-text\">This website is secured by</span>\n <a href=\"https://patchstack.com\" class=\"logoText\">\n <img class=\"patch-logo\" src=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTg0IiBoZWlnaHQ9IjIyIiB2aWV3Qm94PSIwIDAgMTg0IDIyIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTUwLjQwMDEgMTEuNTAwOEM1MC40MDAxIDkuMTAwNzggNDkuMzAwMSA4LjEwMDc4IDQ2LjYwMDEgOC4xMDA3OEM0NC4wMDAxIDguMTAwNzggNDIuNzAwMSA5LjIwMDc4IDQyLjcwMDEgMTEuNTAwOEM0Mi43MDAxIDEzLjgwMDggNDQuMDAwMSAxNC45MDA4IDQ2LjYwMDEgMTQuOTAwOEM0OS4zMDAxIDE0LjkwMDggNTAuNDAwMSAxMy44MDA4IDUwLjQwMDEgMTEuNTAwOFpNNTMuNDAwMSAxMS41MDA4QzUzLjQwMDEgMTUuMzAwOCA1MS4zMDAxIDE3LjYwMDggNDcuNDAwMSAxNy42MDA4QzQ1LjQwMDEgMTcuNjAwOCA0My42MDAxIDE2LjUwMDggNDIuNzAwMSAxNC41MDA4VjIxLjUwMDhIMzkuNjAwMVY1LjYwMDc4SDQyLjcwMDFWOC41MDA3OEM0My42MDAxIDYuNTAwNzggNDUuNDAwMSA1LjMwMDc4IDQ3LjUwMDEgNS4zMDA3OEM1MS40MDAxIDUuMzAwNzggNTMuNDAwMSA3LjcwMDc4IDUzLjQwMDEgMTEuNTAwOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNjYuNDAwMSAxMS40OTg0QzY2LjQwMDEgOS4xOTg0NCA2NS4xMDAxIDguMDk4NDQgNjIuNTAwMSA4LjA5ODQ0QzU5LjgwMDEgOC4wOTg0NCA1OC43MDAxIDkuMDk4NDQgNTguNzAwMSAxMS40OTg0QzU4LjcwMDEgMTMuNzk4NCA1OS44MDAxIDE0Ljg5ODQgNjIuNTAwMSAxNC44OTg0QzY1LjEwMDEgMTQuODk4NCA2Ni40MDAxIDEzLjc5ODQgNjYuNDAwMSAxMS40OTg0Wk02Ni4zMDAxIDUuNTk4NDRINjkuNDAwMVYxNy4zOTg0SDY2LjMwMDFWMTQuNDk4NEM2NS40MDAxIDE2LjQ5ODQgNjMuNzAwMSAxNy42OTg0IDYxLjYwMDEgMTcuNjk4NEM1Ny43MDAxIDE3LjY5ODQgNTUuNjAwMSAxNS4yOTg0IDU1LjYwMDEgMTEuNTk4NEM1NS42MDAxIDcuNzk4NDQgNTcuNjAwMSA1LjM5ODQ0IDYxLjQwMDEgNS4zOTg0NEM2My41MDAxIDUuMzk4NDQgNjUuNDAwMSA2LjU5ODQ0IDY2LjIwMDEgOC41OTg0NFY1LjU5ODQ0SDY2LjMwMDFaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTgxLjM5OTkgOC4zSDc3LjM5OTlWMTQuN0g4MS4wOTk5VjE3LjRINzcuOTk5OUM3NS43OTk5IDE3LjQgNzQuMjk5OSAxNS45IDc0LjI5OTkgMTMuN1Y4LjNINzEuMzk5OVY1LjZINzQuMjk5OVYySDc3LjM5OTlWNS41SDgxLjM5OTlWOC4zWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik05My42OTk5IDEyLjIwMDhMOTYuNjk5OSAxMi45MDA4Qzk1Ljk5OTkgMTYuMDAwOCA5My42OTk5IDE3LjYwMDggODkuOTk5OSAxNy42MDA4Qzg3Ljc5OTkgMTcuNjAwOCA4Ni4wOTk5IDE3LjAwMDggODQuNzk5OSAxNS45MDA4QzgzLjQ5OTkgMTQuODAwOCA4Mi44OTk5IDEzLjMwMDggODIuODk5OSAxMS41MDA4QzgyLjg5OTkgOS42MDA3OCA4My40OTk5IDguMTAwNzggODQuNzk5OSA3LjAwMDc4Qzg2LjA5OTkgNS45MDA3OCA4Ny43OTk5IDUuMzAwNzggODkuOTk5OSA1LjMwMDc4QzkzLjY5OTkgNS4zMDA3OCA5NS45OTk5IDYuOTAwNzggOTYuNjk5OSAxMC4wMDA4TDkzLjY5OTkgMTAuNzAwOEM5My4yOTk5IDguODAwNzggOTIuMjk5OSA4LjEwMDc4IDg5Ljg5OTkgOC4xMDA3OEM4Ni45OTk5IDguMTAwNzggODUuODk5OSA5LjIwMDc4IDg1Ljg5OTkgMTEuNTAwOEM4NS44OTk5IDEzLjgwMDggODYuOTk5OSAxNC45MDA4IDg5Ljg5OTkgMTQuOTAwOEM5Mi4yOTk5IDE0LjkwMDggOTMuMjk5OSAxNC4yMDA4IDkzLjY5OTkgMTIuMjAwOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTExLjggMTAuNlYxNy40SDEwOC43VjExLjJDMTA4LjcgOSAxMDcuOCA4LjEgMTA1LjkgOC4xQzEwMy42IDguMSAxMDIuNCA5LjMgMTAyLjQgMTEuN1YxNy4zSDk5LjI5OThWMC41SDEwMi40VjguM0MxMDMuMSA2LjMgMTA0LjYgNS4zIDEwNyA1LjNDMTEwLjIgNS4zIDExMS44IDcuMSAxMTEuOCAxMC42WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMTQuMSAxNC4wOTg0TDExNy4xIDEzLjI5ODRDMTE3LjQgMTQuNzk4NCAxMTguMyAxNS4yOTg0IDEyMC4yIDE1LjI5ODRDMTIxLjggMTUuMjk4NCAxMjIuNyAxNC44OTg0IDEyMi43IDE0LjA5ODRDMTIyLjcgMTMuMjk4NCAxMjIuMiAxMi45OTg0IDEyMC42IDEyLjc5ODRMMTE4LjIgMTIuNDk4NEMxMTUuOSAxMi4xOTg0IDExNC41IDEwLjg5ODQgMTE0LjUgOC45OTg0NEMxMTQuNSA2Ljc5ODQ0IDExNi41IDUuMzk4NDQgMTE5LjggNS4zOTg0NEMxMjMuMSA1LjM5ODQ0IDEyNSA2LjY5ODQ0IDEyNS41IDguODk4NDRMMTIyLjUgOS41OTg0NEMxMjIuMyA4LjA5ODQ0IDEyMS41IDcuNjk4NDQgMTE5LjkgNy42OTg0NEMxMTguNCA3LjY5ODQ0IDExNy42IDguMDk4NDQgMTE3LjYgOC44OTg0NEMxMTcuNiA5LjU5ODQ0IDExOC4xIDkuOTk4NDQgMTE5LjMgMTAuMDk4NEwxMjIuMiAxMC40OTg0QzEyNC40IDEwLjc5ODQgMTI1LjggMTEuOTk4NCAxMjUuOCAxMy44OTg0QzEyNS44IDE2LjI5ODQgMTIzLjcgMTcuNzk4NCAxMjAuMSAxNy43OTg0QzExNi43IDE3LjU5ODQgMTE0LjUgMTYuMTk4NCAxMTQuMSAxNC4wOTg0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMzYuNyA4LjNIMTMyLjdWMTQuN0gxMzYuNFYxNy40SDEzMy4zQzEzMS4xIDE3LjQgMTI5LjYgMTUuOSAxMjkuNiAxMy43VjguM0gxMjYuN1Y1LjZIMTI5LjZWMkgxMzIuN1Y1LjVIMTM2LjdWOC4zWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNDkuMiAxMS40OTg0QzE0OS4yIDkuMTk4NDQgMTQ3LjkgOC4wOTg0NCAxNDUuMyA4LjA5ODQ0QzE0Mi42IDguMDk4NDQgMTQxLjUgOS4wOTg0NCAxNDEuNSAxMS40OTg0QzE0MS41IDEzLjc5ODQgMTQyLjYgMTQuODk4NCAxNDUuMyAxNC44OTg0QzE0Ny45IDE0Ljg5ODQgMTQ5LjIgMTMuNzk4NCAxNDkuMiAxMS40OTg0Wk0xNDkuMSA1LjU5ODQ0SDE1Mi4yVjE3LjM5ODRIMTQ5LjFWMTQuNDk4NEMxNDguMiAxNi40OTg0IDE0Ni41IDE3LjY5ODQgMTQ0LjQgMTcuNjk4NEMxNDAuNSAxNy42OTg0IDEzOC40IDE1LjI5ODQgMTM4LjQgMTEuNTk4NEMxMzguNCA3Ljc5ODQ0IDE0MC40IDUuMzk4NDQgMTQ0LjIgNS4zOTg0NEMxNDYuMyA1LjM5ODQ0IDE0OC4yIDYuNTk4NDQgMTQ5IDguNTk4NDRWNS41OTg0NEgxNDkuMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTY1LjYgMTIuMjAwOEwxNjguNiAxMi45MDA4QzE2Ny45IDE2LjAwMDggMTY1LjYgMTcuNjAwOCAxNjEuOSAxNy42MDA4QzE1OS43IDE3LjYwMDggMTU4IDE3LjAwMDggMTU2LjcgMTUuOTAwOEMxNTUuNCAxNC44MDA4IDE1NC44IDEzLjMwMDggMTU0LjggMTEuNTAwOEMxNTQuOCA5LjYwMDc4IDE1NS40IDguMTAwNzggMTU2LjcgNy4wMDA3OEMxNTggNS45MDA3OCAxNTkuNyA1LjMwMDc4IDE2MS45IDUuMzAwNzhDMTY1LjYgNS4zMDA3OCAxNjcuOSA2LjkwMDc4IDE2OC42IDEwLjAwMDhMMTY1LjYgMTAuNzAwOEMxNjUuMiA4LjgwMDc4IDE2NC4yIDguMTAwNzggMTYxLjggOC4xMDA3OEMxNTguOSA4LjEwMDc4IDE1Ny44IDkuMjAwNzggMTU3LjggMTEuNTAwOEMxNTcuOCAxMy44MDA4IDE1OC45IDE0LjkwMDggMTYxLjggMTQuOTAwOEMxNjQuMSAxNC45MDA4IDE2NS4xIDE0LjIwMDggMTY1LjYgMTIuMjAwOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTgwLjI1NyAxNy40TDE3Ni42NTcgMTIuM0wxNzQuMTU3IDE0LjZWMTcuNEgxNzEuMTU3VjAuNUgxNzQuMTU3VjExLjFMMTc5Ljg1NyA1LjZIMTgzLjc1N0wxNzguNTU3IDEwLjVMMTgzLjk1NyAxNy40SDE4MC4yNTdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTAgMjEuNTAwOEg3LjNWMTYuMzAwOEgwVjIxLjUwMDhaIiBmaWxsPSIjQUZFNjE0Ii8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNy4yOTk4IDIxLjUwMDhIMTQuNTk5OFYxNi4zMDA4SDcuMjk5OFYyMS41MDA4WiIgZmlsbD0iIzZFQkUwMCIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE0LjYwMDEgMTYuM0gyOS4yMDAxVjAuNUgxNC42MDAxVjE2LjNaIiBmaWxsPSIjQUZFNjE0Ii8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxMUgxNC42VjAuNUgwVjExWiIgZmlsbD0iIzZFQkUwMCIvPgo8L3N2Zz4K\" alt=\"Patchstack Logo\">\n\t\t\t\t</a>\n </div>\n </div>\n \n <div class=\"mobile-bottom-container\">\n <div class=\"mobile-bottom-text-containers\">\n <img class=\"arrow-vector\" src=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iOCIgaGVpZ2h0PSIxMyIgdmlld0JveD0iMCAwIDggMTMiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik03LjQxIDEuNDMzNDRMNiAwLjAyMzQzNzVMMCA2LjAyMzQ0TDYgMTIuMDIzNEw3LjQxIDEwLjYxMzRMMi44MyA2LjAyMzQ0TDcuNDEgMS40MzM0NFoiIGZpbGw9IiNBRkU2MTQiLz4KPC9zdmc+Cg==\" alt=\"Arrow Left\">\n <a href=\"/\" class=\"return-text\">Return to homepage</a>\n </div>\n <div class=\"mobile-bottom-second-containers\">\n <span class=\"secured-text\">This website is secured by</span>\n <a href=\"https://patchstack.com\" class=\"logoText\">\n <img class=\"patch-logo\" src=\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTg0IiBoZWlnaHQ9IjIyIiB2aWV3Qm94PSIwIDAgMTg0IDIyIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTUwLjQwMDEgMTEuNTAwOEM1MC40MDAxIDkuMTAwNzggNDkuMzAwMSA4LjEwMDc4IDQ2LjYwMDEgOC4xMDA3OEM0NC4wMDAxIDguMTAwNzggNDIuNzAwMSA5LjIwMDc4IDQyLjcwMDEgMTEuNTAwOEM0Mi43MDAxIDEzLjgwMDggNDQuMDAwMSAxNC45MDA4IDQ2LjYwMDEgMTQuOTAwOEM0OS4zMDAxIDE0LjkwMDggNTAuNDAwMSAxMy44MDA4IDUwLjQwMDEgMTEuNTAwOFpNNTMuNDAwMSAxMS41MDA4QzUzLjQwMDEgMTUuMzAwOCA1MS4zMDAxIDE3LjYwMDggNDcuNDAwMSAxNy42MDA4QzQ1LjQwMDEgMTcuNjAwOCA0My42MDAxIDE2LjUwMDggNDIuNzAwMSAxNC41MDA4VjIxLjUwMDhIMzkuNjAwMVY1LjYwMDc4SDQyLjcwMDFWOC41MDA3OEM0My42MDAxIDYuNTAwNzggNDUuNDAwMSA1LjMwMDc4IDQ3LjUwMDEgNS4zMDA3OEM1MS40MDAxIDUuMzAwNzggNTMuNDAwMSA3LjcwMDc4IDUzLjQwMDEgMTEuNTAwOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNjYuNDAwMSAxMS40OTg0QzY2LjQwMDEgOS4xOTg0NCA2NS4xMDAxIDguMDk4NDQgNjIuNTAwMSA4LjA5ODQ0QzU5LjgwMDEgOC4wOTg0NCA1OC43MDAxIDkuMDk4NDQgNTguNzAwMSAxMS40OTg0QzU4LjcwMDEgMTMuNzk4NCA1OS44MDAxIDE0Ljg5ODQgNjIuNTAwMSAxNC44OTg0QzY1LjEwMDEgMTQuODk4NCA2Ni40MDAxIDEzLjc5ODQgNjYuNDAwMSAxMS40OTg0Wk02Ni4zMDAxIDUuNTk4NDRINjkuNDAwMVYxNy4zOTg0SDY2LjMwMDFWMTQuNDk4NEM2NS40MDAxIDE2LjQ5ODQgNjMuNzAwMSAxNy42OTg0IDYxLjYwMDEgMTcuNjk4NEM1Ny43MDAxIDE3LjY5ODQgNTUuNjAwMSAxNS4yOTg0IDU1LjYwMDEgMTEuNTk4NEM1NS42MDAxIDcuNzk4NDQgNTcuNjAwMSA1LjM5ODQ0IDYxLjQwMDEgNS4zOTg0NEM2My41MDAxIDUuMzk4NDQgNjUuNDAwMSA2LjU5ODQ0IDY2LjIwMDEgOC41OTg0NFY1LjU5ODQ0SDY2LjMwMDFaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTgxLjM5OTkgOC4zSDc3LjM5OTlWMTQuN0g4MS4wOTk5VjE3LjRINzcuOTk5OUM3NS43OTk5IDE3LjQgNzQuMjk5OSAxNS45IDc0LjI5OTkgMTMuN1Y4LjNINzEuMzk5OVY1LjZINzQuMjk5OVYySDc3LjM5OTlWNS41SDgxLjM5OTlWOC4zWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik05My42OTk5IDEyLjIwMDhMOTYuNjk5OSAxMi45MDA4Qzk1Ljk5OTkgMTYuMDAwOCA5My42OTk5IDE3LjYwMDggODkuOTk5OSAxNy42MDA4Qzg3Ljc5OTkgMTcuNjAwOCA4Ni4wOTk5IDE3LjAwMDggODQuNzk5OSAxNS45MDA4QzgzLjQ5OTkgMTQuODAwOCA4Mi44OTk5IDEzLjMwMDggODIuODk5OSAxMS41MDA4QzgyLjg5OTkgOS42MDA3OCA4My40OTk5IDguMTAwNzggODQuNzk5OSA3LjAwMDc4Qzg2LjA5OTkgNS45MDA3OCA4Ny43OTk5IDUuMzAwNzggODkuOTk5OSA1LjMwMDc4QzkzLjY5OTkgNS4zMDA3OCA5NS45OTk5IDYuOTAwNzggOTYuNjk5OSAxMC4wMDA4TDkzLjY5OTkgMTAuNzAwOEM5My4yOTk5IDguODAwNzggOTIuMjk5OSA4LjEwMDc4IDg5Ljg5OTkgOC4xMDA3OEM4Ni45OTk5IDguMTAwNzggODUuODk5OSA5LjIwMDc4IDg1Ljg5OTkgMTEuNTAwOEM4NS44OTk5IDEzLjgwMDggODYuOTk5OSAxNC45MDA4IDg5Ljg5OTkgMTQuOTAwOEM5Mi4yOTk5IDE0LjkwMDggOTMuMjk5OSAxNC4yMDA4IDkzLjY5OTkgMTIuMjAwOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTExLjggMTAuNlYxNy40SDEwOC43VjExLjJDMTA4LjcgOSAxMDcuOCA4LjEgMTA1LjkgOC4xQzEwMy42IDguMSAxMDIuNCA5LjMgMTAyLjQgMTEuN1YxNy4zSDk5LjI5OThWMC41SDEwMi40VjguM0MxMDMuMSA2LjMgMTA0LjYgNS4zIDEwNyA1LjNDMTEwLjIgNS4zIDExMS44IDcuMSAxMTEuOCAxMC42WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMTQuMSAxNC4wOTg0TDExNy4xIDEzLjI5ODRDMTE3LjQgMTQuNzk4NCAxMTguMyAxNS4yOTg0IDEyMC4yIDE1LjI5ODRDMTIxLjggMTUuMjk4NCAxMjIuNyAxNC44OTg0IDEyMi43IDE0LjA5ODRDMTIyLjcgMTMuMjk4NCAxMjIuMiAxMi45OTg0IDEyMC42IDEyLjc5ODRMMTE4LjIgMTIuNDk4NEMxMTUuOSAxMi4xOTg0IDExNC41IDEwLjg5ODQgMTE0LjUgOC45OTg0NEMxMTQuNSA2Ljc5ODQ0IDExNi41IDUuMzk4NDQgMTE5LjggNS4zOTg0NEMxMjMuMSA1LjM5ODQ0IDEyNSA2LjY5ODQ0IDEyNS41IDguODk4NDRMMTIyLjUgOS41OTg0NEMxMjIuMyA4LjA5ODQ0IDEyMS41IDcuNjk4NDQgMTE5LjkgNy42OTg0NEMxMTguNCA3LjY5ODQ0IDExNy42IDguMDk4NDQgMTE3LjYgOC44OTg0NEMxMTcuNiA5LjU5ODQ0IDExOC4xIDkuOTk4NDQgMTE5LjMgMTAuMDk4NEwxMjIuMiAxMC40OTg0QzEyNC40IDEwLjc5ODQgMTI1LjggMTEuOTk4NCAxMjUuOCAxMy44OTg0QzEyNS44IDE2LjI5ODQgMTIzLjcgMTcuNzk4NCAxMjAuMSAxNy43OTg0QzExNi43IDE3LjU5ODQgMTE0LjUgMTYuMTk4NCAxMTQuMSAxNC4wOTg0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMzYuNyA4LjNIMTMyLjdWMTQuN0gxMzYuNFYxNy40SDEzMy4zQzEzMS4xIDE3LjQgMTI5LjYgMTUuOSAxMjkuNiAxMy43VjguM0gxMjYuN1Y1LjZIMTI5LjZWMkgxMzIuN1Y1LjVIMTM2LjdWOC4zWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNDkuMiAxMS40OTg0QzE0OS4yIDkuMTk4NDQgMTQ3LjkgOC4wOTg0NCAxNDUuMyA4LjA5ODQ0QzE0Mi42IDguMDk4NDQgMTQxLjUgOS4wOTg0NCAxNDEuNSAxMS40OTg0QzE0MS41IDEzLjc5ODQgMTQyLjYgMTQuODk4NCAxNDUuMyAxNC44OTg0QzE0Ny45IDE0Ljg5ODQgMTQ5LjIgMTMuNzk4NCAxNDkuMiAxMS40OTg0Wk0xNDkuMSA1LjU5ODQ0SDE1Mi4yVjE3LjM5ODRIMTQ5LjFWMTQuNDk4NEMxNDguMiAxNi40OTg0IDE0Ni41IDE3LjY5ODQgMTQ0LjQgMTcuNjk4NEMxNDAuNSAxNy42OTg0IDEzOC40IDE1LjI5ODQgMTM4LjQgMTEuNTk4NEMxMzguNCA3Ljc5ODQ0IDE0MC40IDUuMzk4NDQgMTQ0LjIgNS4zOTg0NEMxNDYuMyA1LjM5ODQ0IDE0OC4yIDYuNTk4NDQgMTQ5IDguNTk4NDRWNS41OTg0NEgxNDkuMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTY1LjYgMTIuMjAwOEwxNjguNiAxMi45MDA4QzE2Ny45IDE2LjAwMDggMTY1LjYgMTcuNjAwOCAxNjEuOSAxNy42MDA4QzE1OS43IDE3LjYwMDggMTU4IDE3LjAwMDggMTU2LjcgMTUuOTAwOEMxNTUuNCAxNC44MDA4IDE1NC44IDEzLjMwMDggMTU0LjggMTEuNTAwOEMxNTQuOCA5LjYwMDc4IDE1NS40IDguMTAwNzggMTU2LjcgNy4wMDA3OEMxNTggNS45MDA3OCAxNTkuNyA1LjMwMDc4IDE2MS45IDUuMzAwNzhDMTY1LjYgNS4zMDA3OCAxNjcuOSA2LjkwMDc4IDE2OC42IDEwLjAwMDhMMTY1LjYgMTAuNzAwOEMxNjUuMiA4LjgwMDc4IDE2NC4yIDguMTAwNzggMTYxLjggOC4xMDA3OEMxNTguOSA4LjEwMDc4IDE1Ny44IDkuMjAwNzggMTU3LjggMTEuNTAwOEMxNTcuOCAxMy44MDA4IDE1OC45IDE0LjkwMDggMTYxLjggMTQuOTAwOEMxNjQuMSAxNC45MDA4IDE2NS4xIDE0LjIwMDggMTY1LjYgMTIuMjAwOFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTgwLjI1NyAxNy40TDE3Ni42NTcgMTIuM0wxNzQuMTU3IDE0LjZWMTcuNEgxNzEuMTU3VjAuNUgxNzQuMTU3VjExLjFMMTc5Ljg1NyA1LjZIMTgzLjc1N0wxNzguNTU3IDEwLjVMMTgzLjk1NyAxNy40SDE4MC4yNTdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTAgMjEuNTAwOEg3LjNWMTYuMzAwOEgwVjIxLjUwMDhaIiBmaWxsPSIjQUZFNjE0Ii8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNy4yOTk4IDIxLjUwMDhIMTQuNTk5OFYxNi4zMDA4SDcuMjk5OFYyMS41MDA4WiIgZmlsbD0iIzZFQkUwMCIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE0LjYwMDEgMTYuM0gyOS4yMDAxVjAuNUgxNC42MDAxVjE2LjNaIiBmaWxsPSIjQUZFNjE0Ii8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMCAxMUgxNC42VjAuNUgwVjExWiIgZmlsbD0iIzZFQkUwMCIvPgo8L3N2Zz4K\" alt=\"Patchstack Logo\">\n\t\t\t\t</a>\n </div>\n </div>\n </div>\n</body>\n<script>\n function copyText(id) {\n var copyText = document.getElementById(id)\n copyText.select();\n copyText.setSelectionRange(0, 99999);\n navigator.clipboard.writeText(copyText.value);\n }\n\n function hover(element) {\n element.setAttribute('src', 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkiIGhlaWdodD0iMjMiIHZpZXdCb3g9IjAgMCAxOSAyMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE0IDAuMDIzNDM3NUgwVjE2LjAyMzRIMlYyLjAyMzQ0SDE0VjAuMDIzNDM3NVpNMTkgNC4wMjM0NEg0VjIyLjAyMzRIMTlWNC4wMjM0NFpNMTcgMjAuMDIzNEg2VjYuMDIzNDRIMTdWMjAuMDIzNFoiIGZpbGw9IiNBRkU2MTQiLz4KPC9zdmc+Cg==');\n }\n\n function unhover(element) {\n element.setAttribute('src', 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkiIGhlaWdodD0iMjMiIHZpZXdCb3g9IjAgMCAxOSAyMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE0IDAuMDIzNDM3NUgwVjE2LjAyMzRIMlYyLjAyMzQ0SDE0VjAuMDIzNDM3NVpNMTkgNC4wMjM0NEg0VjIyLjAyMzRIMTlWNC4wMjM0NFpNMTcgMjAuMDIzNEg2VjYuMDIzNDRIMTdWMjAuMDIzNFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=');\n }\n</script>\n</html>`;\n}\n","// Supabase-tunnel guard for AI-builder apps (Lovable / TanStack Start + Supabase).\n//\n// The vibe-coded app's browser talks straight to Supabase, bypassing the app's own server —\n// so a normal in-app WAF never sees the data traffic. The installer patches the generated\n// Supabase client to tunnel every call through this guard (running in the app's own server /\n// Worker). The guard runs the Patchstack protection policy on the tunneled request, then\n// forwards it to Supabase — pinned to the app's own project so it can't be turned into an\n// open proxy (SSRF).\n//\n// The heavy lifting (rule evaluation, dry-run/block, fail-open) is `protection.fetchGuard()`\n// from `createProtection` — this module is just the Supabase-specific tunnel around it.\n\nexport const GUARD_PATH = '/_patchstack/guard';\n\n// Headers we must not copy verbatim when re-emitting the upstream response.\nconst HOP_BY_HOP = new Set(['content-encoding', 'content-length', 'transfer-encoding', 'connection']);\n\n/**\n * @param {object} opts\n * @param {{ fetchGuard: () => (req: Request) => Promise<Response|null> }} opts.protection a createProtection() result\n * @param {string|undefined} opts.supabaseUrl the app's Supabase project URL (server-side env) — the only allowed forward target\n * @param {typeof fetch} [opts.fetchImpl] injectable fetch (tests)\n * @returns {(request: Request) => Promise<Response>}\n */\nexport function createSupabaseGuard({ protection, supabaseUrl, fetchImpl = fetch }) {\n const guard = protection.fetchGuard();\n const allowedOrigin = supabaseUrl ? new URL(supabaseUrl).origin : null;\n\n return async function handleGuardRequest(request) {\n const target = request.headers.get('x-ps-target');\n if (!target) return new Response('patchstack: missing x-ps-target', { status: 400 });\n\n let targetUrl;\n try {\n targetUrl = new URL(target);\n } catch {\n return new Response('patchstack: invalid target', { status: 400 });\n }\n\n // SSRF pin: only ever forward to the app's own Supabase project (origin from server-side\n // env, never the client-supplied header). Anything else — internal hosts, cloud metadata,\n // a different scheme — is rejected before any outbound request.\n if (!allowedOrigin || targetUrl.protocol !== 'https:' || targetUrl.origin !== allowedOrigin) {\n return new Response('patchstack: target not allowed', { status: 403 });\n }\n\n const hasBody = request.method !== 'GET' && request.method !== 'HEAD';\n const bodyText = hasBody ? await request.text() : '';\n\n // Evaluate the tunneled call against the policy. fetchGuard returns a 403 Response when it\n // blocks (block mode + match), or null to allow (allow, or dry-run — it records via onDetect).\n const evalReq = new Request(targetUrl.toString(), {\n method: request.method,\n headers: request.headers,\n body: hasBody ? bodyText : undefined,\n });\n const blocked = await guard(evalReq);\n if (blocked) return blocked;\n\n // Allowed → forward to Supabase, server-side.\n const forwardHeaders = new Headers(request.headers);\n forwardHeaders.delete('x-ps-target');\n forwardHeaders.delete('host');\n const upstream = await fetchImpl(targetUrl.toString(), {\n method: request.method,\n headers: forwardHeaders,\n body: hasBody ? bodyText : undefined,\n redirect: 'manual',\n });\n\n const outHeaders = new Headers();\n upstream.headers.forEach((value, key) => {\n if (!HOP_BY_HOP.has(key.toLowerCase())) outHeaders.set(key, value);\n });\n const buf = await upstream.arrayBuffer();\n const forwarded = new Response(buf, { status: upstream.status, statusText: upstream.statusText, headers: outHeaders });\n\n // Response phase: screen what Supabase returned (query results can leak secrets/PII) —\n // redact the offending spans / withhold, per the response rules. Fail-open if unavailable.\n return protection.screenResponse ? protection.screenResponse(forwarded) : forwarded;\n };\n}\n"],"mappings":"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","names":["DEFAULT_BASE_URL","DEFAULT_CACHE_TTL","JITTER_FRACTION","parseCookies","allow"]}