Allow users to opt-in to spaces that strip signatures

This commit is contained in:
Jon Staab
2025-09-03 09:02:54 -07:00
parent a94883089e
commit 99defc6d79
13 changed files with 281 additions and 58 deletions
+2 -2
View File
@@ -49,7 +49,7 @@
import ThunkToast from "@app/components/ThunkToast.svelte"
import {
INDEXER_RELAYS,
userSettingValues,
userSettingsValues,
deriveChat,
splitChatId,
PLATFORM_NAME,
@@ -130,7 +130,7 @@
const template = templates[i]
thunks.push(
await sendWrapped({pubkeys, template, delay: $userSettingValues.send_delay + ms(i)}),
await sendWrapped({pubkeys, template, delay: $userSettingsValues.send_delay + ms(i)}),
)
}
+3 -3
View File
@@ -31,7 +31,7 @@
import ContentQuote from "@app/components/ContentQuote.svelte"
import ContentTopic from "@app/components/ContentTopic.svelte"
import ContentMention from "@app/components/ContentMention.svelte"
import {entityLink, userSettingValues} from "@app/core/state"
import {entityLink, userSettingsValues} from "@app/core/state"
interface Props {
event: any
@@ -68,7 +68,7 @@
if (!parsed || hideMediaAtDepth <= depth) return false
if (isLink(parsed) && $userSettingValues.show_media && isStartOrEnd(i)) {
if (isLink(parsed) && $userSettingsValues.show_media && isStartOrEnd(i)) {
return true
}
@@ -101,7 +101,7 @@
}
let warning = $state(
$userSettingValues.hide_sensitive && event.tags.find(nthEq(0, "content-warning"))?.[1],
$userSettingsValues.hide_sensitive && event.tags.find(nthEq(0, "content-warning"))?.[1],
)
const shortContent = $derived(
+32
View File
@@ -0,0 +1,32 @@
<script lang="ts">
import Link from "@lib/components/Link.svelte"
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
const back = () => history.back()
</script>
<div class="column gap-4">
<ModalHeader>
{#snippet title()}
<div>What are digital signatures?</div>
{/snippet}
</ModalHeader>
<p>
Most online services ask their users to trust them that they're being honest, and they usually
are. However, traditional social media platforms have the ability to <strong
>create forged content</strong> that can appear to be genuinely authored, but which are actually
counterfeit.
</p>
<p>
On <Link external href="https://nostr.com/">Nostr</Link>, all your content is authenticated
using <strong>digital signatures</strong>, which cryptographically tie a particular person to a
given post or message.
</p>
<p>
The result is that you don't normally have to trust service providers not to tamper with the
information flowing through the network — instead, your client software can prove that a given
piece of data is authentic.
</p>
<Button class="btn btn-primary" onclick={back}>Got it</Button>
</div>
+2 -1
View File
@@ -7,7 +7,7 @@
import Icon from "@lib/components/Icon.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {removeSpaceMembership} from "@app/core/commands"
import {removeSpaceMembership, removeTrustedRelay} from "@app/core/commands"
const {url} = $props()
@@ -18,6 +18,7 @@
try {
await removeSpaceMembership(url)
await removeTrustedRelay(url)
} finally {
loading = false
}
+86
View File
@@ -0,0 +1,86 @@
<script lang="ts">
import {goto} from "$app/navigation"
import {remove} from "@welshman/lib"
import {displayRelayUrl} from "@welshman/util"
import {preventDefault} from "@lib/html"
import Icon from "@lib/components/Icon.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import InfoSignatures from "@app/components/InfoSignatures.svelte"
import {relaysPendingTrust} from "@app/core/state"
import {removeSpaceMembership, addTrustedRelay, removeTrustedRelay} from "@app/core/commands"
import {pushModal} from "@app/util/modal"
type Props = {
url: string
}
const {url}: Props = $props()
const showInfoSignatures = () => pushModal(InfoSignatures)
const untrustSpace = async () => {
loading = true
try {
await removeSpaceMembership(url)
await removeTrustedRelay(url)
goto("/")
} finally {
loading = false
}
}
const trustSpace = async () => {
loading = true
try {
await addTrustedRelay(url)
relaysPendingTrust.update($r => remove(url, $r))
} finally {
loading = false
}
}
let loading = $state(false)
</script>
<form class="column gap-4" onsubmit={preventDefault(trustSpace)}>
<ModalHeader>
{#snippet title()}
Do you trust this space?
{/snippet}
{#snippet info()}
<div>
Only join <span class="text-primary">{displayRelayUrl(url)}</span> if you trust the adminstrator
</div>
{/snippet}
</ModalHeader>
<div class="m-auto flex flex-col gap-4">
<p>
This space has opted not to publish <Button class="link" onclick={showInfoSignatures}
>digital signatures</Button
>, which means that they have the ability to forge messages from other users.
</p>
<p>
If you trust this space's admin, you can continue. Otherwise, it may be safer not to join this
space.
</p>
</div>
<div class="mt-4 flex flex-col gap-2 sm:flex-row sm:justify-between">
<Button class="btn btn-neutral" onclick={untrustSpace} disabled={loading}>
{#if !loading}
<Icon icon="close-circle" />
{/if}
<Spinner {loading}>I don't trust this space</Spinner>
</Button>
<Button type="submit" class="btn btn-primary" disabled={loading}>
{#if !loading}
<Icon icon="check-circle" />
{/if}
<Spinner {loading}>I trust this space, continue</Spinner>
</Button>
</div>
</form>