@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.
Files changed (362) hide show
  1. package/lib/commonjs/index.js +0 -11
  2. package/lib/commonjs/index.js.map +1 -1
  3. package/lib/commonjs/ui/components/AccountMenuButton.js +8 -10
  4. package/lib/commonjs/ui/components/AccountMenuButton.js.map +1 -1
  5. package/lib/commonjs/ui/components/AccountSwitcher.js +65 -35
  6. package/lib/commonjs/ui/components/AccountSwitcher.js.map +1 -1
  7. package/lib/commonjs/ui/context/OxyContext.js +124 -93
  8. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  9. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +2 -2
  10. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
  11. package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js +12 -12
  12. package/lib/commonjs/ui/hooks/queries/usePaymentQueries.js.map +1 -1
  13. package/lib/commonjs/ui/hooks/queries/useServicesQueries.js +8 -7
  14. package/lib/commonjs/ui/hooks/queries/useServicesQueries.js.map +1 -1
  15. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +11 -6
  16. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  17. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +3 -3
  18. package/lib/commonjs/ui/screens/CreateAccountScreen.js +6 -4
  19. package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
  20. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +8 -7
  21. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  22. package/lib/commonjs/ui/screens/FileManagementScreen.js +13 -13
  23. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  24. package/lib/commonjs/ui/screens/HistoryViewScreen.js +7 -7
  25. package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
  26. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +5 -5
  27. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  28. package/lib/commonjs/ui/screens/ManageAccountScreen.js +17 -18
  29. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  30. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +3 -3
  31. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +9 -9
  33. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  34. package/lib/commonjs/ui/screens/ProfileScreen.js +1 -1
  35. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +4 -4
  37. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
  38. package/lib/commonjs/ui/screens/SearchSettingsScreen.js +6 -6
  39. package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -1
  40. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +6 -6
  41. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  42. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +4 -4
  43. package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  44. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +4 -4
  45. package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  46. package/lib/module/index.js +0 -5
  47. package/lib/module/index.js.map +1 -1
  48. package/lib/module/ui/components/AccountMenuButton.js +8 -10
  49. package/lib/module/ui/components/AccountMenuButton.js.map +1 -1
  50. package/lib/module/ui/components/AccountSwitcher.js +65 -35
  51. package/lib/module/ui/components/AccountSwitcher.js.map +1 -1
  52. package/lib/module/ui/context/OxyContext.js +124 -93
  53. package/lib/module/ui/context/OxyContext.js.map +1 -1
  54. package/lib/module/ui/hooks/queries/useAccountQueries.js +2 -2
  55. package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
  56. package/lib/module/ui/hooks/queries/usePaymentQueries.js +12 -12
  57. package/lib/module/ui/hooks/queries/usePaymentQueries.js.map +1 -1
  58. package/lib/module/ui/hooks/queries/useServicesQueries.js +9 -7
  59. package/lib/module/ui/hooks/queries/useServicesQueries.js.map +1 -1
  60. package/lib/module/ui/screens/AccountSettingsScreen.js +11 -6
  61. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  62. package/lib/module/ui/screens/AccountSwitcherScreen.js +3 -3
  63. package/lib/module/ui/screens/CreateAccountScreen.js +6 -4
  64. package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
  65. package/lib/module/ui/screens/EditProfileFieldScreen.js +8 -7
  66. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  67. package/lib/module/ui/screens/FileManagementScreen.js +13 -13
  68. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  69. package/lib/module/ui/screens/HistoryViewScreen.js +7 -7
  70. package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
  71. package/lib/module/ui/screens/LanguageSelectorScreen.js +5 -5
  72. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  73. package/lib/module/ui/screens/ManageAccountScreen.js +17 -18
  74. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  75. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +3 -3
  76. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  77. package/lib/module/ui/screens/PrivacySettingsScreen.js +9 -9
  78. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  79. package/lib/module/ui/screens/ProfileScreen.js +1 -1
  80. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  81. package/lib/module/ui/screens/SavesCollectionsScreen.js +4 -4
  82. package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
  83. package/lib/module/ui/screens/SearchSettingsScreen.js +6 -6
  84. package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -1
  85. package/lib/module/ui/screens/WelcomeNewUserScreen.js +6 -6
  86. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  87. package/lib/module/ui/screens/trust/TrustCenterScreen.js +4 -4
  88. package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
  89. package/lib/module/ui/screens/trust/TrustRewardsScreen.js +4 -4
  90. package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
  91. package/lib/typescript/commonjs/index.d.ts +0 -1
  92. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  93. package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts +5 -7
  94. package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts.map +1 -1
  95. package/lib/typescript/commonjs/ui/components/AccountSwitcher.d.ts.map +1 -1
  96. package/lib/typescript/commonjs/ui/components/ActivityIndicator.d.ts +1 -1
  97. package/lib/typescript/commonjs/ui/components/ActivityIndicator.d.ts.map +1 -1
  98. package/lib/typescript/commonjs/ui/components/CrossFadeIcon.d.ts +2 -1
  99. package/lib/typescript/commonjs/ui/components/CrossFadeIcon.d.ts.map +1 -1
  100. package/lib/typescript/commonjs/ui/components/FontLoader.d.ts +1 -1
  101. package/lib/typescript/commonjs/ui/components/FontLoader.d.ts.map +1 -1
  102. package/lib/typescript/commonjs/ui/components/HelperText.d.ts +1 -1
  103. package/lib/typescript/commonjs/ui/components/HelperText.d.ts.map +1 -1
  104. package/lib/typescript/commonjs/ui/components/TextField/Addons/Outline.d.ts +2 -1
  105. package/lib/typescript/commonjs/ui/components/TextField/Addons/Outline.d.ts.map +1 -1
  106. package/lib/typescript/commonjs/ui/components/TextField/Addons/Underline.d.ts +2 -1
  107. package/lib/typescript/commonjs/ui/components/TextField/Addons/Underline.d.ts.map +1 -1
  108. package/lib/typescript/commonjs/ui/components/TextField/Adornment/TextFieldAffix.d.ts +1 -1
  109. package/lib/typescript/commonjs/ui/components/TextField/Adornment/TextFieldIcon.d.ts +1 -1
  110. package/lib/typescript/commonjs/ui/components/TextField/Label/InputLabel.d.ts +1 -1
  111. package/lib/typescript/commonjs/ui/components/TextField/Label/LabelBackground.d.ts +2 -1
  112. package/lib/typescript/commonjs/ui/components/TextField/Label/LabelBackground.d.ts.map +1 -1
  113. package/lib/typescript/commonjs/ui/components/TextField/TextFieldFlat.d.ts +2 -1
  114. package/lib/typescript/commonjs/ui/components/TextField/TextFieldFlat.d.ts.map +1 -1
  115. package/lib/typescript/commonjs/ui/components/TextField/TextFieldOutlined.d.ts +2 -1
  116. package/lib/typescript/commonjs/ui/components/TextField/TextFieldOutlined.d.ts.map +1 -1
  117. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +11 -26
  118. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  119. package/lib/typescript/commonjs/ui/context/ThemeContext.d.ts +1 -1
  120. package/lib/typescript/commonjs/ui/context/ThemeContext.d.ts.map +1 -1
  121. package/lib/typescript/commonjs/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
  122. package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  123. package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts +3 -3
  124. package/lib/typescript/commonjs/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  125. package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  126. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  127. package/lib/typescript/module/index.d.ts +60 -61
  128. package/lib/typescript/module/index.d.ts.map +1 -1
  129. package/lib/typescript/module/ui/client.d.ts +26 -26
  130. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  131. package/lib/typescript/module/ui/components/AccountMenuButton.d.ts +5 -7
  132. package/lib/typescript/module/ui/components/AccountMenuButton.d.ts.map +1 -1
  133. package/lib/typescript/module/ui/components/AccountSwitcher.d.ts +1 -1
  134. package/lib/typescript/module/ui/components/AccountSwitcher.d.ts.map +1 -1
  135. package/lib/typescript/module/ui/components/ActivityIndicator.d.ts +2 -2
  136. package/lib/typescript/module/ui/components/ActivityIndicator.d.ts.map +1 -1
  137. package/lib/typescript/module/ui/components/BottomSheetRouter.d.ts +1 -1
  138. package/lib/typescript/module/ui/components/BottomSheetRouter.d.ts.map +1 -1
  139. package/lib/typescript/module/ui/components/CrossFadeIcon.d.ts +4 -3
  140. package/lib/typescript/module/ui/components/CrossFadeIcon.d.ts.map +1 -1
  141. package/lib/typescript/module/ui/components/FontLoader.d.ts +1 -1
  142. package/lib/typescript/module/ui/components/FontLoader.d.ts.map +1 -1
  143. package/lib/typescript/module/ui/components/HelperText.d.ts +1 -1
  144. package/lib/typescript/module/ui/components/HelperText.d.ts.map +1 -1
  145. package/lib/typescript/module/ui/components/Icon.d.ts +1 -1
  146. package/lib/typescript/module/ui/components/Icon.d.ts.map +1 -1
  147. package/lib/typescript/module/ui/components/IconButton/IconButton.d.ts +3 -3
  148. package/lib/typescript/module/ui/components/IconButton/IconButton.d.ts.map +1 -1
  149. package/lib/typescript/module/ui/components/IconButton/utils.d.ts +1 -1
  150. package/lib/typescript/module/ui/components/IconButton/utils.d.ts.map +1 -1
  151. package/lib/typescript/module/ui/components/OxyPayButton.d.ts +1 -1
  152. package/lib/typescript/module/ui/components/OxyPayButton.d.ts.map +1 -1
  153. package/lib/typescript/module/ui/components/OxyProvider.d.ts +1 -1
  154. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  155. package/lib/typescript/module/ui/components/StepBasedScreen.d.ts +2 -2
  156. package/lib/typescript/module/ui/components/StepBasedScreen.d.ts.map +1 -1
  157. package/lib/typescript/module/ui/components/Surface.d.ts +2 -2
  158. package/lib/typescript/module/ui/components/Surface.d.ts.map +1 -1
  159. package/lib/typescript/module/ui/components/TextField/Addons/Outline.d.ts +3 -2
  160. package/lib/typescript/module/ui/components/TextField/Addons/Outline.d.ts.map +1 -1
  161. package/lib/typescript/module/ui/components/TextField/Addons/Underline.d.ts +3 -2
  162. package/lib/typescript/module/ui/components/TextField/Addons/Underline.d.ts.map +1 -1
  163. package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldAdornment.d.ts +3 -3
  164. package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldAdornment.d.ts.map +1 -1
  165. package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldAffix.d.ts +3 -3
  166. package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldAffix.d.ts.map +1 -1
  167. package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldIcon.d.ts +4 -4
  168. package/lib/typescript/module/ui/components/TextField/Adornment/TextFieldIcon.d.ts.map +1 -1
  169. package/lib/typescript/module/ui/components/TextField/Adornment/types.d.ts +1 -1
  170. package/lib/typescript/module/ui/components/TextField/Adornment/types.d.ts.map +1 -1
  171. package/lib/typescript/module/ui/components/TextField/Adornment/utils.d.ts +1 -1
  172. package/lib/typescript/module/ui/components/TextField/Adornment/utils.d.ts.map +1 -1
  173. package/lib/typescript/module/ui/components/TextField/Label/InputLabel.d.ts +2 -2
  174. package/lib/typescript/module/ui/components/TextField/Label/InputLabel.d.ts.map +1 -1
  175. package/lib/typescript/module/ui/components/TextField/Label/LabelBackground.d.ts +3 -2
  176. package/lib/typescript/module/ui/components/TextField/Label/LabelBackground.d.ts.map +1 -1
  177. package/lib/typescript/module/ui/components/TextField/TextFieldFlat.d.ts +3 -2
  178. package/lib/typescript/module/ui/components/TextField/TextFieldFlat.d.ts.map +1 -1
  179. package/lib/typescript/module/ui/components/TextField/TextFieldOutlined.d.ts +3 -2
  180. package/lib/typescript/module/ui/components/TextField/TextFieldOutlined.d.ts.map +1 -1
  181. package/lib/typescript/module/ui/components/TextField/helpers.d.ts +3 -3
  182. package/lib/typescript/module/ui/components/TextField/helpers.d.ts.map +1 -1
  183. package/lib/typescript/module/ui/components/TextField/types.d.ts +1 -1
  184. package/lib/typescript/module/ui/components/TextField/types.d.ts.map +1 -1
  185. package/lib/typescript/module/ui/components/TextField.d.ts +4 -4
  186. package/lib/typescript/module/ui/components/TextField.d.ts.map +1 -1
  187. package/lib/typescript/module/ui/components/TouchableRipple/TouchableRipple.d.ts +3 -3
  188. package/lib/typescript/module/ui/components/TouchableRipple/TouchableRipple.d.ts.map +1 -1
  189. package/lib/typescript/module/ui/components/TouchableRipple/TouchableRipple.native.d.ts +3 -3
  190. package/lib/typescript/module/ui/components/TouchableRipple/TouchableRipple.native.d.ts.map +1 -1
  191. package/lib/typescript/module/ui/components/TouchableRipple/utils.d.ts +1 -1
  192. package/lib/typescript/module/ui/components/TouchableRipple/utils.d.ts.map +1 -1
  193. package/lib/typescript/module/ui/components/Typography/AnimatedText.d.ts +3 -3
  194. package/lib/typescript/module/ui/components/Typography/AnimatedText.d.ts.map +1 -1
  195. package/lib/typescript/module/ui/components/accountMenuRows.d.ts +1 -1
  196. package/lib/typescript/module/ui/components/accountMenuRows.d.ts.map +1 -1
  197. package/lib/typescript/module/ui/components/feedback/ProgressIndicator.d.ts +1 -1
  198. package/lib/typescript/module/ui/components/feedback/ProgressIndicator.d.ts.map +1 -1
  199. package/lib/typescript/module/ui/components/feedback/constants.d.ts +1 -1
  200. package/lib/typescript/module/ui/components/feedback/constants.d.ts.map +1 -1
  201. package/lib/typescript/module/ui/components/feedback/useFeedbackForm.d.ts +1 -1
  202. package/lib/typescript/module/ui/components/feedback/useFeedbackForm.d.ts.map +1 -1
  203. package/lib/typescript/module/ui/components/payment/PaymentDetailsStep.d.ts +1 -1
  204. package/lib/typescript/module/ui/components/payment/PaymentDetailsStep.d.ts.map +1 -1
  205. package/lib/typescript/module/ui/components/payment/PaymentMethodStep.d.ts +1 -1
  206. package/lib/typescript/module/ui/components/payment/PaymentMethodStep.d.ts.map +1 -1
  207. package/lib/typescript/module/ui/components/payment/PaymentReviewStep.d.ts +1 -1
  208. package/lib/typescript/module/ui/components/payment/PaymentReviewStep.d.ts.map +1 -1
  209. package/lib/typescript/module/ui/components/payment/PaymentSuccessStep.d.ts +1 -1
  210. package/lib/typescript/module/ui/components/payment/PaymentSuccessStep.d.ts.map +1 -1
  211. package/lib/typescript/module/ui/components/payment/PaymentSummaryStep.d.ts +1 -1
  212. package/lib/typescript/module/ui/components/payment/PaymentSummaryStep.d.ts.map +1 -1
  213. package/lib/typescript/module/ui/components/payment/constants.d.ts +1 -1
  214. package/lib/typescript/module/ui/components/payment/constants.d.ts.map +1 -1
  215. package/lib/typescript/module/ui/components/payment/paymentStyles.d.ts +1 -1
  216. package/lib/typescript/module/ui/components/payment/paymentStyles.d.ts.map +1 -1
  217. package/lib/typescript/module/ui/components/theming.d.ts +1 -1
  218. package/lib/typescript/module/ui/components/theming.d.ts.map +1 -1
  219. package/lib/typescript/module/ui/context/OxyContext.d.ts +14 -29
  220. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  221. package/lib/typescript/module/ui/context/ThemeContext.d.ts +1 -1
  222. package/lib/typescript/module/ui/context/ThemeContext.d.ts.map +1 -1
  223. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +2 -2
  224. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  225. package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts +1 -1
  226. package/lib/typescript/module/ui/hooks/queries/usePaymentQueries.d.ts.map +1 -1
  227. package/lib/typescript/module/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
  228. package/lib/typescript/module/ui/hooks/queryClient.d.ts +1 -1
  229. package/lib/typescript/module/ui/hooks/queryClient.d.ts.map +1 -1
  230. package/lib/typescript/module/ui/hooks/useAuth.d.ts +1 -1
  231. package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
  232. package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts +1 -1
  233. package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts.map +1 -1
  234. package/lib/typescript/module/ui/hooks/useLanguageManagement.d.ts +1 -1
  235. package/lib/typescript/module/ui/hooks/useLanguageManagement.d.ts.map +1 -1
  236. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts +1 -1
  237. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
  238. package/lib/typescript/module/ui/hooks/useStorage.d.ts +1 -1
  239. package/lib/typescript/module/ui/hooks/useStorage.d.ts.map +1 -1
  240. package/lib/typescript/module/ui/index.d.ts +28 -28
  241. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  242. package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts +1 -1
  243. package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts.map +1 -1
  244. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  245. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  246. package/lib/typescript/module/ui/screens/AccountMembersScreen.d.ts +1 -1
  247. package/lib/typescript/module/ui/screens/AccountMembersScreen.d.ts.map +1 -1
  248. package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts +1 -1
  249. package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  250. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts +4 -4
  251. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  252. package/lib/typescript/module/ui/screens/AccountVerificationScreen.d.ts +1 -1
  253. package/lib/typescript/module/ui/screens/AccountVerificationScreen.d.ts.map +1 -1
  254. package/lib/typescript/module/ui/screens/AppInfoScreen.d.ts +1 -1
  255. package/lib/typescript/module/ui/screens/AppInfoScreen.d.ts.map +1 -1
  256. package/lib/typescript/module/ui/screens/AvatarCropScreen.d.ts +1 -1
  257. package/lib/typescript/module/ui/screens/AvatarCropScreen.d.ts.map +1 -1
  258. package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts +1 -1
  259. package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts.map +1 -1
  260. package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts +1 -1
  261. package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  262. package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts +1 -1
  263. package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  264. package/lib/typescript/module/ui/screens/FAQScreen.d.ts +1 -1
  265. package/lib/typescript/module/ui/screens/FAQScreen.d.ts.map +1 -1
  266. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts +1 -1
  267. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
  268. package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts +1 -1
  269. package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
  270. package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts +1 -1
  271. package/lib/typescript/module/ui/screens/FollowersListScreen.d.ts.map +1 -1
  272. package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts +1 -1
  273. package/lib/typescript/module/ui/screens/FollowingListScreen.d.ts.map +1 -1
  274. package/lib/typescript/module/ui/screens/HelpSupportScreen.d.ts +1 -1
  275. package/lib/typescript/module/ui/screens/HelpSupportScreen.d.ts.map +1 -1
  276. package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts +1 -1
  277. package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
  278. package/lib/typescript/module/ui/screens/LanguageSelectorScreen.d.ts +1 -1
  279. package/lib/typescript/module/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
  280. package/lib/typescript/module/ui/screens/LearnMoreUsernamesScreen.d.ts +1 -1
  281. package/lib/typescript/module/ui/screens/LearnMoreUsernamesScreen.d.ts.map +1 -1
  282. package/lib/typescript/module/ui/screens/LegalDocumentsScreen.d.ts +1 -1
  283. package/lib/typescript/module/ui/screens/LegalDocumentsScreen.d.ts.map +1 -1
  284. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts +1 -1
  285. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  286. package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts +1 -1
  287. package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts.map +1 -1
  288. package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts +1 -1
  289. package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts.map +1 -1
  290. package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts +2 -2
  291. package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  292. package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts +1 -1
  293. package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts.map +1 -1
  294. package/lib/typescript/module/ui/screens/PremiumSubscriptionScreen.d.ts +1 -1
  295. package/lib/typescript/module/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
  296. package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts +1 -1
  297. package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  298. package/lib/typescript/module/ui/screens/ProfileScreen.d.ts +1 -1
  299. package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
  300. package/lib/typescript/module/ui/screens/SavesCollectionsScreen.d.ts +1 -1
  301. package/lib/typescript/module/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
  302. package/lib/typescript/module/ui/screens/SearchSettingsScreen.d.ts +1 -1
  303. package/lib/typescript/module/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
  304. package/lib/typescript/module/ui/screens/UserLinksScreen.d.ts +1 -1
  305. package/lib/typescript/module/ui/screens/UserLinksScreen.d.ts.map +1 -1
  306. package/lib/typescript/module/ui/screens/UserListScreen.d.ts +1 -1
  307. package/lib/typescript/module/ui/screens/UserListScreen.d.ts.map +1 -1
  308. package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts +1 -1
  309. package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  310. package/lib/typescript/module/ui/screens/trust/TrustAboutScreen.d.ts +1 -1
  311. package/lib/typescript/module/ui/screens/trust/TrustAboutScreen.d.ts.map +1 -1
  312. package/lib/typescript/module/ui/screens/trust/TrustCenterScreen.d.ts +1 -1
  313. package/lib/typescript/module/ui/screens/trust/TrustCenterScreen.d.ts.map +1 -1
  314. package/lib/typescript/module/ui/screens/trust/TrustFAQScreen.d.ts +1 -1
  315. package/lib/typescript/module/ui/screens/trust/TrustFAQScreen.d.ts.map +1 -1
  316. package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts +1 -1
  317. package/lib/typescript/module/ui/screens/trust/TrustLeaderboardScreen.d.ts.map +1 -1
  318. package/lib/typescript/module/ui/screens/trust/TrustRewardsScreen.d.ts +1 -1
  319. package/lib/typescript/module/ui/screens/trust/TrustRewardsScreen.d.ts.map +1 -1
  320. package/lib/typescript/module/ui/screens/trust/TrustRulesScreen.d.ts +1 -1
  321. package/lib/typescript/module/ui/screens/trust/TrustRulesScreen.d.ts.map +1 -1
  322. package/lib/typescript/module/ui/server.d.ts +2 -2
  323. package/lib/typescript/module/ui/server.d.ts.map +1 -1
  324. package/lib/typescript/module/ui/types/fileManagement.d.ts +1 -1
  325. package/lib/typescript/module/ui/types/fileManagement.d.ts.map +1 -1
  326. package/lib/typescript/module/ui/types/navigation.d.ts +1 -1
  327. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  328. package/lib/typescript/module/ui/utils/fileManagement.d.ts +1 -1
  329. package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
  330. package/package.json +21 -20
  331. package/src/index.ts +0 -5
  332. package/src/ui/components/AccountMenuButton.tsx +9 -11
  333. package/src/ui/components/AccountSwitcher.tsx +71 -37
  334. package/src/ui/context/OxyContext.tsx +127 -122
  335. package/src/ui/hooks/queries/useAccountQueries.ts +2 -2
  336. package/src/ui/hooks/queries/usePaymentQueries.ts +12 -12
  337. package/src/ui/hooks/queries/useServicesQueries.ts +9 -6
  338. package/src/ui/screens/AccountSettingsScreen.tsx +9 -5
  339. package/src/ui/screens/AccountSwitcherScreen.tsx +3 -3
  340. package/src/ui/screens/CreateAccountScreen.tsx +6 -4
  341. package/src/ui/screens/EditProfileFieldScreen.tsx +8 -7
  342. package/src/ui/screens/FileManagementScreen.tsx +13 -13
  343. package/src/ui/screens/HistoryViewScreen.tsx +7 -7
  344. package/src/ui/screens/LanguageSelectorScreen.tsx +5 -5
  345. package/src/ui/screens/ManageAccountScreen.tsx +17 -18
  346. package/src/ui/screens/PremiumSubscriptionScreen.tsx +3 -3
  347. package/src/ui/screens/PrivacySettingsScreen.tsx +9 -9
  348. package/src/ui/screens/ProfileScreen.tsx +1 -1
  349. package/src/ui/screens/SavesCollectionsScreen.tsx +5 -5
  350. package/src/ui/screens/SearchSettingsScreen.tsx +6 -6
  351. package/src/ui/screens/WelcomeNewUserScreen.tsx +6 -6
  352. package/src/ui/screens/trust/TrustCenterScreen.tsx +5 -5
  353. package/src/ui/screens/trust/TrustRewardsScreen.tsx +4 -4
  354. package/lib/commonjs/ui/components/ActiveAccountBanner.js +0 -144
  355. package/lib/commonjs/ui/components/ActiveAccountBanner.js.map +0 -1
  356. package/lib/module/ui/components/ActiveAccountBanner.js +0 -141
  357. package/lib/module/ui/components/ActiveAccountBanner.js.map +0 -1
  358. package/lib/typescript/commonjs/ui/components/ActiveAccountBanner.d.ts +0 -4
  359. package/lib/typescript/commonjs/ui/components/ActiveAccountBanner.d.ts.map +0 -1
  360. package/lib/typescript/module/ui/components/ActiveAccountBanner.d.ts +0 -4
  361. package/lib/typescript/module/ui/components/ActiveAccountBanner.d.ts.map +0 -1
  362. 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
