mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 19:07:06 +00:00
Tweak access terminology, relay access attempts
This commit is contained in:
@@ -170,26 +170,38 @@
|
|||||||
</FieldInline>
|
</FieldInline>
|
||||||
<FieldInline>
|
<FieldInline>
|
||||||
{#snippet label()}
|
{#snippet label()}
|
||||||
<p>Access Control</p>
|
<strong>Restricted</strong>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
{#snippet input()}
|
{#snippet input()}
|
||||||
<div class="flex items-center justify-end gap-4">
|
<input type="checkbox" class="checkbox" bind:checked={values.isRestricted} />
|
||||||
<span class="flex gap-3">
|
<span class="text-sm opacity-75">Only allow members to send messages</span>
|
||||||
<input type="checkbox" class="checkbox" bind:checked={values.isClosed} />
|
|
||||||
Closed
|
|
||||||
</span>
|
|
||||||
<span class="flex gap-3">
|
|
||||||
<input type="checkbox" class="checkbox" bind:checked={values.isPrivate} />
|
|
||||||
Private
|
|
||||||
</span>
|
|
||||||
<span class="flex gap-3">
|
|
||||||
<input type="checkbox" class="checkbox" bind:checked={values.isHidden} />
|
|
||||||
Hidden
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{/snippet}
|
{/snippet}
|
||||||
{#snippet info()}
|
</FieldInline>
|
||||||
<p>Only members can send messages to closed groups and read messages from private groups.</p>
|
<FieldInline>
|
||||||
|
{#snippet label()}
|
||||||
|
<strong>Private</strong>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet input()}
|
||||||
|
<input type="checkbox" class="checkbox" bind:checked={values.isPrivate} />
|
||||||
|
<span class="text-sm opacity-75">Only allow members to read messages</span>
|
||||||
|
{/snippet}
|
||||||
|
</FieldInline>
|
||||||
|
<FieldInline>
|
||||||
|
{#snippet label()}
|
||||||
|
<strong>Hidden</strong>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet input()}
|
||||||
|
<input type="checkbox" class="checkbox" bind:checked={values.isHidden} />
|
||||||
|
<span class="text-sm opacity-75">Hide this group from non-members</span>
|
||||||
|
{/snippet}
|
||||||
|
</FieldInline>
|
||||||
|
<FieldInline>
|
||||||
|
{#snippet label()}
|
||||||
|
<strong>Closed</strong>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet input()}
|
||||||
|
<input type="checkbox" class="checkbox" bind:checked={values.isClosed} />
|
||||||
|
<span class="text-sm opacity-75">Ignore requests to join</span>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</FieldInline>
|
</FieldInline>
|
||||||
{@render footer({loading})}
|
{@render footer({loading})}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
import SpaceJoinConfirm, {confirmSpaceJoin} from "@app/components/SpaceJoinConfirm.svelte"
|
import SpaceJoinConfirm, {confirmSpaceJoin} from "@app/components/SpaceJoinConfirm.svelte"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
import {checkRelayAccess} from "@app/core/commands"
|
import {attemptRelayAccess} from "@app/core/commands"
|
||||||
import {deriveSocket} from "@app/core/state"
|
import {deriveSocket} from "@app/core/state"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const message = await checkRelayAccess(url, claim)
|
const message = await attemptRelayAccess(url, claim)
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
return pushToast({theme: "error", message, timeout: 30_000})
|
return pushToast({theme: "error", message, timeout: 30_000})
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ import {
|
|||||||
userRelaySelections,
|
userRelaySelections,
|
||||||
userInboxRelaySelections,
|
userInboxRelaySelections,
|
||||||
nip44EncryptToSelf,
|
nip44EncryptToSelf,
|
||||||
loadRelay,
|
|
||||||
dropSession,
|
dropSession,
|
||||||
tagEventForComment,
|
tagEventForComment,
|
||||||
tagEventForQuote,
|
tagEventForQuote,
|
||||||
@@ -264,43 +263,7 @@ export const canEnforceNip70 = async (url: string) => {
|
|||||||
return socket.auth.status !== AuthStatus.None
|
return socket.auth.status !== AuthStatus.None
|
||||||
}
|
}
|
||||||
|
|
||||||
export const checkRelayAccess = async (url: string, claim = "") => {
|
export const attemptRelayAccess = async (url: string, claim = "") => {
|
||||||
const socket = Pool.get().get(url)
|
|
||||||
|
|
||||||
await attemptAuth(url)
|
|
||||||
|
|
||||||
const thunk = publishJoinRequest({url, claim})
|
|
||||||
const error = await waitForThunkError(thunk)
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
const message =
|
|
||||||
socket.auth.details?.replace(/^\w+: /, "") ||
|
|
||||||
error.replace(/^\w+: /, "") ||
|
|
||||||
"join request rejected"
|
|
||||||
|
|
||||||
// If it's a strict NIP 29 relay don't worry about requesting access
|
|
||||||
// TODO: remove this if relay29 ever gets less strict
|
|
||||||
if (message === "missing group (`h`) tag") return
|
|
||||||
|
|
||||||
// Ignore messages about the relay ignoring ours
|
|
||||||
if (error?.startsWith("mute: ")) return
|
|
||||||
|
|
||||||
// Ignore rejected empty claims
|
|
||||||
if (!claim && error?.includes("invite code")) return
|
|
||||||
|
|
||||||
return message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const checkRelayProfile = async (url: string) => {
|
|
||||||
const relay = await loadRelay(url)
|
|
||||||
|
|
||||||
if (!relay) {
|
|
||||||
return "Sorry, we weren't able to find that relay."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const checkRelayConnection = async (url: string) => {
|
|
||||||
const socket = Pool.get().get(url)
|
const socket = Pool.get().get(url)
|
||||||
|
|
||||||
socket.attemptToOpen()
|
socket.attemptToOpen()
|
||||||
@@ -313,39 +276,30 @@ export const checkRelayConnection = async (url: string) => {
|
|||||||
if (socket.status !== SocketStatus.Open) {
|
if (socket.status !== SocketStatus.Open) {
|
||||||
return `Failed to connect`
|
return `Failed to connect`
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export const checkRelayAuth = async (url: string) => {
|
|
||||||
const socket = Pool.get().get(url)
|
|
||||||
const okStatuses = [AuthStatus.None, AuthStatus.Ok]
|
|
||||||
|
|
||||||
await attemptAuth(url)
|
await attemptAuth(url)
|
||||||
|
|
||||||
// Only raise an error if it's not a timeout.
|
// Only raise an error if it's not a timeout.
|
||||||
// If it is, odds are the problem is with our signer, not the relay
|
// If it is, odds are the problem is with our signer, not the relay
|
||||||
if (!okStatuses.includes(socket.auth.status)) {
|
if (![AuthStatus.None, AuthStatus.Ok].includes(socket.auth.status)) {
|
||||||
if (socket.auth.details) {
|
if (socket.auth.details) {
|
||||||
return `Failed to authenticate (${socket.auth.details})`
|
return `Failed to authenticate (${socket.auth.details})`
|
||||||
} else {
|
} else {
|
||||||
return `Failed to authenticate (${last(socket.auth.status.split(":"))})`
|
return `Failed to authenticate (${last(socket.auth.status.split(":"))})`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export const attemptRelayAccess = async (url: string, claim = "") => {
|
const thunk = publishJoinRequest({url, claim})
|
||||||
const checks = [
|
const error = await waitForThunkError(thunk)
|
||||||
() => checkRelayConnection(url),
|
|
||||||
() => checkRelayAccess(url, claim),
|
|
||||||
() => checkRelayAuth(url),
|
|
||||||
]
|
|
||||||
|
|
||||||
for (const check of checks) {
|
// Ignore messages about the relay ignoring our messages
|
||||||
const error = await check()
|
if (error?.startsWith("mute: ")) return
|
||||||
|
|
||||||
if (error) {
|
// If it's a strict NIP 29 relay don't worry about requesting access
|
||||||
return error
|
// TODO: remove this if relay29 ever gets less strict
|
||||||
}
|
if (error?.includes("missing group (`h`) tag")) return
|
||||||
}
|
|
||||||
|
return error?.replace(/^\w+: /, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deletions
|
// Deletions
|
||||||
|
|||||||
@@ -390,6 +390,7 @@
|
|||||||
<div class="py-20">
|
<div class="py-20">
|
||||||
<div class="card2 col-8 m-auto max-w-md items-center text-center">
|
<div class="card2 col-8 m-auto max-w-md items-center text-center">
|
||||||
<p class="opacity-75">You aren't currently a member of this room.</p>
|
<p class="opacity-75">You aren't currently a member of this room.</p>
|
||||||
|
{#if !$room?.isClosed}
|
||||||
{#if $membershipStatus === MembershipStatus.Pending}
|
{#if $membershipStatus === MembershipStatus.Pending}
|
||||||
<Button class="btn btn-neutral btn-sm" disabled={leaving} onclick={leave}>
|
<Button class="btn btn-neutral btn-sm" disabled={leaving} onclick={leave}>
|
||||||
<Icon icon={ClockCircle} />
|
<Icon icon={ClockCircle} />
|
||||||
@@ -405,6 +406,7 @@
|
|||||||
Join Room
|
Join Room
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -452,9 +454,10 @@
|
|||||||
<div class="chat__compose bg-base-200" bind:this={chatCompose}>
|
<div class="chat__compose bg-base-200" bind:this={chatCompose}>
|
||||||
{#if $room?.isPrivate && $membershipStatus !== MembershipStatus.Granted}
|
{#if $room?.isPrivate && $membershipStatus !== MembershipStatus.Granted}
|
||||||
<!-- pass -->
|
<!-- pass -->
|
||||||
{:else if $room?.isClosed && $membershipStatus !== MembershipStatus.Granted}
|
{:else if $room?.isRestricted && $membershipStatus !== MembershipStatus.Granted}
|
||||||
<div class="bg-alt card m-4 flex flex-row items-center justify-between px-4 py-3">
|
<div class="bg-alt card m-4 flex flex-row items-center justify-between px-4 py-3">
|
||||||
<p>Only members are allowed to post to this room.</p>
|
<p>Only members are allowed to post to this room.</p>
|
||||||
|
{#if !$room?.isClosed}
|
||||||
{#if $membershipStatus === MembershipStatus.Pending}
|
{#if $membershipStatus === MembershipStatus.Pending}
|
||||||
<Button class="btn btn-neutral btn-sm" disabled={leaving} onclick={leave}>
|
<Button class="btn btn-neutral btn-sm" disabled={leaving} onclick={leave}>
|
||||||
<Icon icon={ClockCircle} />
|
<Icon icon={ClockCircle} />
|
||||||
@@ -470,6 +473,7 @@
|
|||||||
Ask to Join
|
Ask to Join
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user