@oxyhq/services 13.0.2 → 13.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/index.js +0 -11
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/components/AccountMenuButton.js +8 -10
- package/lib/commonjs/ui/components/AccountMenuButton.js.map +1 -1
- package/lib/commonjs/ui/components/AccountSwitcher.js +65 -35
- package/lib/commonjs/ui/components/AccountSwitcher.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +124 -93
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +2 -2
- package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js +12 -12
- package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/useServicesQueries.js +8 -7
- package/lib/commonjs/ui/hooks/queries/useServicesQueries.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +11 -6
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +3 -3
- package/lib/commonjs/ui/screens/CreateAccountScreen.js +6 -4
- package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +8 -7
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +13 -13
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HistoryViewScreen.js +7 -7
- package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +5 -5
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ManageAccountScreen.js +17 -18
- package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +3 -3
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +9 -9
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +4 -4
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SearchSettingsScreen.js +6 -6
- package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +6 -6
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +4 -4
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +4 -4
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
- package/lib/module/index.js +0 -5
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/components/AccountMenuButton.js +8 -10
- package/lib/module/ui/components/AccountMenuButton.js.map +1 -1
- package/lib/module/ui/components/AccountSwitcher.js +65 -35
- package/lib/module/ui/components/AccountSwitcher.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +124 -93
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/queries/useAccountQueries.js +2 -2
- package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
- package/lib/module/ui/hooks/queries/usePaymentQueries.js +12 -12
- package/lib/module/ui/hooks/queries/usePaymentQueries.js.map +1 -1
- package/lib/module/ui/hooks/queries/useServicesQueries.js +9 -7
- package/lib/module/ui/hooks/queries/useServicesQueries.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +11 -6
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +3 -3
- package/lib/module/ui/screens/CreateAccountScreen.js +6 -4
- package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/EditProfileFieldScreen.js +8 -7
- package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +13 -13
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/HistoryViewScreen.js +7 -7
- package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +5 -5
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/ManageAccountScreen.js +17 -18
- package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +3 -3
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/PrivacySettingsScreen.js +9 -9
- package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +1 -1
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/SavesCollectionsScreen.js +4 -4
- package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
- package/lib/module/ui/screens/SearchSettingsScreen.js +6 -6
- package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/WelcomeNewUserScreen.js +6 -6
- package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustCenterScreen.js +4 -4
- package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js +4 -4
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +0 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts +5 -7
- package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/AccountSwitcher.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/ActivityIndicator.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/ActivityIndicator.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/CrossFadeIcon.d.ts +2 -1
- package/lib/typescript/commonjs/ui/components/CrossFadeIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/FontLoader.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/FontLoader.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/HelperText.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/HelperText.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/TextField/Addons/Outline.d.ts +2 -1
- package/lib/typescript/commonjs/ui/components/TextField/Addons/Outline.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/TextField/Addons/Underline.d.ts +2 -1
- package/lib/typescript/commonjs/ui/components/TextField/Addons/Underline.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/TextField/Adornment/TextFieldAffix.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/TextField/Adornment/TextFieldIcon.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/TextField/Label/InputLabel.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/TextField/Label/LabelBackground.d.ts +2 -1
- package/lib/typescript/commonjs/ui/components/TextField/Label/LabelBackground.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/TextField/TextFieldFlat.d.ts +2 -1
- package/lib/typescript/commonjs/ui/components/TextField/TextFieldFlat.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/TextField/TextFieldOutlined.d.ts +2 -1
- package/lib/typescript/commonjs/ui/components/TextField/TextFieldOutlined.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +11 -26
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/ThemeContext.d.ts +1 -1
- package/lib/typescript/commonjs/ui/context/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts +3 -3
- package/lib/typescript/commonjs/ui/screens/CreateAccountScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +60 -61
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/client.d.ts +26 -26
- package/lib/typescript/module/ui/client.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/AccountMenuButton.d.ts +5 -7
- package/lib/typescript/module/ui/components/AccountMenuButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/AccountSwitcher.d.ts +1 -1
- package/lib/typescript/module/ui/components/AccountSwitcher.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/ActivityIndicator.d.ts +2 -2
- package/lib/typescript/module/ui/components/ActivityIndicator.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/BottomSheetRouter.d.ts +1 -1
- package/lib/typescript/module/ui/components/BottomSheetRouter.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/CrossFadeIcon.d.ts +4 -3
- package/lib/typescript/module/ui/components/CrossFadeIcon.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/FontLoader.d.ts +1 -1
- package/lib/typescript/module/ui/components/FontLoader.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/HelperText.d.ts +1 -1
- package/lib/typescript/module/ui/components/HelperText.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/Icon.d.ts +1 -1
- package/lib/typescript/module/ui/components/Icon.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/IconButton/IconButton.d.ts +3 -3
- package/lib/typescript/module/ui/components/IconButton/IconButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/IconButton/utils.d.ts +1 -1
- package/lib/typescript/module/ui/components/IconButton/utils.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyPayButton.d.ts +1 -1
- package/lib/typescript/module/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/StepBasedScreen.d.ts +2 -2
- package/lib/typescript/module/ui/components/StepBasedScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/Surface.d.ts +2 -2
- package/lib/typescript/module/ui/components/Surface.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Addons/Outline.d.ts +3 -2
- package/lib/typescript/module/ui/components/TextField/Addons/Outline.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Addons/Underline.d.ts +3 -2
- package/lib/typescript/module/ui/components/TextField/Addons/Underline.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldAdornment.d.ts +3 -3
- package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldAdornment.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldAffix.d.ts +3 -3
- package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldAffix.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldIcon.d.ts +4 -4
- package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldIcon.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Adornment/types.d.ts +1 -1
- package/lib/typescript/module/ui/components/TextField/Adornment/types.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Adornment/utils.d.ts +1 -1
- package/lib/typescript/module/ui/components/TextField/Adornment/utils.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Label/InputLabel.d.ts +2 -2
- package/lib/typescript/module/ui/components/TextField/Label/InputLabel.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/Label/LabelBackground.d.ts +3 -2
- package/lib/typescript/module/ui/components/TextField/Label/LabelBackground.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/TextFieldFlat.d.ts +3 -2
- package/lib/typescript/module/ui/components/TextField/TextFieldFlat.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/TextFieldOutlined.d.ts +3 -2
- package/lib/typescript/module/ui/components/TextField/TextFieldOutlined.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/helpers.d.ts +3 -3
- package/lib/typescript/module/ui/components/TextField/helpers.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField/types.d.ts +1 -1
- package/lib/typescript/module/ui/components/TextField/types.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TextField.d.ts +4 -4
- package/lib/typescript/module/ui/components/TextField.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TouchableRipple/TouchableRipple.d.ts +3 -3
- package/lib/typescript/module/ui/components/TouchableRipple/TouchableRipple.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TouchableRipple/TouchableRipple.native.d.ts +3 -3
- package/lib/typescript/module/ui/components/TouchableRipple/TouchableRipple.native.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/TouchableRipple/utils.d.ts +1 -1
- package/lib/typescript/module/ui/components/TouchableRipple/utils.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/Typography/AnimatedText.d.ts +3 -3
- package/lib/typescript/module/ui/components/Typography/AnimatedText.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/accountMenuRows.d.ts +1 -1
- package/lib/typescript/module/ui/components/accountMenuRows.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/feedback/ProgressIndicator.d.ts +1 -1
- package/lib/typescript/module/ui/components/feedback/ProgressIndicator.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/feedback/constants.d.ts +1 -1
- package/lib/typescript/module/ui/components/feedback/constants.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/feedback/useFeedbackForm.d.ts +1 -1
- package/lib/typescript/module/ui/components/feedback/useFeedbackForm.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentDetailsStep.d.ts +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentDetailsStep.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentMethodStep.d.ts +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentMethodStep.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentReviewStep.d.ts +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentReviewStep.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentSuccessStep.d.ts +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentSuccessStep.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentSummaryStep.d.ts +1 -1
- package/lib/typescript/module/ui/components/payment/PaymentSummaryStep.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/constants.d.ts +1 -1
- package/lib/typescript/module/ui/components/payment/constants.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/payment/paymentStyles.d.ts +1 -1
- package/lib/typescript/module/ui/components/payment/paymentStyles.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/theming.d.ts +1 -1
- package/lib/typescript/module/ui/components/theming.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts +14 -29
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/ThemeContext.d.ts +1 -1
- package/lib/typescript/module/ui/context/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +2 -2
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queryClient.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/queryClient.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useAuth.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useLanguageManagement.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/useLanguageManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useStorage.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/useStorage.d.ts.map +1 -1
- package/lib/typescript/module/ui/index.d.ts +28 -28
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts +1 -1
- package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountMembersScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/AccountMembersScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts +4 -4
- package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountVerificationScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/AccountVerificationScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AppInfoScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/AppInfoScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AvatarCropScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/AvatarCropScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FAQScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/FAQScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/HelpSupportScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/HelpSupportScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/LanguageSelectorScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/LearnMoreUsernamesScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/LearnMoreUsernamesScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/LegalDocumentsScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/LegalDocumentsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts +2 -2
- package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PremiumSubscriptionScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ProfileScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/SavesCollectionsScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/SearchSettingsScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/UserLinksScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/UserLinksScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/UserListScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/UserListScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustAboutScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustAboutScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustCenterScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustCenterScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustFAQScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustFAQScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustRewardsScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustRewardsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustRulesScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/TrustRulesScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/server.d.ts +2 -2
- package/lib/typescript/module/ui/server.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/fileManagement.d.ts +1 -1
- package/lib/typescript/module/ui/types/fileManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/fileManagement.d.ts +1 -1
- package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
- package/package.json +21 -20
- package/src/index.ts +0 -5
- package/src/ui/components/AccountMenuButton.tsx +9 -11
- package/src/ui/components/AccountSwitcher.tsx +71 -37
- package/src/ui/context/OxyContext.tsx +127 -122
- package/src/ui/hooks/queries/useAccountQueries.ts +2 -2
- package/src/ui/hooks/queries/usePaymentQueries.ts +12 -12
- package/src/ui/hooks/queries/useServicesQueries.ts +9 -6
- package/src/ui/screens/AccountSettingsScreen.tsx +9 -5
- package/src/ui/screens/AccountSwitcherScreen.tsx +3 -3
- package/src/ui/screens/CreateAccountScreen.tsx +6 -4
- package/src/ui/screens/EditProfileFieldScreen.tsx +8 -7
- package/src/ui/screens/FileManagementScreen.tsx +13 -13
- package/src/ui/screens/HistoryViewScreen.tsx +7 -7
- package/src/ui/screens/LanguageSelectorScreen.tsx +5 -5
- package/src/ui/screens/ManageAccountScreen.tsx +17 -18
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +3 -3
- package/src/ui/screens/PrivacySettingsScreen.tsx +9 -9
- package/src/ui/screens/ProfileScreen.tsx +1 -1
- package/src/ui/screens/SavesCollectionsScreen.tsx +5 -5
- package/src/ui/screens/SearchSettingsScreen.tsx +6 -6
- package/src/ui/screens/WelcomeNewUserScreen.tsx +6 -6
- package/src/ui/screens/trust/TrustCenterScreen.tsx +5 -5
- package/src/ui/screens/trust/TrustRewardsScreen.tsx +4 -4
- package/lib/commonjs/ui/components/ActiveAccountBanner.js +0 -144
- package/lib/commonjs/ui/components/ActiveAccountBanner.js.map +0 -1
- package/lib/module/ui/components/ActiveAccountBanner.js +0 -141
- package/lib/module/ui/components/ActiveAccountBanner.js.map +0 -1
- package/lib/typescript/commonjs/ui/components/ActiveAccountBanner.d.ts +0 -4
- package/lib/typescript/commonjs/ui/components/ActiveAccountBanner.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/ActiveAccountBanner.d.ts +0 -4
- package/lib/typescript/module/ui/components/ActiveAccountBanner.d.ts.map +0 -1
- package/src/ui/components/ActiveAccountBanner.tsx +0 -130
|
@@ -111,12 +111,12 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
111
111
|
const {
|
|
112
112
|
activeSessionId,
|
|
113
113
|
switchSession,
|
|
114
|
+
switchToAccount,
|
|
114
115
|
removeSession,
|
|
115
116
|
logout,
|
|
116
117
|
logoutAll,
|
|
117
118
|
accounts,
|
|
118
|
-
|
|
119
|
-
setActingAs,
|
|
119
|
+
user,
|
|
120
120
|
oxyServices,
|
|
121
121
|
} = useOxy();
|
|
122
122
|
const { t, locale } = useI18n();
|
|
@@ -125,6 +125,7 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
125
125
|
const { accounts: deviceAccounts } = useDeviceAccounts();
|
|
126
126
|
|
|
127
127
|
const [busySessionId, setBusySessionId] = useState<string | null>(null);
|
|
128
|
+
const [switchingAccountId, setSwitchingAccountId] = useState<string | null>(null);
|
|
128
129
|
const [removingSessionId, setRemovingSessionId] = useState<string | null>(null);
|
|
129
130
|
const [signingOut, setSigningOut] = useState(false);
|
|
130
131
|
const [signingOutAll, setSigningOutAll] = useState(false);
|
|
@@ -140,19 +141,37 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
140
141
|
return [...current, ...others];
|
|
141
142
|
}, [deviceAccounts]);
|
|
142
143
|
|
|
143
|
-
const isSwitching = busySessionId !== null;
|
|
144
|
+
const isSwitching = busySessionId !== null || switchingAccountId !== null;
|
|
144
145
|
const actionDisabled = isSwitching || signingOut || signingOutAll;
|
|
145
146
|
|
|
147
|
+
// Account ids that are already signed in as REAL device sessions. After a
|
|
148
|
+
// `switchToAccount` the target becomes a device session (and the personal
|
|
149
|
+
// account always is one), so it would otherwise appear BOTH as a device row
|
|
150
|
+
// (Section A) and a graph row (Section B). We dedupe by hiding such accounts
|
|
151
|
+
// from the graph — they show in Section A, where the active one is flagged
|
|
152
|
+
// current.
|
|
153
|
+
const deviceUserIds = useMemo<Set<string>>(
|
|
154
|
+
() => new Set(deviceAccounts.map((account) => account.user.id).filter((id): id is string => Boolean(id))),
|
|
155
|
+
[deviceAccounts],
|
|
156
|
+
);
|
|
157
|
+
|
|
146
158
|
// --- Account graph (Section B) ---
|
|
159
|
+
// The switchable graph minus accounts that are already device sessions
|
|
160
|
+
// (deduped into Section A). This is the set Section B renders and searches.
|
|
161
|
+
const graphAccounts = useMemo<AccountNode[]>(
|
|
162
|
+
() => accounts.filter((node) => !deviceUserIds.has(node.accountId)),
|
|
163
|
+
[accounts, deviceUserIds],
|
|
164
|
+
);
|
|
165
|
+
|
|
147
166
|
const filtered = useMemo<AccountNode[]>(() => {
|
|
148
167
|
const q = query.trim().toLowerCase();
|
|
149
|
-
if (!q) return
|
|
150
|
-
return
|
|
168
|
+
if (!q) return graphAccounts;
|
|
169
|
+
return graphAccounts.filter((node) => {
|
|
151
170
|
const name = getAccountDisplayName(node.account, locale).toLowerCase();
|
|
152
171
|
const username = (node.account?.username ?? '').toLowerCase();
|
|
153
172
|
return name.includes(q) || username.includes(q);
|
|
154
173
|
});
|
|
155
|
-
}, [
|
|
174
|
+
}, [graphAccounts, query, locale]);
|
|
156
175
|
|
|
157
176
|
const yourAccounts = useMemo(
|
|
158
177
|
() => toTree(filtered.filter((node) => node.relationship !== 'member')),
|
|
@@ -165,11 +184,8 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
165
184
|
|
|
166
185
|
const handleSwitchDevice = useCallback(async (sessionId: string) => {
|
|
167
186
|
if (busySessionId) return;
|
|
168
|
-
// Tapping the already-active sign-in
|
|
169
|
-
// personal account (clearing any account-graph switch). When already on
|
|
170
|
-
// the personal account this just closes.
|
|
187
|
+
// Tapping the already-active sign-in just closes — it IS the current account.
|
|
171
188
|
if (sessionId === activeSessionId) {
|
|
172
|
-
if (actingAs !== null) setActingAs(null);
|
|
173
189
|
onClose();
|
|
174
190
|
return;
|
|
175
191
|
}
|
|
@@ -177,9 +193,6 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
177
193
|
try {
|
|
178
194
|
await onBeforeSessionChange?.();
|
|
179
195
|
await switchSession(sessionId);
|
|
180
|
-
// The active sign-in changed; any account-graph switch belonged to the
|
|
181
|
-
// previous sign-in, so the new sign-in starts on its personal account.
|
|
182
|
-
if (actingAs !== null) setActingAs(null);
|
|
183
196
|
toast.success(t('accountSwitcher.toasts.switchSuccess') || 'Switched account');
|
|
184
197
|
onClose();
|
|
185
198
|
} catch (error) {
|
|
@@ -190,7 +203,7 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
190
203
|
} finally {
|
|
191
204
|
setBusySessionId(null);
|
|
192
205
|
}
|
|
193
|
-
}, [activeSessionId, busySessionId,
|
|
206
|
+
}, [activeSessionId, busySessionId, switchSession, t, onClose, onBeforeSessionChange]);
|
|
194
207
|
|
|
195
208
|
const handleRemoveDevice = useCallback(async (sessionId: string) => {
|
|
196
209
|
if (sessionId === activeSessionId || removingSessionId) return;
|
|
@@ -238,18 +251,40 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
238
251
|
}
|
|
239
252
|
}, [signingOutAll, logoutAll, t, onClose, onBeforeSessionChange]);
|
|
240
253
|
|
|
241
|
-
const handleSelectAccount = useCallback((node: AccountNode) => {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
254
|
+
const handleSelectAccount = useCallback(async (node: AccountNode) => {
|
|
255
|
+
if (switchingAccountId) return;
|
|
256
|
+
// Already the active account → just close (it would also be deduped from
|
|
257
|
+
// the graph, but guard defensively).
|
|
258
|
+
if (node.accountId === user?.id) {
|
|
259
|
+
onClose();
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
setSwitchingAccountId(node.accountId);
|
|
263
|
+
try {
|
|
264
|
+
await onBeforeSessionChange?.();
|
|
265
|
+
// Switching INTO a graph account is a REAL session switch — the whole
|
|
266
|
+
// app becomes that account (no delegation header).
|
|
267
|
+
await switchToAccount(node.accountId);
|
|
268
|
+
toast.success(t('accountSwitcher.toasts.switchSuccess') || 'Switched account');
|
|
269
|
+
onClose();
|
|
270
|
+
} catch (error) {
|
|
271
|
+
if (!isDev()) {
|
|
272
|
+
loggerUtil.warn('Switch account failed', { component: 'AccountSwitcher' }, error as unknown);
|
|
273
|
+
}
|
|
274
|
+
toast.error(t('accountSwitcher.toasts.switchFailed') || 'Failed to switch account');
|
|
275
|
+
} finally {
|
|
276
|
+
setSwitchingAccountId(null);
|
|
277
|
+
}
|
|
278
|
+
}, [switchingAccountId, user?.id, switchToAccount, t, onClose, onBeforeSessionChange]);
|
|
246
279
|
|
|
247
280
|
const renderAccountNode = useCallback((node: AccountNode, isChild: boolean) => {
|
|
248
281
|
const displayName = getAccountDisplayName(node.account, locale);
|
|
249
282
|
const username = node.account?.username ? `@${node.account.username}` : null;
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
283
|
+
// Current account = the active session's user. After a real-session
|
|
284
|
+
// switch `user` IS this account (such accounts are normally deduped out of
|
|
285
|
+
// the graph, but the check stays correct/defensive if one lingers).
|
|
286
|
+
const active = node.accountId === user?.id;
|
|
287
|
+
const isNodeSwitching = switchingAccountId === node.accountId;
|
|
253
288
|
const role = node.callerMembership?.role;
|
|
254
289
|
const avatarUri = node.account?.avatar
|
|
255
290
|
? oxyServices.getFileDownloadUrl(node.account.avatar, 'thumb')
|
|
@@ -267,11 +302,13 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
267
302
|
accessibilityLabel={displayName}
|
|
268
303
|
accessibilityState={{ selected: active }}
|
|
269
304
|
onPress={() => handleSelectAccount(node)}
|
|
305
|
+
disabled={isSwitching}
|
|
270
306
|
activeOpacity={0.6}
|
|
271
307
|
style={[
|
|
272
308
|
styles.accountRow,
|
|
273
309
|
isChild && styles.childRow,
|
|
274
310
|
active && { backgroundColor: colors.primarySubtle },
|
|
311
|
+
isSwitching && !isNodeSwitching && styles.rowDisabled,
|
|
275
312
|
]}
|
|
276
313
|
>
|
|
277
314
|
<Avatar uri={avatarUri} name={displayName} size={isChild ? 28 : 34} />
|
|
@@ -305,10 +342,14 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
305
342
|
<Ionicons name="settings-outline" size={16} color={colors.textSecondary} />
|
|
306
343
|
</TouchableOpacity>
|
|
307
344
|
) : null}
|
|
308
|
-
{
|
|
345
|
+
{isNodeSwitching ? (
|
|
346
|
+
<ActivityIndicator color={colors.primary} size="small" />
|
|
347
|
+
) : active ? (
|
|
348
|
+
<Ionicons name="checkmark" size={20} color={colors.primary} />
|
|
349
|
+
) : null}
|
|
309
350
|
</TouchableOpacity>
|
|
310
351
|
);
|
|
311
|
-
}, [
|
|
352
|
+
}, [user?.id, switchingAccountId, isSwitching, colors, handleSelectAccount, locale, onOpenAccountSettings, oxyServices, t]);
|
|
312
353
|
|
|
313
354
|
const renderTree = useCallback((entries: TreeEntry[]) => (
|
|
314
355
|
entries.map((entry) => (
|
|
@@ -333,11 +374,9 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
333
374
|
{deviceRows.map((row) => {
|
|
334
375
|
const isBusy = busySessionId === row.sessionId;
|
|
335
376
|
const isRemoving = removingSessionId === row.sessionId;
|
|
336
|
-
// The active
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
// active) account — tappable to return to it.
|
|
340
|
-
const isCurrentAccount = row.isActive && actingAs === null;
|
|
377
|
+
// The active device session IS the current account — there is no
|
|
378
|
+
// separate acting-as concept; switching makes `user` that account.
|
|
379
|
+
const isCurrentAccount = row.isActive;
|
|
341
380
|
return (
|
|
342
381
|
<TouchableOpacity
|
|
343
382
|
key={`device-${row.sessionId}`}
|
|
@@ -371,11 +410,6 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
371
410
|
<ActivityIndicator color={colors.primary} size="small" />
|
|
372
411
|
) : isCurrentAccount ? (
|
|
373
412
|
<Ionicons name="checkmark" size={20} color={colors.primary} />
|
|
374
|
-
) : row.isActive ? (
|
|
375
|
-
// Active sign-in while switched into another account:
|
|
376
|
-
// no current-checkmark, no sign-out (can't sign out the
|
|
377
|
-
// active session here) — tap the row to return to it.
|
|
378
|
-
null
|
|
379
413
|
) : isRemoving ? (
|
|
380
414
|
<ActivityIndicator color={colors.textSecondary} size="small" />
|
|
381
415
|
) : (
|
|
@@ -420,12 +454,12 @@ export const AccountSwitcherView: React.FC<AccountSwitcherActions> = ({
|
|
|
420
454
|
</Text>
|
|
421
455
|
</TouchableOpacity>
|
|
422
456
|
|
|
423
|
-
{/* Section B — account graph */}
|
|
424
|
-
{
|
|
457
|
+
{/* Section B — account graph (switchable accounts not already a device session) */}
|
|
458
|
+
{graphAccounts.length > 0 ? (
|
|
425
459
|
<>
|
|
426
460
|
<Divider color={colors.border} spacing={4} />
|
|
427
461
|
|
|
428
|
-
{
|
|
462
|
+
{graphAccounts.length > 6 ? (
|
|
429
463
|
<View style={[styles.searchBox, { backgroundColor: colors.card, borderColor: colors.border }]}>
|
|
430
464
|
<Ionicons name="search" size={16} color={colors.textSecondary} />
|
|
431
465
|
<TextInput
|
|
@@ -161,42 +161,26 @@ export interface OxyContextState {
|
|
|
161
161
|
// the caller). The cryptographic Commons/DID "identity" is a SEPARATE concept.
|
|
162
162
|
//
|
|
163
163
|
// UX concept: the user picks an account and the WHOLE app becomes that account
|
|
164
|
-
// — a genuine
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
// surfaces; `actingAs` is the low-level mechanism state.
|
|
169
|
-
/**
|
|
170
|
-
* The id of the account switched INTO (`X-Acting-As`), or `null` when the
|
|
171
|
-
* active account is the sign-in's own personal account. This is the underlying
|
|
172
|
-
* mechanism state — UI should present the result through {@link activeAccount}
|
|
173
|
-
* rather than framing it as delegation.
|
|
174
|
-
*/
|
|
175
|
-
actingAs: string | null;
|
|
164
|
+
// — a genuine, REAL-SESSION switch (`switchToAccount`), identical to switching
|
|
165
|
+
// between device sign-ins. There is NO separate "active account" concept:
|
|
166
|
+
// `user` IS the active account after a switch. The removed `X-Acting-As`
|
|
167
|
+
// delegation header is gone entirely.
|
|
176
168
|
/** Every account the caller can access — own personal root, owned, and shared — from `listAccounts()`. */
|
|
177
169
|
accounts: AccountNode[];
|
|
178
170
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* account, or while the switched-into id has not yet appeared in the loaded
|
|
182
|
-
* `accounts` list.
|
|
183
|
-
*/
|
|
184
|
-
actingAsAccount: AccountNode | null;
|
|
185
|
-
/**
|
|
186
|
-
* The effective ACTIVE account presented across the whole app — the account
|
|
187
|
-
* the user switched into when one is set and resolved, otherwise the signed-in
|
|
188
|
-
* user's own personal account. This is the single "who am I" source every
|
|
189
|
-
* identity surface (header avatar/name, profile chrome, context cues) should
|
|
190
|
-
* read, so a switch is reflected everywhere as a real account change.
|
|
171
|
+
* Switch the active session INTO an account from the {@link accounts} graph
|
|
172
|
+
* (a managed org/project/bot, or an account shared with the caller).
|
|
191
173
|
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
174
|
+
* Mints and plants a REAL session for the target via
|
|
175
|
+
* `oxyServices.switchToAccount`, then commits it into context state the SAME
|
|
176
|
+
* way sign-in / {@link switchSession} do — so afterwards `user` IS the target
|
|
177
|
+
* account and every request authenticates as it. The minted session joins the
|
|
178
|
+
* device multi-account set (server-set httpOnly `oxy_rt_<authuser>` cookie), so
|
|
179
|
+
* it survives reload / `refresh-all` and appears in the device account list
|
|
180
|
+
* exactly like a device sign-in. Refreshes the account graph and invalidates
|
|
181
|
+
* all React Query data so everything reloads as the new account.
|
|
197
182
|
*/
|
|
198
|
-
|
|
199
|
-
setActingAs: (accountId: string | null) => void;
|
|
183
|
+
switchToAccount: (accountId: string) => Promise<void>;
|
|
200
184
|
refreshAccounts: () => Promise<void>;
|
|
201
185
|
createAccount: (data: CreateAccountInput) => Promise<AccountNode>;
|
|
202
186
|
}
|
|
@@ -1325,6 +1309,29 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
1325
1309
|
}
|
|
1326
1310
|
}
|
|
1327
1311
|
|
|
1312
|
+
// LAST-ACTIVE-ACCOUNT priority (web multi-account). When the user has an
|
|
1313
|
+
// explicit persisted active slot (`oxy_active_authuser`, written on every
|
|
1314
|
+
// device sign-in / account SWITCH / cookie restore), the multi-account
|
|
1315
|
+
// refresh-cookie restore is the ONLY cold-boot step that honors WHICH slot
|
|
1316
|
+
// was last active — `restoreViaRefreshCookie` selects it via
|
|
1317
|
+
// `selectActiveRefreshAccount(accounts, readActiveAuthuser())`. The
|
|
1318
|
+
// `fedcm-silent` and per-apex `silent-iframe` steps only ever recover the
|
|
1319
|
+
// PRIMARY central IdP session, so if either ran first they would clobber a
|
|
1320
|
+
// switched (managed/org) account back to the primary on reload — the exact
|
|
1321
|
+
// "switch is lost on reload" regression. So when a slot selection exists we
|
|
1322
|
+
// run cookie-restore BEFORE those probes (and disable the later duplicate).
|
|
1323
|
+
//
|
|
1324
|
+
// Read ONCE here (synchronously usable by the step `enabled` gates below).
|
|
1325
|
+
// It is non-null ONLY on first-party `*.oxy.so` web apps that persist the
|
|
1326
|
+
// slot — a cross-apex RP never writes it (its restore funnels through
|
|
1327
|
+
// `handleWebSSOSession`, which does not touch the authuser), and native has
|
|
1328
|
+
// no localStorage, so both keep their existing order untouched. The
|
|
1329
|
+
// earlier `stored-session` step still runs first (FIX-A latency), and when
|
|
1330
|
+
// a slot exists but its cookies have all lapsed, cookie-restore simply
|
|
1331
|
+
// returns no accounts and the chain falls through to the cross-domain
|
|
1332
|
+
// fallbacks exactly as before.
|
|
1333
|
+
const prioritizeMultiAccount = isWebBrowser() && readActiveAuthuser() !== null;
|
|
1334
|
+
|
|
1328
1335
|
try {
|
|
1329
1336
|
const outcome = await runColdBoot<true>({
|
|
1330
1337
|
steps: [
|
|
@@ -1419,6 +1426,28 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
1419
1426
|
return { kind: 'session', session: true };
|
|
1420
1427
|
},
|
|
1421
1428
|
},
|
|
1429
|
+
{
|
|
1430
|
+
// 2.75) LAST-ACTIVE multi-account restore (WEB, prioritized). Runs
|
|
1431
|
+
// ONLY when an explicit persisted slot selection exists
|
|
1432
|
+
// (`prioritizeMultiAccount`) — i.e. the user previously signed in or
|
|
1433
|
+
// SWITCHED accounts on this first-party app. It runs BEFORE the
|
|
1434
|
+
// `fedcm-silent` / `silent-iframe` probes (which only ever recover the
|
|
1435
|
+
// PRIMARY central session) so a switched managed/org account survives
|
|
1436
|
+
// reload instead of being clobbered back to the primary. The restore
|
|
1437
|
+
// itself is the SAME `restoreViaRefreshCookie` as the terminal-tier
|
|
1438
|
+
// step below: it rotates every device-local `oxy_rt_<authuser>` cookie
|
|
1439
|
+
// and picks the persisted slot via `selectActiveRefreshAccount`,
|
|
1440
|
+
// committing it (token + state + durable persistence + `markAuthResolved`).
|
|
1441
|
+
// When no slot is persisted this is disabled and the original order is
|
|
1442
|
+
// unchanged; when the slot's cookies have lapsed it returns no accounts
|
|
1443
|
+
// and the chain falls through to the cross-domain fallbacks below.
|
|
1444
|
+
id: 'cookie-restore-active',
|
|
1445
|
+
enabled: () => prioritizeMultiAccount,
|
|
1446
|
+
run: async () => {
|
|
1447
|
+
const restored = await restoreViaRefreshCookie();
|
|
1448
|
+
return restored ? { kind: 'session', session: true } : { kind: 'skip' };
|
|
1449
|
+
},
|
|
1450
|
+
},
|
|
1422
1451
|
{
|
|
1423
1452
|
// 3) FedCM silent reauthn (Chrome) against the CENTRAL IdP
|
|
1424
1453
|
// (auth.oxy.so). `silentSignInWithFedCM` plants the access token
|
|
@@ -1493,8 +1522,15 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
1493
1522
|
// is correct; cross-domain restore is handled by the SSO bounce.
|
|
1494
1523
|
// FIX-D: `restoreViaRefreshCookie` bounds the request with
|
|
1495
1524
|
// `COOKIE_RESTORE_TIMEOUT` so a cross-domain stall cannot hang here.
|
|
1525
|
+
//
|
|
1526
|
+
// Disabled when `prioritizeMultiAccount` already ran the
|
|
1527
|
+
// `cookie-restore-active` step above (an explicit persisted slot) — that
|
|
1528
|
+
// earlier step is the identical restore, so this terminal-tier copy
|
|
1529
|
+
// would be a redundant second `refreshAllSessions`. It still runs in the
|
|
1530
|
+
// common no-persisted-slot case (e.g. first visit to a first-party app
|
|
1531
|
+
// whose central refresh cookies already exist).
|
|
1496
1532
|
id: 'cookie-restore',
|
|
1497
|
-
enabled: () => isWebBrowser(),
|
|
1533
|
+
enabled: () => isWebBrowser() && !prioritizeMultiAccount,
|
|
1498
1534
|
run: async () => {
|
|
1499
1535
|
const restored = await restoreViaRefreshCookie();
|
|
1500
1536
|
return restored ? { kind: 'session', session: true } : { kind: 'skip' };
|
|
@@ -2018,38 +2054,8 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
2018
2054
|
});
|
|
2019
2055
|
|
|
2020
2056
|
// --- Account graph state ---
|
|
2021
|
-
const [actingAs, setActingAsState] = useState<string | null>(null);
|
|
2022
2057
|
const [accounts, setAccounts] = useState<AccountNode[]>([]);
|
|
2023
2058
|
|
|
2024
|
-
// Latest `actingAs`, mirrored into a ref so `refreshAccounts` can reconcile a
|
|
2025
|
-
// stale switch without taking `actingAs` as a dependency (which would re-run
|
|
2026
|
-
// the account load on every switch). See the reconciliation block below.
|
|
2027
|
-
const actingAsRef = useRef(actingAs);
|
|
2028
|
-
actingAsRef.current = actingAs;
|
|
2029
|
-
// `setActingAs` is declared after `refreshAccounts`; route the reconciliation
|
|
2030
|
-
// clear through a ref so the load callback can call the latest implementation.
|
|
2031
|
-
const setActingAsRef = useRef<((accountId: string | null) => void) | null>(null);
|
|
2032
|
-
|
|
2033
|
-
// Restore actingAs from storage on startup
|
|
2034
|
-
useEffect(() => {
|
|
2035
|
-
if (!storage || !initialized) return;
|
|
2036
|
-
let mounted = true;
|
|
2037
|
-
(async () => {
|
|
2038
|
-
try {
|
|
2039
|
-
const stored = await storage.getItem(`${storageKeyPrefix}_acting_as`);
|
|
2040
|
-
if (mounted && stored) {
|
|
2041
|
-
setActingAsState(stored);
|
|
2042
|
-
oxyServices.setActingAs(stored);
|
|
2043
|
-
}
|
|
2044
|
-
} catch (err) {
|
|
2045
|
-
if (__DEV__) {
|
|
2046
|
-
loggerUtil.debug('Failed to restore actingAs from storage', { component: 'OxyContext' }, err as unknown);
|
|
2047
|
-
}
|
|
2048
|
-
}
|
|
2049
|
-
})();
|
|
2050
|
-
return () => { mounted = false; };
|
|
2051
|
-
}, [storage, initialized, storageKeyPrefix, oxyServices]);
|
|
2052
|
-
|
|
2053
2059
|
// Load the unified account graph when authenticated
|
|
2054
2060
|
const refreshAccounts = useCallback(async (): Promise<void> => {
|
|
2055
2061
|
if (!isAuthenticated || !tokenReady || !oxyServices.getAccessToken()) {
|
|
@@ -2060,15 +2066,6 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
2060
2066
|
try {
|
|
2061
2067
|
const list = await oxyServices.listAccounts();
|
|
2062
2068
|
setAccounts(list);
|
|
2063
|
-
// Reconcile a stale switch: if the active account was switched INTO an id
|
|
2064
|
-
// that is no longer accessible (account removed/archived, or it belonged
|
|
2065
|
-
// to a now-inactive sign-in), drop back to the personal account so the
|
|
2066
|
-
// app never keeps sending a dead `X-Acting-As` header. `list` is the
|
|
2067
|
-
// authoritative accessible set on a successful fetch.
|
|
2068
|
-
const current = actingAsRef.current;
|
|
2069
|
-
if (current && !list.some((node) => node.accountId === current)) {
|
|
2070
|
-
setActingAsRef.current?.(null);
|
|
2071
|
-
}
|
|
2072
2069
|
} catch (err) {
|
|
2073
2070
|
if (isUnauthorizedStatus(err)) {
|
|
2074
2071
|
setAccounts([]);
|
|
@@ -2087,47 +2084,64 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
2087
2084
|
}
|
|
2088
2085
|
}, [isAuthenticated, initialized, tokenReady, refreshAccounts]);
|
|
2089
2086
|
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
if (
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2087
|
+
// Switch the active session INTO an account from the unified graph. In the
|
|
2088
|
+
// REAL-SESSION model this is identical to switching device sign-ins: mint a
|
|
2089
|
+
// real session for the target and make the whole app that account. The removed
|
|
2090
|
+
// `X-Acting-As` delegation header is gone — `oxyServices.switchToAccount`
|
|
2091
|
+
// plants the minted access token (the refresh token is the server-set httpOnly
|
|
2092
|
+
// `oxy_rt_<authuser>` cookie, so the session joins the device multi-account set
|
|
2093
|
+
// and survives reload / `refresh-all`). We then commit the session into context
|
|
2094
|
+
// state the SAME way sign-in / `switchSession` do, refresh the account graph,
|
|
2095
|
+
// and invalidate every query so all data reloads as the new account.
|
|
2096
|
+
const switchToAccount = useCallback(async (accountId: string): Promise<void> => {
|
|
2097
|
+
const result = await oxyServices.switchToAccount(accountId);
|
|
2098
|
+
if (!result?.user || !result?.sessionId) {
|
|
2099
|
+
throw new Error('Account switch did not return a valid session');
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
// `oxyServices.switchToAccount` already planted `result.accessToken` as the
|
|
2103
|
+
// active token; mirror the minted session into the multi-account store and
|
|
2104
|
+
// mark it current, recording the device `authuser` slot so web silent-switch
|
|
2105
|
+
// and the device account chooser can address it.
|
|
2106
|
+
const now = new Date();
|
|
2107
|
+
const clientSession: ClientSession = {
|
|
2108
|
+
sessionId: result.sessionId,
|
|
2109
|
+
deviceId: result.deviceId || '',
|
|
2110
|
+
expiresAt: result.expiresAt || new Date(now.getTime() + DEFAULT_SESSION_VALIDITY_MS).toISOString(),
|
|
2111
|
+
lastActive: now.toISOString(),
|
|
2112
|
+
userId: result.user.id?.toString() ?? '',
|
|
2113
|
+
isCurrent: true,
|
|
2114
|
+
...(typeof result.authuser === 'number' ? { authuser: result.authuser } : null),
|
|
2115
|
+
};
|
|
2116
|
+
updateSessions([clientSession], { merge: true });
|
|
2117
|
+
setActiveSessionId(result.sessionId);
|
|
2118
|
+
if (isWebBrowser() && typeof result.authuser === 'number') {
|
|
2119
|
+
writeActiveAuthuser(result.authuser);
|
|
2120
|
+
}
|
|
2121
|
+
await persistSessionDurably(result.sessionId);
|
|
2122
|
+
|
|
2123
|
+
// Fetch the canonical User for the new account (the switch result carries
|
|
2124
|
+
// only MinimalUserData); fall back to that minimal shape if the profile
|
|
2125
|
+
// fetch fails so the app still reflects the switched identity.
|
|
2126
|
+
let fullUser: User;
|
|
2127
|
+
try {
|
|
2128
|
+
fullUser = await oxyServices.getCurrentUser();
|
|
2129
|
+
} catch (profileError) {
|
|
2130
|
+
if (__DEV__) {
|
|
2131
|
+
loggerUtil.debug('Failed to fetch full user after account switch; using switch result user', { component: 'OxyContext', method: 'switchToAccount' }, profileError as unknown);
|
|
2110
2132
|
}
|
|
2133
|
+
fullUser = result.user as unknown as User;
|
|
2111
2134
|
}
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
// account's user when a switch is set and resolved, otherwise the signed-in
|
|
2123
|
-
// user's own personal account. Derived (no effect) so identity surfaces always
|
|
2124
|
-
// render the current account without separate syncing. Falls back to `user`
|
|
2125
|
-
// while a just-set switch has not yet resolved in `accounts`, so the header
|
|
2126
|
-
// never flashes empty mid-switch.
|
|
2127
|
-
const activeAccount = useMemo<User | null>(
|
|
2128
|
-
() => (actingAs && actingAsAccount ? actingAsAccount.account : user),
|
|
2129
|
-
[actingAs, actingAsAccount, user],
|
|
2130
|
-
);
|
|
2135
|
+
loginSuccess(fullUser);
|
|
2136
|
+
onAuthStateChange?.(fullUser);
|
|
2137
|
+
|
|
2138
|
+
// Reload the switchable account graph (the new active account's relationships
|
|
2139
|
+
// differ) and invalidate every query so all data refetches as the new
|
|
2140
|
+
// account — the deviceAccounts probe re-enumerates the multi-account set so
|
|
2141
|
+
// the switched account now appears as a device session.
|
|
2142
|
+
await refreshAccounts();
|
|
2143
|
+
queryClient.invalidateQueries();
|
|
2144
|
+
}, [oxyServices, updateSessions, setActiveSessionId, persistSessionDurably, loginSuccess, onAuthStateChange, refreshAccounts, queryClient]);
|
|
2131
2145
|
|
|
2132
2146
|
const createAccountFn = useCallback(async (data: CreateAccountInput): Promise<AccountNode> => {
|
|
2133
2147
|
const account = await oxyServices.createAccount(data);
|
|
@@ -2177,11 +2191,8 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
2177
2191
|
useFollow: useFollowHook,
|
|
2178
2192
|
showBottomSheet: showBottomSheetForContext,
|
|
2179
2193
|
openAvatarPicker,
|
|
2180
|
-
actingAs,
|
|
2181
2194
|
accounts,
|
|
2182
|
-
|
|
2183
|
-
activeAccount,
|
|
2184
|
-
setActingAs,
|
|
2195
|
+
switchToAccount,
|
|
2185
2196
|
refreshAccounts,
|
|
2186
2197
|
createAccount: createAccountFn,
|
|
2187
2198
|
}), [
|
|
@@ -2224,11 +2235,8 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
2224
2235
|
user,
|
|
2225
2236
|
showBottomSheetForContext,
|
|
2226
2237
|
openAvatarPicker,
|
|
2227
|
-
actingAs,
|
|
2228
2238
|
accounts,
|
|
2229
|
-
|
|
2230
|
-
activeAccount,
|
|
2231
|
-
setActingAs,
|
|
2239
|
+
switchToAccount,
|
|
2232
2240
|
refreshAccounts,
|
|
2233
2241
|
createAccountFn,
|
|
2234
2242
|
]);
|
|
@@ -2297,11 +2305,8 @@ const LOADING_STATE: OxyContextState = {
|
|
|
2297
2305
|
clientId: null,
|
|
2298
2306
|
oxyServices: LOADING_STATE_OXY_SERVICES,
|
|
2299
2307
|
openAvatarPicker: () => {},
|
|
2300
|
-
actingAs: null,
|
|
2301
2308
|
accounts: [],
|
|
2302
|
-
|
|
2303
|
-
activeAccount: null,
|
|
2304
|
-
setActingAs: () => {},
|
|
2309
|
+
switchToAccount: () => rejectMissingProvider<void>(),
|
|
2305
2310
|
refreshAccounts: () => rejectMissingProvider<void>(),
|
|
2306
2311
|
createAccount: () => rejectMissingProvider<AccountNode>(),
|
|
2307
2312
|
};
|
|
@@ -232,11 +232,11 @@ export const useAuthorizedApps = (options?: { enabled?: boolean }) => {
|
|
|
232
232
|
* Get privacy settings for a user
|
|
233
233
|
*/
|
|
234
234
|
export const usePrivacySettings = (userId?: string, options?: { enabled?: boolean }) => {
|
|
235
|
-
const { oxyServices, activeSessionId,
|
|
235
|
+
const { oxyServices, activeSessionId, user } = useOxy();
|
|
236
236
|
// When no explicit user id is supplied, target the ACTIVE account (the
|
|
237
237
|
// account switched into) so "my privacy settings" reflects the current
|
|
238
238
|
// account, matching the imperative PrivacySettingsScreen.
|
|
239
|
-
const targetUserId = userId ||
|
|
239
|
+
const targetUserId = userId || user?.id;
|
|
240
240
|
|
|
241
241
|
return useQuery({
|
|
242
242
|
queryKey: queryKeys.privacy.settings(targetUserId),
|