@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.
Files changed (450) hide show
  1. package/lib/commonjs/index.js +211 -49
  2. package/lib/commonjs/index.js.map +1 -1
  3. package/lib/commonjs/ui/client.js +25 -4
  4. package/lib/commonjs/ui/client.js.map +1 -1
  5. package/lib/commonjs/ui/components/AccountMenu.js +485 -0
  6. package/lib/commonjs/ui/components/AccountMenu.js.map +1 -0
  7. package/lib/commonjs/ui/components/AccountMenuButton.js +120 -0
  8. package/lib/commonjs/ui/components/AccountMenuButton.js.map +1 -0
  9. package/lib/commonjs/ui/components/ActingAsBanner.js +2 -2
  10. package/lib/commonjs/ui/components/ActingAsBanner.js.map +1 -1
  11. package/lib/commonjs/ui/components/ProfileCard.js +2 -2
  12. package/lib/commonjs/ui/components/ProfileCard.js.map +1 -1
  13. package/lib/commonjs/ui/components/StepBasedScreen.js +2 -2
  14. package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -1
  15. package/lib/commonjs/ui/components/accountMenuRows.js +45 -0
  16. package/lib/commonjs/ui/components/accountMenuRows.js.map +1 -0
  17. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js +5 -5
  18. package/lib/commonjs/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  19. package/lib/commonjs/ui/components/payment/PaymentMethodStep.js +3 -2
  20. package/lib/commonjs/ui/components/payment/PaymentMethodStep.js.map +1 -1
  21. package/lib/commonjs/ui/components/theming.js +2 -2
  22. package/lib/commonjs/ui/components/theming.js.map +1 -1
  23. package/lib/commonjs/ui/context/OxyContext.js +59 -131
  24. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  25. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +36 -2
  26. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  27. package/lib/commonjs/ui/hooks/mutations/mutationKeys.js +6 -0
  28. package/lib/commonjs/ui/hooks/mutations/mutationKeys.js.map +1 -1
  29. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +138 -1
  30. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  31. package/lib/commonjs/ui/hooks/queries/queryKeys.js +67 -2
  32. package/lib/commonjs/ui/hooks/queries/queryKeys.js.map +1 -1
  33. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +27 -2
  34. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
  35. package/lib/commonjs/ui/hooks/useAuth.js +13 -2
  36. package/lib/commonjs/ui/hooks/useAuth.js.map +1 -1
  37. package/lib/commonjs/ui/hooks/useSessionManagement.js +30 -0
  38. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  39. package/lib/commonjs/ui/index.js +132 -85
  40. package/lib/commonjs/ui/index.js.map +1 -1
  41. package/lib/commonjs/ui/navigation/routes.js +6 -7
  42. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  43. package/lib/commonjs/ui/screens/AccountVerificationScreen.js +3 -2
  44. package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
  45. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js +202 -0
  46. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js.map +1 -0
  47. package/lib/commonjs/ui/screens/CreateManagedAccountScreen.js +3 -2
  48. package/lib/commonjs/ui/screens/CreateManagedAccountScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +3 -2
  50. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  51. package/lib/commonjs/ui/screens/FAQScreen.js +7 -4
  52. package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/FeedbackScreen.js +21 -16
  54. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/HelpSupportScreen.js +3 -2
  56. package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
  57. package/lib/commonjs/ui/screens/HistoryViewScreen.js +7 -4
  58. package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
  59. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +3 -2
  60. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  61. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +6 -4
  62. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
  63. package/lib/commonjs/ui/screens/ManageAccountScreen.js +780 -0
  64. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -0
  65. package/lib/commonjs/ui/screens/NotificationsScreen.js +175 -0
  66. package/lib/commonjs/ui/screens/NotificationsScreen.js.map +1 -0
  67. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +18 -12
  68. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  69. package/lib/commonjs/ui/screens/PreferencesScreen.js +220 -0
  70. package/lib/commonjs/ui/screens/PreferencesScreen.js.map +1 -0
  71. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +14 -10
  72. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  73. package/lib/commonjs/ui/screens/ProfileScreen.js +3 -3
  74. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  75. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +8 -5
  76. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
  77. package/lib/commonjs/ui/screens/SearchSettingsScreen.js +6 -4
  78. package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -1
  79. package/lib/commonjs/ui/screens/UserLinksScreen.js +3 -2
  80. package/lib/commonjs/ui/screens/UserLinksScreen.js.map +1 -1
  81. package/lib/commonjs/ui/screens/UserListScreen.js +2 -2
  82. package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
  83. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +3 -2
  84. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  85. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +3 -2
  86. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  87. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +2 -2
  88. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  89. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +4 -3
  90. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  91. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +3 -2
  92. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  93. package/lib/commonjs/ui/utils/activeAuthuser.js +85 -0
  94. package/lib/commonjs/ui/utils/activeAuthuser.js.map +1 -0
  95. package/lib/module/index.js +58 -16
  96. package/lib/module/index.js.map +1 -1
  97. package/lib/module/ui/client.js +5 -3
  98. package/lib/module/ui/client.js.map +1 -1
  99. package/lib/module/ui/components/AccountMenu.js +480 -0
  100. package/lib/module/ui/components/AccountMenu.js.map +1 -0
  101. package/lib/module/ui/components/AccountMenuButton.js +115 -0
  102. package/lib/module/ui/components/AccountMenuButton.js.map +1 -0
  103. package/lib/module/ui/components/ActingAsBanner.js +2 -2
  104. package/lib/module/ui/components/ActingAsBanner.js.map +1 -1
  105. package/lib/module/ui/components/ProfileCard.js +1 -1
  106. package/lib/module/ui/components/ProfileCard.js.map +1 -1
  107. package/lib/module/ui/components/StepBasedScreen.js +1 -1
  108. package/lib/module/ui/components/StepBasedScreen.js.map +1 -1
  109. package/lib/module/ui/components/accountMenuRows.js +41 -0
  110. package/lib/module/ui/components/accountMenuRows.js.map +1 -0
  111. package/lib/module/ui/components/payment/PaymentDetailsStep.js +1 -1
  112. package/lib/module/ui/components/payment/PaymentDetailsStep.js.map +1 -1
  113. package/lib/module/ui/components/payment/PaymentMethodStep.js +1 -1
  114. package/lib/module/ui/components/payment/PaymentMethodStep.js.map +1 -1
  115. package/lib/module/ui/components/theming.js +1 -1
  116. package/lib/module/ui/components/theming.js.map +1 -1
  117. package/lib/module/ui/context/OxyContext.js +59 -131
  118. package/lib/module/ui/context/OxyContext.js.map +1 -1
  119. package/lib/module/ui/context/hooks/useAuthOperations.js +36 -2
  120. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  121. package/lib/module/ui/hooks/mutations/mutationKeys.js +6 -0
  122. package/lib/module/ui/hooks/mutations/mutationKeys.js.map +1 -1
  123. package/lib/module/ui/hooks/mutations/useAccountMutations.js +135 -1
  124. package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  125. package/lib/module/ui/hooks/queries/queryKeys.js +60 -1
  126. package/lib/module/ui/hooks/queries/queryKeys.js.map +1 -1
  127. package/lib/module/ui/hooks/queries/useAccountQueries.js +24 -0
  128. package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
  129. package/lib/module/ui/hooks/useAuth.js +13 -2
  130. package/lib/module/ui/hooks/useAuth.js.map +1 -1
  131. package/lib/module/ui/hooks/useSessionManagement.js +30 -0
  132. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  133. package/lib/module/ui/index.js +34 -78
  134. package/lib/module/ui/index.js.map +1 -1
  135. package/lib/module/ui/navigation/routes.js +6 -7
  136. package/lib/module/ui/navigation/routes.js.map +1 -1
  137. package/lib/module/ui/screens/AccountVerificationScreen.js +1 -1
  138. package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
  139. package/lib/module/ui/screens/ConnectedAppsScreen.js +198 -0
  140. package/lib/module/ui/screens/ConnectedAppsScreen.js.map +1 -0
  141. package/lib/module/ui/screens/CreateManagedAccountScreen.js +1 -1
  142. package/lib/module/ui/screens/CreateManagedAccountScreen.js.map +1 -1
  143. package/lib/module/ui/screens/EditProfileFieldScreen.js +1 -1
  144. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  145. package/lib/module/ui/screens/FAQScreen.js +3 -1
  146. package/lib/module/ui/screens/FAQScreen.js.map +1 -1
  147. package/lib/module/ui/screens/FeedbackScreen.js +6 -2
  148. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  149. package/lib/module/ui/screens/HelpSupportScreen.js +1 -1
  150. package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
  151. package/lib/module/ui/screens/HistoryViewScreen.js +3 -1
  152. package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
  153. package/lib/module/ui/screens/LanguageSelectorScreen.js +1 -1
  154. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  155. package/lib/module/ui/screens/LegalDocumentsScreen.js +2 -1
  156. package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
  157. package/lib/module/ui/screens/ManageAccountScreen.js +775 -0
  158. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -0
  159. package/lib/module/ui/screens/NotificationsScreen.js +169 -0
  160. package/lib/module/ui/screens/NotificationsScreen.js.map +1 -0
  161. package/lib/module/ui/screens/PaymentGatewayScreen.js +9 -3
  162. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  163. package/lib/module/ui/screens/PreferencesScreen.js +214 -0
  164. package/lib/module/ui/screens/PreferencesScreen.js.map +1 -0
  165. package/lib/module/ui/screens/PrivacySettingsScreen.js +4 -1
  166. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  167. package/lib/module/ui/screens/ProfileScreen.js +2 -2
  168. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  169. package/lib/module/ui/screens/SavesCollectionsScreen.js +3 -1
  170. package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
  171. package/lib/module/ui/screens/SearchSettingsScreen.js +2 -1
  172. package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -1
  173. package/lib/module/ui/screens/UserLinksScreen.js +1 -1
  174. package/lib/module/ui/screens/UserLinksScreen.js.map +1 -1
  175. package/lib/module/ui/screens/UserListScreen.js +1 -1
  176. package/lib/module/ui/screens/UserListScreen.js.map +1 -1
  177. package/lib/module/ui/screens/karma/KarmaAboutScreen.js +1 -1
  178. package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  179. package/lib/module/ui/screens/karma/KarmaFAQScreen.js +1 -1
  180. package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  181. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
  182. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  183. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +1 -1
  184. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  185. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
  186. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  187. package/lib/module/ui/utils/activeAuthuser.js +79 -0
  188. package/lib/module/ui/utils/activeAuthuser.js.map +1 -0
  189. package/lib/typescript/commonjs/index.d.ts +23 -6
  190. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  191. package/lib/typescript/commonjs/ui/client.d.ts +7 -2
  192. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  193. package/lib/typescript/commonjs/ui/components/AccountMenu.d.ts +23 -0
  194. package/lib/typescript/commonjs/ui/components/AccountMenu.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts +19 -0
  196. package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/ui/components/accountMenuRows.d.ts +27 -0
  198. package/lib/typescript/commonjs/ui/components/accountMenuRows.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  200. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  201. package/lib/typescript/commonjs/ui/hooks/mutations/mutationKeys.d.ts +5 -0
  202. package/lib/typescript/commonjs/ui/hooks/mutations/mutationKeys.d.ts.map +1 -1
  203. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +26 -1
  204. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  205. package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts +32 -3
  206. package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts.map +1 -1
  207. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts +10 -1
  208. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  209. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts +8 -2
  210. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -1
  211. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
  212. package/lib/typescript/commonjs/ui/index.d.ts +32 -18
  213. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  214. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
  215. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  216. package/lib/typescript/{module/ui/screens/AccountOverviewScreen.d.ts → commonjs/ui/screens/ConnectedAppsScreen.d.ts} +1 -1
  217. package/lib/typescript/commonjs/ui/screens/ConnectedAppsScreen.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/ui/screens/FAQScreen.d.ts.map +1 -1
  219. package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
  220. package/lib/typescript/commonjs/ui/screens/HistoryViewScreen.d.ts.map +1 -1
  221. package/lib/typescript/commonjs/ui/screens/LegalDocumentsScreen.d.ts.map +1 -1
  222. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts +13 -0
  223. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -0
  224. package/lib/typescript/commonjs/ui/screens/{AccountOverviewScreen.d.ts → NotificationsScreen.d.ts} +1 -1
  225. package/lib/typescript/commonjs/ui/screens/NotificationsScreen.d.ts.map +1 -0
  226. package/lib/typescript/commonjs/ui/screens/PaymentGatewayScreen.d.ts +1 -1
  227. package/lib/typescript/commonjs/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  228. package/lib/typescript/commonjs/ui/screens/{AccountSettingsScreen.d.ts → PreferencesScreen.d.ts} +2 -5
  229. package/lib/typescript/commonjs/ui/screens/PreferencesScreen.d.ts.map +1 -0
  230. package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  231. package/lib/typescript/commonjs/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
  232. package/lib/typescript/commonjs/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
  233. package/lib/typescript/commonjs/ui/utils/activeAuthuser.d.ts +42 -0
  234. package/lib/typescript/commonjs/ui/utils/activeAuthuser.d.ts.map +1 -0
  235. package/lib/typescript/module/index.d.ts +23 -6
  236. package/lib/typescript/module/index.d.ts.map +1 -1
  237. package/lib/typescript/module/ui/client.d.ts +7 -2
  238. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  239. package/lib/typescript/module/ui/components/AccountMenu.d.ts +23 -0
  240. package/lib/typescript/module/ui/components/AccountMenu.d.ts.map +1 -0
  241. package/lib/typescript/module/ui/components/AccountMenuButton.d.ts +19 -0
  242. package/lib/typescript/module/ui/components/AccountMenuButton.d.ts.map +1 -0
  243. package/lib/typescript/module/ui/components/accountMenuRows.d.ts +27 -0
  244. package/lib/typescript/module/ui/components/accountMenuRows.d.ts.map +1 -0
  245. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  246. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  247. package/lib/typescript/module/ui/hooks/mutations/mutationKeys.d.ts +5 -0
  248. package/lib/typescript/module/ui/hooks/mutations/mutationKeys.d.ts.map +1 -1
  249. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +26 -1
  250. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  251. package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts +32 -3
  252. package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts.map +1 -1
  253. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts +10 -1
  254. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  255. package/lib/typescript/module/ui/hooks/useAuth.d.ts +8 -2
  256. package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
  257. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
  258. package/lib/typescript/module/ui/index.d.ts +32 -18
  259. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  260. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  261. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  262. package/lib/typescript/module/ui/screens/{AccountSettingsScreen.d.ts → ConnectedAppsScreen.d.ts} +2 -5
  263. package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts.map +1 -0
  264. package/lib/typescript/module/ui/screens/FAQScreen.d.ts.map +1 -1
  265. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
  266. package/lib/typescript/module/ui/screens/HistoryViewScreen.d.ts.map +1 -1
  267. package/lib/typescript/module/ui/screens/LegalDocumentsScreen.d.ts.map +1 -1
  268. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts +13 -0
  269. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -0
  270. package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts +5 -0
  271. package/lib/typescript/module/ui/screens/NotificationsScreen.d.ts.map +1 -0
  272. package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts +1 -1
  273. package/lib/typescript/module/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  274. package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts +5 -0
  275. package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts.map +1 -0
  276. package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
  277. package/lib/typescript/module/ui/screens/SavesCollectionsScreen.d.ts.map +1 -1
  278. package/lib/typescript/module/ui/screens/SearchSettingsScreen.d.ts.map +1 -1
  279. package/lib/typescript/module/ui/utils/activeAuthuser.d.ts +42 -0
  280. package/lib/typescript/module/ui/utils/activeAuthuser.d.ts.map +1 -0
  281. package/package.json +20 -9
  282. package/src/index.ts +141 -47
  283. package/src/ui/client.ts +7 -2
  284. package/src/ui/components/AccountMenu.tsx +534 -0
  285. package/src/ui/components/AccountMenuButton.tsx +113 -0
  286. package/src/ui/components/ActingAsBanner.tsx +2 -2
  287. package/src/ui/components/ProfileCard.tsx +1 -1
  288. package/src/ui/components/StepBasedScreen.tsx +1 -1
  289. package/src/ui/components/accountMenuRows.ts +60 -0
  290. package/src/ui/components/payment/PaymentDetailsStep.tsx +1 -1
  291. package/src/ui/components/payment/PaymentMethodStep.tsx +1 -1
  292. package/src/ui/components/theming.tsx +1 -1
  293. package/src/ui/context/OxyContext.tsx +61 -145
  294. package/src/ui/context/hooks/useAuthOperations.ts +36 -2
  295. package/src/ui/hooks/mutations/mutationKeys.ts +11 -0
  296. package/src/ui/hooks/mutations/useAccountMutations.ts +154 -2
  297. package/src/ui/hooks/queries/queryKeys.ts +54 -4
  298. package/src/ui/hooks/queries/useAccountQueries.ts +25 -1
  299. package/src/ui/hooks/useAuth.ts +23 -4
  300. package/src/ui/hooks/useSessionManagement.ts +29 -0
  301. package/src/ui/index.ts +37 -98
  302. package/src/ui/navigation/routes.ts +9 -11
  303. package/src/ui/screens/AccountVerificationScreen.tsx +1 -1
  304. package/src/ui/screens/ConnectedAppsScreen.tsx +225 -0
  305. package/src/ui/screens/CreateManagedAccountScreen.tsx +1 -1
  306. package/src/ui/screens/EditProfileFieldScreen.tsx +1 -1
  307. package/src/ui/screens/FAQScreen.tsx +3 -1
  308. package/src/ui/screens/FeedbackScreen.tsx +6 -10
  309. package/src/ui/screens/HelpSupportScreen.tsx +1 -1
  310. package/src/ui/screens/HistoryViewScreen.tsx +3 -1
  311. package/src/ui/screens/LanguageSelectorScreen.tsx +1 -1
  312. package/src/ui/screens/LegalDocumentsScreen.tsx +2 -1
  313. package/src/ui/screens/ManageAccountScreen.tsx +1102 -0
  314. package/src/ui/screens/NotificationsScreen.tsx +189 -0
  315. package/src/ui/screens/PaymentGatewayScreen.tsx +10 -12
  316. package/src/ui/screens/PreferencesScreen.tsx +263 -0
  317. package/src/ui/screens/PrivacySettingsScreen.tsx +4 -1
  318. package/src/ui/screens/ProfileScreen.tsx +2 -2
  319. package/src/ui/screens/SavesCollectionsScreen.tsx +3 -1
  320. package/src/ui/screens/SearchSettingsScreen.tsx +2 -1
  321. package/src/ui/screens/UserLinksScreen.tsx +1 -1
  322. package/src/ui/screens/UserListScreen.tsx +1 -1
  323. package/src/ui/screens/karma/KarmaAboutScreen.tsx +1 -1
  324. package/src/ui/screens/karma/KarmaFAQScreen.tsx +1 -1
  325. package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +1 -1
  326. package/src/ui/screens/karma/KarmaRewardsScreen.tsx +1 -1
  327. package/src/ui/screens/karma/KarmaRulesScreen.tsx +1 -1
  328. package/src/ui/utils/activeAuthuser.ts +78 -0
  329. package/lib/commonjs/ui/components/feedback/index.js +0 -54
  330. package/lib/commonjs/ui/components/feedback/index.js.map +0 -1
  331. package/lib/commonjs/ui/components/icon/index.js +0 -21
  332. package/lib/commonjs/ui/components/icon/index.js.map +0 -1
  333. package/lib/commonjs/ui/components/index.js +0 -104
  334. package/lib/commonjs/ui/components/index.js.map +0 -1
  335. package/lib/commonjs/ui/components/modals/index.js +0 -14
  336. package/lib/commonjs/ui/components/modals/index.js.map +0 -1
  337. package/lib/commonjs/ui/components/payment/index.js +0 -80
  338. package/lib/commonjs/ui/components/payment/index.js.map +0 -1
  339. package/lib/commonjs/ui/hooks/index.js +0 -92
  340. package/lib/commonjs/ui/hooks/index.js.map +0 -1
  341. package/lib/commonjs/ui/hooks/mutations/index.js +0 -68
  342. package/lib/commonjs/ui/hooks/mutations/index.js.map +0 -1
  343. package/lib/commonjs/ui/hooks/queries/index.js +0 -155
  344. package/lib/commonjs/ui/hooks/queries/index.js.map +0 -1
  345. package/lib/commonjs/ui/screens/AccountCenterScreen.js +0 -344
  346. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +0 -1
  347. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +0 -724
  348. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +0 -1
  349. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +0 -643
  350. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +0 -1
  351. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +0 -1029
  352. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +0 -1
  353. package/lib/commonjs/ui/screens/SessionManagementScreen.js +0 -512
  354. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +0 -1
  355. package/lib/commonjs/ui/styles/index.js +0 -39
  356. package/lib/commonjs/ui/styles/index.js.map +0 -1
  357. package/lib/module/ui/components/feedback/index.js +0 -8
  358. package/lib/module/ui/components/feedback/index.js.map +0 -1
  359. package/lib/module/ui/components/icon/index.js +0 -5
  360. package/lib/module/ui/components/icon/index.js.map +0 -1
  361. package/lib/module/ui/components/index.js +0 -18
  362. package/lib/module/ui/components/index.js.map +0 -1
  363. package/lib/module/ui/components/modals/index.js +0 -4
  364. package/lib/module/ui/components/modals/index.js.map +0 -1
  365. package/lib/module/ui/components/payment/index.js +0 -10
  366. package/lib/module/ui/components/payment/index.js.map +0 -1
  367. package/lib/module/ui/hooks/index.js +0 -11
  368. package/lib/module/ui/hooks/index.js.map +0 -1
  369. package/lib/module/ui/hooks/mutations/index.js +0 -15
  370. package/lib/module/ui/hooks/mutations/index.js.map +0 -1
  371. package/lib/module/ui/hooks/queries/index.js +0 -26
  372. package/lib/module/ui/hooks/queries/index.js.map +0 -1
  373. package/lib/module/ui/screens/AccountCenterScreen.js +0 -339
  374. package/lib/module/ui/screens/AccountCenterScreen.js.map +0 -1
  375. package/lib/module/ui/screens/AccountOverviewScreen.js +0 -719
  376. package/lib/module/ui/screens/AccountOverviewScreen.js.map +0 -1
  377. package/lib/module/ui/screens/AccountSettingsScreen.js +0 -638
  378. package/lib/module/ui/screens/AccountSettingsScreen.js.map +0 -1
  379. package/lib/module/ui/screens/AccountSwitcherScreen.js +0 -1024
  380. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +0 -1
  381. package/lib/module/ui/screens/SessionManagementScreen.js +0 -508
  382. package/lib/module/ui/screens/SessionManagementScreen.js.map +0 -1
  383. package/lib/module/ui/styles/index.js +0 -6
  384. package/lib/module/ui/styles/index.js.map +0 -1
  385. package/lib/typescript/commonjs/ui/components/feedback/index.d.ts +0 -7
  386. package/lib/typescript/commonjs/ui/components/feedback/index.d.ts.map +0 -1
  387. package/lib/typescript/commonjs/ui/components/icon/index.d.ts +0 -4
  388. package/lib/typescript/commonjs/ui/components/icon/index.d.ts.map +0 -1
  389. package/lib/typescript/commonjs/ui/components/index.d.ts +0 -13
  390. package/lib/typescript/commonjs/ui/components/index.d.ts.map +0 -1
  391. package/lib/typescript/commonjs/ui/components/modals/index.d.ts +0 -2
  392. package/lib/typescript/commonjs/ui/components/modals/index.d.ts.map +0 -1
  393. package/lib/typescript/commonjs/ui/components/payment/index.d.ts +0 -9
  394. package/lib/typescript/commonjs/ui/components/payment/index.d.ts.map +0 -1
  395. package/lib/typescript/commonjs/ui/hooks/index.d.ts +0 -9
  396. package/lib/typescript/commonjs/ui/hooks/index.d.ts.map +0 -1
  397. package/lib/typescript/commonjs/ui/hooks/mutations/index.d.ts +0 -9
  398. package/lib/typescript/commonjs/ui/hooks/mutations/index.d.ts.map +0 -1
  399. package/lib/typescript/commonjs/ui/hooks/queries/index.d.ts +0 -13
  400. package/lib/typescript/commonjs/ui/hooks/queries/index.d.ts.map +0 -1
  401. package/lib/typescript/commonjs/ui/screens/AccountCenterScreen.d.ts +0 -5
  402. package/lib/typescript/commonjs/ui/screens/AccountCenterScreen.d.ts.map +0 -1
  403. package/lib/typescript/commonjs/ui/screens/AccountOverviewScreen.d.ts.map +0 -1
  404. package/lib/typescript/commonjs/ui/screens/AccountSettingsScreen.d.ts.map +0 -1
  405. package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts +0 -5
  406. package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts.map +0 -1
  407. package/lib/typescript/commonjs/ui/screens/SessionManagementScreen.d.ts +0 -5
  408. package/lib/typescript/commonjs/ui/screens/SessionManagementScreen.d.ts.map +0 -1
  409. package/lib/typescript/commonjs/ui/styles/index.d.ts +0 -4
  410. package/lib/typescript/commonjs/ui/styles/index.d.ts.map +0 -1
  411. package/lib/typescript/module/ui/components/feedback/index.d.ts +0 -7
  412. package/lib/typescript/module/ui/components/feedback/index.d.ts.map +0 -1
  413. package/lib/typescript/module/ui/components/icon/index.d.ts +0 -4
  414. package/lib/typescript/module/ui/components/icon/index.d.ts.map +0 -1
  415. package/lib/typescript/module/ui/components/index.d.ts +0 -13
  416. package/lib/typescript/module/ui/components/index.d.ts.map +0 -1
  417. package/lib/typescript/module/ui/components/modals/index.d.ts +0 -2
  418. package/lib/typescript/module/ui/components/modals/index.d.ts.map +0 -1
  419. package/lib/typescript/module/ui/components/payment/index.d.ts +0 -9
  420. package/lib/typescript/module/ui/components/payment/index.d.ts.map +0 -1
  421. package/lib/typescript/module/ui/hooks/index.d.ts +0 -9
  422. package/lib/typescript/module/ui/hooks/index.d.ts.map +0 -1
  423. package/lib/typescript/module/ui/hooks/mutations/index.d.ts +0 -9
  424. package/lib/typescript/module/ui/hooks/mutations/index.d.ts.map +0 -1
  425. package/lib/typescript/module/ui/hooks/queries/index.d.ts +0 -13
  426. package/lib/typescript/module/ui/hooks/queries/index.d.ts.map +0 -1
  427. package/lib/typescript/module/ui/screens/AccountCenterScreen.d.ts +0 -5
  428. package/lib/typescript/module/ui/screens/AccountCenterScreen.d.ts.map +0 -1
  429. package/lib/typescript/module/ui/screens/AccountOverviewScreen.d.ts.map +0 -1
  430. package/lib/typescript/module/ui/screens/AccountSettingsScreen.d.ts.map +0 -1
  431. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts +0 -5
  432. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +0 -1
  433. package/lib/typescript/module/ui/screens/SessionManagementScreen.d.ts +0 -5
  434. package/lib/typescript/module/ui/screens/SessionManagementScreen.d.ts.map +0 -1
  435. package/lib/typescript/module/ui/styles/index.d.ts +0 -4
  436. package/lib/typescript/module/ui/styles/index.d.ts.map +0 -1
  437. package/src/ui/components/feedback/index.ts +0 -6
  438. package/src/ui/components/icon/index.ts +0 -3
  439. package/src/ui/components/index.ts +0 -15
  440. package/src/ui/components/modals/index.ts +0 -1
  441. package/src/ui/components/payment/index.ts +0 -9
  442. package/src/ui/hooks/index.ts +0 -13
  443. package/src/ui/hooks/mutations/index.ts +0 -25
  444. package/src/ui/hooks/queries/index.ts +0 -61
  445. package/src/ui/screens/AccountCenterScreen.tsx +0 -182
  446. package/src/ui/screens/AccountOverviewScreen.tsx +0 -696
  447. package/src/ui/screens/AccountSettingsScreen.tsx +0 -620
  448. package/src/ui/screens/AccountSwitcherScreen.tsx +0 -1003
  449. package/src/ui/screens/SessionManagementScreen.tsx +0 -477
  450. 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 { FAIRWalletIcon } from '../icon';
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 { FAIRWalletIcon } from '../icon';
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';
@@ -1,5 +1,5 @@
1
1
  import { useTheme } from '@oxyhq/bloom/theme';
