podcast manager
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 91 lines 2.6 kB view raw
1import {useSignal} from '@preact/signals' 2import {nanoid} from 'nanoid' 3import {useCallback} from 'preact/hooks' 4 5import {generateSignableJwt} from '#common/crypto/jwks' 6import {jwtSchema} from '#common/crypto/jwts' 7import {RealmBrand} from '#realm/protocol/index' 8 9import {useRealmConnection} from '../context-connection' 10import {useRealmIdentity} from '../context-identity' 11 12export const RealmConnectionManager: preact.FunctionComponent = () => { 13 const {identity} = useRealmIdentity() 14 const connection = useRealmConnection() 15 16 const invitation = useSignal<string>() 17 const register = useCallback(() => { 18 console.debug('register realm') 19 connection.connectopts.value = { 20 realmid: RealmBrand.generate(), 21 register: true, 22 } 23 }, [connection.connectopts]) 24 25 const exchange = useCallback(() => { 26 console.debug('exchange invitation:', invitation.value) 27 jwtSchema 28 .parseAsync(invitation.value) 29 .then((token) => { 30 connection.connectopts.value = { 31 realmid: RealmBrand.parse(token.claims.aud), 32 invitation: invitation.value, 33 } 34 }) 35 .catch((exc: unknown) => { 36 console.error('couldnt exchange', exc) 37 }) 38 }, [invitation, connection.connectopts]) 39 40 const generate = useCallback(() => { 41 if (!connection.realm.value) return 42 43 identity 44 .sign( 45 generateSignableJwt({ 46 aud: connection.realm.value.realmid, 47 iss: identity.identid, 48 sub: 'invitation', 49 jti: nanoid(), 50 exp: Date.now() + 5 * 60, 51 }), 52 ) 53 .then((token) => (invitation.value = token)) 54 .catch((exc: unknown) => { 55 console.error('error generating invite', exc) 56 }) 57 }, [invitation, connection.realm, identity]) 58 59 return connection.realm.value ? ( 60 <div> 61 <pre> 62 {connection.connected.value ? ' 🟢 Connected: ' : ' 🔴 Disconnected: '} 63 {connection.realm.value.realmid} '/' {identity.identid} '/' {identity.latest} 64 </pre> 65 <textarea value={invitation.value} /> 66 <br /> 67 <button type="button" onClick={generate}> 68 Generate Invitation 69 </button> 70 </div> 71 ) : ( 72 <div> 73 <h1> 74 Connection: <code>NONE</code> 75 </h1> 76 <p> 77 Generate a new realm:{' '} 78 <button type="button" onClick={register}> 79 Register 80 </button> 81 </p> 82 <p> 83 Exchange an invite: 84 <textarea value={invitation.value} onInput={(e) => (invitation.value = e.currentTarget.value)} /> 85 <button type="button" onClick={exchange}> 86 Exchange 87 </button> 88 </p> 89 </div> 90 ) 91}