From 64b669685c0119fed748404c16f023ef599660ed Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 25 Jun 2025 17:24:50 +0300 Subject: [PATCH] Activity notification public preference settings (#8504) --- bskyweb/cmd/bskyweb/server.go | 1 + package.json | 4 +- src/Navigation.tsx | 9 + src/lib/routes/types.ts | 1 + src/routes.ts | 1 + .../Settings/AccessibilitySettings.tsx | 19 +- .../Settings/ActivityPrivacySettings.tsx | 138 ++++++++++++++ src/screens/Settings/AppPasswords.tsx | 6 +- src/screens/Settings/AppearanceSettings.tsx | 9 +- .../Settings/ExternalMediaPreferences.tsx | 7 +- .../Settings/FollowingFeedPreferences.tsx | 5 +- .../components/PreferenceControls.tsx | 16 +- .../Settings/NotificationSettings/index.tsx | 1 - .../Settings/PrivacyAndSecuritySettings.tsx | 48 +++++ src/screens/Settings/Settings.tsx | 4 +- .../Settings/components/SettingsList.tsx | 23 ++- src/state/queries/activity-subscriptions.ts | 77 ++++++++ .../queries/messages/actor-declaration.ts | 4 +- yarn.lock | 174 +++++++++--------- 19 files changed, 406 insertions(+), 141 deletions(-) create mode 100644 src/screens/Settings/ActivityPrivacySettings.tsx create mode 100644 src/state/queries/activity-subscriptions.ts diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go index ef796920d6..1654b3e498 100644 --- a/bskyweb/cmd/bskyweb/server.go +++ b/bskyweb/cmd/bskyweb/server.go @@ -275,6 +275,7 @@ func serve(cctx *cli.Context) error { e.GET("/settings/appearance", server.WebGeneric) e.GET("/settings/account", server.WebGeneric) e.GET("/settings/privacy-and-security", server.WebGeneric) + e.GET("/settings/privacy-and-security/activity", server.WebGeneric) e.GET("/settings/content-and-media", server.WebGeneric) e.GET("/settings/interests", server.WebGeneric) e.GET("/settings/about", server.WebGeneric) diff --git a/package.json b/package.json index 7c1c3dee92..0ab2956088 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "icons:optimize": "svgo -f ./assets/icons" }, "dependencies": { - "@atproto/api": "^0.15.16", + "@atproto/api": "^0.15.17", "@bitdrift/react-native": "^0.6.8", "@braintree/sanitize-url": "^6.0.2", "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", @@ -218,7 +218,7 @@ "zod": "^3.20.2" }, "devDependencies": { - "@atproto/dev-env": "^0.3.144", + "@atproto/dev-env": "^0.3.146", "@babel/core": "^7.26.0", "@babel/preset-env": "^7.26.0", "@babel/runtime": "^7.26.0", diff --git a/src/Navigation.tsx b/src/Navigation.tsx index a779e2b8df..5f82772281 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -84,6 +84,7 @@ import {SearchScreen} from '#/screens/Search' import {AboutSettingsScreen} from '#/screens/Settings/AboutSettings' import {AccessibilitySettingsScreen} from '#/screens/Settings/AccessibilitySettings' import {AccountSettingsScreen} from '#/screens/Settings/AccountSettings' +import {ActivityPrivacySettingsScreen} from '#/screens/Settings/ActivityPrivacySettings' import {AppearanceSettingsScreen} from '#/screens/Settings/AppearanceSettings' import {AppIconSettingsScreen} from '#/screens/Settings/AppIconSettings' import {AppPasswordsScreen} from '#/screens/Settings/AppPasswords' @@ -391,6 +392,14 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) { requireAuth: true, }} /> + ActivityPrivacySettingsScreen} + options={{ + title: title(msg`Privacy and Security`), + requireAuth: true, + }} + /> NotificationSettingsScreen} diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts index c92be34c23..abc1dc4f40 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts @@ -51,6 +51,7 @@ export type CommonNavigatorParams = { AppearanceSettings: undefined AccountSettings: undefined PrivacyAndSecuritySettings: undefined + ActivityPrivacySettings: undefined ContentAndMediaSettings: undefined NotificationSettings: undefined ReplyNotificationSettings: undefined diff --git a/src/routes.ts b/src/routes.ts index b66a0ae53f..763f060a1c 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -50,6 +50,7 @@ export const router = new Router({ SavedFeeds: '/settings/saved-feeds', AccountSettings: '/settings/account', PrivacyAndSecuritySettings: '/settings/privacy-and-security', + ActivityPrivacySettings: '/settings/privacy-and-security/activity', ContentAndMediaSettings: '/settings/content-and-media', InterestsSettings: '/settings/interests', AboutSettings: '/settings/about', diff --git a/src/screens/Settings/AccessibilitySettings.tsx b/src/screens/Settings/AccessibilitySettings.tsx index ee26697d2d..dbabd2f6f3 100644 --- a/src/screens/Settings/AccessibilitySettings.tsx +++ b/src/screens/Settings/AccessibilitySettings.tsx @@ -1,8 +1,8 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {NativeStackScreenProps} from '@react-navigation/native-stack' +import {type NativeStackScreenProps} from '@react-navigation/native-stack' -import {CommonNavigatorParams} from '#/lib/routes/types' +import {type CommonNavigatorParams} from '#/lib/routes/types' import {isNative} from '#/platform/detection' import { useHapticsDisabled, @@ -16,12 +16,10 @@ import { } from '#/state/preferences/large-alt-badge' import * as SettingsList from '#/screens/Settings/components/SettingsList' import {atoms as a} from '#/alf' -import {Admonition} from '#/components/Admonition' import * as Toggle from '#/components/forms/Toggle' import {Accessibility_Stroke2_Corner2_Rounded as AccessibilityIcon} from '#/components/icons/Accessibility' import {Haptic_Stroke2_Corner2_Rounded as HapticIcon} from '#/components/icons/Haptic' import * as Layout from '#/components/Layout' -import {InlineLinkText} from '#/components/Link' type Props = NativeStackScreenProps< CommonNavigatorParams, @@ -100,19 +98,6 @@ export function AccessibilitySettingsScreen({}: Props) { )} - - - - Autoplay options have moved to the{' '} - - Content and Media settings - - . - - - diff --git a/src/screens/Settings/ActivityPrivacySettings.tsx b/src/screens/Settings/ActivityPrivacySettings.tsx new file mode 100644 index 0000000000..0d12b25001 --- /dev/null +++ b/src/screens/Settings/ActivityPrivacySettings.tsx @@ -0,0 +1,138 @@ +import {View} from 'react-native' +import {type AppBskyNotificationDeclaration} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import { + type AllNavigatorParams, + type NativeStackScreenProps, +} from '#/lib/routes/types' +import { + useNotificationDeclarationMutation, + useNotificationDeclarationQuery, +} from '#/state/queries/activity-subscriptions' +import {atoms as a, useTheme} from '#/alf' +import {Admonition} from '#/components/Admonition' +import * as Toggle from '#/components/forms/Toggle' +import {BellRinging_Stroke2_Corner0_Rounded as BellRingingIcon} from '#/components/icons/BellRinging' +import * as Layout from '#/components/Layout' +import {Loader} from '#/components/Loader' +import * as SettingsList from './components/SettingsList' +import {ItemTextWithSubtitle} from './NotificationSettings/components/ItemTextWithSubtitle' + +type Props = NativeStackScreenProps< + AllNavigatorParams, + 'ActivityPrivacySettings' +> +export function ActivityPrivacySettingsScreen({}: Props) { + const { + data: notificationDeclaration, + isPending, + isError, + } = useNotificationDeclarationQuery() + + return ( + + + + + + Privacy and Security + + + + + + + + + Allow others to get notified of your posts + } + subtitleText={ + + This feature allows users to receive notifications for your + new posts and replies. Who do you want to enable this for? + + } + /> + + + {isError ? ( + + Failed to load preference. + + ) : isPending ? ( + + + + ) : ( + + )} + + + + + ) +} + +export function Inner({ + notificationDeclaration, +}: { + notificationDeclaration: { + uri?: string + cid?: string + value: AppBskyNotificationDeclaration.Record + } +}) { + const t = useTheme() + const {_} = useLingui() + const {mutate} = useNotificationDeclarationMutation() + + const onChangeFilter = ([declaration]: string[]) => { + mutate({ + $type: 'app.bsky.notification.declaration', + allowSubscriptions: declaration, + }) + } + + return ( + + + + + + Anyone who follows me + + + + + + Only followers who I follow + + + + + + No one + + + + + ) +} diff --git a/src/screens/Settings/AppPasswords.tsx b/src/screens/Settings/AppPasswords.tsx index 9a900a3ee5..05ebcd80df 100644 --- a/src/screens/Settings/AppPasswords.tsx +++ b/src/screens/Settings/AppPasswords.tsx @@ -7,12 +7,12 @@ import Animated, { LinearTransition, StretchOutY, } from 'react-native-reanimated' -import {ComAtprotoServerListAppPasswords} from '@atproto/api' +import {type ComAtprotoServerListAppPasswords} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {NativeStackScreenProps} from '@react-navigation/native-stack' +import {type NativeStackScreenProps} from '@react-navigation/native-stack' -import {CommonNavigatorParams} from '#/lib/routes/types' +import {type CommonNavigatorParams} from '#/lib/routes/types' import {cleanError} from '#/lib/strings/errors' import {isWeb} from '#/platform/detection' import { diff --git a/src/screens/Settings/AppearanceSettings.tsx b/src/screens/Settings/AppearanceSettings.tsx index 4a8a61cd23..d0158aaa84 100644 --- a/src/screens/Settings/AppearanceSettings.tsx +++ b/src/screens/Settings/AppearanceSettings.tsx @@ -1,4 +1,4 @@ -import React, {useCallback} from 'react' +import {useCallback} from 'react' import Animated, { FadeInUp, FadeOutUp, @@ -9,14 +9,17 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {IS_INTERNAL} from '#/lib/app-info' -import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types' +import { + type CommonNavigatorParams, + type NativeStackScreenProps, +} from '#/lib/routes/types' import {useGate} from '#/lib/statsig/statsig' import {isNative} from '#/platform/detection' import {useSetThemePrefs, useThemePrefs} from '#/state/shell' import {SettingsListItem as AppIconSettingsListItem} from '#/screens/Settings/AppIconSettings/SettingsListItem' import {atoms as a, native, useAlf, useTheme} from '#/alf' import * as ToggleButton from '#/components/forms/ToggleButton' -import {Props as SVGIconProps} from '#/components/icons/common' +import {type Props as SVGIconProps} from '#/components/icons/common' import {Moon_Stroke2_Corner0_Rounded as MoonIcon} from '#/components/icons/Moon' import {Phone_Stroke2_Corner0_Rounded as PhoneIcon} from '#/components/icons/Phone' import {TextSize_Stroke2_Corner0_Rounded as TextSize} from '#/components/icons/TextSize' diff --git a/src/screens/Settings/ExternalMediaPreferences.tsx b/src/screens/Settings/ExternalMediaPreferences.tsx index ae859295f8..1f0040fb38 100644 --- a/src/screens/Settings/ExternalMediaPreferences.tsx +++ b/src/screens/Settings/ExternalMediaPreferences.tsx @@ -2,9 +2,12 @@ import {Fragment} from 'react' import {View} from 'react-native' import {Trans} from '@lingui/macro' -import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types' import { - EmbedPlayerSource, + type CommonNavigatorParams, + type NativeStackScreenProps, +} from '#/lib/routes/types' +import { + type EmbedPlayerSource, externalEmbedLabels, } from '#/lib/strings/embed-player' import { diff --git a/src/screens/Settings/FollowingFeedPreferences.tsx b/src/screens/Settings/FollowingFeedPreferences.tsx index ea9455ab1a..7f1ae1d326 100644 --- a/src/screens/Settings/FollowingFeedPreferences.tsx +++ b/src/screens/Settings/FollowingFeedPreferences.tsx @@ -1,7 +1,10 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types' +import { + type CommonNavigatorParams, + type NativeStackScreenProps, +} from '#/lib/routes/types' import { usePreferencesQuery, useSetFeedViewPreferencesMutation, diff --git a/src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx b/src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx index 487827d66b..12e965699d 100644 --- a/src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx +++ b/src/screens/Settings/NotificationSettings/components/PreferenceControls.tsx @@ -114,7 +114,7 @@ export function Inner({ a.py_xs, platform({ native: [a.justify_between], - web: [a.flex_row_reverse, a.gap_md], + web: [a.flex_row_reverse, a.gap_sm], }), ]}> + style={[a.flex_row, a.py_xs, a.gap_sm]}> + style={[a.flex_row, a.py_xs, a.gap_sm]}> - Activity from others} subtitleText={ diff --git a/src/screens/Settings/PrivacyAndSecuritySettings.tsx b/src/screens/Settings/PrivacyAndSecuritySettings.tsx index 61a8f81cc9..1305108461 100644 --- a/src/screens/Settings/PrivacyAndSecuritySettings.tsx +++ b/src/screens/Settings/PrivacyAndSecuritySettings.tsx @@ -1,14 +1,17 @@ import {View} from 'react-native' +import {type AppBskyNotificationDeclaration} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {type NativeStackScreenProps} from '@react-navigation/native-stack' import {type CommonNavigatorParams} from '#/lib/routes/types' +import {useNotificationDeclarationQuery} from '#/state/queries/activity-subscriptions' import {useAppPasswordsQuery} from '#/state/queries/app-passwords' import {useSession} from '#/state/session' import * as SettingsList from '#/screens/Settings/components/SettingsList' import {atoms as a, useTheme} from '#/alf' import * as Admonition from '#/components/Admonition' +import {BellRinging_Stroke2_Corner0_Rounded as BellRingingIcon} from '#/components/icons/BellRinging' import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlashIcon} from '#/components/icons/EyeSlash' import {Key_Stroke2_Corner2_Rounded as KeyIcon} from '#/components/icons/Key' import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/icons/Shield' @@ -16,6 +19,7 @@ import * as Layout from '#/components/Layout' import {InlineLinkText} from '#/components/Link' import {Email2FAToggle} from './components/Email2FAToggle' import {PwiOptOut} from './components/PwiOptOut' +import {ItemTextWithSubtitle} from './NotificationSettings/components/ItemTextWithSubtitle' type Props = NativeStackScreenProps< CommonNavigatorParams, @@ -26,6 +30,11 @@ export function PrivacyAndSecuritySettingsScreen({}: Props) { const t = useTheme() const {data: appPasswords} = useAppPasswordsQuery() const {currentAccount} = useSession() + const { + data: notificationDeclaration, + isPending, + isError, + } = useNotificationDeclarationQuery() return ( @@ -71,6 +80,22 @@ export function PrivacyAndSecuritySettingsScreen({}: Props) { )} + + + Allow others get notified of your posts} + subtitleText={ + + } + showSkeleton={isPending} + /> + @@ -111,3 +136,26 @@ export function PrivacyAndSecuritySettingsScreen({}: Props) { ) } + +function NotificationDeclaration({ + data, + isError, +}: { + data?: { + value: AppBskyNotificationDeclaration.Record + } + isError?: boolean +}) { + if (isError) { + return Error loading preference + } + switch (data?.value?.allowSubscriptions) { + case 'mutuals': + return Only people you follow + case 'none': + return No one + case 'followers': + default: + return Only your followers + } +} diff --git a/src/screens/Settings/Settings.tsx b/src/screens/Settings/Settings.tsx index e1d1970708..2ee3af78d6 100644 --- a/src/screens/Settings/Settings.tsx +++ b/src/screens/Settings/Settings.tsx @@ -3,7 +3,7 @@ import {LayoutAnimation, Pressable, View} from 'react-native' import {Linking} from 'react-native' import {useReducedMotion} from 'react-native-reanimated' import {type AppBskyActorDefs, moderateProfile} from '@atproto/api' -import {msg, t, Trans} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' import {type NativeStackScreenProps} from '@react-navigation/native-stack' @@ -384,7 +384,7 @@ function DevOptions() { ...persisted.get('reminders'), lastEmailConfirm: lastEmailConfirm.toISOString(), }) - Toast.show(t`You probably want to restart the app now.`) + Toast.show(_(msg`You probably want to restart the app now.`)) } return ( diff --git a/src/screens/Settings/components/SettingsList.tsx b/src/screens/Settings/components/SettingsList.tsx index 520df41187..6d17990478 100644 --- a/src/screens/Settings/components/SettingsList.tsx +++ b/src/screens/Settings/components/SettingsList.tsx @@ -1,15 +1,20 @@ -import React, {useContext, useMemo} from 'react' -import {GestureResponderEvent, StyleProp, View, ViewStyle} from 'react-native' +import {createContext, useContext, useMemo} from 'react' +import { + type GestureResponderEvent, + type StyleProp, + View, + type ViewStyle, +} from 'react-native' import {HITSLOP_10} from '#/lib/constants' -import {atoms as a, useTheme, ViewStyleProp} from '#/alf' +import {atoms as a, useTheme, type ViewStyleProp} from '#/alf' import * as Button from '#/components/Button' import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRightIcon} from '#/components/icons/Chevron' -import {Link, LinkProps} from '#/components/Link' +import {Link, type LinkProps} from '#/components/Link' import {createPortalGroup} from '#/components/Portal' import {Text} from '#/components/Typography' -const ItemContext = React.createContext({ +const ItemContext = createContext({ destructive: false, withinGroup: false, }) @@ -91,7 +96,7 @@ export function Item({ a.px_xl, a.py_sm, a.align_center, - a.gap_md, + a.gap_sm, a.w_full, a.flex_row, {minHeight: 48}, @@ -100,9 +105,9 @@ export function Item({ // existing padding a.pl_xl.paddingLeft + // icon - 28 + + 24 + // gap - a.gap_md.gap, + a.gap_sm.gap, }, style, ]}> @@ -175,7 +180,7 @@ export function PressableItem({ export function ItemIcon({ icon: Comp, - size = 'xl', + size = 'lg', color: colorProp, }: Omit, 'position'> & { color?: string diff --git a/src/state/queries/activity-subscriptions.ts b/src/state/queries/activity-subscriptions.ts new file mode 100644 index 0000000000..039c605312 --- /dev/null +++ b/src/state/queries/activity-subscriptions.ts @@ -0,0 +1,77 @@ +import {type AppBskyNotificationDeclaration} from '@atproto/api' +import {t} from '@lingui/macro' +import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' + +import {useAgent, useSession} from '#/state/session' +import * as Toast from '#/view/com/util/Toast' + +const RQKEY_getNotificationDeclaration = ['notification-declaration'] + +export function useNotificationDeclarationQuery() { + const agent = useAgent() + const {currentAccount} = useSession() + return useQuery({ + queryKey: RQKEY_getNotificationDeclaration, + queryFn: async () => { + try { + const response = await agent.app.bsky.notification.declaration.get({ + repo: currentAccount!.did, + rkey: 'self', + }) + return response + } catch (err) { + if ( + err instanceof Error && + err.message.startsWith('Could not locate record') + ) { + return { + value: { + $type: 'app.bsky.notification.declaration', + allowSubscriptions: 'followers', + } satisfies AppBskyNotificationDeclaration.Record, + } + } else { + throw err + } + } + }, + }) +} + +export function useNotificationDeclarationMutation() { + const agent = useAgent() + const {currentAccount} = useSession() + const queryClient = useQueryClient() + return useMutation({ + mutationFn: async (record: AppBskyNotificationDeclaration.Record) => { + const response = await agent.com.atproto.repo.putRecord({ + repo: currentAccount!.did, + collection: 'app.bsky.notification.declaration', + rkey: 'self', + record, + }) + return response + }, + onMutate: value => { + queryClient.setQueryData( + RQKEY_getNotificationDeclaration, + (old?: { + uri: string + cid: string + value: AppBskyNotificationDeclaration.Record + }) => { + if (!old) return old + return { + value, + } + }, + ) + }, + onError: () => { + Toast.show(t`Failed to update notification declaration`) + queryClient.invalidateQueries({ + queryKey: RQKEY_getNotificationDeclaration, + }) + }, + }) +} diff --git a/src/state/queries/messages/actor-declaration.ts b/src/state/queries/messages/actor-declaration.ts index 34fb10935e..a5adb39d9f 100644 --- a/src/state/queries/messages/actor-declaration.ts +++ b/src/state/queries/messages/actor-declaration.ts @@ -1,4 +1,4 @@ -import {AppBskyActorDefs} from '@atproto/api' +import {type AppBskyActorDefs} from '@atproto/api' import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' @@ -19,7 +19,7 @@ export function useUpdateActorDeclaration({ return useMutation({ mutationFn: async (allowIncoming: 'all' | 'none' | 'following') => { if (!currentAccount) throw new Error('Not signed in') - const result = await agent.api.com.atproto.repo.putRecord({ + const result = await agent.com.atproto.repo.putRecord({ repo: currentAccount.did, collection: 'chat.bsky.actor.declaration', rkey: 'self', diff --git a/yarn.lock b/yarn.lock index 3280cbb9b7..4e74c53c52 100644 --- a/yarn.lock +++ b/yarn.lock @@ -63,10 +63,10 @@ "@atproto/xrpc" "^0.7.0" "@atproto/xrpc-server" "^0.8.0" -"@atproto/api@^0.15.16": - version "0.15.16" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.15.16.tgz#1962e7067e03a661e17c3164874596ef1e7ed7ad" - integrity sha512-ZNBrzBg2l0lHreKik1lJn8lrhAktwlY8NUPBU/hO9dwjAnDHQTiSzNFZt65dp9djmqZ75sX/VJ+heNuaJBvnhQ== +"@atproto/api@^0.15.17": + version "0.15.17" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.15.17.tgz#851f0bb138817509b5d453661eeb694db1f953a8" + integrity sha512-spHsfs052kamVX2foY4gz+wc8y4VdteXCG60xpG0pFsXJ47ueLVM8qdT/v9+Ii9FNRAvE+VVcGyAo/94P9Smrw== dependencies: "@atproto/common-web" "^0.4.2" "@atproto/lexicon" "^0.4.11" @@ -77,14 +77,14 @@ tlds "^1.234.0" zod "^3.23.8" -"@atproto/aws@^0.2.22": - version "0.2.22" - resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.22.tgz#14a664c06e3569945e4ab143d3a8a03400c7d1de" - integrity sha512-xZ+0/zHHmpgzdLJGTDkFl5Wd39Wm5MyyMLdGYSzyt0wGTBmH6Ktp7ZgR8rmQVNYN1+VkMcdClAiNhg+BSH3mRw== +"@atproto/aws@^0.2.24": + version "0.2.24" + resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.24.tgz#c8e7a804710d70be3aa2fa292c1ece4c05127891" + integrity sha512-4XZQGitPJR56tFt1bzPJKOqp3vTVcfVsEAFo9FGWp7Es+jj742aVgfWEe64O0VoZp3ZTiD7XhwsLJArz7NJTlQ== dependencies: "@atproto/common" "^0.4.11" "@atproto/crypto" "^0.4.4" - "@atproto/repo" "^0.8.2" + "@atproto/repo" "^0.8.4" "@aws-sdk/client-cloudfront" "^3.261.0" "@aws-sdk/client-kms" "^3.196.0" "@aws-sdk/client-s3" "^3.224.0" @@ -94,21 +94,21 @@ multiformats "^9.9.0" uint8arrays "3.0.0" -"@atproto/bsky@^0.0.161": - version "0.0.161" - resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.161.tgz#671280c1d40f5c4eb0cc31d338a9e950acbf0ce0" - integrity sha512-L4uzadjt+oyVq3+W7rc1A+X2DyZDsTfeSD15w7k6+6JzICp32qavDuVjut3CIBqXCt7ykvSDujApyLsB/lcWJQ== +"@atproto/bsky@^0.0.163": + version "0.0.163" + resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.163.tgz#b58445a255419452c62d45f8954973927bc7f220" + integrity sha512-dOcO4KTSutw4nTCvYfe7d4EdBAxjTOQBubbD3rTGHpFhGxFxudk0oXccvmNSaPolGIn2xJu6MSFKgXI7HIZXGg== dependencies: "@atproto-labs/fetch-node" "0.1.9" "@atproto-labs/xrpc-utils" "0.0.16" - "@atproto/api" "^0.15.16" + "@atproto/api" "^0.15.17" "@atproto/common" "^0.4.11" "@atproto/crypto" "^0.4.4" "@atproto/did" "^0.1.5" "@atproto/identity" "^0.4.8" "@atproto/lexicon" "^0.4.11" - "@atproto/repo" "^0.8.2" - "@atproto/sync" "^0.1.26" + "@atproto/repo" "^0.8.4" + "@atproto/sync" "^0.1.28" "@atproto/syntax" "^0.4.0" "@atproto/xrpc-server" "^0.8.0" "@bufbuild/protobuf" "^1.5.0" @@ -218,21 +218,21 @@ "@noble/hashes" "^1.6.1" uint8arrays "3.0.0" -"@atproto/dev-env@^0.3.144": - version "0.3.144" - resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.144.tgz#cd2949ff870ca4cde23b4c377b08740a2e64151f" - integrity sha512-ND0oGp7itSnXxlAHlFxYjGFyCcu0f4eSucImVtKRxTcW8UeyyTtJcQP8OyNvtC8j13YjbW124r0g25Wlm0j9XQ== +"@atproto/dev-env@^0.3.146": + version "0.3.146" + resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.146.tgz#dfe6bff226f580eaa9aa8bb8d2e1a7205fa1ca11" + integrity sha512-V1iVpMx281dPIAyyAd7ApgggNHWAyXmgXpXQ2WbejtyjAbcpH0y8swheCxpVdPKgH2PVUaJWXOvjUCaQ8fpmsA== dependencies: - "@atproto/api" "^0.15.16" - "@atproto/bsky" "^0.0.161" + "@atproto/api" "^0.15.17" + "@atproto/bsky" "^0.0.163" "@atproto/bsync" "^0.0.20" "@atproto/common-web" "^0.4.2" "@atproto/crypto" "^0.4.4" "@atproto/identity" "^0.4.8" "@atproto/lexicon" "^0.4.11" - "@atproto/ozone" "^0.1.121" - "@atproto/pds" "^0.4.150" - "@atproto/sync" "^0.1.26" + "@atproto/ozone" "^0.1.122" + "@atproto/pds" "^0.4.152" + "@atproto/sync" "^0.1.28" "@atproto/syntax" "^0.4.0" "@atproto/xrpc-server" "^0.8.0" "@did-plc/lib" "^0.0.1" @@ -259,18 +259,18 @@ "@atproto/common-web" "^0.4.2" "@atproto/crypto" "^0.4.4" -"@atproto/jwk-jose@0.1.8": - version "0.1.8" - resolved "https://registry.yarnpkg.com/@atproto/jwk-jose/-/jwk-jose-0.1.8.tgz#2dc8ad2cc900e7bc231add293f6518b06dc017ec" - integrity sha512-aoU2Q0GpIl388KhCcv9YvAxNscALUv3xzLq5gjVPdJ+zmqw94nGZNcjiNvpnbfS+VQM9e2DrrTuwmDXnxfrrSA== +"@atproto/jwk-jose@0.1.9": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@atproto/jwk-jose/-/jwk-jose-0.1.9.tgz#bd4a899ea2d497808300c40106795f5645c01f75" + integrity sha512-HT9GcUe6htDxI5OSYXWdeS6QZ9lpuDDvJk508ppi8a48E/1f8eumoM0QhgbFRF9IKAnnFrtnZDOAvljQzFKwwQ== dependencies: - "@atproto/jwk" "0.3.0" + "@atproto/jwk" "0.4.0" jose "^5.2.0" -"@atproto/jwk@0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@atproto/jwk/-/jwk-0.3.0.tgz#275fa676f6b5988ddedf4ee0475dd285de9b831b" - integrity sha512-MIAXyNMGu1tCNHjqW/8jqfE/wgWCIoK2cJ0mR6UxwhNPvkbe35TcpRYJdtQu/E6MUd7TziyDBa/GO4dKAiePhQ== +"@atproto/jwk@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@atproto/jwk/-/jwk-0.4.0.tgz#f32265be172492c38434c556a124b954f249cee8" + integrity sha512-tvp4iZrzqEzKCeTOKz50/o6WdsZzOuWmWjF6On5QAp04fLwLpsFu2Hixgx/lA1KBO0O4sns7YSGcAqSSX6Rdog== dependencies: multiformats "^9.9.0" zod "^3.23.8" @@ -286,32 +286,32 @@ multiformats "^9.9.0" zod "^3.23.8" -"@atproto/oauth-provider-api@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-api/-/oauth-provider-api-0.1.4.tgz#a775182e3648dc693a04e3cb604eb62cd9ddfd8c" - integrity sha512-3PRrf0gTAVMCETjtIH/3AaQaHBDbjsRBc/OYrlWBZ9IPplchBXtQGH/KcnjE4kK2Ef8p45qQSl3dNWg3EXsbHQ== +"@atproto/oauth-provider-api@0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-api/-/oauth-provider-api-0.1.6.tgz#769a70caaac9b5144f9f867518523d1568a6b47c" + integrity sha512-4Q6ZCnTmmdiWiA+KMrfbZmqjxTSgMe+YE68+3RccwOCIgPt171TiDHGKIayep9n1RDnuucVQoqvVXOT4kmAsjw== dependencies: - "@atproto/jwk" "0.3.0" - "@atproto/oauth-types" "0.3.0" + "@atproto/jwk" "0.4.0" + "@atproto/oauth-types" "0.4.0" -"@atproto/oauth-provider-frontend@0.1.8": - version "0.1.8" - resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-frontend/-/oauth-provider-frontend-0.1.8.tgz#21d944566c63f54524f239a10f7c65d150982f40" - integrity sha512-uqfHv+n2xq7vTpuBP1Red7PhpaAbbJbwSbRsSfplJQ16XmF5NCMU8dHGCGRTEHngLZ9UquuIefN3w1QTrNzD0w== +"@atproto/oauth-provider-frontend@0.1.10": + version "0.1.10" + resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-frontend/-/oauth-provider-frontend-0.1.10.tgz#d7176819d0ae1401ca5d70f7afec253621901a79" + integrity sha512-bOFpi5OIxWv4Q9ci1+PAXEzIZaiu5inepC7pRFYqgqgLoCO0MWH/5Qkn/f6jMpDwPdtBqAiPg9tjE7E3le6NJA== optionalDependencies: - "@atproto/oauth-provider-api" "0.1.4" + "@atproto/oauth-provider-api" "0.1.6" -"@atproto/oauth-provider-ui@0.1.9": - version "0.1.9" - resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-ui/-/oauth-provider-ui-0.1.9.tgz#8c43a1affa94ecb537072e6d569b8a24cdd42e72" - integrity sha512-a6/VAeQWRMxpgnqo/TuqXg3EW2tO68jLh8Mv1uyV1NiZbT7fNlgkII/djIl3fLoEa95I3p236NZxjhKELSBbGg== +"@atproto/oauth-provider-ui@0.1.11": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-ui/-/oauth-provider-ui-0.1.11.tgz#cb6194ac0b93f1d4b5d6717f80c55a3a20a8c690" + integrity sha512-9fflyDt4Y3RDJIfbonxVeMbQtLLQrkQSDhWhPXp9xbZ/uYBddaAw+svBfFoMY7dxdlJbQeUPobsUctEm3qAILg== optionalDependencies: - "@atproto/oauth-provider-api" "0.1.4" + "@atproto/oauth-provider-api" "0.1.6" -"@atproto/oauth-provider@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.9.1.tgz#0147b75d1ad444455159f0a687ce87b3b49a2894" - integrity sha512-2Gm3jv45cGLmUQV0C4/orCJBsHu4wajy+JTN9f/ATX3vvjnFtAd/1GRvAMKDGXtdF7VIjNFlD+4lqhoDxYJpng== +"@atproto/oauth-provider@^0.9.3": + version "0.9.3" + resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.9.3.tgz#047b2e520e5cf127385adddc1dca47207b0ca113" + integrity sha512-TAhsCYDB/1twEA1vqjLAz7lxKI8W59eNs239MujE35Cc9l4lRHyMopoFv5JmgNnxDvloB5l6RxpTbXVC6wnKpQ== dependencies: "@atproto-labs/fetch" "0.2.3" "@atproto-labs/fetch-node" "0.1.9" @@ -320,12 +320,12 @@ "@atproto-labs/simple-store-memory" "0.1.3" "@atproto/common" "^0.4.11" "@atproto/did" "0.1.5" - "@atproto/jwk" "0.3.0" - "@atproto/jwk-jose" "0.1.8" - "@atproto/oauth-provider-api" "0.1.4" - "@atproto/oauth-provider-frontend" "0.1.8" - "@atproto/oauth-provider-ui" "0.1.9" - "@atproto/oauth-types" "0.3.0" + "@atproto/jwk" "0.4.0" + "@atproto/jwk-jose" "0.1.9" + "@atproto/oauth-provider-api" "0.1.6" + "@atproto/oauth-provider-frontend" "0.1.10" + "@atproto/oauth-provider-ui" "0.1.11" + "@atproto/oauth-types" "0.4.0" "@atproto/syntax" "0.4.0" "@hapi/accept" "^6.0.3" "@hapi/address" "^5.1.1" @@ -339,20 +339,20 @@ jose "^5.2.0" zod "^3.23.8" -"@atproto/oauth-types@0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@atproto/oauth-types/-/oauth-types-0.3.0.tgz#8d49d939486ac281bc13d0b1fe4462b7e519fdf0" - integrity sha512-ptfsJARKODXfuOoDQag4a6PpEkDEj4Urz3jOmnQZy2YspPc/TNm1o0HglU0YehELv1vfhh9gEz40BJztPPhiLA== +"@atproto/oauth-types@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@atproto/oauth-types/-/oauth-types-0.4.0.tgz#fb110717dd1e8593adffc6eaa85e7ab4f0713740" + integrity sha512-FrRH9JsPw9H4JxfPDrbrI+pB102tbHTygajfHay7xwz78HPOjSbWPRgWW2hYS4w8vDYdB3PYbBj1jPoKetW7LA== dependencies: - "@atproto/jwk" "0.3.0" + "@atproto/jwk" "0.4.0" zod "^3.23.8" -"@atproto/ozone@^0.1.121": - version "0.1.121" - resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.121.tgz#309b7e876f3b598ed4e79bb5a79e2346931588fe" - integrity sha512-kc3NxiXSPqQmWz8yXlV5cFnZ469ViQd0AexEMw467AcB8ikK1WSxhLsa1EiNAQuLOOpyeXSmAKGAUFHzSOIMpw== +"@atproto/ozone@^0.1.122": + version "0.1.122" + resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.122.tgz#4eabeb20aa68b9a7c65169a2e8db45cbe4376c86" + integrity sha512-yn/lCL+o+Lpj2+XABGx3cvjRU0YXKlrXfJHaGvGbG5KyY0qs8TcK5RV6aL33DqEacF07wXql/D8Ccwj1b1qCqA== dependencies: - "@atproto/api" "^0.15.16" + "@atproto/api" "^0.15.17" "@atproto/common" "^0.4.11" "@atproto/crypto" "^0.4.4" "@atproto/identity" "^0.4.8" @@ -377,21 +377,21 @@ undici "^6.14.1" ws "^8.12.0" -"@atproto/pds@^0.4.150": - version "0.4.150" - resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.150.tgz#45686b05b8ed46e265efa5231ab16e6eda72a8e8" - integrity sha512-CPT6H2uDTe4ZAyxQbws2dIlmdFFf6GQGwMc0OE3kI1wBBaLHprpexjM2Gd4ObtYNxGOOV0fwoCDAth8qqZ4XVw== +"@atproto/pds@^0.4.152": + version "0.4.152" + resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.152.tgz#4a7b5ebda2eb0c8b7dbd60df5660ba30169b73e9" + integrity sha512-weXY6M5QHGa0hQ92tJn78OLENf3q0E72tPKE8lCASgj2YTyxaIy0vckfUyaAlyxkR0KpQqRF+WJuAAs04PJwUA== dependencies: "@atproto-labs/fetch-node" "0.1.9" "@atproto-labs/xrpc-utils" "0.0.16" - "@atproto/api" "^0.15.16" - "@atproto/aws" "^0.2.22" + "@atproto/api" "^0.15.17" + "@atproto/aws" "^0.2.24" "@atproto/common" "^0.4.11" "@atproto/crypto" "^0.4.4" "@atproto/identity" "^0.4.8" "@atproto/lexicon" "^0.4.11" - "@atproto/oauth-provider" "^0.9.1" - "@atproto/repo" "^0.8.2" + "@atproto/oauth-provider" "^0.9.3" + "@atproto/repo" "^0.8.4" "@atproto/syntax" "^0.4.0" "@atproto/xrpc" "^0.7.0" "@atproto/xrpc-server" "^0.8.0" @@ -424,10 +424,10 @@ undici "^6.19.8" zod "^3.23.8" -"@atproto/repo@^0.8.2": - version "0.8.2" - resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.8.2.tgz#7953cb2c637c94505da76f74a784b2aae050c204" - integrity sha512-lP0g5Uw3TUC2Tc7te8YKCpRoIhBYI+Uvn11fupGEaMcMjgLdYtB0Kc0AiqWXF42KqlBG9dAEoJITi2GRzDNHUg== +"@atproto/repo@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.8.4.tgz#f6a1b4bce8cf86cd1825069f9cd2916a5f86e774" + integrity sha512-WgyARo6UcOnhbRsRVuNjXOH5MPTTHVDsaIavPeQl5erq5foE/pQKC7B7FLTJmhpC6GPZHJ5M2doAyXRXv5UHGA== dependencies: "@atproto/common" "^0.4.11" "@atproto/common-web" "^0.4.2" @@ -439,15 +439,15 @@ varint "^6.0.0" zod "^3.23.8" -"@atproto/sync@^0.1.26": - version "0.1.26" - resolved "https://registry.yarnpkg.com/@atproto/sync/-/sync-0.1.26.tgz#6be2876be612d9cd704452598ee679b2e912cfe3" - integrity sha512-bpUIajtPrE3RgFW8mIfrI4EM/LJ4JjQhI5fsqc78zCHZawuflpllf1aH70roDWWiskMWoiLWnVRxdYXdeEgbXA== +"@atproto/sync@^0.1.28": + version "0.1.28" + resolved "https://registry.yarnpkg.com/@atproto/sync/-/sync-0.1.28.tgz#7c5c469dd899b4be86e5d993af66646c71d63eaf" + integrity sha512-faCsOwcYQHxHmNWRPykV0hTccXaG15XoUMZozfmoFOKFSliTgDETTovSAVe05mNSBUvMWUGl8fdEwHRzq1Q8sA== dependencies: "@atproto/common" "^0.4.11" "@atproto/identity" "^0.4.8" "@atproto/lexicon" "^0.4.11" - "@atproto/repo" "^0.8.2" + "@atproto/repo" "^0.8.4" "@atproto/syntax" "^0.4.0" "@atproto/xrpc-server" "^0.8.0" multiformats "^9.9.0"