@oxyhq/services 6.10.8 → 7.0.0
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 +211 -49
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/client.js +25 -4
- package/lib/commonjs/ui/client.js.map +1 -1
- package/lib/commonjs/ui/components/AccountMenu.js +485 -0
- package/lib/commonjs/ui/components/AccountMenu.js.map +1 -0
- package/lib/commonjs/ui/components/AccountMenuButton.js +120 -0
- package/lib/commonjs/ui/components/AccountMenuButton.js.map +1 -0
- package/lib/commonjs/ui/components/ActingAsBanner.js +2 -2
- package/lib/commonjs/ui/components/ActingAsBanner.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileCard.js +2 -2
- package/lib/commonjs/ui/components/ProfileCard.js.map +1 -1
- package/lib/commonjs/ui/components/StepBasedScreen.js +2 -2
- package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/commonjs/ui/components/accountMenuRows.js +45 -0
- package/lib/commonjs/ui/components/accountMenuRows.js.map +1 -0
- package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js +5 -5
- package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js.map +1 -1
- package/lib/commonjs/ui/components/payment/PaymentMethodStep.js +3 -2
- package/lib/commonjs/ui/components/payment/PaymentMethodStep.js.map +1 -1
- package/lib/commonjs/ui/components/theming.js +2 -2
- package/lib/commonjs/ui/components/theming.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +59 -131
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +36 -2
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/hooks/mutations/mutationKeys.js +6 -0
- package/lib/commonjs/ui/hooks/mutations/mutationKeys.js.map +1 -1
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +138 -1
- package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/queryKeys.js +67 -2
- package/lib/commonjs/ui/hooks/queries/queryKeys.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +27 -2
- package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAuth.js +13 -2
- package/lib/commonjs/ui/hooks/useAuth.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionManagement.js +30 -0
- package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/commonjs/ui/index.js +132 -85
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/navigation/routes.js +6 -7
- package/lib/commonjs/ui/navigation/routes.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js +3 -2
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ConnectedAppsScreen.js +202 -0
- package/lib/commonjs/ui/screens/ConnectedAppsScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/CreateManagedAccountScreen.js +3 -2
- package/lib/commonjs/ui/screens/CreateManagedAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +3 -2
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FAQScreen.js +7 -4
- package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +21 -16
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HelpSupportScreen.js +3 -2
- package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HistoryViewScreen.js +7 -4
- package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +3 -2
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +6 -4
- package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ManageAccountScreen.js +780 -0
- package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/NotificationsScreen.js +175 -0
- package/lib/commonjs/ui/screens/NotificationsScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +18 -12
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PreferencesScreen.js +220 -0
- package/lib/commonjs/ui/screens/PreferencesScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +14 -10
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +3 -3
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +8 -5
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SearchSettingsScreen.js +6 -4
- package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserLinksScreen.js +3 -2
- package/lib/commonjs/ui/screens/UserLinksScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserListScreen.js +2 -2
- package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +3 -2
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +3 -2
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +2 -2
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +4 -3
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +3 -2
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/commonjs/ui/utils/activeAuthuser.js +85 -0
- package/lib/commonjs/ui/utils/activeAuthuser.js.map +1 -0
- package/lib/module/index.js +58 -16
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/client.js +5 -3
- package/lib/module/ui/client.js.map +1 -1
- package/lib/module/ui/components/AccountMenu.js +480 -0
- package/lib/module/ui/components/AccountMenu.js.map +1 -0
- package/lib/module/ui/components/AccountMenuButton.js +115 -0
- package/lib/module/ui/components/AccountMenuButton.js.map +1 -0
- package/lib/module/ui/components/ActingAsBanner.js +2 -2
- package/lib/module/ui/components/ActingAsBanner.js.map +1 -1
- package/lib/module/ui/components/ProfileCard.js +1 -1
- package/lib/module/ui/components/ProfileCard.js.map +1 -1
- package/lib/module/ui/components/StepBasedScreen.js +1 -1
- package/lib/module/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/module/ui/components/accountMenuRows.js +41 -0
- package/lib/module/ui/components/accountMenuRows.js.map +1 -0
- package/lib/module/ui/components/payment/PaymentDetailsStep.js +1 -1
- package/lib/module/ui/components/payment/PaymentDetailsStep.js.map +1 -1
- package/lib/module/ui/components/payment/PaymentMethodStep.js +1 -1
- package/lib/module/ui/components/payment/PaymentMethodStep.js.map +1 -1
- package/lib/module/ui/components/theming.js +1 -1
- package/lib/module/ui/components/theming.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +59 -131
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +36 -2
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/hooks/mutations/mutationKeys.js +6 -0
- package/lib/module/ui/hooks/mutations/mutationKeys.js.map +1 -1
- package/lib/module/ui/hooks/mutations/useAccountMutations.js +135 -1
- package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
- package/lib/module/ui/hooks/queries/queryKeys.js +60 -1
- package/lib/module/ui/hooks/queries/queryKeys.js.map +1 -1
- package/lib/module/ui/hooks/queries/useAccountQueries.js +24 -0
- package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
- package/lib/module/ui/hooks/useAuth.js +13 -2
- package/lib/module/ui/hooks/useAuth.js.map +1 -1
- package/lib/module/ui/hooks/useSessionManagement.js +30 -0
- package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/module/ui/index.js +34 -78
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/navigation/routes.js +6 -7
- package/lib/module/ui/navigation/routes.js.map +1 -1
- package/lib/module/ui/screens/AccountVerificationScreen.js +1 -1
- package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
- package/lib/module/ui/screens/ConnectedAppsScreen.js +198 -0
- package/lib/module/ui/screens/ConnectedAppsScreen.js.map +1 -0
- package/lib/module/ui/screens/CreateManagedAccountScreen.js +1 -1
- package/lib/module/ui/screens/CreateManagedAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/EditProfileFieldScreen.js +1 -1
- package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/module/ui/screens/FAQScreen.js +3 -1
- package/lib/module/ui/screens/FAQScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +6 -2
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/HelpSupportScreen.js +1 -1
- package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
- package/lib/module/ui/screens/HistoryViewScreen.js +3 -1
- package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/LegalDocumentsScreen.js +2 -1
- package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
- package/lib/module/ui/screens/ManageAccountScreen.js +775 -0
- package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -0
- package/lib/module/ui/screens/NotificationsScreen.js +169 -0
- package/lib/module/ui/screens/NotificationsScreen.js.map +1 -0
- package/lib/module/ui/screens/PaymentGatewayScreen.js +9 -3
- package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/module/ui/screens/PreferencesScreen.js +214 -0
- package/lib/module/ui/screens/PreferencesScreen.js.map +1 -0
- package/lib/module/ui/screens/PrivacySettingsScreen.js +4 -1
- package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +2 -2
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/SavesCollectionsScreen.js +3 -1
- package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
- package/lib/module/ui/screens/SearchSettingsScreen.js +2 -1
- package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/UserLinksScreen.js +1 -1
- package/lib/module/ui/screens/UserLinksScreen.js.map +1 -1
- package/lib/module/ui/screens/UserListScreen.js +1 -1
- package/lib/module/ui/screens/UserListScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/module/ui/utils/activeAuthuser.js +79 -0
- package/lib/module/ui/utils/activeAuthuser.js.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +23 -6
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/client.d.ts +7 -2
- package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/AccountMenu.d.ts +23 -0
- package/lib/typescript/commonjs/ui/components/AccountMenu.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts +19 -0
- package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/accountMenuRows.d.ts +27 -0
- package/lib/typescript/commonjs/ui/components/accountMenuRows.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/mutationKeys.d.ts +5 -0
- package/lib/typescript/commonjs/ui/hooks/mutations/mutationKeys.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +26 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts +32 -3
- package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts +10 -1
- package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts +8 -2
- package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/index.d.ts +32 -18
- package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/{module/ui/screens/AccountOverviewScreen.d.ts → commonjs/ui/screens/ConnectedAppsScreen.d.ts} +1 -1
- package/lib/typescript/commonjs/ui/screens/ConnectedAppsScreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/FAQScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/HistoryViewScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/LegalDocumentsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts +13 -0
- package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/{AccountOverviewScreen.d.ts → NotificationsScreen.d.ts} +1 -1
- package/lib/typescript/commonjs/ui/screens/NotificationsScreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/PaymentGatewayScreen.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/{AccountSettingsScreen.d.ts → PreferencesScreen.d.ts} +2 -5
- package/lib/typescript/commonjs/ui/screens/PreferencesScreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/activeAuthuser.d.ts +42 -0
- package/lib/typescript/commonjs/ui/utils/activeAuthuser.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +23 -6
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/client.d.ts +7 -2
- package/lib/typescript/module/ui/client.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/AccountMenu.d.ts +23 -0
- package/lib/typescript/module/ui/components/AccountMenu.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/AccountMenuButton.d.ts +19 -0
- package/lib/typescript/module/ui/components/AccountMenuButton.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/accountMenuRows.d.ts +27 -0
- package/lib/typescript/module/ui/components/accountMenuRows.d.ts.map +1 -0
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/mutations/mutationKeys.d.ts +5 -0
- package/lib/typescript/module/ui/hooks/mutations/mutationKeys.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +26 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts +32 -3
- package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts +10 -1
- package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useAuth.d.ts +8 -2
- package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/index.d.ts +32 -18
- package/lib/typescript/module/ui/index.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/{AccountSettingsScreen.d.ts → ConnectedAppsScreen.d.ts} +2 -5
- package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/FAQScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/LegalDocumentsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts +13 -0
- package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts +5 -0
- package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts +1 -1
- package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts +5 -0
- package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/activeAuthuser.d.ts +42 -0
- package/lib/typescript/module/ui/utils/activeAuthuser.d.ts.map +1 -0
- package/package.json +20 -9
- package/src/index.ts +141 -47
- package/src/ui/client.ts +7 -2
- package/src/ui/components/AccountMenu.tsx +534 -0
- package/src/ui/components/AccountMenuButton.tsx +113 -0
- package/src/ui/components/ActingAsBanner.tsx +2 -2
- package/src/ui/components/ProfileCard.tsx +1 -1
- package/src/ui/components/StepBasedScreen.tsx +1 -1
- package/src/ui/components/accountMenuRows.ts +60 -0
- package/src/ui/components/payment/PaymentDetailsStep.tsx +1 -1
- package/src/ui/components/payment/PaymentMethodStep.tsx +1 -1
- package/src/ui/components/theming.tsx +1 -1
- package/src/ui/context/OxyContext.tsx +61 -145
- package/src/ui/context/hooks/useAuthOperations.ts +36 -2
- package/src/ui/hooks/mutations/mutationKeys.ts +11 -0
- package/src/ui/hooks/mutations/useAccountMutations.ts +154 -2
- package/src/ui/hooks/queries/queryKeys.ts +54 -4
- package/src/ui/hooks/queries/useAccountQueries.ts +25 -1
- package/src/ui/hooks/useAuth.ts +23 -4
- package/src/ui/hooks/useSessionManagement.ts +29 -0
- package/src/ui/index.ts +37 -98
- package/src/ui/navigation/routes.ts +9 -11
- package/src/ui/screens/AccountVerificationScreen.tsx +1 -1
- package/src/ui/screens/ConnectedAppsScreen.tsx +225 -0
- package/src/ui/screens/CreateManagedAccountScreen.tsx +1 -1
- package/src/ui/screens/EditProfileFieldScreen.tsx +1 -1
- package/src/ui/screens/FAQScreen.tsx +3 -1
- package/src/ui/screens/FeedbackScreen.tsx +6 -10
- package/src/ui/screens/HelpSupportScreen.tsx +1 -1
- package/src/ui/screens/HistoryViewScreen.tsx +3 -1
- package/src/ui/screens/LanguageSelectorScreen.tsx +1 -1
- package/src/ui/screens/LegalDocumentsScreen.tsx +2 -1
- package/src/ui/screens/ManageAccountScreen.tsx +1102 -0
- package/src/ui/screens/NotificationsScreen.tsx +189 -0
- package/src/ui/screens/PaymentGatewayScreen.tsx +10 -12
- package/src/ui/screens/PreferencesScreen.tsx +263 -0
- package/src/ui/screens/PrivacySettingsScreen.tsx +4 -1
- package/src/ui/screens/ProfileScreen.tsx +2 -2
- package/src/ui/screens/SavesCollectionsScreen.tsx +3 -1
- package/src/ui/screens/SearchSettingsScreen.tsx +2 -1
- package/src/ui/screens/UserLinksScreen.tsx +1 -1
- package/src/ui/screens/UserListScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaAboutScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaFAQScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaRewardsScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaRulesScreen.tsx +1 -1
- package/src/ui/utils/activeAuthuser.ts +78 -0
- package/lib/commonjs/ui/components/feedback/index.js +0 -54
- package/lib/commonjs/ui/components/feedback/index.js.map +0 -1
- package/lib/commonjs/ui/components/icon/index.js +0 -21
- package/lib/commonjs/ui/components/icon/index.js.map +0 -1
- package/lib/commonjs/ui/components/index.js +0 -104
- package/lib/commonjs/ui/components/index.js.map +0 -1
- package/lib/commonjs/ui/components/modals/index.js +0 -14
- package/lib/commonjs/ui/components/modals/index.js.map +0 -1
- package/lib/commonjs/ui/components/payment/index.js +0 -80
- package/lib/commonjs/ui/components/payment/index.js.map +0 -1
- package/lib/commonjs/ui/hooks/index.js +0 -92
- package/lib/commonjs/ui/hooks/index.js.map +0 -1
- package/lib/commonjs/ui/hooks/mutations/index.js +0 -68
- package/lib/commonjs/ui/hooks/mutations/index.js.map +0 -1
- package/lib/commonjs/ui/hooks/queries/index.js +0 -155
- package/lib/commonjs/ui/hooks/queries/index.js.map +0 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +0 -344
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +0 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +0 -724
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +0 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +0 -643
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +0 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +0 -1029
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +0 -1
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +0 -512
- package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +0 -1
- package/lib/commonjs/ui/styles/index.js +0 -39
- package/lib/commonjs/ui/styles/index.js.map +0 -1
- package/lib/module/ui/components/feedback/index.js +0 -8
- package/lib/module/ui/components/feedback/index.js.map +0 -1
- package/lib/module/ui/components/icon/index.js +0 -5
- package/lib/module/ui/components/icon/index.js.map +0 -1
- package/lib/module/ui/components/index.js +0 -18
- package/lib/module/ui/components/index.js.map +0 -1
- package/lib/module/ui/components/modals/index.js +0 -4
- package/lib/module/ui/components/modals/index.js.map +0 -1
- package/lib/module/ui/components/payment/index.js +0 -10
- package/lib/module/ui/components/payment/index.js.map +0 -1
- package/lib/module/ui/hooks/index.js +0 -11
- package/lib/module/ui/hooks/index.js.map +0 -1
- package/lib/module/ui/hooks/mutations/index.js +0 -15
- package/lib/module/ui/hooks/mutations/index.js.map +0 -1
- package/lib/module/ui/hooks/queries/index.js +0 -26
- package/lib/module/ui/hooks/queries/index.js.map +0 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +0 -339
- package/lib/module/ui/screens/AccountCenterScreen.js.map +0 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +0 -719
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +0 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +0 -638
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +0 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +0 -1024
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +0 -1
- package/lib/module/ui/screens/SessionManagementScreen.js +0 -508
- package/lib/module/ui/screens/SessionManagementScreen.js.map +0 -1
- package/lib/module/ui/styles/index.js +0 -6
- package/lib/module/ui/styles/index.js.map +0 -1
- package/lib/typescript/commonjs/ui/components/feedback/index.d.ts +0 -7
- package/lib/typescript/commonjs/ui/components/feedback/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/icon/index.d.ts +0 -4
- package/lib/typescript/commonjs/ui/components/icon/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/index.d.ts +0 -13
- package/lib/typescript/commonjs/ui/components/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/modals/index.d.ts +0 -2
- package/lib/typescript/commonjs/ui/components/modals/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/components/payment/index.d.ts +0 -9
- package/lib/typescript/commonjs/ui/components/payment/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/hooks/index.d.ts +0 -9
- package/lib/typescript/commonjs/ui/hooks/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/index.d.ts +0 -9
- package/lib/typescript/commonjs/ui/hooks/mutations/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/hooks/queries/index.d.ts +0 -13
- package/lib/typescript/commonjs/ui/hooks/queries/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/AccountCenterScreen.d.ts +0 -5
- package/lib/typescript/commonjs/ui/screens/AccountCenterScreen.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/AccountOverviewScreen.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts +0 -5
- package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/screens/SessionManagementScreen.d.ts +0 -5
- package/lib/typescript/commonjs/ui/screens/SessionManagementScreen.d.ts.map +0 -1
- package/lib/typescript/commonjs/ui/styles/index.d.ts +0 -4
- package/lib/typescript/commonjs/ui/styles/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/feedback/index.d.ts +0 -7
- package/lib/typescript/module/ui/components/feedback/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/icon/index.d.ts +0 -4
- package/lib/typescript/module/ui/components/icon/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/index.d.ts +0 -13
- package/lib/typescript/module/ui/components/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/modals/index.d.ts +0 -2
- package/lib/typescript/module/ui/components/modals/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/components/payment/index.d.ts +0 -9
- package/lib/typescript/module/ui/components/payment/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/hooks/index.d.ts +0 -9
- package/lib/typescript/module/ui/hooks/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/hooks/mutations/index.d.ts +0 -9
- package/lib/typescript/module/ui/hooks/mutations/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/hooks/queries/index.d.ts +0 -13
- package/lib/typescript/module/ui/hooks/queries/index.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/AccountCenterScreen.d.ts +0 -5
- package/lib/typescript/module/ui/screens/AccountCenterScreen.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/AccountOverviewScreen.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts +0 -5
- package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +0 -1
- package/lib/typescript/module/ui/screens/SessionManagementScreen.d.ts +0 -5
- package/lib/typescript/module/ui/screens/SessionManagementScreen.d.ts.map +0 -1
- package/lib/typescript/module/ui/styles/index.d.ts +0 -4
- package/lib/typescript/module/ui/styles/index.d.ts.map +0 -1
- package/src/ui/components/feedback/index.ts +0 -6
- package/src/ui/components/icon/index.ts +0 -3
- package/src/ui/components/index.ts +0 -15
- package/src/ui/components/modals/index.ts +0 -1
- package/src/ui/components/payment/index.ts +0 -9
- package/src/ui/hooks/index.ts +0 -13
- package/src/ui/hooks/mutations/index.ts +0 -25
- package/src/ui/hooks/queries/index.ts +0 -61
- package/src/ui/screens/AccountCenterScreen.tsx +0 -182
- package/src/ui/screens/AccountOverviewScreen.tsx +0 -696
- package/src/ui/screens/AccountSettingsScreen.tsx +0 -620
- package/src/ui/screens/AccountSwitcherScreen.tsx +0 -1003
- package/src/ui/screens/SessionManagementScreen.tsx +0 -477
- package/src/ui/styles/index.ts +0 -3
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { User, ClientSession } from '@oxyhq/core';
|
|
2
|
+
import { getAccountDisplayName, getAccountFallbackHandle } from '@oxyhq/core';
|
|
3
|
+
|
|
4
|
+
export interface AccountRow {
|
|
5
|
+
sessionId: string;
|
|
6
|
+
isActive: boolean;
|
|
7
|
+
displayName: string;
|
|
8
|
+
secondary: string | null;
|
|
9
|
+
avatarUri?: string;
|
|
10
|
+
user: User | null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface BuildAccountRowsInput {
|
|
14
|
+
sessions: ClientSession[] | null | undefined;
|
|
15
|
+
activeSessionId: string | null | undefined;
|
|
16
|
+
user: User | null | undefined;
|
|
17
|
+
locale: string;
|
|
18
|
+
getAvatarUrl: (avatarId: string) => string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Pure builder for `AccountMenu` rows. Extracted so the multi-account display
|
|
23
|
+
* logic can be unit-tested without rendering React Native.
|
|
24
|
+
*
|
|
25
|
+
* Each `sessions[i]` becomes one row. Only the row matching `activeSessionId`
|
|
26
|
+
* carries the loaded `user` payload — the others are placeholders shown by
|
|
27
|
+
* fallback handle. This mirrors how `OxyContext` only hydrates one user at a
|
|
28
|
+
* time.
|
|
29
|
+
*/
|
|
30
|
+
export function buildAccountRows({
|
|
31
|
+
sessions,
|
|
32
|
+
activeSessionId,
|
|
33
|
+
user,
|
|
34
|
+
locale,
|
|
35
|
+
getAvatarUrl,
|
|
36
|
+
}: BuildAccountRowsInput): AccountRow[] {
|
|
37
|
+
return (sessions ?? []).map((session: ClientSession) => {
|
|
38
|
+
const isActive = session.sessionId === activeSessionId;
|
|
39
|
+
const candidate: Partial<User> | null = isActive ? user ?? null : null;
|
|
40
|
+
const displayName = getAccountDisplayName(
|
|
41
|
+
candidate ?? { username: undefined },
|
|
42
|
+
locale,
|
|
43
|
+
);
|
|
44
|
+
const handle = getAccountFallbackHandle(candidate ?? { username: undefined });
|
|
45
|
+
const secondary = (candidate?.email)
|
|
46
|
+
?? (handle && candidate?.username ? `@${handle}` : handle)
|
|
47
|
+
?? null;
|
|
48
|
+
const avatarUri = candidate?.avatar
|
|
49
|
+
? getAvatarUrl(candidate.avatar)
|
|
50
|
+
: undefined;
|
|
51
|
+
return {
|
|
52
|
+
sessionId: session.sessionId,
|
|
53
|
+
isActive,
|
|
54
|
+
displayName,
|
|
55
|
+
secondary,
|
|
56
|
+
avatarUri,
|
|
57
|
+
user: isActive ? user ?? null : null,
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
@@ -4,7 +4,7 @@ import { View, Text, Animated, TouchableOpacity, Clipboard, Linking } from 'reac
|
|
|
4
4
|
import { Ionicons } from '@expo/vector-icons';
|
|
5
5
|
import { Button } from '@oxyhq/bloom/button';
|
|
6
6
|
import TextField from '../TextField';
|
|
7
|
-
import
|
|
7
|
+
import FAIRWalletIcon from '../icon/FAIRWalletIcon';
|
|
8
8
|
import { createPaymentStyles } from './paymentStyles';
|
|
9
9
|
import { toast } from '@oxyhq/bloom';
|
|
10
10
|
import type { CardDetails, PaymentColors, PaymentStepAnimations } from './types';
|
|
@@ -4,7 +4,7 @@ import { View, Text, Animated } from 'react-native';
|
|
|
4
4
|
import { Ionicons } from '@expo/vector-icons';
|
|
5
5
|
import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
|
|
6
6
|
import { Button } from '@oxyhq/bloom/button';
|
|
7
|
-
import
|
|
7
|
+
import FAIRWalletIcon from '../icon/FAIRWalletIcon';
|
|
8
8
|
import { createPaymentStyles } from './paymentStyles';
|
|
9
9
|
import type { PaymentMethod, PaymentColors, PaymentStepAnimations } from './types';
|
|
10
10
|
import { useI18n } from '../../hooks/useI18n';
|
|
@@ -25,6 +25,7 @@ import { useAuthOperations } from './hooks/useAuthOperations';
|
|
|
25
25
|
import { useDeviceManagement } from '../hooks/useDeviceManagement';
|
|
26
26
|
import { getStorageKeys, createPlatformStorage, type StorageInterface } from '../utils/storageHelpers';
|
|
27
27
|
import { isInvalidSessionError, isTimeoutOrNetworkError } from '../utils/errorHandlers';
|
|
28
|
+
import { readActiveAuthuser, writeActiveAuthuser } from '../utils/activeAuthuser';
|
|
28
29
|
import type { RouteName } from '../navigation/routes';
|
|
29
30
|
import { showBottomSheet as globalShowBottomSheet } from '../navigation/bottomSheetManager';
|
|
30
31
|
import { useQueryClient } from '@tanstack/react-query';
|
|
@@ -97,76 +98,9 @@ export interface OxyContextState {
|
|
|
97
98
|
|
|
98
99
|
const OxyContext = createContext<OxyContextState | null>(null);
|
|
99
100
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
* as a fallback). The token is already signed and verified server-side; the
|
|
104
|
-
* client decodes the payload purely to recover the session id — it does NOT and
|
|
105
|
-
* MUST NOT verify the signature.
|
|
106
|
-
*/
|
|
107
|
-
interface RefreshAccessTokenClaims {
|
|
108
|
-
sessionId?: string;
|
|
109
|
-
userId?: string;
|
|
110
|
-
id?: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Decode the payload of a JWT WITHOUT verifying its signature.
|
|
115
|
-
*
|
|
116
|
-
* The server (`POST /auth/refresh`) has already minted and signed this access
|
|
117
|
-
* token; we only need to recover the `sessionId` claim from it on cold boot.
|
|
118
|
-
* Returns `null` for any malformed input rather than throwing, so a bad token
|
|
119
|
-
* simply falls through to the unauthenticated path.
|
|
120
|
-
*
|
|
121
|
-
* Implemented with manual base64url decoding (no `jwt-decode` dependency added
|
|
122
|
-
* to `@oxyhq/services`). Works on web (where this cold-boot path runs) via
|
|
123
|
-
* `atob`; if `atob` is unavailable (non-browser runtime) it is treated as
|
|
124
|
-
* undecodable and returns `null`.
|
|
125
|
-
*/
|
|
126
|
-
function decodeAccessTokenClaims(token: string): RefreshAccessTokenClaims | null {
|
|
127
|
-
if (!token || typeof token !== 'string') {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
const segments = token.split('.');
|
|
131
|
-
if (segments.length !== 3) {
|
|
132
|
-
return null;
|
|
133
|
-
}
|
|
134
|
-
const payloadSegment = segments[1];
|
|
135
|
-
if (!payloadSegment) {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
try {
|
|
139
|
-
const base64 = payloadSegment.replace(/-/g, '+').replace(/_/g, '/');
|
|
140
|
-
const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '=');
|
|
141
|
-
if (typeof atob !== 'function') {
|
|
142
|
-
return null;
|
|
143
|
-
}
|
|
144
|
-
const json = decodeURIComponent(
|
|
145
|
-
atob(padded)
|
|
146
|
-
.split('')
|
|
147
|
-
.map((char) => `%${`00${char.charCodeAt(0).toString(16)}`.slice(-2)}`)
|
|
148
|
-
.join(''),
|
|
149
|
-
);
|
|
150
|
-
const parsed: unknown = JSON.parse(json);
|
|
151
|
-
if (parsed === null || typeof parsed !== 'object') {
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
const claims = parsed as Record<string, unknown>;
|
|
155
|
-
return {
|
|
156
|
-
sessionId: typeof claims.sessionId === 'string' ? claims.sessionId : undefined,
|
|
157
|
-
userId: typeof claims.userId === 'string' ? claims.userId : undefined,
|
|
158
|
-
id: typeof claims.id === 'string' ? claims.id : undefined,
|
|
159
|
-
};
|
|
160
|
-
} catch {
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/** Server response shape of `POST /auth/refresh`. */
|
|
166
|
-
interface RefreshCookieResponse {
|
|
167
|
-
accessToken?: string;
|
|
168
|
-
sessionId?: string;
|
|
169
|
-
}
|
|
101
|
+
// Active-authuser persistence helpers (web localStorage; native no-op) live in
|
|
102
|
+
// `../utils/activeAuthuser` so the session-management and auth-operations hooks
|
|
103
|
+
// can share them without re-importing this 1k-line context file.
|
|
170
104
|
|
|
171
105
|
export interface OxyContextProviderProps {
|
|
172
106
|
children: ReactNode;
|
|
@@ -519,111 +453,93 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
519
453
|
const onAuthStateChangeRef = useRef(onAuthStateChange);
|
|
520
454
|
onAuthStateChangeRef.current = onAuthStateChange;
|
|
521
455
|
|
|
522
|
-
// Cold-boot session restore via the secure refresh
|
|
456
|
+
// Cold-boot session restore via the secure refresh cookies (web only).
|
|
523
457
|
//
|
|
524
|
-
//
|
|
525
|
-
//
|
|
526
|
-
//
|
|
527
|
-
//
|
|
528
|
-
//
|
|
529
|
-
//
|
|
530
|
-
//
|
|
531
|
-
// a fresh session access token. JS never sees the refresh cookie (httpOnly) —
|
|
532
|
-
// that is the security property.
|
|
458
|
+
// Calls `oxyServices.refreshAllSessions()` → `POST /auth/refresh-all` with
|
|
459
|
+
// `credentials: 'include'`. The server rotates every device-local
|
|
460
|
+
// `oxy_rt_${authuser}` cookie in parallel and returns one entry per valid
|
|
461
|
+
// account (Google-style multi-account). On an older server that lacks the
|
|
462
|
+
// multi-account endpoint, the SDK transparently falls back to the legacy
|
|
463
|
+
// `/auth/refresh` single-account path and wraps the result in the same
|
|
464
|
+
// shape, so this caller doesn't branch.
|
|
533
465
|
//
|
|
534
|
-
//
|
|
535
|
-
//
|
|
536
|
-
//
|
|
466
|
+
// Active-account selection: the persisted `oxy_active_authuser` slot index
|
|
467
|
+
// wins when it matches a returned account; otherwise the lowest `authuser`
|
|
468
|
+
// is picked. JS never sees the refresh cookies (httpOnly).
|
|
469
|
+
//
|
|
470
|
+
// Returns `true` when at least one session was restored (caller short-
|
|
471
|
+
// circuits the bearer path); `false` on no signed-in accounts / any failure
|
|
472
|
+
// (caller proceeds unauthenticated through the existing flow — nothing is
|
|
473
|
+
// cleared).
|
|
537
474
|
const restoreViaRefreshCookie = useCallback(async (): Promise<boolean> => {
|
|
538
475
|
if (!isWebBrowser()) {
|
|
539
476
|
return false;
|
|
540
477
|
}
|
|
541
478
|
|
|
542
|
-
|
|
543
|
-
if (!apiBaseUrl) {
|
|
544
|
-
return false;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
let response: Response;
|
|
479
|
+
let snapshot;
|
|
548
480
|
try {
|
|
549
|
-
|
|
550
|
-
// HttpService here: it would attach the (absent) bearer and does not send
|
|
551
|
-
// cookies. The refresh cookie is scoped to `Path=/auth/refresh` and sent
|
|
552
|
-
// automatically same-site.
|
|
553
|
-
response = await fetch(`${apiBaseUrl.replace(/\/$/, '')}/auth/refresh`, {
|
|
554
|
-
method: 'POST',
|
|
555
|
-
credentials: 'include',
|
|
556
|
-
headers: { Accept: 'application/json' },
|
|
557
|
-
});
|
|
481
|
+
snapshot = await oxyServices.refreshAllSessions();
|
|
558
482
|
} catch (fetchError) {
|
|
559
483
|
// Offline / network error — fall through to the cached/stored-session flow.
|
|
560
484
|
if (__DEV__) {
|
|
561
|
-
loggerUtil.debug('Refresh-cookie restore network error (expected when offline)', { component: 'OxyContext', method: 'restoreViaRefreshCookie' }, fetchError as unknown);
|
|
485
|
+
loggerUtil.debug('Refresh-all cookie restore network error (expected when offline)', { component: 'OxyContext', method: 'restoreViaRefreshCookie' }, fetchError as unknown);
|
|
562
486
|
}
|
|
563
487
|
return false;
|
|
564
488
|
}
|
|
565
489
|
|
|
566
|
-
|
|
567
|
-
if (!response.ok) {
|
|
568
|
-
return false;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
let payload: RefreshCookieResponse;
|
|
572
|
-
try {
|
|
573
|
-
payload = (await response.json()) as RefreshCookieResponse;
|
|
574
|
-
} catch {
|
|
575
|
-
return false;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
const accessToken = payload.accessToken;
|
|
579
|
-
if (!accessToken) {
|
|
580
|
-
return false;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
// Recover the session id from the (server-signed) access-token claims, or
|
|
584
|
-
// from the response body if the server included it. Decode-only; the server
|
|
585
|
-
// already verified the signature.
|
|
586
|
-
const claims = decodeAccessTokenClaims(accessToken);
|
|
587
|
-
const sessionId = payload.sessionId ?? claims?.sessionId;
|
|
588
|
-
if (!sessionId) {
|
|
589
|
-
// A token with no resolvable session id cannot drive multi-session state.
|
|
490
|
+
if (snapshot.accounts.length === 0) {
|
|
590
491
|
return false;
|
|
591
492
|
}
|
|
592
493
|
|
|
593
|
-
//
|
|
594
|
-
//
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
494
|
+
// Pick the active account: persisted authuser if it still matches a returned
|
|
495
|
+
// account, otherwise the lowest authuser (deterministic). The server has
|
|
496
|
+
// already sorted ascending so [0] is the lowest.
|
|
497
|
+
const persistedAuthuser = readActiveAuthuser();
|
|
498
|
+
const matched = persistedAuthuser !== null
|
|
499
|
+
? snapshot.accounts.find((a) => a.authuser === persistedAuthuser)
|
|
500
|
+
: undefined;
|
|
501
|
+
const activeAccount = matched ?? snapshot.accounts[0];
|
|
502
|
+
|
|
503
|
+
// Plant the active access token. Sibling accounts' access tokens stay in
|
|
504
|
+
// the snapshot (the chooser can drive a per-account refresh via
|
|
505
|
+
// `refreshTokenViaCookie({authuser})` on switch).
|
|
506
|
+
oxyServices.httpService.setTokens(activeAccount.accessToken);
|
|
507
|
+
|
|
508
|
+
// Fetch the full user with the freshly planted token. The refresh-all
|
|
509
|
+
// payload includes a minimal user shape (id, username, name, avatar,
|
|
510
|
+
// email, color) — sufficient for the chooser but the auth store wants the
|
|
511
|
+
// canonical User document for downstream rendering.
|
|
598
512
|
let fullUser: User;
|
|
599
513
|
try {
|
|
600
514
|
fullUser = await oxyServices.getCurrentUser();
|
|
601
515
|
} catch (userError) {
|
|
602
|
-
// Token planted but profile fetch failed (e.g. transient network). Do
|
|
603
|
-
// claim a restored session; fall through so the stored-session flow
|
|
604
|
-
// retry. Leave the planted token in place — it is valid and harmless.
|
|
516
|
+
// Token planted but profile fetch failed (e.g. transient network). Do
|
|
517
|
+
// not claim a restored session; fall through so the stored-session flow
|
|
518
|
+
// can retry. Leave the planted token in place — it is valid and harmless.
|
|
605
519
|
if (__DEV__) {
|
|
606
|
-
loggerUtil.debug('Refresh-cookie restore: getCurrentUser failed', { component: 'OxyContext', method: 'restoreViaRefreshCookie' }, userError as unknown);
|
|
520
|
+
loggerUtil.debug('Refresh-all cookie restore: getCurrentUser failed', { component: 'OxyContext', method: 'restoreViaRefreshCookie' }, userError as unknown);
|
|
607
521
|
}
|
|
608
522
|
return false;
|
|
609
523
|
}
|
|
610
524
|
|
|
611
|
-
|
|
525
|
+
// Build a ClientSession per returned account so the multi-session store
|
|
526
|
+
// reflects every device-local slot, not just the active one. The active
|
|
527
|
+
// account is flagged `isCurrent: true`.
|
|
612
528
|
const now = new Date();
|
|
613
|
-
const
|
|
614
|
-
sessionId,
|
|
529
|
+
const clientSessions: ClientSession[] = snapshot.accounts.map((account) => ({
|
|
530
|
+
sessionId: account.sessionId,
|
|
615
531
|
deviceId: '',
|
|
616
|
-
expiresAt: new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
532
|
+
expiresAt: account.expiresAt || new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
617
533
|
lastActive: now.toISOString(),
|
|
618
|
-
userId,
|
|
619
|
-
isCurrent:
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
await persistSessionDurably(sessionId);
|
|
534
|
+
userId: account.user?.id,
|
|
535
|
+
isCurrent: account.sessionId === activeAccount.sessionId,
|
|
536
|
+
authuser: account.authuser,
|
|
537
|
+
}));
|
|
538
|
+
|
|
539
|
+
updateSessionsRef.current(clientSessions, { merge: true });
|
|
540
|
+
setActiveSessionIdRef.current(activeAccount.sessionId);
|
|
541
|
+
writeActiveAuthuser(activeAccount.authuser);
|
|
542
|
+
await persistSessionDurably(activeAccount.sessionId);
|
|
627
543
|
|
|
628
544
|
loginSuccessRef.current(fullUser);
|
|
629
545
|
onAuthStateChangeRef.current?.(fullUser);
|
|
@@ -8,6 +8,8 @@ import { handleAuthError, isInvalidSessionError } from '../../utils/errorHandler
|
|
|
8
8
|
import type { StorageInterface } from '../../utils/storageHelpers';
|
|
9
9
|
import type { OxyServices } from '@oxyhq/core';
|
|
10
10
|
import { SignatureService } from '@oxyhq/core';
|
|
11
|
+
import { isWebBrowser } from '../../hooks/useWebSSO';
|
|
12
|
+
import { clearActiveAuthuser } from '../../utils/activeAuthuser';
|
|
11
13
|
|
|
12
14
|
/** Type guard for error objects with optional code and status properties */
|
|
13
15
|
function isErrorWithCodeOrStatus(error: unknown): error is { code?: string; status?: number; message?: string } {
|
|
@@ -300,7 +302,19 @@ export const useAuthOperations = ({
|
|
|
300
302
|
|
|
301
303
|
try {
|
|
302
304
|
const sessionToLogout = targetSessionId || activeSessionId;
|
|
303
|
-
|
|
305
|
+
// Web multi-account: when the target session carries an `authuser`
|
|
306
|
+
// slot index it is backed by an httpOnly `oxy_rt_${n}` cookie. Use
|
|
307
|
+
// the cookie-cleared logout endpoint so the server can `Set-Cookie`
|
|
308
|
+
// an immediate expiry alongside revoking the family. Native and
|
|
309
|
+
// legacy sessions (no `authuser` plumbed yet) fall through to the
|
|
310
|
+
// bearer-protected endpoint.
|
|
311
|
+
const targetSession = sessionsRef.current.find((s) => s.sessionId === sessionToLogout);
|
|
312
|
+
const targetAuthuser = targetSession?.authuser;
|
|
313
|
+
if (isWebBrowser() && typeof targetAuthuser === 'number') {
|
|
314
|
+
await oxyServices.logoutSessionByAuthuser(targetAuthuser);
|
|
315
|
+
} else {
|
|
316
|
+
await oxyServices.logoutSession(activeSessionId, sessionToLogout);
|
|
317
|
+
}
|
|
304
318
|
|
|
305
319
|
const filteredSessions = sessionsRef.current.filter((session) => session.sessionId !== sessionToLogout);
|
|
306
320
|
updateSessions(filteredSessions, { merge: false });
|
|
@@ -355,7 +369,27 @@ export const useAuthOperations = ({
|
|
|
355
369
|
}
|
|
356
370
|
|
|
357
371
|
try {
|
|
358
|
-
|
|
372
|
+
// Semantics intentionally diverge by platform to match user expectation:
|
|
373
|
+
// - Web: "Sign out of all accounts" = sign out every device-local
|
|
374
|
+
// account on THIS device. The cookie endpoint is the only path
|
|
375
|
+
// that can `Set-Cookie` an immediate expiry on every
|
|
376
|
+
// `oxy_rt_${n}` slot (plus legacy `oxy_rt`) AND revoke every
|
|
377
|
+
// presented family server-side. The bearer-protected
|
|
378
|
+
// `logoutAllSessions(activeSessionId)` would only revoke the
|
|
379
|
+
// active user's sessions across devices and leave sibling
|
|
380
|
+
// accounts' cookies sitting on this device — wrong UX for the
|
|
381
|
+
// chooser's "Sign out of all accounts".
|
|
382
|
+
// - Native: there are no per-account cookies; "Sign out of all"
|
|
383
|
+
// keeps its long-standing "revoke every session of THIS user"
|
|
384
|
+
// meaning via the bearer endpoint.
|
|
385
|
+
// After clearing on web, also drop the persisted active-authuser so
|
|
386
|
+
// the next cold boot starts from a clean slate.
|
|
387
|
+
if (isWebBrowser()) {
|
|
388
|
+
await oxyServices.logoutAllSessionsViaCookie();
|
|
389
|
+
clearActiveAuthuser();
|
|
390
|
+
} else {
|
|
391
|
+
await oxyServices.logoutAllSessions(activeSessionId);
|
|
392
|
+
}
|
|
359
393
|
await clearSessionState();
|
|
360
394
|
} catch (error) {
|
|
361
395
|
handleAuthError(error, {
|
|
@@ -14,6 +14,12 @@ export const mutationKeys = {
|
|
|
14
14
|
uploadAvatar: ['mutation', 'account', 'uploadAvatar'] as const,
|
|
15
15
|
updateSettings: ['mutation', 'account', 'updateSettings'] as const,
|
|
16
16
|
updatePrivacySettings: ['mutation', 'account', 'updatePrivacySettings'] as const,
|
|
17
|
+
updateNotificationPreferences: [
|
|
18
|
+
'mutation',
|
|
19
|
+
'account',
|
|
20
|
+
'updateNotificationPreferences',
|
|
21
|
+
] as const,
|
|
22
|
+
updateUserPreferences: ['mutation', 'account', 'updateUserPreferences'] as const,
|
|
17
23
|
uploadFile: ['mutation', 'account', 'uploadFile'] as const,
|
|
18
24
|
},
|
|
19
25
|
|
|
@@ -25,4 +31,9 @@ export const mutationKeys = {
|
|
|
25
31
|
updateDeviceName: ['mutation', 'session', 'updateDeviceName'] as const,
|
|
26
32
|
removeDevice: ['mutation', 'session', 'removeDevice'] as const,
|
|
27
33
|
},
|
|
34
|
+
|
|
35
|
+
// Connected apps (FedCM grants)
|
|
36
|
+
connectedApps: {
|
|
37
|
+
revoke: ['mutation', 'connectedApps', 'revoke'] as const,
|
|
38
|
+
},
|
|
28
39
|
} as const;
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
2
2
|
import { authenticatedApiCall } from '@oxyhq/core';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type {
|
|
4
|
+
AssetUploadInput,
|
|
5
|
+
NotificationPreferences,
|
|
6
|
+
PrivacySettings,
|
|
7
|
+
User,
|
|
8
|
+
UserPreferences,
|
|
9
|
+
} from '@oxyhq/core';
|
|
10
|
+
import {
|
|
11
|
+
queryKeys,
|
|
12
|
+
invalidateAccountQueries,
|
|
13
|
+
invalidateConnectedAppsQueries,
|
|
14
|
+
invalidateUserQueries,
|
|
15
|
+
invalidateSessionQueries,
|
|
16
|
+
} from '../queries/queryKeys';
|
|
5
17
|
import { mutationKeys } from './mutationKeys';
|
|
6
18
|
import { useOxy } from '../../context/OxyContext';
|
|
7
19
|
import { toast } from '@oxyhq/bloom';
|
|
@@ -505,6 +517,146 @@ interface UploadResult {
|
|
|
505
517
|
id?: string;
|
|
506
518
|
}
|
|
507
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Update the authenticated user's notification preferences with optimistic
|
|
522
|
+
* updates. Persisted on the User document via `PUT /users/me` — same cache-
|
|
523
|
+
* invalidation behaviour as `useUpdateProfile`.
|
|
524
|
+
*/
|
|
525
|
+
export const useUpdateNotificationPreferences = () => {
|
|
526
|
+
const { oxyServices, activeSessionId } = useOxy();
|
|
527
|
+
const queryClient = useQueryClient();
|
|
528
|
+
|
|
529
|
+
return useMutation({
|
|
530
|
+
mutationKey: [...mutationKeys.account.updateNotificationPreferences],
|
|
531
|
+
mutationFn: async (preferences: Partial<NotificationPreferences>) => {
|
|
532
|
+
return authenticatedApiCall<User>(
|
|
533
|
+
oxyServices,
|
|
534
|
+
activeSessionId,
|
|
535
|
+
() => oxyServices.updateNotificationPreferences(preferences)
|
|
536
|
+
);
|
|
537
|
+
},
|
|
538
|
+
onMutate: async (preferences) => {
|
|
539
|
+
await queryClient.cancelQueries({ queryKey: queryKeys.accounts.current() });
|
|
540
|
+
const previousUser = queryClient.getQueryData<User>(queryKeys.accounts.current());
|
|
541
|
+
|
|
542
|
+
if (previousUser) {
|
|
543
|
+
queryClient.setQueryData<User>(queryKeys.accounts.current(), {
|
|
544
|
+
...previousUser,
|
|
545
|
+
notificationPreferences: {
|
|
546
|
+
...previousUser.notificationPreferences,
|
|
547
|
+
...preferences,
|
|
548
|
+
},
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
return { previousUser };
|
|
553
|
+
},
|
|
554
|
+
onError: (error, _preferences, context) => {
|
|
555
|
+
if (context?.previousUser) {
|
|
556
|
+
const current = queryClient.getQueryData<User>(queryKeys.accounts.current());
|
|
557
|
+
if (current) {
|
|
558
|
+
queryClient.setQueryData<User>(queryKeys.accounts.current(), {
|
|
559
|
+
...current,
|
|
560
|
+
notificationPreferences: context.previousUser.notificationPreferences,
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
toast.error(
|
|
565
|
+
error instanceof Error
|
|
566
|
+
? error.message
|
|
567
|
+
: 'Failed to update notification preferences'
|
|
568
|
+
);
|
|
569
|
+
},
|
|
570
|
+
onSuccess: (data) => {
|
|
571
|
+
queryClient.setQueryData(queryKeys.accounts.current(), data);
|
|
572
|
+
useAuthStore.getState().setUser(data);
|
|
573
|
+
invalidateAccountQueries(queryClient);
|
|
574
|
+
},
|
|
575
|
+
});
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Update the authenticated user's general preferences (language, theme,
|
|
580
|
+
* reduce-motion, timezone). Persisted on the User document via
|
|
581
|
+
* `PUT /users/me`.
|
|
582
|
+
*/
|
|
583
|
+
export const useUpdateUserPreferences = () => {
|
|
584
|
+
const { oxyServices, activeSessionId } = useOxy();
|
|
585
|
+
const queryClient = useQueryClient();
|
|
586
|
+
|
|
587
|
+
return useMutation({
|
|
588
|
+
mutationKey: [...mutationKeys.account.updateUserPreferences],
|
|
589
|
+
mutationFn: async (preferences: Partial<UserPreferences>) => {
|
|
590
|
+
return authenticatedApiCall<User>(
|
|
591
|
+
oxyServices,
|
|
592
|
+
activeSessionId,
|
|
593
|
+
() => oxyServices.updateUserPreferences(preferences)
|
|
594
|
+
);
|
|
595
|
+
},
|
|
596
|
+
onMutate: async (preferences) => {
|
|
597
|
+
await queryClient.cancelQueries({ queryKey: queryKeys.accounts.current() });
|
|
598
|
+
const previousUser = queryClient.getQueryData<User>(queryKeys.accounts.current());
|
|
599
|
+
|
|
600
|
+
if (previousUser) {
|
|
601
|
+
queryClient.setQueryData<User>(queryKeys.accounts.current(), {
|
|
602
|
+
...previousUser,
|
|
603
|
+
userPreferences: {
|
|
604
|
+
...previousUser.userPreferences,
|
|
605
|
+
...preferences,
|
|
606
|
+
},
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return { previousUser };
|
|
611
|
+
},
|
|
612
|
+
onError: (error, _preferences, context) => {
|
|
613
|
+
if (context?.previousUser) {
|
|
614
|
+
const current = queryClient.getQueryData<User>(queryKeys.accounts.current());
|
|
615
|
+
if (current) {
|
|
616
|
+
queryClient.setQueryData<User>(queryKeys.accounts.current(), {
|
|
617
|
+
...current,
|
|
618
|
+
userPreferences: context.previousUser.userPreferences,
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
toast.error(error instanceof Error ? error.message : 'Failed to update preferences');
|
|
623
|
+
},
|
|
624
|
+
onSuccess: (data) => {
|
|
625
|
+
queryClient.setQueryData(queryKeys.accounts.current(), data);
|
|
626
|
+
useAuthStore.getState().setUser(data);
|
|
627
|
+
invalidateAccountQueries(queryClient);
|
|
628
|
+
},
|
|
629
|
+
});
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Revoke the authenticated user's authorization for a specific RP origin.
|
|
634
|
+
* Removes the FedCM grant so the origin no longer appears in the user's
|
|
635
|
+
* "Connected apps" list — next sign-in from that origin will require explicit
|
|
636
|
+
* re-consent.
|
|
637
|
+
*/
|
|
638
|
+
export const useRevokeAuthorizedApp = () => {
|
|
639
|
+
const { oxyServices, activeSessionId } = useOxy();
|
|
640
|
+
const queryClient = useQueryClient();
|
|
641
|
+
|
|
642
|
+
return useMutation({
|
|
643
|
+
mutationKey: [...mutationKeys.connectedApps.revoke],
|
|
644
|
+
mutationFn: async (origin: string) => {
|
|
645
|
+
return authenticatedApiCall<void>(oxyServices, activeSessionId, () =>
|
|
646
|
+
oxyServices.revokeAuthorizedApp(origin)
|
|
647
|
+
);
|
|
648
|
+
},
|
|
649
|
+
onSuccess: () => {
|
|
650
|
+
invalidateConnectedAppsQueries(queryClient);
|
|
651
|
+
},
|
|
652
|
+
onError: (error) => {
|
|
653
|
+
toast.error(
|
|
654
|
+
error instanceof Error ? error.message : 'Failed to revoke authorized app'
|
|
655
|
+
);
|
|
656
|
+
},
|
|
657
|
+
});
|
|
658
|
+
};
|
|
659
|
+
|
|
508
660
|
/**
|
|
509
661
|
* Upload file with authentication handling and progress tracking
|
|
510
662
|
*/
|