- actingAs,
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 accounts;
150
- return accounts.filter((node) => {
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
- }, [accounts, query, locale]);
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 returns to that sign-in's own
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, actingAs, setActingAs, switchSession, t, onClose, onBeforeSessionChange]);
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
- // The personal (self) account = no delegation (acting-as null).
243
- setActingAs(node.relationship === 'self' ? null : node.accountId);
244
- onClose();
245
- }, [setActingAs, onClose]);
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
- const active = node.relationship === 'self'
251
- ? actingAs === null
252
- : actingAs === node.accountId;
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
- {active ? <Ionicons name="checkmark" size={20} color={colors.primary} /> : null}
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
- }, [actingAs, colors, handleSelectAccount, locale, onOpenAccountSettings, oxyServices, t]);
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 sign-in is THE current account only when no
337
- // account-graph switch is in effect; otherwise a switched-into
338
- // account is current and this row reads as the signed-in (but not
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
- {accounts.length > 0 ? (
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
- {accounts.length > 6 ? (
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 switch, NOT an "acting on behalf of" delegation. `actingAs` +
165
- // `X-Acting-As` remain the underlying transport (the only one that works for
166
- // passwordless org/project/bot accounts), but the framing everywhere is simply
167
- // "this is the active account". Read {@link activeAccount} for "who am I"
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
- * The {@link AccountNode} switched into, resolved from `accounts` by
180
- * `actingAs`. `null` when the active account is the sign-in's own personal
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
- * It is a {@link User} (the personal user, or the switched-into account's
193
- * embedded user) so every identity surface renders it identically. Falls back
194
- * to the personal `user` during the brief window after a switch before
195
- * `accounts` has loaded the switched-into node, so the header never flashes
196
- * empty. `null` only when signed out.
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
- activeAccount: User | null;
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
- const setActingAs = useCallback((accountId: string | null) => {
2091
- oxyServices.setActingAs(accountId);
2092
- setActingAsState(accountId);
2093
- // Switching the acting-as identity changes every server response, but React
2094
- // Query keys are not namespaced by the acting-as target, so the cache would
2095
- // otherwise keep serving the previous account's data. Invalidate everything
2096
- // so each query refetches under the new identity (the next request carries
2097
- // the updated `X-Acting-As` header). `invalidateQueries` (not `clear`) keeps
2098
- // the account list/switcher populated mid-switch instead of blanking out.
2099
- queryClient.invalidateQueries();
2100
- // Persist to storage
2101
- if (storage) {
2102
- if (accountId) {
2103
- storage.setItem(`${storageKeyPrefix}_acting_as`, accountId).catch((persistError) => {
2104
- loggerUtil.debug('Failed to persist acting-as account', { component: 'OxyContext' }, persistError as unknown);
2105
- });
2106
- } else {
2107
- storage.removeItem(`${storageKeyPrefix}_acting_as`).catch((persistError) => {
2108
- loggerUtil.debug('Failed to clear acting-as account', { component: 'OxyContext' }, persistError as unknown);
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
- }, [oxyServices, storage, storageKeyPrefix, queryClient]);
2113
- setActingAsRef.current = setActingAs;
2114
-
2115
- // The account switched into, resolved from the loaded graph.
2116
- const actingAsAccount = useMemo<AccountNode | null>(() => {
2117
- if (!actingAs) return null;
2118
- return accounts.find((node) => node.accountId === actingAs) ?? null;
2119
- }, [actingAs, accounts]);
2120
-
2121
- // The effective ACTIVE account presented across the app: the switched-into
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
- actingAsAccount,
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
- actingAsAccount,
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
- actingAsAccount: null,
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, activeAccount } = useOxy();
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 || activeAccount?.id;
239
+ const targetUserId = userId || user?.id;
240
240
 
241
241
  return useQuery({
242
242
  queryKey: queryKeys.privacy.settings(targetUserId),