diff --git a/src/api/hooks/nostr/useBunker.ts b/src/api/hooks/nostr/useBunker.ts index f0213da22..2b5e8c433 100644 --- a/src/api/hooks/nostr/useBunker.ts +++ b/src/api/hooks/nostr/useBunker.ts @@ -1,28 +1,23 @@ import { NSecSigner } from '@nostrify/nostrify'; -import { nip19 } from 'nostr-tools'; import { useEffect, useState } from 'react'; import { useNostr } from 'soapbox/contexts/nostr-context'; import { NBunker, NBunkerOpts } from 'soapbox/features/nostr/NBunker'; import { NKeys } from 'soapbox/features/nostr/keys'; import { useAppSelector } from 'soapbox/hooks'; - -const secretStorageKey = 'soapbox:nip46:secret'; - -sessionStorage.setItem(secretStorageKey, crypto.randomUUID()); +import { useBunkerStore } from 'soapbox/hooks/useBunkerStore'; function useBunker() { const { relay } = useNostr(); + const { authorizations, connections } = useBunkerStore(); const [isSubscribed, setIsSubscribed] = useState(false); const [isSubscribing, setIsSubscribing] = useState(true); - const authorizations = useAppSelector((state) => state.bunker.authorizations); - const connection = useAppSelector((state) => { const accessToken = state.auth.tokens[state.auth.me!]?.access_token; if (accessToken) { - return state.bunker.connections.find((conn) => conn.accessToken === accessToken); + return connections.find((conn) => conn.accessToken === accessToken); } }); @@ -38,14 +33,11 @@ function useBunker() { const user = NKeys.get(pubkey) ?? window.nostr; if (!user) return; - const decoded = nip19.decode(bunkerSeckey); - if (decoded.type !== 'nsec') return; - return { authorizedPubkey, signers: { user, - bunker: new NSecSigner(decoded.data), + bunker: new NSecSigner(bunkerSeckey), }, }; })(), @@ -55,22 +47,16 @@ function useBunker() { const user = NKeys.get(pubkey) ?? window.nostr; if (!user) return result; - const decoded = nip19.decode(bunkerSeckey); - if (decoded.type !== 'nsec') return result; - result.push({ secret, signers: { user, - bunker: new NSecSigner(decoded.data), + bunker: new NSecSigner(bunkerSeckey), }, }); return result; }, [] as NBunkerOpts['authorizations']), - onAuthorize(authorizedPubkey) { - sessionStorage.setItem(secretStorageKey, crypto.randomUUID()); - }, onSubscribed() { setIsSubscribed(true); setIsSubscribing(false); diff --git a/src/features/nostr/NBunker.ts b/src/features/nostr/NBunker.ts index 91ee10110..3b41a376e 100644 --- a/src/features/nostr/NBunker.ts +++ b/src/features/nostr/NBunker.ts @@ -27,7 +27,6 @@ export interface NBunkerOpts { relay: NRelay; connection?: NBunkerConnection; authorizations: NBunkerAuthorization[]; - onAuthorize(pubkey: string): void; onSubscribed(): void; } @@ -36,7 +35,6 @@ export class NBunker { private relay: NRelay; private connection?: NBunkerConnection; private authorizations: NBunkerAuthorization[]; - private onAuthorize: (pubkey: string) => void; private onSubscribed: () => void; private controller = new AbortController(); @@ -45,7 +43,6 @@ export class NBunker { this.relay = opts.relay; this.connection = opts.connection; this.authorizations = opts.authorizations; - this.onAuthorize = opts.onAuthorize; this.onSubscribed = opts.onSubscribed; this.open(); @@ -171,8 +168,6 @@ export class NBunker { const [, secret] = request.params; if (secret === authorization.secret) { - this.onAuthorize(event.pubkey); - await this.sendResponse(event.pubkey, { id: request.id, result: 'ack', diff --git a/src/hooks/useBunkerStore.ts b/src/hooks/useBunkerStore.ts index 586abfd5a..1ab4f2664 100644 --- a/src/hooks/useBunkerStore.ts +++ b/src/hooks/useBunkerStore.ts @@ -77,6 +77,8 @@ const stateSchema = z.object({ interface BunkerState { connections: BunkerConnection[]; authorizations: BunkerAuthorization[]; + authorize(pubkey: string): BunkerURI; + connect(request: BunkerConnectRequest): void; } export const useBunkerStore = create()( @@ -132,6 +134,15 @@ export const useBunkerStore = create()( }); }); }, + + /** Revoke any connections associated with the access token. */ + revoke(accessToken: string) { + setState((state) => { + return produce(state, (draft) => { + draft.connections = draft.connections.filter((conn) => conn.accessToken !== accessToken); + }); + }); + }, }), { name: 'soapbox:bunker', diff --git a/src/reducers/index.ts b/src/reducers/index.ts index 685944cd6..2f5d286e6 100644 --- a/src/reducers/index.ts +++ b/src/reducers/index.ts @@ -7,7 +7,6 @@ import admin from './admin'; import aliases from './aliases'; import auth from './auth'; import backups from './backups'; -import bunker from './bunker'; import chat_message_lists from './chat-message-lists'; import chat_messages from './chat-messages'; import chats from './chats'; @@ -112,5 +111,4 @@ export default combineReducers({ trending_statuses, trends, user_lists, - bunker: bunker.reducer, }); \ No newline at end of file