feat(forms): validate submitter npub on submission forms (#22)

The embed submission forms accepted any free-text identifier and published it,
so they were an easy spam vector. Add a shared, testable NIP-19 validator and
require a well-formed npub before a submission is sent.

- js/utils/validateNpub.js: validateNpubHex() decodes via nostr-tools nip19 and
  returns the 64-char hex pubkey, or null for anything that isn't a real npub
  (free text, wrong prefix, bad checksum, wrong NIP-19 entity). Also exposed as
  window.validateNpubHex for the classic iframe form scripts.
- Application form (required npub): submit is blocked unless valid; the decoded
  hex is written into the application body for canonical storage/matching.
- Feature-request / bug-fix / feedback (optional npub): stays optional, but a
  non-empty value must be a valid npub or submit is blocked with an inline error.
- Tests: tests/validate-npub.test.mjs (real nostr-tools, no implementation mirror).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-25 08:31:45 -04:00
1 parent fdcf034464
commit e4e5c552c7
7 files changed
+203 -5

No files matched your search

+16 -5
View File
@@ -414,11 +414,22 @@ toward freshness and looked identical. Gave each a structural identity:
Source still to pin: the loop issuing 30000/30002/30005/30015 per contact.
### 22. Anti-spam: validate npub on application / submission forms
- [ ] Application/submission forms accept too much spam. Require the submitter's
identifier to be a valid `npub` (NIP-19) — regex/decoder validation client-side
so submission only succeeds for a well-formed npub (and normalize to hex for
storage). Reject/disable submit otherwise with a clear inline error. Pairs with
#23 (the submissions should become structured data, not DMs).
- [x] **DONE 2026-06-24.** Added a shared, testable NIP-19 validator
(`js/utils/validateNpub.js`, exposes `window.validateNpubHex`) and wired it
into all four embed submission forms (`components/iframe_forms/`):
- **Application** (`applicantNpub`, required): submit is blocked unless the
npub decodes to a 64-char hex pubkey; the hex is also written into the
application body for canonical storage/whitelist matching.
- **Feature-request / bug-fix / feedback** (`userNpub`, optional): the npub
stays optional, but a non-empty value must be a valid npub or submit is
blocked with a clear inline error.
Validation decodes via the real nostr-tools `nip19` (checksum + prefix +
hex shape), so spam/free-text/`note1…`/tampered npubs are rejected.
Unit tests: `tests/validate-npub.test.mjs` (real nostr-tools). Pairs with #23
(submissions should become structured data, not DMs).
- [ ] **VERIFY live**: open each form embed — application rejects a junk npub and
only sends with a valid npub1…; the optional forms send when the npub is
blank but reject a malformed one.
### 23. Admin submissions tab — structured submissions + approve/deny UI (SCALING)
- [ ] Replace the current DM-based submission flow with **custom structured data**