Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork client

fix: ensure com.atproto.* calls go through without proxying #35

merged opened by mary.my.id targeting main

atproto-proxy behavior seems ambiguous right now, it's not really clear whether PDS implementors should interpret atproto-proxy before or after PDS' own route handlers. This PR ensures that com.atproto.* calls go through without a proxy set (with some exception)

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:ia76kvnndjutgedggx2ibrem/sh.tangled.repo.pull/3mbn7dkbqhm22
+84 -41
Diff #1
+2 -1
src/ageAssurance/data.tsx
··· 20 snoozeBirthdateUpdateAllowedForDid, 21 } from '#/state/birthdate' 22 import {useAgent, useSession} from '#/state/session' 23 import * as debug from '#/ageAssurance/debug' 24 import {logger} from '#/ageAssurance/logger' 25 import { ··· 323 agent: AtpAgent 324 }): Promise<OtherRequiredData> { 325 if (debug.enabled) return debug.resolve(debug.otherRequiredData) 326 - const [prefs] = await Promise.all([agent.getPreferences()]) 327 const data: OtherRequiredData = { 328 birthdate: prefs.birthDate ? prefs.birthDate.toISOString() : undefined, 329 }
··· 20 snoozeBirthdateUpdateAllowedForDid, 21 } from '#/state/birthdate' 22 import {useAgent, useSession} from '#/state/session' 23 + import {pdsAgent} from '#/state/session/agent' 24 import * as debug from '#/ageAssurance/debug' 25 import {logger} from '#/ageAssurance/logger' 26 import { ··· 324 agent: AtpAgent 325 }): Promise<OtherRequiredData> { 326 if (debug.enabled) return debug.resolve(debug.otherRequiredData) 327 + const [prefs] = await Promise.all([pdsAgent(agent).getPreferences()]) 328 const data: OtherRequiredData = { 329 birthdate: prefs.birthDate ? prefs.birthDate.toISOString() : undefined, 330 }
+2 -1
src/ageAssurance/useBeginAgeAssurance.ts
··· 10 } from '#/lib/constants' 11 import {isNetworkError} from '#/lib/hooks/useCleanError' 12 import {useAgent} from '#/state/session' 13 import {usePatchAgeAssuranceServerState} from '#/ageAssurance' 14 import {logger} from '#/ageAssurance/logger' 15 import {BLUESKY_PROXY_DID} from '#/env' ··· 38 39 const { 40 data: {token}, 41 - } = await agent.com.atproto.server.getServiceAuth({ 42 aud: BLUESKY_PROXY_DID, 43 lxm: `app.bsky.ageassurance.begin`, 44 })
··· 10 } from '#/lib/constants' 11 import {isNetworkError} from '#/lib/hooks/useCleanError' 12 import {useAgent} from '#/state/session' 13 + import {pdsAgent} from '#/state/session/agent' 14 import {usePatchAgeAssuranceServerState} from '#/ageAssurance' 15 import {logger} from '#/ageAssurance/logger' 16 import {BLUESKY_PROXY_DID} from '#/env' ··· 39 40 const { 41 data: {token}, 42 + } = await pdsAgent(agent).com.atproto.server.getServiceAuth({ 43 aud: BLUESKY_PROXY_DID, 44 lxm: `app.bsky.ageassurance.begin`, 45 })
+2 -1
src/components/dialogs/EmailDialog/data/useConfirmEmail.ts
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent, useSession} from '#/state/session' 4 5 export function useConfirmEmail({ 6 onSuccess, ··· 15 throw new Error('No email found for the current account') 16 } 17 18 - await agent.com.atproto.server.confirmEmail({ 19 email: currentAccount.email.trim(), 20 token: token.trim(), 21 })
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent, useSession} from '#/state/session' 4 + import {pdsAgent} from '#/state/session/agent' 5 6 export function useConfirmEmail({ 7 onSuccess, ··· 16 throw new Error('No email found for the current account') 17 } 18 19 + await pdsAgent(agent).com.atproto.server.confirmEmail({ 20 email: currentAccount.email.trim(), 21 token: token.trim(), 22 })
+2 -1
src/components/dialogs/EmailDialog/data/useManageEmail2FA.ts
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent, useSession} from '#/state/session' 4 5 export function useManageEmail2FA() { 6 const agent = useAgent() ··· 17 throw new Error('No email found for the current account') 18 } 19 20 - await agent.com.atproto.server.updateEmail({ 21 email: currentAccount.email, 22 emailAuthFactor: enabled, 23 token,
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent, useSession} from '#/state/session' 4 + import {pdsAgent} from '#/state/session/agent' 5 6 export function useManageEmail2FA() { 7 const agent = useAgent() ··· 18 throw new Error('No email found for the current account') 19 } 20 21 + await pdsAgent(agent).com.atproto.server.updateEmail({ 22 email: currentAccount.email, 23 emailAuthFactor: enabled, 24 token,
+3 -1
src/components/dialogs/EmailDialog/data/useRequestEmailUpdate.ts
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent} from '#/state/session' 4 5 export function useRequestEmailUpdate() { 6 const agent = useAgent() 7 8 return useMutation({ 9 mutationFn: async () => { 10 - return (await agent.com.atproto.server.requestEmailUpdate()).data 11 }, 12 }) 13 }
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent} from '#/state/session' 4 + import {pdsAgent} from '#/state/session/agent' 5 6 export function useRequestEmailUpdate() { 7 const agent = useAgent() 8 9 return useMutation({ 10 mutationFn: async () => { 11 + return (await pdsAgent(agent).com.atproto.server.requestEmailUpdate()) 12 + .data 13 }, 14 }) 15 }
+2 -1
src/components/dialogs/EmailDialog/data/useRequestEmailVerification.ts
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent} from '#/state/session' 4 5 export function useRequestEmailVerification() { 6 const agent = useAgent() 7 8 return useMutation({ 9 mutationFn: async () => { 10 - await agent.com.atproto.server.requestEmailConfirmation() 11 }, 12 }) 13 }
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent} from '#/state/session' 4 + import {pdsAgent} from '#/state/session/agent' 5 6 export function useRequestEmailVerification() { 7 const agent = useAgent() 8 9 return useMutation({ 10 mutationFn: async () => { 11 + await pdsAgent(agent).com.atproto.server.requestEmailConfirmation() 12 }, 13 }) 14 }
+5 -1
src/components/dialogs/EmailDialog/data/useUpdateEmail.ts
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent} from '#/state/session' 4 import {useRequestEmailUpdate} from '#/components/dialogs/EmailDialog/data/useRequestEmailUpdate' 5 6 async function updateEmailAndRefreshSession( ··· 8 email: string, 9 token?: string, 10 ) { 11 - await agent.com.atproto.server.updateEmail({email: email.trim(), token}) 12 await agent.resumeSession(agent.session!) 13 } 14
··· 1 import {useMutation} from '@tanstack/react-query' 2 3 import {useAgent} from '#/state/session' 4 + import {pdsAgent} from '#/state/session/agent' 5 import {useRequestEmailUpdate} from '#/components/dialogs/EmailDialog/data/useRequestEmailUpdate' 6 7 async function updateEmailAndRefreshSession( ··· 9 email: string, 10 token?: string, 11 ) { 12 + await pdsAgent(agent).com.atproto.server.updateEmail({ 13 + email: email.trim(), 14 + token, 15 + }) 16 await agent.resumeSession(agent.session!) 17 } 18
+2 -1
src/components/intents/VerifyEmailIntentDialog.tsx
··· 5 6 import {isNative} from '#/platform/detection' 7 import {useAgent, useSession} from '#/state/session' 8 import {atoms as a, useBreakpoints, useTheme} from '#/alf' 9 import {Button, ButtonIcon, ButtonText} from '#/components/Button' 10 import * as Dialog from '#/components/Dialog' ··· 51 52 const onPressResendEmail = async () => { 53 setSending(true) 54 - await agent.com.atproto.server.requestEmailConfirmation() 55 setSending(false) 56 setStatus('resent') 57 }
··· 5 6 import {isNative} from '#/platform/detection' 7 import {useAgent, useSession} from '#/state/session' 8 + import {pdsAgent} from '#/state/session/agent' 9 import {atoms as a, useBreakpoints, useTheme} from '#/alf' 10 import {Button, ButtonIcon, ButtonText} from '#/components/Button' 11 import * as Dialog from '#/components/Dialog' ··· 52 53 const onPressResendEmail = async () => { 54 setSending(true) 55 + await pdsAgent(agent).com.atproto.server.requestEmailConfirmation() 56 setSending(false) 57 setStatus('resent') 58 }
+4 -3
src/components/live/queries.ts
··· 16 import {updateProfileShadow} from '#/state/cache/profile-shadow' 17 import {useLiveNowConfig} from '#/state/service-config' 18 import {useAgent, useSession} from '#/state/session' 19 import * as Toast from '#/view/com/util/Toast' 20 import {useDialogContext} from '#/components/Dialog' 21 ··· 108 const repo = currentAccount.did 109 const collection = 'app.bsky.actor.status' 110 111 - const existing = await agent.com.atproto.repo 112 - .getRecord({repo, collection, rkey: 'self'}) 113 .catch(_e => undefined) 114 115 - await agent.com.atproto.repo.putRecord({ 116 repo, 117 collection, 118 rkey: 'self',
··· 16 import {updateProfileShadow} from '#/state/cache/profile-shadow' 17 import {useLiveNowConfig} from '#/state/service-config' 18 import {useAgent, useSession} from '#/state/session' 19 + import {pdsAgent} from '#/state/session/agent' 20 import * as Toast from '#/view/com/util/Toast' 21 import {useDialogContext} from '#/components/Dialog' 22 ··· 109 const repo = currentAccount.did 110 const collection = 'app.bsky.actor.status' 111 112 + const existing = await pdsAgent(agent) 113 + .com.atproto.repo.getRecord({repo, collection, rkey: 'self'}) 114 .catch(_e => undefined) 115 116 + await pdsAgent(agent).com.atproto.repo.putRecord({ 117 repo, 118 collection, 119 rkey: 'self',
+2 -1
src/lib/api/index.ts
··· 34 createThreadgateRecord, 35 threadgateAllowUISettingToAllowRecordValue, 36 } from '#/state/queries/threadgate' 37 import { 38 type EmbedDraft, 39 type PostDraft, ··· 172 } 173 174 try { 175 - await agent.com.atproto.repo.applyWrites({ 176 repo: agent.assertDid, 177 writes: writes, 178 validate: true,
··· 34 createThreadgateRecord, 35 threadgateAllowUISettingToAllowRecordValue, 36 } from '#/state/queries/threadgate' 37 + import {pdsAgent} from '#/state/session/agent' 38 import { 39 type EmbedDraft, 40 type PostDraft, ··· 173 } 174 175 try { 176 + await pdsAgent(agent).com.atproto.repo.applyWrites({ 177 repo: agent.assertDid, 178 writes: writes, 179 validate: true,
+2 -1
src/lib/generate-starterpack.ts
··· 15 import {sanitizeHandle} from '#/lib/strings/handles' 16 import {enforceLen} from '#/lib/strings/helpers' 17 import {useAgent} from '#/state/session' 18 import type * as bsky from '#/types/bsky' 19 20 export const createStarterPackList = async ({ ··· 44 }, 45 ) 46 if (!list) throw new Error('List creation failed') 47 - await agent.com.atproto.repo.applyWrites({ 48 repo: agent.session!.did, 49 writes: profiles.map(p => createListItem({did: p.did, listUri: list.uri})), 50 })
··· 15 import {sanitizeHandle} from '#/lib/strings/handles' 16 import {enforceLen} from '#/lib/strings/helpers' 17 import {useAgent} from '#/state/session' 18 + import {pdsAgent} from '#/state/session/agent' 19 import type * as bsky from '#/types/bsky' 20 21 export const createStarterPackList = async ({ ··· 45 }, 46 ) 47 if (!list) throw new Error('List creation failed') 48 + await pdsAgent(agent).com.atproto.repo.applyWrites({ 49 repo: agent.session!.did, 50 writes: profiles.map(p => createListItem({did: p.did, listUri: list.uri})), 51 })
+2 -1
src/lib/media/video/upload.shared.ts
··· 3 import {msg} from '@lingui/macro' 4 5 import {VIDEO_SERVICE_DID} from '#/lib/constants' 6 import {UploadLimitError} from '#/lib/media/video/errors' 7 import {getServiceAuthAudFromUrl} from '#/lib/strings/url-helpers' 8 import {createVideoAgent} from './util' ··· 22 if (!pdsAud) { 23 throw new Error('Agent does not have a PDS URL') 24 } 25 - const {data: serviceAuth} = await agent.com.atproto.server.getServiceAuth({ 26 aud: aud ?? pdsAud, 27 lxm, 28 exp,
··· 3 import {msg} from '@lingui/macro' 4 5 import {VIDEO_SERVICE_DID} from '#/lib/constants' 6 + import {pdsAgent} from '#/state/session/agent' 7 import {UploadLimitError} from '#/lib/media/video/errors' 8 import {getServiceAuthAudFromUrl} from '#/lib/strings/url-helpers' 9 import {createVideoAgent} from './util' ··· 23 if (!pdsAud) { 24 throw new Error('Agent does not have a PDS URL') 25 } 26 + const {data: serviceAuth} = await pdsAgent(agent).com.atproto.server.getServiceAuth({ 27 aud: aud ?? pdsAud, 28 lxm, 29 exp,
+2 -1
src/screens/Deactivated.tsx
··· 14 useSession, 15 useSessionApi, 16 } from '#/state/session' 17 import {useLoggedOutViewControls} from '#/state/shell/logged-out' 18 import {Logo} from '#/view/icons/Logo' 19 import {atoms as a, useTheme} from '#/alf' ··· 69 const handleActivate = React.useCallback(async () => { 70 try { 71 setPending(true) 72 - await agent.com.atproto.server.activateAccount() 73 await queryClient.resetQueries() 74 await agent.resumeSession(agent.session!) 75 } catch (e: any) {
··· 14 useSession, 15 useSessionApi, 16 } from '#/state/session' 17 + import {pdsAgent} from '#/state/session/agent' 18 import {useLoggedOutViewControls} from '#/state/shell/logged-out' 19 import {Logo} from '#/view/icons/Logo' 20 import {atoms as a, useTheme} from '#/alf' ··· 70 const handleActivate = React.useCallback(async () => { 71 try { 72 setPending(true) 73 + await pdsAgent(agent).com.atproto.server.activateAccount() 74 await queryClient.resetQueries() 75 await agent.resumeSession(agent.session!) 76 } catch (e: any) {
+2 -1
src/screens/Onboarding/util.ts
··· 9 import chunk from 'lodash.chunk' 10 11 import {until} from '#/lib/async/until' 12 13 export async function bulkWriteFollows(agent: BskyAgent, dids: string[]) { 14 const session = agent.session ··· 35 36 const chunks = chunk(followWrites, 50) 37 for (const chunk of chunks) { 38 - await agent.com.atproto.repo.applyWrites({ 39 repo: session.did, 40 writes: chunk, 41 })
··· 9 import chunk from 'lodash.chunk' 10 11 import {until} from '#/lib/async/until' 12 + import {pdsAgent} from '#/state/session/agent' 13 14 export async function bulkWriteFollows(agent: BskyAgent, dids: string[]) { 15 const session = agent.session ··· 36 37 const chunks = chunk(followWrites, 50) 38 for (const chunk of chunks) { 39 + await pdsAgent(agent).com.atproto.repo.applyWrites({ 40 repo: session.did, 41 writes: chunk, 42 })
+3 -2
src/screens/Settings/components/ChangePasswordDialog.tsx
··· 9 import {logger} from '#/logger' 10 import {isNative} from '#/platform/detection' 11 import {useAgent, useSession} from '#/state/session' 12 import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' 13 import {android, atoms as a, web} from '#/alf' 14 import {Button, ButtonIcon, ButtonText} from '#/components/Button' ··· 84 setError('') 85 setIsProcessing(true) 86 try { 87 - await agent.com.atproto.server.requestPasswordReset({ 88 email: currentAccount.email, 89 }) 90 setStage(Stages.ChangePassword) ··· 128 setError('') 129 setIsProcessing(true) 130 try { 131 - await agent.com.atproto.server.resetPassword({ 132 token: formattedCode, 133 password: newPassword, 134 })
··· 9 import {logger} from '#/logger' 10 import {isNative} from '#/platform/detection' 11 import {useAgent, useSession} from '#/state/session' 12 + import {pdsAgent} from '#/state/session/agent' 13 import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' 14 import {android, atoms as a, web} from '#/alf' 15 import {Button, ButtonIcon, ButtonText} from '#/components/Button' ··· 85 setError('') 86 setIsProcessing(true) 87 try { 88 + await pdsAgent(agent).com.atproto.server.requestPasswordReset({ 89 email: currentAccount.email, 90 }) 91 setStage(Stages.ChangePassword) ··· 129 setError('') 130 setIsProcessing(true) 131 try { 132 + await pdsAgent(agent).com.atproto.server.resetPassword({ 133 token: formattedCode, 134 password: newPassword, 135 })
+2 -1
src/screens/Settings/components/DeactivateAccountDialog.tsx
··· 5 6 import {logger} from '#/logger' 7 import {useAgent, useSessionApi} from '#/state/session' 8 import {atoms as a, useBreakpoints, useTheme} from '#/alf' 9 import {Button, ButtonIcon, ButtonText} from '#/components/Button' 10 import {type DialogOuterProps} from '#/components/Dialog' ··· 42 const handleDeactivate = React.useCallback(async () => { 43 try { 44 setPending(true) 45 - await agent.com.atproto.server.deactivateAccount({}) 46 control.close(() => { 47 logoutCurrentAccount('Deactivated') 48 })
··· 5 6 import {logger} from '#/logger' 7 import {useAgent, useSessionApi} from '#/state/session' 8 + import {pdsAgent} from '#/state/session/agent' 9 import {atoms as a, useBreakpoints, useTheme} from '#/alf' 10 import {Button, ButtonIcon, ButtonText} from '#/components/Button' 11 import {type DialogOuterProps} from '#/components/Dialog' ··· 43 const handleDeactivate = React.useCallback(async () => { 44 try { 45 setPending(true) 46 + await pdsAgent(agent).com.atproto.server.deactivateAccount({}) 47 control.close(() => { 48 logoutCurrentAccount('Deactivated') 49 })
+3 -2
src/screens/Settings/components/DisableEmail2FADialog.tsx
··· 6 import {cleanError} from '#/lib/strings/errors' 7 import {isNative} from '#/platform/detection' 8 import {useAgent, useSession} from '#/state/session' 9 import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' 10 import * as Toast from '#/view/com/util/Toast' 11 import {atoms as a, useBreakpoints, useTheme} from '#/alf' ··· 41 setError('') 42 setIsProcessing(true) 43 try { 44 - await agent.com.atproto.server.requestEmailUpdate() 45 setStage(Stages.ConfirmCode) 46 } catch (e) { 47 setError(cleanError(String(e))) ··· 55 setIsProcessing(true) 56 try { 57 if (currentAccount?.email) { 58 - await agent.com.atproto.server.updateEmail({ 59 email: currentAccount!.email, 60 token: confirmationCode.trim(), 61 emailAuthFactor: false,
··· 6 import {cleanError} from '#/lib/strings/errors' 7 import {isNative} from '#/platform/detection' 8 import {useAgent, useSession} from '#/state/session' 9 + import {pdsAgent} from '#/state/session/agent' 10 import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' 11 import * as Toast from '#/view/com/util/Toast' 12 import {atoms as a, useBreakpoints, useTheme} from '#/alf' ··· 42 setError('') 43 setIsProcessing(true) 44 try { 45 + await pdsAgent(agent).com.atproto.server.requestEmailUpdate() 46 setStage(Stages.ConfirmCode) 47 } catch (e) { 48 setError(cleanError(String(e))) ··· 56 setIsProcessing(true) 57 try { 58 if (currentAccount?.email) { 59 + await pdsAgent(agent).com.atproto.server.updateEmail({ 60 email: currentAccount!.email, 61 token: confirmationCode.trim(), 62 emailAuthFactor: false,
+2 -1
src/screens/Settings/components/ExportCarDialog.tsx
··· 6 import {saveBytesToDisk} from '#/lib/media/manip' 7 import {logger} from '#/logger' 8 import {useAgent} from '#/state/session' 9 import {atoms as a, useTheme, web} from '#/alf' 10 import {Button, ButtonIcon, ButtonText} from '#/components/Button' 11 import * as Dialog from '#/components/Dialog' ··· 32 try { 33 setLoading(true) 34 const did = agent.session.did 35 - const downloadRes = await agent.com.atproto.sync.getRepo({did}) 36 const saveRes = await saveBytesToDisk( 37 'repo.car', 38 downloadRes.data,
··· 6 import {saveBytesToDisk} from '#/lib/media/manip' 7 import {logger} from '#/logger' 8 import {useAgent} from '#/state/session' 9 + import {pdsAgent} from '#/state/session/agent' 10 import {atoms as a, useTheme, web} from '#/alf' 11 import {Button, ButtonIcon, ButtonText} from '#/components/Button' 12 import * as Dialog from '#/components/Dialog' ··· 33 try { 34 setLoading(true) 35 const did = agent.session.did 36 + const downloadRes = await pdsAgent(agent).com.atproto.sync.getRepo({did}) 37 const saveRes = await saveBytesToDisk( 38 'repo.car', 39 downloadRes.data,
+2 -1
src/screens/SignupQueued.tsx
··· 8 import {logger} from '#/logger' 9 import {isIOS, isWeb} from '#/platform/detection' 10 import {isSignupQueued, useAgent, useSessionApi} from '#/state/session' 11 import {useOnboardingDispatch} from '#/state/shell' 12 import {Logo} from '#/view/icons/Logo' 13 import {atoms as a, native, useBreakpoints, useTheme, web} from '#/alf' ··· 37 const checkStatus = React.useCallback(async () => { 38 setProcessing(true) 39 try { 40 - const res = await agent.com.atproto.temp.checkSignupQueue() 41 if (res.data.activated) { 42 // ready to go, exchange the access token for a usable one and kick off onboarding 43 await agent.sessionManager.refreshSession()
··· 8 import {logger} from '#/logger' 9 import {isIOS, isWeb} from '#/platform/detection' 10 import {isSignupQueued, useAgent, useSessionApi} from '#/state/session' 11 + import {pdsAgent} from '#/state/session/agent' 12 import {useOnboardingDispatch} from '#/state/shell' 13 import {Logo} from '#/view/icons/Logo' 14 import {atoms as a, native, useBreakpoints, useTheme, web} from '#/alf' ··· 38 const checkStatus = React.useCallback(async () => { 39 setProcessing(true) 40 try { 41 + const res = await pdsAgent(agent).com.atproto.temp.checkSignupQueue() 42 if (res.data.activated) { 43 // ready to go, exchange the access token for a usable one and kick off onboarding 44 await agent.sessionManager.refreshSession()
+4 -3
src/state/queries/app-passwords.ts
··· 3 4 import {STALE} from '#/state/queries' 5 import {useAgent} from '../session' 6 7 const RQKEY_ROOT = 'app-passwords' 8 export const RQKEY = () => [RQKEY_ROOT] ··· 13 staleTime: STALE.MINUTES.FIVE, 14 queryKey: RQKEY(), 15 queryFn: async () => { 16 - const res = await agent.com.atproto.server.listAppPasswords({}) 17 return res.data.passwords 18 }, 19 }) ··· 29 >({ 30 mutationFn: async ({name, privileged}) => { 31 return ( 32 - await agent.com.atproto.server.createAppPassword({ 33 name, 34 privileged, 35 }) ··· 48 const agent = useAgent() 49 return useMutation<void, Error, {name: string}>({ 50 mutationFn: async ({name}) => { 51 - await agent.com.atproto.server.revokeAppPassword({ 52 name, 53 }) 54 },
··· 3 4 import {STALE} from '#/state/queries' 5 import {useAgent} from '../session' 6 + import {pdsAgent} from '../session/agent' 7 8 const RQKEY_ROOT = 'app-passwords' 9 export const RQKEY = () => [RQKEY_ROOT] ··· 14 staleTime: STALE.MINUTES.FIVE, 15 queryKey: RQKEY(), 16 queryFn: async () => { 17 + const res = await pdsAgent(agent).com.atproto.server.listAppPasswords({}) 18 return res.data.passwords 19 }, 20 }) ··· 30 >({ 31 mutationFn: async ({name, privileged}) => { 32 return ( 33 + await pdsAgent(agent).com.atproto.server.createAppPassword({ 34 name, 35 privileged, 36 }) ··· 49 const agent = useAgent() 50 return useMutation<void, Error, {name: string}>({ 51 mutationFn: async ({name}) => { 52 + await pdsAgent(agent).com.atproto.server.revokeAppPassword({ 53 name, 54 }) 55 },
+3 -2
src/state/queries/list.ts
··· 17 import {type ImageMeta} from '#/state/gallery' 18 import {STALE} from '#/state/queries' 19 import {useAgent, useSession} from '#/state/session' 20 import {invalidate as invalidateMyLists} from './my-lists' 21 import {RQKEY as PROFILE_LISTS_RQKEY} from './profile-lists' 22 ··· 152 record.avatar = undefined 153 } 154 const res = ( 155 - await agent.com.atproto.repo.putRecord({ 156 repo: currentAccount.did, 157 collection: 'app.bsky.graph.list', 158 rkey, ··· 231 232 // apply in chunks 233 for (const writesChunk of chunk(writes, 10)) { 234 - await agent.com.atproto.repo.applyWrites({ 235 repo: currentAccount.did, 236 writes: writesChunk, 237 })
··· 17 import {type ImageMeta} from '#/state/gallery' 18 import {STALE} from '#/state/queries' 19 import {useAgent, useSession} from '#/state/session' 20 + import {pdsAgent} from '#/state/session/agent' 21 import {invalidate as invalidateMyLists} from './my-lists' 22 import {RQKEY as PROFILE_LISTS_RQKEY} from './profile-lists' 23 ··· 153 record.avatar = undefined 154 } 155 const res = ( 156 + await pdsAgent(agent).com.atproto.repo.putRecord({ 157 repo: currentAccount.did, 158 collection: 'app.bsky.graph.list', 159 rkey, ··· 232 233 // apply in chunks 234 for (const writesChunk of chunk(writes, 10)) { 235 + await pdsAgent(agent).com.atproto.repo.applyWrites({ 236 repo: currentAccount.did, 237 writes: writesChunk, 238 })
+3 -2
src/state/queries/messages/actor-declaration.ts
··· 3 4 import {logger} from '#/logger' 5 import {useAgent, useSession} from '#/state/session' 6 import {RQKEY as PROFILE_RKEY} from '../profile' 7 8 export function useUpdateActorDeclaration({ ··· 19 return useMutation({ 20 mutationFn: async (allowIncoming: 'all' | 'none' | 'following') => { 21 if (!currentAccount) throw new Error('Not signed in') 22 - const result = await agent.com.atproto.repo.putRecord({ 23 repo: currentAccount.did, 24 collection: 'chat.bsky.actor.declaration', 25 rkey: 'self', ··· 69 return useMutation({ 70 mutationFn: async () => { 71 if (!currentAccount) throw new Error('Not signed in') 72 - const result = await agent.api.com.atproto.repo.deleteRecord({ 73 repo: currentAccount.did, 74 collection: 'chat.bsky.actor.declaration', 75 rkey: 'self',
··· 3 4 import {logger} from '#/logger' 5 import {useAgent, useSession} from '#/state/session' 6 + import {pdsAgent} from '#/state/session/agent' 7 import {RQKEY as PROFILE_RKEY} from '../profile' 8 9 export function useUpdateActorDeclaration({ ··· 20 return useMutation({ 21 mutationFn: async (allowIncoming: 'all' | 'none' | 'following') => { 22 if (!currentAccount) throw new Error('Not signed in') 23 + const result = await pdsAgent(agent).com.atproto.repo.putRecord({ 24 repo: currentAccount.did, 25 collection: 'chat.bsky.actor.declaration', 26 rkey: 'self', ··· 70 return useMutation({ 71 mutationFn: async () => { 72 if (!currentAccount) throw new Error('Not signed in') 73 + const result = await pdsAgent(agent).com.atproto.repo.deleteRecord({ 74 repo: currentAccount.did, 75 collection: 'chat.bsky.actor.declaration', 76 rkey: 'self',
+2 -1
src/state/queries/postgate/index.ts
··· 21 POSTGATE_COLLECTION, 22 } from '#/state/queries/postgate/util' 23 import {useAgent} from '#/state/session' 24 import * as bsky from '#/types/bsky' 25 26 export async function getPostgateRecord({ ··· 96 const postUrip = new AtUri(postUri) 97 98 await networkRetry(2, () => 99 - agent.api.com.atproto.repo.putRecord({ 100 repo: agent.session!.did, 101 collection: POSTGATE_COLLECTION, 102 rkey: postUrip.rkey,
··· 21 POSTGATE_COLLECTION, 22 } from '#/state/queries/postgate/util' 23 import {useAgent} from '#/state/session' 24 + import {pdsAgent} from '#/state/session/agent' 25 import * as bsky from '#/types/bsky' 26 27 export async function getPostgateRecord({ ··· 97 const postUrip = new AtUri(postUri) 98 99 await networkRetry(2, () => 100 + pdsAgent(agent).com.atproto.repo.putRecord({ 101 repo: agent.session!.did, 102 collection: POSTGATE_COLLECTION, 103 rkey: postUrip.rkey,
+3 -2
src/state/queries/preferences/index.ts
··· 21 type UsePreferencesQueryResponse, 22 } from '#/state/queries/preferences/types' 23 import {useBlankPrefAuthedAgent as useAgent} from '#/state/session' 24 import {saveLabelers} from '#/state/session/agent-config' 25 import {useAgeAssurance} from '#/ageAssurance' 26 import {makeAgeRestrictedModerationPrefs} from '#/ageAssurance/util' ··· 45 if (!agent.did) { 46 return DEFAULT_LOGGED_OUT_PREFERENCES 47 } else { 48 - const res = await agent.getPreferences() 49 50 // save to local storage to ensure there are labels on initial requests 51 saveLabelers( ··· 100 101 return useMutation({ 102 mutationFn: async () => { 103 - await agent.app.bsky.actor.putPreferences({preferences: []}) 104 // triggers a refetch 105 await queryClient.invalidateQueries({ 106 queryKey: preferencesQueryKey,
··· 21 type UsePreferencesQueryResponse, 22 } from '#/state/queries/preferences/types' 23 import {useBlankPrefAuthedAgent as useAgent} from '#/state/session' 24 + import {pdsAgent} from '#/state/session/agent' 25 import {saveLabelers} from '#/state/session/agent-config' 26 import {useAgeAssurance} from '#/ageAssurance' 27 import {makeAgeRestrictedModerationPrefs} from '#/ageAssurance/util' ··· 46 if (!agent.did) { 47 return DEFAULT_LOGGED_OUT_PREFERENCES 48 } else { 49 + const res = await pdsAgent(agent).getPreferences() 50 51 // save to local storage to ensure there are labels on initial requests 52 saveLabelers( ··· 101 102 return useMutation({ 103 mutationFn: async () => { 104 + await pdsAgent(agent).app.bsky.actor.putPreferences({preferences: []}) 105 // triggers a refetch 106 await queryClient.invalidateQueries({ 107 queryKey: preferencesQueryKey,
+4 -3
src/state/queries/starter-packs.ts
··· 27 import {STALE} from '#/state/queries/index' 28 import {invalidateListMembersQuery} from '#/state/queries/list-members' 29 import {useAgent} from '#/state/session' 30 import * as bsky from '#/types/bsky' 31 32 const RQKEY_ROOT = 'starter-pack' ··· 203 if (removedItems.length !== 0) { 204 const chunks = chunk(removedItems, 50) 205 for (const chunk of chunks) { 206 - await agent.com.atproto.repo.applyWrites({ 207 repo: agent.session!.did, 208 writes: chunk.map(i => ({ 209 $type: 'com.atproto.repo.applyWrites#delete', ··· 220 if (addedProfiles.length > 0) { 221 const chunks = chunk(addedProfiles, 50) 222 for (const chunk of chunks) { 223 - await agent.com.atproto.repo.applyWrites({ 224 repo: agent.session!.did, 225 writes: chunk.map(p => ({ 226 $type: 'com.atproto.repo.applyWrites#create', ··· 237 } 238 239 const rkey = parseStarterPackUri(currentStarterPack.uri)!.rkey 240 - await agent.com.atproto.repo.putRecord({ 241 repo: agent.session!.did, 242 collection: 'app.bsky.graph.starterpack', 243 rkey,
··· 27 import {STALE} from '#/state/queries/index' 28 import {invalidateListMembersQuery} from '#/state/queries/list-members' 29 import {useAgent} from '#/state/session' 30 + import {pdsAgent} from '#/state/session/agent' 31 import * as bsky from '#/types/bsky' 32 33 const RQKEY_ROOT = 'starter-pack' ··· 204 if (removedItems.length !== 0) { 205 const chunks = chunk(removedItems, 50) 206 for (const chunk of chunks) { 207 + await pdsAgent(agent).com.atproto.repo.applyWrites({ 208 repo: agent.session!.did, 209 writes: chunk.map(i => ({ 210 $type: 'com.atproto.repo.applyWrites#delete', ··· 221 if (addedProfiles.length > 0) { 222 const chunks = chunk(addedProfiles, 50) 223 for (const chunk of chunks) { 224 + await pdsAgent(agent).com.atproto.repo.applyWrites({ 225 repo: agent.session!.did, 226 writes: chunk.map(p => ({ 227 $type: 'com.atproto.repo.applyWrites#create', ··· 238 } 239 240 const rkey = parseStarterPackUri(currentStarterPack.uri)!.rkey 241 + await pdsAgent(agent).com.atproto.repo.putRecord({ 242 repo: agent.session!.did, 243 collection: 'app.bsky.graph.starterpack', 244 rkey,
+2 -1
src/state/queries/threadgate/index.ts
··· 18 } from '#/state/queries/threadgate/util' 19 import {useUpdatePostThreadThreadgateQueryCache} from '#/state/queries/usePostThread' 20 import {useAgent} from '#/state/session' 21 import {useThreadgateHiddenReplyUrisAPI} from '#/state/threadgate-hidden-replies' 22 import * as bsky from '#/types/bsky' 23 ··· 162 }) 163 164 await networkRetry(2, () => 165 - agent.api.com.atproto.repo.putRecord({ 166 repo: agent.session!.did, 167 collection: 'app.bsky.feed.threadgate', 168 rkey: postUrip.rkey,
··· 18 } from '#/state/queries/threadgate/util' 19 import {useUpdatePostThreadThreadgateQueryCache} from '#/state/queries/usePostThread' 20 import {useAgent} from '#/state/session' 21 + import {pdsAgent} from '#/state/session/agent' 22 import {useThreadgateHiddenReplyUrisAPI} from '#/state/threadgate-hidden-replies' 23 import * as bsky from '#/types/bsky' 24 ··· 163 }) 164 165 await networkRetry(2, () => 166 + pdsAgent(agent).com.atproto.repo.putRecord({ 167 repo: agent.session!.did, 168 collection: 'app.bsky.feed.threadgate', 169 rkey: postUrip.rkey,
+12 -1
src/state/session/agent.ts
··· 242 }), 243 getAge(birthDate) < 18 && 244 networkRetry(3, () => { 245 - return agent.com.atproto.repo.putRecord({ 246 repo: account.did, 247 collection: 'chat.bsky.actor.declaration', 248 rkey: 'self', ··· 459 } 460 } 461 462 export type {BskyAppAgent}
··· 242 }), 243 getAge(birthDate) < 18 && 244 networkRetry(3, () => { 245 + return pdsAgent(agent).com.atproto.repo.putRecord({ 246 repo: account.did, 247 collection: 'chat.bsky.actor.declaration', 248 rkey: 'self', ··· 459 } 460 } 461 462 + /** 463 + * Returns an agent configured to make requests directly to the user's PDS 464 + * without the appview proxy header. Use this for com.atproto.* methods and 465 + * other PDS-specific operations like preferences. 466 + */ 467 + export function pdsAgent<T extends BaseAgent>(agent: T): T { 468 + const clone = agent.clone() as T 469 + clone.configureProxy(null) 470 + return clone 471 + } 472 + 473 export type {BskyAppAgent}
+2 -1
src/state/session/index.tsx
··· 12 createAgentAndCreateAccount, 13 createAgentAndLogin, 14 createAgentAndResume, 15 sessionAccountToSession, 16 } from './agent' 17 import {type Action, getInitialState, reducer, type State} from './reducer' ··· 248 >(async () => { 249 const agent = state.currentAgentState.agent as BskyAppAgent 250 const signal = cancelPendingTask() 251 - const {data} = await agent.com.atproto.server.getSession() 252 if (signal.aborted) return 253 store.dispatch({ 254 type: 'partial-refresh-session',
··· 12 createAgentAndCreateAccount, 13 createAgentAndLogin, 14 createAgentAndResume, 15 + pdsAgent, 16 sessionAccountToSession, 17 } from './agent' 18 import {type Action, getInitialState, reducer, type State} from './reducer' ··· 249 >(async () => { 250 const agent = state.currentAgentState.agent as BskyAppAgent 251 const signal = cancelPendingTask() 252 + const {data} = await pdsAgent(agent).com.atproto.server.getSession() 253 if (signal.aborted) return 254 store.dispatch({ 255 type: 'partial-refresh-session',
+3 -2
src/view/com/modals/DeleteAccount.tsx
··· 19 import {isAndroid, isWeb} from '#/platform/detection' 20 import {useModalControls} from '#/state/modals' 21 import {useAgent, useSession, useSessionApi} from '#/state/session' 22 import {atoms as a, useTheme as useNewTheme} from '#/alf' 23 import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' 24 import {Text as NewText} from '#/components/Typography' ··· 49 setError('') 50 setIsProcessing(true) 51 try { 52 - await agent.com.atproto.server.requestAccountDelete() 53 setIsEmailSent(true) 54 } catch (e: any) { 55 setError(cleanError(e)) ··· 76 if (!success) { 77 throw new Error('Failed to inform chat service of account deletion') 78 } 79 - await agent.com.atproto.server.deleteAccount({ 80 did: currentAccount.did, 81 password, 82 token,
··· 19 import {isAndroid, isWeb} from '#/platform/detection' 20 import {useModalControls} from '#/state/modals' 21 import {useAgent, useSession, useSessionApi} from '#/state/session' 22 + import {pdsAgent} from '#/state/session/agent' 23 import {atoms as a, useTheme as useNewTheme} from '#/alf' 24 import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' 25 import {Text as NewText} from '#/components/Typography' ··· 50 setError('') 51 setIsProcessing(true) 52 try { 53 + await pdsAgent(agent).com.atproto.server.requestAccountDelete() 54 setIsEmailSent(true) 55 } catch (e: any) { 56 setError(cleanError(e)) ··· 77 if (!success) { 78 throw new Error('Failed to inform chat service of account deletion') 79 } 80 + await pdsAgent(agent).com.atproto.server.deleteAccount({ 81 did: currentAccount.did, 82 password, 83 token,

History

2 rounds 0 comments
sign up or login to add to the discussion
expand 0 comments
pull request successfully merged
2 commits
expand
05c9641d
fix
7630dcd5
fix
expand 0 comments