Authenticate a relay as soon as the user's lists name it
This commit is contained in:
parent
f67ea6fb36
commit
a50b0160bd
1 changed files with 55 additions and 13 deletions
|
|
@ -1,8 +1,10 @@
|
||||||
import {get, writable} from "svelte/store"
|
import {get, writable} from "svelte/store"
|
||||||
import {on, call, dissoc, assoc, uniq} from "@welshman/lib"
|
import {on, call, dissoc, assoc, noop, uniq} from "@welshman/lib"
|
||||||
import {isDVMKind, isEphemeralKind, verifyEvent} from "@welshman/util"
|
import {isDVMKind, isEphemeralKind, verifyEvent} from "@welshman/util"
|
||||||
import type {Socket, RelayMessage, ClientMessage} from "@welshman/net"
|
import type {Socket, RelayMessage, ClientMessage} from "@welshman/net"
|
||||||
import {
|
import {
|
||||||
|
AuthStateEvent,
|
||||||
|
AuthStatus,
|
||||||
SocketEvent,
|
SocketEvent,
|
||||||
isRelayEvent,
|
isRelayEvent,
|
||||||
isRelayOk,
|
isRelayOk,
|
||||||
|
|
@ -16,16 +18,10 @@ import {
|
||||||
matchReason,
|
matchReason,
|
||||||
RelayReasonPrefix,
|
RelayReasonPrefix,
|
||||||
} from "@welshman/net"
|
} from "@welshman/net"
|
||||||
import {
|
import {BlockedRelayLists, MessagingRelayLists, RelayLists, RoomLists, Thunks} from "@welshman/app"
|
||||||
BlockedRelayLists,
|
|
||||||
MessagingRelayLists,
|
|
||||||
RelayLists,
|
|
||||||
RoomLists,
|
|
||||||
Thunks,
|
|
||||||
makeAppPolicyAuth,
|
|
||||||
} from "@welshman/app"
|
|
||||||
import type {AppPolicy, IApp} from "@welshman/app"
|
import type {AppPolicy, IApp} from "@welshman/app"
|
||||||
import {app, logger, appPolicies} from "@app/core"
|
import {merged} from "@welshman/store"
|
||||||
|
import {logger, appPolicies} from "@app/core"
|
||||||
import {BLOCKED_RELAYS} from "@app/env"
|
import {BLOCKED_RELAYS} from "@app/env"
|
||||||
import {userSettingsValues, getSetting, RelayAuthMode} from "@app/settings"
|
import {userSettingsValues, getSetting, RelayAuthMode} from "@app/settings"
|
||||||
|
|
||||||
|
|
@ -63,8 +59,8 @@ export const ingestPolicy: AppPolicy = app =>
|
||||||
|
|
||||||
// Welshman's appPolicyAuthUnlessBlocked, plus the conservative mode: only identify to relays
|
// Welshman's appPolicyAuthUnlessBlocked, plus the conservative mode: only identify to relays
|
||||||
// the user already has a relationship with.
|
// the user already has a relationship with.
|
||||||
export const authPolicy = makeAppPolicyAuth((socket, $app) => {
|
const shouldAuth = (socket: Socket, $app: IApp) => {
|
||||||
const $pubkey = app.get().user?.pubkey
|
const $pubkey = $app.user?.pubkey
|
||||||
|
|
||||||
if (!$pubkey) {
|
if (!$pubkey) {
|
||||||
return false
|
return false
|
||||||
|
|
@ -89,7 +85,53 @@ export const authPolicy = makeAppPolicyAuth((socket, $app) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
})
|
}
|
||||||
|
|
||||||
|
// Everything `shouldAuth` reads, so a socket can ask it again when the answer changes.
|
||||||
|
const makeAuthInputs = ($app: IApp, pubkey: string) =>
|
||||||
|
merged([
|
||||||
|
$app.use(BlockedRelayLists).urls(pubkey).$,
|
||||||
|
$app.use(MessagingRelayLists).urls(pubkey).$,
|
||||||
|
$app.use(RelayLists).urls(pubkey).$,
|
||||||
|
$app.use(RoomLists).urls(pubkey).$,
|
||||||
|
$app.use(Thunks).history,
|
||||||
|
userSettingsValues,
|
||||||
|
])
|
||||||
|
|
||||||
|
// Welshman asks whether to authenticate once, when the challenge arrives. On a first login the
|
||||||
|
// user's lists have not loaded by then, so a space they open answers "no relationship" and stays
|
||||||
|
// unauthenticated for as long as the relay repeats the challenge it already sent. Ask again
|
||||||
|
// whenever one of those lists changes.
|
||||||
|
export const authPolicy: AppPolicy = $app => {
|
||||||
|
const $user = $app.user
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
return noop
|
||||||
|
}
|
||||||
|
|
||||||
|
const authInputs = makeAuthInputs($app, $user.pubkey)
|
||||||
|
|
||||||
|
const policy = (socket: Socket) => {
|
||||||
|
const attemptAuth = () => {
|
||||||
|
if (socket.auth.status === AuthStatus.Requested && shouldAuth(socket, $app)) {
|
||||||
|
socket.auth.doAuth($user.sign)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsubscribers = [
|
||||||
|
on(socket.auth, AuthStateEvent.Status, attemptAuth),
|
||||||
|
authInputs.subscribe(attemptAuth),
|
||||||
|
]
|
||||||
|
|
||||||
|
return () => unsubscribers.forEach(call)
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.pool.socketPolicies.push(policy)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
$app.pool.socketPolicies = $app.pool.socketPolicies.filter(p => p !== policy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const makeBlockPolicy = ($app: IApp) => (socket: Socket) => {
|
const makeBlockPolicy = ($app: IApp) => (socket: Socket) => {
|
||||||
const previousOpen = socket.open
|
const previousOpen = socket.open
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue