feat: configurable Nostr profile (kind 0) from the dashboard - #13
Merged
Conversation
- /dashboard/profile: edit name, display_name, about, picture, banner, website, nip05, lud16, lud06; prefilled from the stored kind 0 (columns + raw content JSON), unknown content keys preserved through config.extra - public/js/profile.js: build + sign client-side via NbreadSigner, mirror to /api/mirror, NIP-42 broadcast to editorRelays, NIP-55 redirect/resume, Blossom uploads for picture/banner - /api/mirror now accepts kind 0 (own-key only; same rate limit + blocked gates; single replaceable slot so no storage growth) - profiles.lud16 column (migration 0006) + upsertProfile parsing — the NIP-57 zaps prerequisite - suggested nip05 <handle>@nbread.lol; surfaced the settings-about override
… + __proto__ edge cases Adversarial review of the #11 diff confirmed four defects, all fixed: - NIP-24 deprecated aliases (displayName/username) no longer ride along in extra where they would fight every edit of the canonical field; they prefill the canonical field when it is absent and are dropped from the republish (NIP-24: ignored/removed when found in the wild) - prefill is now faithful (no trim/caps): republishing must not silently truncate over-cap values published elsewhere; caps still bound the D1 columns and the form maxlength still caps typing - the suggested nip05 only prefills a FIRST profile (prevCreatedAt null), so a deliberately removed nip05 is not resurrected by an unrelated save - extra (server) and the metadata object (client) are null-prototype, so a literal "__proto__" content key survives as data instead of vanishing into the inherited setter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #11.
What
Adds a /dashboard/profile page where a signed-in user edits and publishes their Nostr
kind 0profile metadata — name, display name, about, picture, banner, website, NIP-05, and thelud16lightning address (the NIP-57 zaps prerequisite, #12).src/views/main/profile.tsx+public/js/profile.js— form prefilled from the stored profile; the kind 0 is built and signed entirely client-side through the existingNbreadSigner(NIP-07/46/55/nsec), mirrored to/api/mirror, and broadcast toeditorRelays()with NIP-42 AUTH — the exacteditor.jspublish contract, including the NIP-55/Amber redirect-resume + no-resign retry flow. Blossom uploads are wired to the picture/banner fields./api/mirroraccepts kind 0 (option (a) from the issue): same session gate,ev.pubkey === sess.pubkeytenant isolation, rate limit, and blocked check;mirrorEventalready routed kind 0 toupsertProfile. TheMAX_POSTS_PER_PUBKEYcap stays 30023-only — kind 0 is a single replaceable slot and cannot grow storage.profiles.lud16+ parsing inupsertProfile(open question 4 → column, since zaps must read it on the render path).created_atasprevCreatedAt; the client publishes withmax(now, prev+1)so an edit always wins the(pubkey, 0, '')slot.config.extraand merged back on publish, so a save never erases custom metadata written by other clients. Prefill is faithful (no trim/caps — truncation would rewrite the canonical profile network-wide); caps still bound the D1 columns and form typing.displayName/username) prefill their canonical field when it's absent and are dropped from the republish, per NIP-24.<handle>@nbread.lolpre-fills only a first profile (never resurrects a deliberately removed nip05); shown as a hint otherwise. The settings-About-overrides-profile-bio relationship is surfaced next to the About field.Security
wss:, Blossom hosts); blog pages stay JS-free.<-escaped in a non-executable script tag,__proto__content keys kept as data via null-prototype objects on both sides.Tests
873 passing (14 new): page auth/prefill/XSS, kind-0 mirror accept + cross-key 403 + newest-wins + lud16 caps, storedProfileContent fidelity/alias/
__proto__cases, and the editor kind-guard update.