pqcheck 0.7.6 → 0.7.7
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 +1 -1
- package/bin/pqcheck.js +23 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -185,7 +185,7 @@ curl -s "https://www.quantapact.com/api/scan?domain=stripe.com" | jq '.grade, .s
|
|
|
185
185
|
|
|
186
186
|
Full API reference at [quantapact.com/api](https://quantapact.com/api).
|
|
187
187
|
|
|
188
|
-
**Rate
|
|
188
|
+
**Rate limits:** 300 scans per hour per IP, 20 `--fresh` (force-refresh) scans per hour per IP. No API key required. Returns HTTP 429 if exceeded — back off and retry, or [let us know via the feedback form](https://quantapact.com/feedback) if you need higher limits (we're prioritizing the API tier based on real demand).
|
|
189
189
|
|
|
190
190
|
## Methodology
|
|
191
191
|
|
package/bin/pqcheck.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// =============================================================================
|
|
8
8
|
|
|
9
9
|
const API_BASE = process.env.PQCHECK_API_BASE || "https://quantapact.com";
|
|
10
|
-
const VERSION = "0.7.
|
|
10
|
+
const VERSION = "0.7.7";
|
|
11
11
|
|
|
12
12
|
const ANSI = {
|
|
13
13
|
reset: "\x1b[0m",
|
|
@@ -107,20 +107,31 @@ async function main() {
|
|
|
107
107
|
return; // runWatch handles its own exit; in practice it runs until killed.
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
// --fresh: bypass server cache, force a fresh scan. Useful when verifying
|
|
111
|
+
// a cert/key change you just deployed. Subject to a 20/hr per-IP cap on
|
|
112
|
+
// the server side.
|
|
113
|
+
const fresh = args.includes("--fresh") || args.includes("--force");
|
|
114
|
+
|
|
110
115
|
// One-shot scan(s)
|
|
111
116
|
let worstExit = 0;
|
|
112
117
|
for (const domain of domains) {
|
|
113
|
-
const exit = await runOneScan({ domain, format, quiet, threshold, webhookUrl, multi: domains.length > 1 });
|
|
118
|
+
const exit = await runOneScan({ domain, format, quiet, threshold, webhookUrl, multi: domains.length > 1, fresh });
|
|
114
119
|
if (exit > worstExit) worstExit = exit;
|
|
115
120
|
}
|
|
116
121
|
process.exit(worstExit);
|
|
117
122
|
}
|
|
118
123
|
|
|
119
|
-
async function runOneScan({ domain, format, quiet, threshold, webhookUrl, multi }) {
|
|
120
|
-
if (!quiet && format === "text") process.stderr.write(color("dim", `Scanning ${domain} ...`));
|
|
124
|
+
async function runOneScan({ domain, format, quiet, threshold, webhookUrl, multi, fresh }) {
|
|
125
|
+
if (!quiet && format === "text") process.stderr.write(color("dim", `Scanning ${domain}${fresh ? " (forcing fresh)" : ""} ...`));
|
|
121
126
|
let report;
|
|
122
127
|
try {
|
|
123
|
-
|
|
128
|
+
// --fresh appends ?force=1 to bypass the smart-cache. Use when verifying
|
|
129
|
+
// a cert/key change you just deployed — otherwise scans hit the 1h SWR
|
|
130
|
+
// cache and return up-to-1h-old data. Subject to a 20/hr per-IP cap on
|
|
131
|
+
// the server side; if exceeded, the server silently downgrades to a
|
|
132
|
+
// cached scan and returns that instead of erroring.
|
|
133
|
+
const qs = fresh ? `?domain=${encodeURIComponent(domain)}&force=1` : `?domain=${encodeURIComponent(domain)}`;
|
|
134
|
+
const resp = await fetch(`${API_BASE}/api/scan${qs}`, {
|
|
124
135
|
method: "GET",
|
|
125
136
|
headers: { accept: "application/json", "user-agent": `pqcheck-cli/${VERSION} (scan)` },
|
|
126
137
|
});
|
|
@@ -129,6 +140,12 @@ async function runOneScan({ domain, format, quiet, threshold, webhookUrl, multi
|
|
|
129
140
|
const errBody = await safeJSON(resp);
|
|
130
141
|
console.error(color("red", `error scanning ${domain}: ${resp.status} ${errBody?.error || resp.statusText}`));
|
|
131
142
|
if (errBody?.detail) console.error(color("dim", errBody.detail));
|
|
143
|
+
// Surface the 429 upsell hint if present — tells users how to ask for
|
|
144
|
+
// higher limits via the feedback form. Same demand signal we capture
|
|
145
|
+
// on the homepage.
|
|
146
|
+
if (resp.status === 429 && errBody?.need_more?.feedback_url) {
|
|
147
|
+
console.error(color("dim", `${errBody.need_more.message} → ${errBody.need_more.feedback_url}`));
|
|
148
|
+
}
|
|
132
149
|
return 1;
|
|
133
150
|
}
|
|
134
151
|
report = await resp.json();
|
|
@@ -547,6 +564,7 @@ ${color("bold", "Common flags:")}
|
|
|
547
564
|
-q, --quiet Print only the numeric score
|
|
548
565
|
--watch [seconds] Poll every N seconds (default 300) and report changes
|
|
549
566
|
--webhook <url> POST scan results to a URL (one-shot or each watch tick)
|
|
567
|
+
--fresh Bypass server cache, force a fresh scan (subject to 20/hr per-IP cap)
|
|
550
568
|
|
|
551
569
|
${color("bold", "Subcommand-specific:")}
|
|
552
570
|
pqcheck deps:
|