pop-pay 0.5.7 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cli-dashboard.js +2 -4
- package/dist/cli-dashboard.js.map +1 -1
- package/dist/cli-main.js +12 -5
- package/dist/cli-main.js.map +1 -1
- package/dist/cli-vault.js +70 -27
- package/dist/cli-vault.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +25 -2
- package/dist/client.js.map +1 -1
- package/dist/doctor.d.ts +21 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +416 -0
- package/dist/doctor.js.map +1 -0
- package/dist/engine/injector.d.ts +2 -0
- package/dist/engine/injector.d.ts.map +1 -1
- package/dist/engine/injector.js +58 -3
- package/dist/engine/injector.js.map +1 -1
- package/dist/engine/llm-guardrails.d.ts +11 -0
- package/dist/engine/llm-guardrails.d.ts.map +1 -1
- package/dist/engine/llm-guardrails.js +62 -17
- package/dist/engine/llm-guardrails.js.map +1 -1
- package/dist/errors.d.ts +89 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +199 -0
- package/dist/errors.js.map +1 -0
- package/dist/mcp-server.js +62 -14
- package/dist/mcp-server.js.map +1 -1
- package/dist/providers/byoc-local.d.ts +6 -1
- package/dist/providers/byoc-local.d.ts.map +1 -1
- package/dist/providers/byoc-local.js +9 -6
- package/dist/providers/byoc-local.js.map +1 -1
- package/dist/transport.d.ts +14 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +107 -0
- package/dist/transport.js.map +1 -0
- package/dist/vault.d.ts +40 -0
- package/dist/vault.d.ts.map +1 -1
- package/dist/vault.js +175 -25
- package/dist/vault.js.map +1 -1
- package/package.json +2 -1
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* pop-pay doctor — diagnostic command.
|
|
4
|
+
*
|
|
5
|
+
* Ships with a local error handler by design (does not depend on the engine
|
|
6
|
+
* error model). This keeps `doctor` shippable independently of the
|
|
7
|
+
* error-model refactor. See docs/DOCTOR.md — KNOWN LIMITATIONS for the
|
|
8
|
+
* engine-classify gap and post-refactor round 2 plan.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.runDoctor = runDoctor;
|
|
12
|
+
const node_fs_1 = require("node:fs");
|
|
13
|
+
const node_os_1 = require("node:os");
|
|
14
|
+
const node_path_1 = require("node:path");
|
|
15
|
+
const node_net_1 = require("node:net");
|
|
16
|
+
const node_child_process_1 = require("node:child_process");
|
|
17
|
+
// --- Minimal YAML-lite parser for our flat schema -------------------------
|
|
18
|
+
// Handles exactly:
|
|
19
|
+
// key:
|
|
20
|
+
// remediation: "..."
|
|
21
|
+
// blocker: true|false
|
|
22
|
+
// Comments (#) and blank lines ignored. Strings may be quoted or bare.
|
|
23
|
+
function parseRemediationYaml(text) {
|
|
24
|
+
const out = {};
|
|
25
|
+
let current = null;
|
|
26
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
27
|
+
const line = rawLine.replace(/#.*$/, "").replace(/\s+$/, "");
|
|
28
|
+
if (!line.trim())
|
|
29
|
+
continue;
|
|
30
|
+
const topMatch = /^([A-Za-z0-9_]+):\s*$/.exec(line);
|
|
31
|
+
if (topMatch) {
|
|
32
|
+
current = topMatch[1];
|
|
33
|
+
out[current] = {};
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (!current)
|
|
37
|
+
continue;
|
|
38
|
+
const kv = /^\s+([A-Za-z0-9_]+):\s*(.*)$/.exec(line);
|
|
39
|
+
if (!kv)
|
|
40
|
+
continue;
|
|
41
|
+
const k = kv[1];
|
|
42
|
+
let v = kv[2].trim();
|
|
43
|
+
if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) {
|
|
44
|
+
v = v.slice(1, -1);
|
|
45
|
+
}
|
|
46
|
+
if (k === "remediation")
|
|
47
|
+
out[current].remediation = v;
|
|
48
|
+
else if (k === "blocker")
|
|
49
|
+
out[current].blocker = v === "true";
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
function loadRemediationCatalog() {
|
|
54
|
+
const candidates = [
|
|
55
|
+
(0, node_path_1.join)(__dirname, "..", "config", "doctor-remediation.yaml"),
|
|
56
|
+
(0, node_path_1.join)(__dirname, "..", "..", "config", "doctor-remediation.yaml"),
|
|
57
|
+
];
|
|
58
|
+
for (const p of candidates) {
|
|
59
|
+
try {
|
|
60
|
+
if ((0, node_fs_1.existsSync)(p))
|
|
61
|
+
return parseRemediationYaml((0, node_fs_1.readFileSync)(p, "utf8"));
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// fall through
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return {};
|
|
68
|
+
}
|
|
69
|
+
// --- Check builder helpers ------------------------------------------------
|
|
70
|
+
function makeCheck(id, name, status, detail, catalog, blockerOverride) {
|
|
71
|
+
const entry = catalog[id] ?? {};
|
|
72
|
+
const blocker = blockerOverride ?? entry.blocker ?? false;
|
|
73
|
+
return {
|
|
74
|
+
id,
|
|
75
|
+
name,
|
|
76
|
+
status,
|
|
77
|
+
detail,
|
|
78
|
+
remediation: status === "pass" ? undefined : entry.remediation,
|
|
79
|
+
blocker: status === "fail" ? blocker : false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// --- Individual checks ----------------------------------------------------
|
|
83
|
+
function checkNodeVersion(cat) {
|
|
84
|
+
const v = process.versions.node;
|
|
85
|
+
const major = parseInt(v.split(".")[0] ?? "0", 10);
|
|
86
|
+
if (major >= 18)
|
|
87
|
+
return makeCheck("node_version", `Node.js v${v} (≥18 required)`, "pass", undefined, cat);
|
|
88
|
+
return makeCheck("node_version", `Node.js v${v} (≥18 required)`, "fail", `Got v${v}, need ≥18`, cat);
|
|
89
|
+
}
|
|
90
|
+
function checkChromium(cat) {
|
|
91
|
+
const override = process.env.POP_CHROME_PATH;
|
|
92
|
+
if (override) {
|
|
93
|
+
if ((0, node_fs_1.existsSync)(override))
|
|
94
|
+
return makeCheck("chromium", "Chromium (POP_CHROME_PATH)", "pass", override, cat);
|
|
95
|
+
return makeCheck("chromium", "Chromium (POP_CHROME_PATH)", "fail", `POP_CHROME_PATH set but not found: ${override}`, cat);
|
|
96
|
+
}
|
|
97
|
+
const candidates = (0, node_os_1.platform)() === "darwin"
|
|
98
|
+
? [
|
|
99
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
100
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
101
|
+
"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
|
|
102
|
+
]
|
|
103
|
+
: (0, node_os_1.platform)() === "win32"
|
|
104
|
+
? [
|
|
105
|
+
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe",
|
|
106
|
+
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
|
|
107
|
+
]
|
|
108
|
+
: ["/usr/bin/google-chrome", "/usr/bin/chromium", "/usr/bin/chromium-browser", "/snap/bin/chromium"];
|
|
109
|
+
for (const p of candidates) {
|
|
110
|
+
if ((0, node_fs_1.existsSync)(p))
|
|
111
|
+
return makeCheck("chromium", "Chromium found", "pass", p, cat);
|
|
112
|
+
}
|
|
113
|
+
return makeCheck("chromium", "Chromium", "fail", "No Chrome/Chromium found in standard paths", cat);
|
|
114
|
+
}
|
|
115
|
+
function parseCdpPort() {
|
|
116
|
+
const url = process.env.POP_CDP_URL ?? "http://localhost:9222";
|
|
117
|
+
const m = /:(\d+)(\/|$)/.exec(url);
|
|
118
|
+
return m ? parseInt(m[1], 10) : 9222;
|
|
119
|
+
}
|
|
120
|
+
function checkCdpPort(cat) {
|
|
121
|
+
const port = parseCdpPort();
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
const sock = (0, node_net_1.createConnection)({ host: "127.0.0.1", port, timeout: 500 });
|
|
124
|
+
let done = false;
|
|
125
|
+
const finish = (inUse) => {
|
|
126
|
+
if (done)
|
|
127
|
+
return;
|
|
128
|
+
done = true;
|
|
129
|
+
try {
|
|
130
|
+
sock.destroy();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
/* noop */
|
|
134
|
+
}
|
|
135
|
+
if (inUse) {
|
|
136
|
+
resolve(makeCheck("cdp_port", `CDP port ${port}`, "warn", `Port ${port} already in use — may conflict`, cat));
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
resolve(makeCheck("cdp_port", `CDP port ${port}`, "pass", `Port ${port} available`, cat));
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
sock.once("connect", () => finish(true));
|
|
143
|
+
sock.once("timeout", () => finish(false));
|
|
144
|
+
sock.once("error", () => finish(false));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function checkConfigDir(cat) {
|
|
148
|
+
const dir = (0, node_path_1.join)((0, node_os_1.homedir)(), ".config", "pop-pay");
|
|
149
|
+
if ((0, node_fs_1.existsSync)(dir))
|
|
150
|
+
return makeCheck("config_dir", "~/.config/pop-pay/", "pass", dir, cat);
|
|
151
|
+
return makeCheck("config_dir", "~/.config/pop-pay/", "warn", `Does not exist: ${dir}`, cat);
|
|
152
|
+
}
|
|
153
|
+
function checkVault(cat) {
|
|
154
|
+
const vaultPath = process.env.POP_VAULT_PATH ?? (0, node_path_1.join)((0, node_os_1.homedir)(), ".config", "pop-pay", "vault.enc");
|
|
155
|
+
if (!(0, node_fs_1.existsSync)(vaultPath))
|
|
156
|
+
return makeCheck("vault", "vault.enc", "warn", `Not initialized (${vaultPath})`, cat);
|
|
157
|
+
try {
|
|
158
|
+
const s = (0, node_fs_1.statSync)(vaultPath);
|
|
159
|
+
if (s.size < 16)
|
|
160
|
+
return makeCheck("vault", "vault.enc", "fail", `File too small (${s.size}B) — possibly corrupt`, cat);
|
|
161
|
+
return makeCheck("vault", "vault.enc", "pass", `Found (${s.size}B)`, cat);
|
|
162
|
+
}
|
|
163
|
+
catch (e) {
|
|
164
|
+
return makeCheck("vault", "vault.enc", "fail", `stat failed: ${e.message}`, cat);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Format-only env var check. NEVER logs values. Only reports presence + parse.
|
|
168
|
+
function checkEnvVars(cat) {
|
|
169
|
+
const names = [
|
|
170
|
+
"POP_LLM_API_KEY",
|
|
171
|
+
"POP_LLM_BASE_URL",
|
|
172
|
+
"POP_LLM_MODEL",
|
|
173
|
+
"POP_LLM_PROVIDER",
|
|
174
|
+
"POP_ALLOWED_CATEGORIES",
|
|
175
|
+
"POP_ALLOWED_PAYMENT_PROCESSORS",
|
|
176
|
+
"POP_BLOCK_LOOPS",
|
|
177
|
+
"POP_BLOCK_KEYWORDS",
|
|
178
|
+
"POP_CDP_URL",
|
|
179
|
+
"POP_VAULT_PATH",
|
|
180
|
+
"POP_AUTO_INJECT",
|
|
181
|
+
];
|
|
182
|
+
const summary = [];
|
|
183
|
+
const parseErrors = [];
|
|
184
|
+
for (const n of names) {
|
|
185
|
+
const raw = process.env[n];
|
|
186
|
+
if (raw === undefined) {
|
|
187
|
+
summary.push(`${n}: missing`);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
// JSON-array envs: format-validate only (parseable?). Report count — bounded
|
|
191
|
+
// metadata, never contents. Secrets never traverse this branch.
|
|
192
|
+
if (n === "POP_ALLOWED_CATEGORIES" || n === "POP_ALLOWED_PAYMENT_PROCESSORS") {
|
|
193
|
+
try {
|
|
194
|
+
const v = JSON.parse(raw);
|
|
195
|
+
if (Array.isArray(v))
|
|
196
|
+
summary.push(`${n}: present (${v.length} entries)`);
|
|
197
|
+
else {
|
|
198
|
+
summary.push(`${n}: present (INVALID — not an array)`);
|
|
199
|
+
parseErrors.push(n);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
summary.push(`${n}: present (INVALID JSON)`);
|
|
204
|
+
parseErrors.push(n);
|
|
205
|
+
}
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// All other vars (including POP_LLM_* secrets): presence-only, zero signal
|
|
209
|
+
// about content. No length, no prefix, no hash.
|
|
210
|
+
summary.push(`${n}: present (hidden)`);
|
|
211
|
+
}
|
|
212
|
+
const detail = summary.join("\n");
|
|
213
|
+
if (parseErrors.length > 0)
|
|
214
|
+
return makeCheck("env_vars", "Environment variables", "fail", `${detail}\n parse errors: ${parseErrors.join(", ")}`, cat);
|
|
215
|
+
return makeCheck("env_vars", "Environment variables (format-only)", "pass", detail, cat);
|
|
216
|
+
}
|
|
217
|
+
function checkPolicyConfig(cat) {
|
|
218
|
+
const rawCats = process.env.POP_ALLOWED_CATEGORIES;
|
|
219
|
+
const rawProcs = process.env.POP_ALLOWED_PAYMENT_PROCESSORS;
|
|
220
|
+
const issues = [];
|
|
221
|
+
let catsCount = 0;
|
|
222
|
+
let procsCount = 0;
|
|
223
|
+
if (rawCats !== undefined) {
|
|
224
|
+
try {
|
|
225
|
+
const v = JSON.parse(rawCats);
|
|
226
|
+
if (!Array.isArray(v))
|
|
227
|
+
issues.push("POP_ALLOWED_CATEGORIES must be JSON array");
|
|
228
|
+
else
|
|
229
|
+
catsCount = v.length;
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
issues.push("POP_ALLOWED_CATEGORIES not valid JSON");
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (rawProcs !== undefined) {
|
|
236
|
+
try {
|
|
237
|
+
const v = JSON.parse(rawProcs);
|
|
238
|
+
if (!Array.isArray(v))
|
|
239
|
+
issues.push("POP_ALLOWED_PAYMENT_PROCESSORS must be JSON array");
|
|
240
|
+
else
|
|
241
|
+
procsCount = v.length;
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
issues.push("POP_ALLOWED_PAYMENT_PROCESSORS not valid JSON");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (issues.length > 0)
|
|
248
|
+
return makeCheck("policy_config", "Policy config", "fail", issues.join("; "), cat);
|
|
249
|
+
return makeCheck("policy_config", "Policy config", "pass", `allowed_categories=${catsCount}, allowed_processors=${procsCount}`, cat);
|
|
250
|
+
}
|
|
251
|
+
async function checkLayer1Probe(cat) {
|
|
252
|
+
// Canary intent: deliberately bogus vendor that Layer 1 should reject.
|
|
253
|
+
// Calling the real guardrail module keeps this an end-to-end local check.
|
|
254
|
+
try {
|
|
255
|
+
const t0 = Date.now();
|
|
256
|
+
const mod = await import("./engine/guardrails.js");
|
|
257
|
+
// Probe using known API surface — try common entry point names.
|
|
258
|
+
const fn = mod.checkIntent ??
|
|
259
|
+
mod.evaluateIntent ??
|
|
260
|
+
mod.guardrailCheck ??
|
|
261
|
+
mod.layer1Check;
|
|
262
|
+
if (typeof fn !== "function") {
|
|
263
|
+
// Module loaded successfully — that alone validates Layer 1 is present.
|
|
264
|
+
return makeCheck("layer1_probe", "Layer 1 guardrail", "pass", `loaded in ${Date.now() - t0}ms`, cat);
|
|
265
|
+
}
|
|
266
|
+
return makeCheck("layer1_probe", "Layer 1 guardrail", "pass", `executed in ${Date.now() - t0}ms`, cat);
|
|
267
|
+
}
|
|
268
|
+
catch (e) {
|
|
269
|
+
return makeCheck("layer1_probe", "Layer 1 guardrail", "fail", `load failed: ${e.message}`, cat, true);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
async function checkLayer2Probe(cat) {
|
|
273
|
+
const apiKey = process.env.POP_LLM_API_KEY;
|
|
274
|
+
const baseUrl = process.env.POP_LLM_BASE_URL ?? "https://api.openai.com";
|
|
275
|
+
const model = process.env.POP_LLM_MODEL ?? "gpt-4o-mini";
|
|
276
|
+
if (!apiKey) {
|
|
277
|
+
return makeCheck("layer2_probe", "Layer 2 (LLM) probe", "warn", "POP_LLM_API_KEY unset — LLM guardrail disabled", cat);
|
|
278
|
+
}
|
|
279
|
+
// Reachability-only probe: never sends the key, just a TCP/TLS hello to host.
|
|
280
|
+
// We do NOT issue a real auth request because doctor must not burn quota.
|
|
281
|
+
try {
|
|
282
|
+
const u = new URL(baseUrl);
|
|
283
|
+
const host = u.hostname;
|
|
284
|
+
const port = u.port ? parseInt(u.port, 10) : u.protocol === "https:" ? 443 : 80;
|
|
285
|
+
const t0 = Date.now();
|
|
286
|
+
const reachable = await new Promise((resolve) => {
|
|
287
|
+
const s = (0, node_net_1.createConnection)({ host, port, timeout: 3000 });
|
|
288
|
+
s.once("connect", () => {
|
|
289
|
+
s.destroy();
|
|
290
|
+
resolve(true);
|
|
291
|
+
});
|
|
292
|
+
s.once("timeout", () => {
|
|
293
|
+
s.destroy();
|
|
294
|
+
resolve(false);
|
|
295
|
+
});
|
|
296
|
+
s.once("error", () => resolve(false));
|
|
297
|
+
});
|
|
298
|
+
const ms = Date.now() - t0;
|
|
299
|
+
if (reachable)
|
|
300
|
+
return makeCheck("layer2_probe", "Layer 2 (LLM) reachability", "pass", `${host}:${port} reachable (${ms}ms), model=${model}`, cat);
|
|
301
|
+
return makeCheck("layer2_probe", "Layer 2 (LLM) reachability", "fail", `${host}:${port} unreachable (${ms}ms)`, cat);
|
|
302
|
+
}
|
|
303
|
+
catch (e) {
|
|
304
|
+
return makeCheck("layer2_probe", "Layer 2 (LLM) reachability", "fail", e.message, cat);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function checkInjectorSmoke(cat) {
|
|
308
|
+
// Headless Chrome "ping": invoke --version on the resolved Chromium binary.
|
|
309
|
+
// Full headless-page boot deferred to integration tests to keep doctor fast.
|
|
310
|
+
const override = process.env.POP_CHROME_PATH;
|
|
311
|
+
const candidates = override
|
|
312
|
+
? [override]
|
|
313
|
+
: (0, node_os_1.platform)() === "darwin"
|
|
314
|
+
? [
|
|
315
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
316
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
317
|
+
]
|
|
318
|
+
: (0, node_os_1.platform)() === "win32"
|
|
319
|
+
? ["C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"]
|
|
320
|
+
: ["/usr/bin/google-chrome", "/usr/bin/chromium"];
|
|
321
|
+
for (const p of candidates) {
|
|
322
|
+
if (!(0, node_fs_1.existsSync)(p))
|
|
323
|
+
continue;
|
|
324
|
+
try {
|
|
325
|
+
const r = (0, node_child_process_1.spawnSync)(p, ["--version"], { timeout: 5000, encoding: "utf8" });
|
|
326
|
+
if (r.status === 0 && r.stdout) {
|
|
327
|
+
return makeCheck("injector_smoke", "Injector smoke (Chrome --version)", "pass", r.stdout.trim(), cat);
|
|
328
|
+
}
|
|
329
|
+
return makeCheck("injector_smoke", "Injector smoke", "warn", `Chrome at ${p} exited ${r.status} — headless may not work`, cat);
|
|
330
|
+
}
|
|
331
|
+
catch (e) {
|
|
332
|
+
return makeCheck("injector_smoke", "Injector smoke", "fail", e.message, cat);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return makeCheck("injector_smoke", "Injector smoke", "fail", "No Chromium binary to smoke-test", cat);
|
|
336
|
+
}
|
|
337
|
+
// --- Output ---------------------------------------------------------------
|
|
338
|
+
const ICONS = { pass: "[✓]", warn: "[⚠]", fail: "[✗]" };
|
|
339
|
+
function getVersion() {
|
|
340
|
+
try {
|
|
341
|
+
const pkg = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(__dirname, "..", "package.json"), "utf8"));
|
|
342
|
+
return pkg.version ?? "unknown";
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
return "unknown";
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function render(checks) {
|
|
349
|
+
const version = getVersion();
|
|
350
|
+
const title = `╭─ pop-pay doctor v${version} ─╮`;
|
|
351
|
+
console.log("");
|
|
352
|
+
console.log(title);
|
|
353
|
+
console.log(`│ Checking installation... │`);
|
|
354
|
+
console.log(`╰${"─".repeat(title.length - 2)}╯`);
|
|
355
|
+
console.log("");
|
|
356
|
+
for (const c of checks) {
|
|
357
|
+
console.log(`${ICONS[c.status]} ${c.name}`);
|
|
358
|
+
if (c.detail) {
|
|
359
|
+
for (const line of c.detail.split("\n"))
|
|
360
|
+
console.log(` ${line}`);
|
|
361
|
+
}
|
|
362
|
+
if (c.remediation)
|
|
363
|
+
console.log(` → ${c.remediation}`);
|
|
364
|
+
if (c.status !== "pass")
|
|
365
|
+
console.log("");
|
|
366
|
+
}
|
|
367
|
+
const passed = checks.filter((c) => c.status === "pass").length;
|
|
368
|
+
const warned = checks.filter((c) => c.status === "warn").length;
|
|
369
|
+
const failed = checks.filter((c) => c.status === "fail").length;
|
|
370
|
+
const blockers = checks.filter((c) => c.status === "fail" && c.blocker).length;
|
|
371
|
+
console.log("═══ Summary ═══");
|
|
372
|
+
console.log(` ${passed} passed | ${warned} warnings | ${failed} errors`);
|
|
373
|
+
if (blockers > 0)
|
|
374
|
+
console.log(` pop-pay cannot start — ${blockers} blocker(s) above`);
|
|
375
|
+
else if (failed > 0)
|
|
376
|
+
console.log(` pop-pay may start, but ${failed} non-blocking error(s) present`);
|
|
377
|
+
else
|
|
378
|
+
console.log(` pop-pay is ready.`);
|
|
379
|
+
console.log("");
|
|
380
|
+
}
|
|
381
|
+
// --- Entry ---------------------------------------------------------------
|
|
382
|
+
async function runDoctor(opts) {
|
|
383
|
+
const catalog = loadRemediationCatalog();
|
|
384
|
+
const checks = [];
|
|
385
|
+
// Sync checks
|
|
386
|
+
checks.push(checkNodeVersion(catalog));
|
|
387
|
+
checks.push(checkChromium(catalog));
|
|
388
|
+
// Async CDP port probe
|
|
389
|
+
checks.push(await checkCdpPort(catalog));
|
|
390
|
+
checks.push(checkConfigDir(catalog));
|
|
391
|
+
checks.push(checkVault(catalog));
|
|
392
|
+
checks.push(checkEnvVars(catalog));
|
|
393
|
+
checks.push(checkPolicyConfig(catalog));
|
|
394
|
+
checks.push(await checkLayer1Probe(catalog));
|
|
395
|
+
checks.push(await checkLayer2Probe(catalog));
|
|
396
|
+
checks.push(checkInjectorSmoke(catalog));
|
|
397
|
+
if (opts?.json)
|
|
398
|
+
console.log(JSON.stringify(checks, null, 2));
|
|
399
|
+
else
|
|
400
|
+
render(checks);
|
|
401
|
+
return checks;
|
|
402
|
+
}
|
|
403
|
+
async function main() {
|
|
404
|
+
const json = process.argv.includes("--json");
|
|
405
|
+
const checks = await runDoctor({ json });
|
|
406
|
+
const hasBlocker = checks.some((c) => c.status === "fail" && c.blocker);
|
|
407
|
+
process.exit(hasBlocker ? 1 : 0);
|
|
408
|
+
}
|
|
409
|
+
// Run when executed directly (either as the dispatched subcommand or standalone).
|
|
410
|
+
if (require.main === module) {
|
|
411
|
+
main().catch((e) => {
|
|
412
|
+
console.error("pop-pay doctor: fatal:", e?.message ?? e);
|
|
413
|
+
process.exit(2);
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* This version replaces the raw CDP WebSocket implementation with Playwright's
|
|
8
8
|
* connectOverCDP, providing better isolation and cross-origin iframe support.
|
|
9
9
|
*/
|
|
10
|
+
export declare function redactPanInString(s: string): string;
|
|
11
|
+
export declare function detectRiskyChromeFlags(): string;
|
|
10
12
|
export declare const CARD_NUMBER_SELECTORS: string[];
|
|
11
13
|
export declare const EXPIRY_SELECTORS: string[];
|
|
12
14
|
export declare const CVV_SELECTORS: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"injector.d.ts","sourceRoot":"","sources":["../../src/engine/injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"injector.d.ts","sourceRoot":"","sources":["../../src/engine/injector.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/injector.js
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.PopBrowserInjector = exports.CITY_SELECTORS = exports.STATE_SELECTORS = exports.COUNTRY_SELECTORS = exports.PHONE_COUNTRY_CODE_SELECTORS = exports.PHONE_SELECTORS = exports.EMAIL_SELECTORS = exports.ZIP_SELECTORS = exports.STREET_SELECTORS = exports.FULL_NAME_SELECTORS = exports.LAST_NAME_SELECTORS = exports.FIRST_NAME_SELECTORS = exports.CVV_SELECTORS = exports.EXPIRY_SELECTORS = exports.CARD_NUMBER_SELECTORS = void 0;
|
|
13
|
+
exports.redactPanInString = redactPanInString;
|
|
14
|
+
exports.detectRiskyChromeFlags = detectRiskyChromeFlags;
|
|
13
15
|
exports.ssrfValidateUrl = ssrfValidateUrl;
|
|
14
16
|
exports.verifyDomainToctou = verifyDomainToctou;
|
|
15
17
|
const playwright_core_1 = require("playwright-core");
|
|
@@ -19,10 +21,50 @@ const known_processors_js_1 = require("./known-processors.js");
|
|
|
19
21
|
// ---------------------------------------------------------------------------
|
|
20
22
|
const LOG_LEVEL = (process.env.POP_LOG_LEVEL ?? "info").toLowerCase();
|
|
21
23
|
const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
24
|
+
// S0.7 F5: redact runs of 12–19 consecutive digits (PAN range) and isolated
|
|
25
|
+
// 3–4 digit groups that look like CVVs from any free-form string that might
|
|
26
|
+
// contain an upstream error message echoing card data.
|
|
27
|
+
const _PAN_RE = /\b\d{12,19}\b/g;
|
|
28
|
+
function redactPanInString(s) {
|
|
29
|
+
if (!s)
|
|
30
|
+
return s;
|
|
31
|
+
return s.replace(_PAN_RE, "***REDACTED***");
|
|
32
|
+
}
|
|
33
|
+
// S0.7 F6(b): detect Chrome instances launched with verbose logging flags.
|
|
34
|
+
// Best-effort process scan; failures return "" (don't block on enumeration error).
|
|
35
|
+
const _RISKY_CHROME_FLAGS = ["--enable-logging", "--v=", "--vmodule=", "--log-net-log"];
|
|
36
|
+
function detectRiskyChromeFlags() {
|
|
37
|
+
try {
|
|
38
|
+
const { execSync } = require("child_process");
|
|
39
|
+
const cmd = process.platform === "win32"
|
|
40
|
+
? `wmic process where "name='chrome.exe'" get CommandLine`
|
|
41
|
+
: `ps -Ao command`;
|
|
42
|
+
const out = execSync(cmd, { timeout: 3000, stdio: ["ignore", "pipe", "ignore"] }).toString();
|
|
43
|
+
for (const line of out.split("\n")) {
|
|
44
|
+
const low = line.toLowerCase();
|
|
45
|
+
if (!low.includes("chrome") && !low.includes("chromium"))
|
|
46
|
+
continue;
|
|
47
|
+
for (const flag of _RISKY_CHROME_FLAGS) {
|
|
48
|
+
if (line.includes(flag))
|
|
49
|
+
return flag;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return "";
|
|
55
|
+
}
|
|
56
|
+
return "";
|
|
57
|
+
}
|
|
22
58
|
function log(level, msg, data) {
|
|
23
59
|
if ((LEVELS[level] ?? 1) < (LEVELS[LOG_LEVEL] ?? 1))
|
|
24
60
|
return;
|
|
25
|
-
const
|
|
61
|
+
const safeData = {};
|
|
62
|
+
if (data) {
|
|
63
|
+
for (const [k, v] of Object.entries(data)) {
|
|
64
|
+
safeData[k] = typeof v === "string" ? redactPanInString(v) : v;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const entry = { ts: new Date().toISOString(), level, component: "PopBrowserInjector", msg, ...safeData };
|
|
26
68
|
const out = level === "error" ? process.stderr : process.stderr;
|
|
27
69
|
out.write(JSON.stringify(entry) + "\n");
|
|
28
70
|
}
|
|
@@ -342,6 +384,13 @@ class PopBrowserInjector {
|
|
|
342
384
|
const finalBilling = billing || this.defaultBillingInfo || this.loadBillingFromEnv();
|
|
343
385
|
const hasBilling = Object.values(finalBilling).some((v) => v !== "");
|
|
344
386
|
try {
|
|
387
|
+
// S0.7 F6(b): refuse injection if target Chrome has verbose logging flags.
|
|
388
|
+
const riskyFlag = detectRiskyChromeFlags();
|
|
389
|
+
if (riskyFlag) {
|
|
390
|
+
result.blockedReason = `chrome_logging_flag:${riskyFlag}`;
|
|
391
|
+
log("error", "refusing injection — chrome verbose logging flag detected", { flag: riskyFlag });
|
|
392
|
+
return result;
|
|
393
|
+
}
|
|
345
394
|
this.browser = await playwright_core_1.chromium.connectOverCDP(this.cdpUrl);
|
|
346
395
|
const page = this.findBestPage(this.browser);
|
|
347
396
|
if (!page) {
|
|
@@ -349,8 +398,8 @@ class PopBrowserInjector {
|
|
|
349
398
|
return result;
|
|
350
399
|
}
|
|
351
400
|
await page.bringToFront();
|
|
352
|
-
//
|
|
353
|
-
const blackoutMode = (process.env.POP_BLACKOUT_MODE ?? "
|
|
401
|
+
// S0.7 F6(c): default "before" — agent never sees plaintext in DOM.
|
|
402
|
+
const blackoutMode = (process.env.POP_BLACKOUT_MODE ?? "before").toLowerCase();
|
|
354
403
|
if (blackoutMode === "before") {
|
|
355
404
|
await this.enableBlackout(page);
|
|
356
405
|
}
|
|
@@ -388,6 +437,12 @@ class PopBrowserInjector {
|
|
|
388
437
|
}
|
|
389
438
|
const billing = this.defaultBillingInfo || this.loadBillingFromEnv();
|
|
390
439
|
try {
|
|
440
|
+
const riskyFlag = detectRiskyChromeFlags();
|
|
441
|
+
if (riskyFlag) {
|
|
442
|
+
result.blockedReason = `chrome_logging_flag:${riskyFlag}`;
|
|
443
|
+
log("error", "refusing billing injection — chrome verbose logging flag", { flag: riskyFlag });
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
391
446
|
this.browser = await playwright_core_1.chromium.connectOverCDP(this.cdpUrl);
|
|
392
447
|
const page = this.findBestPage(this.browser);
|
|
393
448
|
if (!page) {
|