2
- import { getTheme } from '../styles';
2
+ import { getTheme } from '../styles/theme';
3
3
  import type { InternalTheme } from './types';
4
4
 
5
5
  /**
@@ -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
- * Minimal, decode-only shape of the session access-token JWT claims the
102
- * `POST /auth/refresh` endpoint returns. We only read `sessionId` (and `userId`
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 cookie (web only).
456
+ // Cold-boot session restore via the secure refresh cookies (web only).
523
457
  //
524
- // On a hard reload the in-app, bearer-protected token fetch
525
- // (`getTokenBySession` `/session/token/:id`) 401s because there is no token
526
- // in memory yet, which previously cleared the session and bounced the user to
527
- // sign-in. Instead we call `POST {apiBaseUrl}/auth/refresh` with
528
- // `credentials: 'include'` and NO Authorization header: the browser
529
- // automatically attaches the first-party httpOnly `oxy_rt` cookie (set at
530
- // login/signup/fedcm-exchange), the server validates + rotates it and returns
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
- // Returns `true` when the session was restored (caller short-circuits the
535
- // bearer path); `false` on 401 / no durable cookie / any failure (caller
536
- // proceeds unauthenticated through the existing flow nothing is cleared).
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
- const apiBaseUrl = oxyServices.getBaseURL();
543
- if (!apiBaseUrl) {
544
- return false;
545
- }
546
-
547
- let response: Response;
479
+ let snapshot;
548
480
  try {
549
- // Direct credentialed, no-auth POST. We deliberately bypass the SDK's
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
- // 401 (no/expired/reused cookie) and any non-2xx → no durable session.
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
- // Plant the fresh access token. The refresh token stays in the httpOnly
594
- // cookie and is never touched by JS.
595
- oxyServices.httpService.setTokens(accessToken);
596
-
597
- // Fetch the full user with the freshly planted token.
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 not
603
- // claim a restored session; fall through so the stored-session flow can
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
- const userId = fullUser.id?.toString() ?? claims?.userId ?? '';
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 clientSession: ClientSession = {
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: true,
620
- };
621
-
622
- // Restore the active session into the multi-session store (merge: keep any
623
- // other sessions intact) and durably persist BEFORE notifying listeners.
624
- updateSessionsRef.current([clientSession], { merge: true });
625
- setActiveSessionIdRef.current(sessionId);
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
- await oxyServices.logoutSession(activeSessionId, sessionToLogout);
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
- await oxyServices.logoutAllSessions(activeSessionId);
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 { AssetUploadInput, PrivacySettings, User } from '@oxyhq/core';
4
- import { queryKeys, invalidateAccountQueries, invalidateUserQueries, invalidateSessionQueries } from '../queries/queryKeys';
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
  */