From dd006badfc9e333d70ecd34f795165d6018ab80a Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Mon, 22 Sep 2025 14:05:57 -0700 Subject: [PATCH] Bring back blossom feature detection --- .env.template | 1 + src/app/core/commands.ts | 49 ++++++++++++++++++++++-- src/app/core/state.ts | 2 + src/app/editor/index.ts | 2 +- src/routes/spaces/[relay]/+layout.svelte | 4 ++ 5 files changed, 53 insertions(+), 5 deletions(-) diff --git a/.env.template b/.env.template index 95f36d0..2bcd2b2 100644 --- a/.env.template +++ b/.env.template @@ -1,4 +1,5 @@ VITE_DEFAULT_PUBKEYS=06639a386c9c1014217622ccbcf40908c4f1a0c33e23f8d6d68f4abf655f8f71,266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5,391819e2f2f13b90cac7209419eb574ef7c0d1f4e81867fc24c47a3ce5e8a248,3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d,3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24,55f04590674f3648f4cdc9dc8ce32da2a282074cd0b020596ee033d12d385185,58c741aa630c2da35a56a77c1d05381908bd10504fdd2d8b43f725efa6d23196,61066504617ee79387021e18c89fb79d1ddbc3e7bff19cf2298f40466f8715e9,6389be6491e7b693e9f368ece88fcd145f07c068d2c1bbae4247b9b5ef439d32,63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed,6e75f7972397ca3295e0f4ca0fbc6eb9cc79be85bafdd56bd378220ca8eee74e,76c71aae3a491f1d9eec47cba17e229cda4113a0bbb6e6ae1776d7643e29cafa,7fa56f5d6962ab1e3cd424e758c3002b8665f7b0d8dcee9fe9e288d7751ac194,82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2,84dee6e676e5bb67b4ad4e042cf70cbd8681155db535942fcc6a0533858a7240,97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322,b676ded7c768d66a757aa3967b1243d90bf57afb09d1044d3219d8d424e4aea0,dace63b00c42e6e017d00dd190a9328386002ff597b841eb5ef91de4f1ce8491,eeb11961b25442b16389fe6c7ebea9adf0ac36dd596816ea7119e521b8821b9e,fe7f6bc6f7338b76bbf80db402ade65953e20b2f23e66e898204b63cc42539a3 +VITE_DEFAULT_BLOSSOM_SERVERS=https://blossom.primal.net/ VITE_BURROW_URL= VITE_PLATFORM_URL=https://flotilla.social VITE_PLATFORM_TERMS=https://flotilla.social/terms diff --git a/src/app/core/commands.ts b/src/app/core/commands.ts index cc27aba..f607f8d 100644 --- a/src/app/core/commands.ts +++ b/src/app/core/commands.ts @@ -3,6 +3,7 @@ import * as nip19 from "nostr-tools/nip19" import {get} from "svelte/store" import type {Override, MakeOptional} from "@welshman/lib" import { + first, sha256, randomId, append, @@ -16,6 +17,8 @@ import { parseJson, fromPairs, last, + simpleCache, + normalizeUrl, } from "@welshman/lib" import {decrypt, Nip01Signer} from "@welshman/signer" import type {UploadTask} from "@welshman/editor" @@ -57,6 +60,7 @@ import { getTagValue, getTagValues, uploadBlob, + canUploadBlob, encryptFile, makeBlossomAuthEvent, } from "@welshman/util" @@ -92,6 +96,7 @@ import { INDEXER_RELAYS, NOTIFIER_PUBKEY, NOTIFIER_RELAY, + DEFAULT_BLOSSOM_SERVERS, userRoomsByUrl, userSettingsValues, canDecrypt, @@ -660,17 +665,53 @@ export const enableGiftWraps = () => { // File upload -export const getBlossomServer = () => { +export const normalizeBlossomUrl = (url: string) => normalizeUrl(url.replace(/^ws/, "http")) + +export const hasBlossomSupport = simpleCache(async ([url]: [string]) => { + const server = normalizeBlossomUrl(url) + const $signer = signer.get() || Nip01Signer.ephemeral() + const headers: Record = { + "X-Content-Type": "text/plain", + "X-Content-Length": "1", + "X-SHA-256": "73cb3858a687a8494ca3323053016282f3dad39d42cf62ca4e79dda2aac7d9ac", + } + + try { + const authEvent = await $signer.sign(makeBlossomAuthEvent({action: "upload", server})) + const res = await canUploadBlob(server, {authEvent, headers}) + + return res.status === 200 + } catch (e) { + if (!String(e).match(/Failed to fetch|NetworkError/)) { + console.error(e) + } + } + + return false +}) + +export type GetBlossomServerOptions = { + url?: string +} + +export const getBlossomServer = async (options: GetBlossomServerOptions = {}) => { + if (options.url) { + if (await hasBlossomSupport(options.url)) { + return normalizeBlossomUrl(options.url) + } + } + const userUrls = getTagValues("server", getListTags(userBlossomServers.get())) for (const url of userUrls) { - return url.replace(/^ws/, "http") + return normalizeBlossomUrl(url) } - return "https://cdn.satellite.earth" + return first(DEFAULT_BLOSSOM_SERVERS)! } export type UploadFileOptions = { + url?: string encrypt?: boolean } @@ -703,7 +744,7 @@ export const uploadFile = async (file: File, options: UploadFileOptions = {}) => }) } - const server = getBlossomServer() + const server = await getBlossomServer(options) const hashes = [await sha256(await file.arrayBuffer())] const $signer = signer.get() || Nip01Signer.ephemeral() const authTemplate = makeBlossomAuthEvent({action: "upload", server, hashes}) diff --git a/src/app/core/state.ts b/src/app/core/state.ts index 4b124f5..aef205d 100644 --- a/src/app/core/state.ts +++ b/src/app/core/state.ts @@ -140,6 +140,8 @@ export const PLATFORM_ACCENT = import.meta.env.VITE_PLATFORM_ACCENT export const PLATFORM_DESCRIPTION = import.meta.env.VITE_PLATFORM_DESCRIPTION +export const DEFAULT_BLOSSOM_SERVERS = fromCsv(import.meta.env.VITE_DEFAULT_BLOSSOM_SERVERS) + export const BURROW_URL = import.meta.env.VITE_BURROW_URL export const DEFAULT_PUBKEYS = import.meta.env.VITE_DEFAULT_PUBKEYS diff --git a/src/app/editor/index.ts b/src/app/editor/index.ts index f7f140b..e8c1d03 100644 --- a/src/app/editor/index.ts +++ b/src/app/editor/index.ts @@ -51,7 +51,7 @@ export const makeEditor = async ({ }, fileUpload: { config: { - upload: (attrs: FileAttributes) => uploadFile(attrs.file, {encrypt: true}), + upload: (attrs: FileAttributes) => uploadFile(attrs.file, {url, encrypt: true}), onDrop: () => uploading?.set(true), onComplete: () => uploading?.set(false), onUploadError(currentEditor, task) { diff --git a/src/routes/spaces/[relay]/+layout.svelte b/src/routes/spaces/[relay]/+layout.svelte index 5c2d0e4..4c5d541 100644 --- a/src/routes/spaces/[relay]/+layout.svelte +++ b/src/routes/spaces/[relay]/+layout.svelte @@ -22,6 +22,7 @@ userRoomsByUrl, } from "@app/core/state" import {pullConservatively} from "@app/core/requests" + import {hasBlossomSupport} from "@app/core/commands" import {notifications} from "@app/util/notifications" type Props = { @@ -66,6 +67,9 @@ } }) + // Prime our cache so we can upload images quicker + hasBlossomSupport(url) + // Load group meta, threads, calendar events, comments, and recent messages // for user rooms to help with a quick page transition pullConservatively({