Support auth-protected images
This commit is contained in:
@@ -141,7 +141,7 @@
|
||||
<ContentToken value={parsed.value} />
|
||||
{:else if isLink(parsed)}
|
||||
{#if isBlock(i)}
|
||||
<ContentLinkBlock value={parsed.value} />
|
||||
<ContentLinkBlock value={parsed.value} {event} />
|
||||
{:else}
|
||||
<ContentLinkInline value={parsed.value} />
|
||||
{/if}
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
import {preventDefault, stopPropagation} from "@lib/html"
|
||||
import Link from "@lib/components/Link.svelte"
|
||||
import ContentLinkDetail from "@app/components/ContentLinkDetail.svelte"
|
||||
import ContentLinkBlockImage from "@app/components/ContentLinkBlockImage.svelte"
|
||||
import {pushModal} from "@app/modal"
|
||||
|
||||
const {value} = $props()
|
||||
const {value, event} = $props()
|
||||
|
||||
let hideImage = $state(false)
|
||||
|
||||
@@ -37,7 +38,7 @@
|
||||
</video>
|
||||
{:else if url.match(/\.(jpe?g|png|gif|webp)$/)}
|
||||
<button type="button" onclick={stopPropagation(preventDefault(expand))}>
|
||||
<img alt="Link preview" src={imgproxy(url)} class="m-auto max-h-96 rounded-box" />
|
||||
<ContentLinkBlockImage {event} {value} />
|
||||
</button>
|
||||
{:else}
|
||||
{#await loadPreview()}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<script lang="ts">
|
||||
import {onDestroy} from "svelte"
|
||||
import {now} from "@welshman/lib"
|
||||
import {BLOSSOM_AUTH, makeEvent, getTags, getTagValue, tagsFromIMeta} from "@welshman/util"
|
||||
import {signer} from "@welshman/app"
|
||||
import {imgproxy} from "@app/state"
|
||||
|
||||
const {value, event} = $props()
|
||||
|
||||
const url = value.url.toString()
|
||||
|
||||
// If we fail to fetch the image, try authenticating if we have a blossom hash
|
||||
const onerror = async () => {
|
||||
const meta = getTags("imeta", event.tags)
|
||||
.map(tagsFromIMeta)
|
||||
.find(meta => getTagValue("url", meta) === url)
|
||||
const hash = meta ? getTagValue("x", meta) : undefined
|
||||
|
||||
if (hash && $signer) {
|
||||
const event = await signer.get().sign(
|
||||
makeEvent(BLOSSOM_AUTH, {
|
||||
tags: [
|
||||
["t", "get"],
|
||||
["x", hash],
|
||||
["expiration", String(now() + 30)],
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
Authorization: `Nostr ${btoa(JSON.stringify(event))}`,
|
||||
},
|
||||
})
|
||||
|
||||
if (res.status === 200) {
|
||||
src = URL.createObjectURL(await res.blob())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let src = $state(imgproxy(url))
|
||||
|
||||
onDestroy(() => {
|
||||
URL.revokeObjectURL(src)
|
||||
})
|
||||
</script>
|
||||
|
||||
<img alt="" {src} {onerror} class="m-auto max-h-96 rounded-box" />
|
||||
+4
-1
@@ -41,6 +41,7 @@ import {
|
||||
loadMutes,
|
||||
loadFollows,
|
||||
loadProfile,
|
||||
loadRelaySelections,
|
||||
loadInboxRelaySelections,
|
||||
} from "@welshman/app"
|
||||
import {createScroller} from "@lib/html"
|
||||
@@ -384,7 +385,9 @@ export const listenForNotifications = () => {
|
||||
return () => controller.abort()
|
||||
}
|
||||
|
||||
export const loadUserData = (pubkey: string, relays: string[] = []) => {
|
||||
export const loadUserData = async (pubkey: string, relays: string[] = []) => {
|
||||
await Promise.race([sleep(3000), loadRelaySelections(pubkey, relays)])
|
||||
|
||||
const promise = Promise.race([
|
||||
sleep(3000),
|
||||
Promise.all([
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ export const IMGPROXY_URL = "https://imgproxy.coracle.social"
|
||||
export const REACTION_KINDS = [REACTION, ZAP_RESPONSE]
|
||||
|
||||
export const NIP46_PERMS =
|
||||
"nip04_encrypt,nip04_decrypt,nip44_encrypt,nip44_decrypt," +
|
||||
"nip44_encrypt,nip44_decrypt," +
|
||||
[CLIENT_AUTH, AUTH_JOIN, MESSAGE, THREAD, COMMENT, GROUPS, WRAP, REACTION]
|
||||
.map(k => `sign_event:${k}`)
|
||||
.join(",")
|
||||
|
||||
@@ -18,16 +18,17 @@
|
||||
|
||||
const onsubmit = preventDefault(async () => {
|
||||
const json = JSON.stringify($state.snapshot(settings))
|
||||
const content = await $signer!.nip04.encrypt($pubkey!, json)
|
||||
const content = await $signer!.nip44.encrypt($pubkey!, json)
|
||||
const relays = Router.get().FromUser().getUrls()
|
||||
|
||||
publishThunk({
|
||||
event: createEvent(SETTINGS, {content}),
|
||||
relays: Router.get().FromUser().getUrls(),
|
||||
relays,
|
||||
})
|
||||
|
||||
publishThunk({
|
||||
event: createEvent(MUTES, {tags: mutedPubkeys.map(tagPubkey)}),
|
||||
relays: Router.get().FromUser().getUrls(),
|
||||
relays,
|
||||
})
|
||||
|
||||
pushToast({message: "Your settings have been saved!"})
|
||||
|
||||
Reference in New Issue
Block a user