← back to Domain Sniper
register: refuse re-registration of domains in data/owned.json (exit 5)
ed0c01ff6594dd20ef8cf1ab06323a032fc39cec · 2026-05-12 18:32:48 -0700 · steve
Audit of register.js found DRY-RUN default, validated domain regex,
and no availability-leak codepath — all clean. One gap: the README
calls owned.json the single-source-of-truth for 'what we already
grabbed' but register.js was not actually consulting it.
Added alreadyOwned() check that loads data/owned.json (tolerates
either ["d.com",…] or {domains:[…]} shape, gracefully no-ops when
the file is absent). Hits before backend detection so a typo'd
re-register attempt fails fast with exit 5 — distinct from the
existing exit codes (2 usage, 3 no-creds, 4 reg-failed).
Verified: owned → exit 5 with red REFUSED banner; fresh → normal flow.
Files touched
Diff
commit ed0c01ff6594dd20ef8cf1ab06323a032fc39cec
Author: steve <steve@designerwallcoverings.com>
Date: Tue May 12 18:32:48 2026 -0700
register: refuse re-registration of domains in data/owned.json (exit 5)
Audit of register.js found DRY-RUN default, validated domain regex,
and no availability-leak codepath — all clean. One gap: the README
calls owned.json the single-source-of-truth for 'what we already
grabbed' but register.js was not actually consulting it.
Added alreadyOwned() check that loads data/owned.json (tolerates
either ["d.com",…] or {domains:[…]} shape, gracefully no-ops when
the file is absent). Hits before backend detection so a typo'd
re-register attempt fails fast with exit 5 — distinct from the
existing exit codes (2 usage, 3 no-creds, 4 reg-failed).
Verified: owned → exit 5 with red REFUSED banner; fresh → normal flow.
---
register.js | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/register.js b/register.js
index 181542a..660c7f6 100644
--- a/register.js
+++ b/register.js
@@ -23,6 +23,20 @@ const path = require('path');
const DATA_DIR = path.join(__dirname, 'data');
const LOG_FILE = path.join(DATA_DIR, 'registrations.jsonl');
+const OWNED_FILE = path.join(DATA_DIR, 'owned.json');
+
+// Defensive: never re-register a domain Steve already owns. data/owned.json
+// is the single-source-of-truth list per the README. File may not exist yet —
+// in that case there's nothing to compare against, so allow the registration.
+function alreadyOwned(domain) {
+ if (!fs.existsSync(OWNED_FILE)) return false;
+ try {
+ const j = JSON.parse(fs.readFileSync(OWNED_FILE, 'utf8'));
+ const list = Array.isArray(j) ? j : (Array.isArray(j.domains) ? j.domains : []);
+ const target = domain.toLowerCase();
+ return list.some((d) => typeof d === 'string' && d.toLowerCase() === target);
+ } catch { return false; }
+}
function detectBackend() {
if (process.env.NAMESILO_API_KEY) return 'namesilo';
@@ -112,6 +126,11 @@ async function main() {
console.error(`invalid domain syntax: ${domain}`);
process.exit(2);
}
+ if (alreadyOwned(domain)) {
+ console.error(`\n \x1b[31mREFUSED:\x1b[0m ${domain} is in data/owned.json — already owned.`);
+ console.error(` Remove it from owned.json first if you really intend to re-register.\n`);
+ process.exit(5);
+ }
const backend = detectBackend();
← d315f31 ct-source-certspotter: mark both adapters STALLED with react
·
back to Domain Sniper
·
owned-check: extract shared module + extend safety to honeyp 46c5487 →