diff options
| author | Adam Soltys <[email protected]> | 2026-10-18 22:53:39 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-18 22:53:39 -0700 |
| commit | 31ef5c01527e110ed8a4faa500c72a1773586b50 (patch) | |
| tree | ea4f2bac0dffd74c574fc5309f46c5b0f085ad22 /src/media-upload.js | |
| parent | 15f3b1f80a5ed99e7d2db17e46318f4abe3797ce (diff) | |
| download | coinosv3-31ef5c01527e110ed8a4faa500c72a1773586b50.tar.gz coinosv3-31ef5c01527e110ed8a4faa500c72a1773586b50.zip | |
Sign media uploads with the user's Nostr login identity
Diffstat (limited to 'src/media-upload.js')
| -rw-r--r-- | src/media-upload.js | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/media-upload.js b/src/media-upload.js index d7a99e1..f851943 100644 --- a/src/media-upload.js +++ b/src/media-upload.js @@ -20,6 +20,16 @@ export class MediaUploadError extends Error { } } +// Private Blossom hosts authorize the user's Nostr identity, which can differ +// from the wallet's sync key. Resolve once for the whole upload (including HLS). +export async function mediaUploadSigner(wallet, hook) { + const id = hook('nostrLoginIdentity'); + if (!id) return (event) => wallet.nostrSign(event); + const signer = id.signer || await hook('nostrLoginResume'); + if (!signer) throw new MediaUploadError('no-identity'); + return (event) => signer.signEvent(event); +} + async function fileHash(file) { const hash = sha256.create(); const chunk = 4 * 1024 * 1024; @@ -64,7 +74,7 @@ function putWithProgress(url, { body, headers, signal }, onProgress) { } // BUD-02 upload. `signEvent` is deliberately injected: the app can use its -// always-available wallet identity, while tests need no secret key. +// signed-in Nostr identity, while tests need no secret key. export async function uploadPublicMedia(file, signEvent, { servers = mediaServers(PUBLIC_MEDIA_SERVERS), fetcher = globalThis.fetch, @@ -112,6 +122,7 @@ export async function uploadPublicMedia(file, signEvent, { } } const details = failures.map((x) => [x.status, x.reason].filter(Boolean).join(' ')).filter(Boolean).join('; '); + if (failures.length && failures.every((x) => x.status === 401 || x.status === 403)) throw new MediaUploadError('unauthorized', details); if (failures.length && failures.every((x) => x.status === 413)) throw new MediaUploadError('too-big', details); if (failures.length && failures.every((x) => x.status === 415)) throw new MediaUploadError('unsupported', details); throw new MediaUploadError('failed', details); |
