@oxyhq/services 28.0.0 → 29.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 (324) hide show
  1. package/NOTICE +10 -9
  2. package/README.md +65 -2
  3. package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionModule.kt +178 -0
  4. package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionProvider.kt +99 -0
  5. package/android/src/main/java/so/oxy/devicesession/OxyDeviceSessionStore.kt +115 -0
  6. package/expo-module.config.json +1 -0
  7. package/lib/commonjs/index.js +60 -16
  8. package/lib/commonjs/index.js.map +1 -1
  9. package/lib/commonjs/ui/boot/runProviderColdBoot.js +7 -0
  10. package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
  11. package/lib/commonjs/ui/client.js +12 -7
  12. package/lib/commonjs/ui/client.js.map +1 -1
  13. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +10 -27
  14. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
  15. package/lib/commonjs/ui/components/OxyAuthChooser.js +132 -44
  16. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  17. package/lib/commonjs/ui/components/OxyProvider.js +4 -2
  18. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  19. package/lib/commonjs/ui/components/SurfaceScreen.js +31 -3
  20. package/lib/commonjs/ui/components/SurfaceScreen.js.map +1 -1
  21. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +209 -84
  22. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  23. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +25 -7
  24. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +1 -1
  25. package/lib/commonjs/ui/components/authChooser/primitives.js +35 -22
  26. package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
  27. package/lib/commonjs/ui/components/authChooser/types.js +11 -0
  28. package/lib/commonjs/ui/components/authChooser/types.js.map +1 -1
  29. package/lib/commonjs/ui/context/OxyContext.js +257 -306
  30. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  31. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +27 -37
  32. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  33. package/lib/commonjs/ui/context/oxyContextHelpers.js +0 -29
  34. package/lib/commonjs/ui/context/oxyContextHelpers.js.map +1 -1
  35. package/lib/commonjs/ui/context/useOxyAccountGraph.js +6 -17
  36. package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
  37. package/lib/commonjs/ui/hooks/accountDialogSnapshot.js +42 -0
  38. package/lib/commonjs/ui/hooks/accountDialogSnapshot.js.map +1 -0
  39. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +0 -19
  40. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  41. package/lib/commonjs/ui/hooks/useDeviceSwitcher.js +57 -0
  42. package/lib/commonjs/ui/hooks/useDeviceSwitcher.js.map +1 -0
  43. package/lib/commonjs/ui/hooks/useI18n.js +22 -3
  44. package/lib/commonjs/ui/hooks/useI18n.js.map +1 -1
  45. package/lib/commonjs/ui/hooks/useSessionManagement.js +46 -153
  46. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  47. package/lib/commonjs/ui/index.js +12 -7
  48. package/lib/commonjs/ui/index.js.map +1 -1
  49. package/lib/commonjs/ui/navigation/routes.js +85 -73
  50. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  51. package/lib/commonjs/ui/navigation/surfaces.js +8 -7
  52. package/lib/commonjs/ui/navigation/surfaces.js.map +1 -1
  53. package/lib/commonjs/ui/runtime/createOxyRuntime.js +433 -0
  54. package/lib/commonjs/ui/runtime/createOxyRuntime.js.map +1 -0
  55. package/lib/commonjs/ui/runtime/index.js +63 -0
  56. package/lib/commonjs/ui/runtime/index.js.map +1 -0
  57. package/lib/commonjs/ui/runtime/runtimeContext.js +83 -0
  58. package/lib/commonjs/ui/runtime/runtimeContext.js.map +1 -0
  59. package/lib/commonjs/ui/runtime/types.js +6 -0
  60. package/lib/commonjs/ui/runtime/types.js.map +1 -0
  61. package/lib/commonjs/ui/runtime/useRuntimeSnapshot.js +57 -0
  62. package/lib/commonjs/ui/runtime/useRuntimeSnapshot.js.map +1 -0
  63. package/lib/commonjs/ui/server.js +1 -2
  64. package/lib/commonjs/ui/server.js.map +1 -1
  65. package/lib/commonjs/ui/session/authStore.js +45 -9
  66. package/lib/commonjs/ui/session/authStore.js.map +1 -1
  67. package/lib/commonjs/ui/session/sharedDeviceCredentialStore.js +306 -0
  68. package/lib/commonjs/ui/session/sharedDeviceCredentialStore.js.map +1 -0
  69. package/lib/commonjs/ui/stores/authStore.js +154 -55
  70. package/lib/commonjs/ui/stores/authStore.js.map +1 -1
  71. package/lib/commonjs/ui/utils/avatarUtils.js +2 -36
  72. package/lib/commonjs/ui/utils/avatarUtils.js.map +1 -1
  73. package/lib/module/index.js +16 -8
  74. package/lib/module/index.js.map +1 -1
  75. package/lib/module/ui/boot/runProviderColdBoot.js +7 -0
  76. package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
  77. package/lib/module/ui/client.js +1 -2
  78. package/lib/module/ui/client.js.map +1 -1
  79. package/lib/module/ui/components/OxyAccountDialogScreen.js +10 -27
  80. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
  81. package/lib/module/ui/components/OxyAuthChooser.js +134 -44
  82. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  83. package/lib/module/ui/components/OxyProvider.js +5 -3
  84. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  85. package/lib/module/ui/components/SurfaceScreen.js +33 -5
  86. package/lib/module/ui/components/SurfaceScreen.js.map +1 -1
  87. package/lib/module/ui/components/authChooser/AccountsMenuView.js +210 -85
  88. package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  89. package/lib/module/ui/components/authChooser/SignInEntryView.js +25 -7
  90. package/lib/module/ui/components/authChooser/SignInEntryView.js.map +1 -1
  91. package/lib/module/ui/components/authChooser/primitives.js +35 -22
  92. package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
  93. package/lib/module/ui/components/authChooser/types.js +11 -0
  94. package/lib/module/ui/components/authChooser/types.js.map +1 -1
  95. package/lib/module/ui/context/OxyContext.js +251 -303
  96. package/lib/module/ui/context/OxyContext.js.map +1 -1
  97. package/lib/module/ui/context/hooks/useAuthOperations.js +27 -37
  98. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  99. package/lib/module/ui/context/oxyContextHelpers.js +0 -28
  100. package/lib/module/ui/context/oxyContextHelpers.js.map +1 -1
  101. package/lib/module/ui/context/useOxyAccountGraph.js +6 -17
  102. package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
  103. package/lib/module/ui/hooks/accountDialogSnapshot.js +38 -0
  104. package/lib/module/ui/hooks/accountDialogSnapshot.js.map +1 -0
  105. package/lib/module/ui/hooks/mutations/useAccountMutations.js +0 -19
  106. package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  107. package/lib/module/ui/hooks/useDeviceSwitcher.js +53 -0
  108. package/lib/module/ui/hooks/useDeviceSwitcher.js.map +1 -0
  109. package/lib/module/ui/hooks/useI18n.js +24 -4
  110. package/lib/module/ui/hooks/useI18n.js.map +1 -1
  111. package/lib/module/ui/hooks/useSessionManagement.js +47 -155
  112. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  113. package/lib/module/ui/index.js +1 -2
  114. package/lib/module/ui/index.js.map +1 -1
  115. package/lib/module/ui/navigation/routes.js +84 -72
  116. package/lib/module/ui/navigation/routes.js.map +1 -1
  117. package/lib/module/ui/navigation/surfaces.js +6 -6
  118. package/lib/module/ui/navigation/surfaces.js.map +1 -1
  119. package/lib/module/ui/runtime/createOxyRuntime.js +430 -0
  120. package/lib/module/ui/runtime/createOxyRuntime.js.map +1 -0
  121. package/lib/module/ui/runtime/index.js +15 -0
  122. package/lib/module/ui/runtime/index.js.map +1 -0
  123. package/lib/module/ui/runtime/runtimeContext.js +75 -0
  124. package/lib/module/ui/runtime/runtimeContext.js.map +1 -0
  125. package/lib/module/ui/runtime/types.js +4 -0
  126. package/lib/module/ui/runtime/types.js.map +1 -0
  127. package/lib/module/ui/runtime/useRuntimeSnapshot.js +52 -0
  128. package/lib/module/ui/runtime/useRuntimeSnapshot.js.map +1 -0
  129. package/lib/module/ui/server.js +0 -1
  130. package/lib/module/ui/server.js.map +1 -1
  131. package/lib/module/ui/session/authStore.js +46 -11
  132. package/lib/module/ui/session/authStore.js.map +1 -1
  133. package/lib/module/ui/session/sharedDeviceCredentialStore.js +302 -0
  134. package/lib/module/ui/session/sharedDeviceCredentialStore.js.map +1 -0
  135. package/lib/module/ui/stores/authStore.js +154 -55
  136. package/lib/module/ui/stores/authStore.js.map +1 -1
  137. package/lib/module/ui/utils/avatarUtils.js +2 -35
  138. package/lib/module/ui/utils/avatarUtils.js.map +1 -1
  139. package/lib/typescript/commonjs/index.d.ts +5 -3
  140. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  141. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  142. package/lib/typescript/commonjs/ui/client.d.ts +1 -2
  143. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  144. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  145. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  146. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  147. package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts.map +1 -1
  148. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts +11 -4
  149. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  150. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +3 -1
  151. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
  152. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +18 -6
  153. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
  154. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +33 -1
  155. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -1
  156. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +35 -4
  157. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  158. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +8 -12
  159. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  160. package/lib/typescript/commonjs/ui/context/oxyContextHelpers.d.ts +0 -2
  161. package/lib/typescript/commonjs/ui/context/oxyContextHelpers.d.ts.map +1 -1
  162. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +9 -1
  163. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  164. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +1 -3
  165. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  166. package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts +15 -0
  167. package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts.map +1 -0
  168. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts +49 -0
  170. package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts.map +1 -0
  171. package/lib/typescript/commonjs/ui/hooks/useI18n.d.ts +13 -0
  172. package/lib/typescript/commonjs/ui/hooks/useI18n.d.ts.map +1 -1
  173. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts +23 -18
  174. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
  175. package/lib/typescript/commonjs/ui/index.d.ts +1 -2
  176. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  177. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +15 -1
  178. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  179. package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts.map +1 -1
  180. package/lib/typescript/commonjs/ui/runtime/createOxyRuntime.d.ts +144 -0
  181. package/lib/typescript/commonjs/ui/runtime/createOxyRuntime.d.ts.map +1 -0
  182. package/lib/typescript/commonjs/ui/runtime/index.d.ts +16 -0
  183. package/lib/typescript/commonjs/ui/runtime/index.d.ts.map +1 -0
  184. package/lib/typescript/commonjs/ui/runtime/runtimeContext.d.ts +43 -0
  185. package/lib/typescript/commonjs/ui/runtime/runtimeContext.d.ts.map +1 -0
  186. package/lib/typescript/commonjs/ui/runtime/types.d.ts +89 -0
  187. package/lib/typescript/commonjs/ui/runtime/types.d.ts.map +1 -0
  188. package/lib/typescript/commonjs/ui/runtime/useRuntimeSnapshot.d.ts +23 -0
  189. package/lib/typescript/commonjs/ui/runtime/useRuntimeSnapshot.d.ts.map +1 -0
  190. package/lib/typescript/commonjs/ui/server.d.ts +0 -1
  191. package/lib/typescript/commonjs/ui/server.d.ts.map +1 -1
  192. package/lib/typescript/commonjs/ui/session/authStore.d.ts +60 -9
  193. package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
  194. package/lib/typescript/commonjs/ui/session/sharedDeviceCredentialStore.d.ts +32 -0
  195. package/lib/typescript/commonjs/ui/session/sharedDeviceCredentialStore.d.ts.map +1 -0
  196. package/lib/typescript/commonjs/ui/stores/authStore.d.ts +49 -5
  197. package/lib/typescript/commonjs/ui/stores/authStore.d.ts.map +1 -1
  198. package/lib/typescript/commonjs/ui/types/navigation.d.ts +26 -0
  199. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  200. package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts +2 -10
  201. package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts.map +1 -1
  202. package/lib/typescript/module/index.d.ts +5 -3
  203. package/lib/typescript/module/index.d.ts.map +1 -1
  204. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  205. package/lib/typescript/module/ui/client.d.ts +1 -2
  206. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  207. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  208. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  209. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  210. package/lib/typescript/module/ui/components/SurfaceScreen.d.ts.map +1 -1
  211. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts +11 -4
  212. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  213. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +3 -1
  214. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
  215. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +18 -6
  216. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
  217. package/lib/typescript/module/ui/components/authChooser/types.d.ts +33 -1
  218. package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -1
  219. package/lib/typescript/module/ui/context/OxyContext.d.ts +35 -4
  220. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  221. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +8 -12
  222. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  223. package/lib/typescript/module/ui/context/oxyContextHelpers.d.ts +0 -2
  224. package/lib/typescript/module/ui/context/oxyContextHelpers.d.ts.map +1 -1
  225. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +9 -1
  226. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  227. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +1 -3
  228. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  229. package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts +15 -0
  230. package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts.map +1 -0
  231. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  232. package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts +49 -0
  233. package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts.map +1 -0
  234. package/lib/typescript/module/ui/hooks/useI18n.d.ts +13 -0
  235. package/lib/typescript/module/ui/hooks/useI18n.d.ts.map +1 -1
  236. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts +23 -18
  237. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
  238. package/lib/typescript/module/ui/index.d.ts +1 -2
  239. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  240. package/lib/typescript/module/ui/navigation/routes.d.ts +15 -1
  241. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  242. package/lib/typescript/module/ui/navigation/surfaces.d.ts.map +1 -1
  243. package/lib/typescript/module/ui/runtime/createOxyRuntime.d.ts +144 -0
  244. package/lib/typescript/module/ui/runtime/createOxyRuntime.d.ts.map +1 -0
  245. package/lib/typescript/module/ui/runtime/index.d.ts +16 -0
  246. package/lib/typescript/module/ui/runtime/index.d.ts.map +1 -0
  247. package/lib/typescript/module/ui/runtime/runtimeContext.d.ts +43 -0
  248. package/lib/typescript/module/ui/runtime/runtimeContext.d.ts.map +1 -0
  249. package/lib/typescript/module/ui/runtime/types.d.ts +89 -0
  250. package/lib/typescript/module/ui/runtime/types.d.ts.map +1 -0
  251. package/lib/typescript/module/ui/runtime/useRuntimeSnapshot.d.ts +23 -0
  252. package/lib/typescript/module/ui/runtime/useRuntimeSnapshot.d.ts.map +1 -0
  253. package/lib/typescript/module/ui/server.d.ts +0 -1
  254. package/lib/typescript/module/ui/server.d.ts.map +1 -1
  255. package/lib/typescript/module/ui/session/authStore.d.ts +60 -9
  256. package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
  257. package/lib/typescript/module/ui/session/sharedDeviceCredentialStore.d.ts +32 -0
  258. package/lib/typescript/module/ui/session/sharedDeviceCredentialStore.d.ts.map +1 -0
  259. package/lib/typescript/module/ui/stores/authStore.d.ts +49 -5
  260. package/lib/typescript/module/ui/stores/authStore.d.ts.map +1 -1
  261. package/lib/typescript/module/ui/types/navigation.d.ts +26 -0
  262. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  263. package/lib/typescript/module/ui/utils/avatarUtils.d.ts +2 -10
  264. package/lib/typescript/module/ui/utils/avatarUtils.d.ts.map +1 -1
  265. package/package.json +6 -7
  266. package/plugins/withSharedDeviceSessionProvider.js +102 -0
  267. package/plugins/withSharedDeviceSessionReader.js +57 -0
  268. package/src/__tests__/esmSourcePurity.test.ts +61 -0
  269. package/src/index.ts +31 -9
  270. package/src/ui/boot/runProviderColdBoot.ts +7 -0
  271. package/src/ui/client.ts +1 -2
  272. package/src/ui/components/OxyAccountDialogScreen.tsx +10 -29
  273. package/src/ui/components/OxyAuthChooser.tsx +149 -50
  274. package/src/ui/components/OxyProvider.tsx +7 -5
  275. package/src/ui/components/SurfaceScreen.tsx +28 -4
  276. package/src/ui/components/authChooser/AccountsMenuView.tsx +246 -96
  277. package/src/ui/components/authChooser/SignInEntryView.tsx +31 -8
  278. package/src/ui/components/authChooser/primitives.tsx +37 -23
  279. package/src/ui/components/authChooser/types.ts +34 -1
  280. package/src/ui/context/OxyContext.tsx +269 -324
  281. package/src/ui/context/hooks/useAuthOperations.ts +32 -35
  282. package/src/ui/context/oxyContextHelpers.ts +0 -30
  283. package/src/ui/context/oxyContextTypes.ts +9 -1
  284. package/src/ui/context/useOxyAccountGraph.ts +5 -19
  285. package/src/ui/hooks/accountDialogSnapshot.ts +37 -0
  286. package/src/ui/hooks/mutations/useAccountMutations.ts +0 -19
  287. package/src/ui/hooks/queries/__tests__/userCache.test.ts +12 -1
  288. package/src/ui/hooks/useDeviceSwitcher.ts +110 -0
  289. package/src/ui/hooks/useI18n.ts +23 -3
  290. package/src/ui/hooks/useSessionManagement.ts +62 -211
  291. package/src/ui/index.ts +1 -2
  292. package/src/ui/navigation/routes.ts +85 -75
  293. package/src/ui/navigation/surfaces.ts +6 -9
  294. package/src/ui/runtime/createOxyRuntime.ts +623 -0
  295. package/src/ui/runtime/index.ts +34 -0
  296. package/src/ui/runtime/runtimeContext.tsx +111 -0
  297. package/src/ui/runtime/types.ts +110 -0
  298. package/src/ui/runtime/useRuntimeSnapshot.ts +52 -0
  299. package/src/ui/server.ts +0 -1
  300. package/src/ui/session/__tests__/authStore.test.ts +90 -0
  301. package/src/ui/session/__tests__/sharedDeviceCredentialStore.test.ts +289 -0
  302. package/src/ui/session/authStore.ts +78 -9
  303. package/src/ui/session/sharedDeviceCredentialStore.ts +318 -0
  304. package/src/ui/stores/authStore.ts +171 -43
  305. package/src/ui/types/navigation.ts +26 -0
  306. package/src/ui/utils/avatarUtils.ts +2 -37
  307. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +0 -64
  308. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +0 -1
  309. package/lib/commonjs/ui/stores/accountStore.js +0 -221
  310. package/lib/commonjs/ui/stores/accountStore.js.map +0 -1
  311. package/lib/module/ui/hooks/useSwitchableAccounts.js +0 -60
  312. package/lib/module/ui/hooks/useSwitchableAccounts.js.map +0 -1
  313. package/lib/module/ui/stores/accountStore.js +0 -213
  314. package/lib/module/ui/stores/accountStore.js.map +0 -1
  315. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts +0 -23
  316. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +0 -1
  317. package/lib/typescript/commonjs/ui/stores/accountStore.d.ts +0 -27
  318. package/lib/typescript/commonjs/ui/stores/accountStore.d.ts.map +0 -1
  319. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts +0 -23
  320. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +0 -1
  321. package/lib/typescript/module/ui/stores/accountStore.d.ts +0 -27
  322. package/lib/typescript/module/ui/stores/accountStore.d.ts.map +0 -1
  323. package/src/ui/hooks/useSwitchableAccounts.ts +0 -75
  324. package/src/ui/stores/accountStore.ts +0 -264
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","useRuntimeSnapshot","runtime","useSyncExternalStore","subscribe","getSnapshot","useRuntimeSelector","selector","isEqual","cache","useRef","getSelection","useCallback","snapshot","cached","current","value"],"sourceRoot":"../../../../src","sources":["ui/runtime/useRuntimeSnapshot.ts"],"mappings":";;;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,kBAAkBA,CAACC,OAAmB,EAAsB;EAC1E,OAAO,IAAAC,2BAAoB,EAACD,OAAO,CAACE,SAAS,EAAEF,OAAO,CAACG,WAAW,EAAEH,OAAO,CAACG,WAAW,CAAC;AAC1F;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,kBAAkBA,CAChCJ,OAAmB,EACnBK,QAA6C,EAC7CC,OAAiC,EAC9B;EACH,MAAMC,KAAK,GAAG,IAAAC,aAAM,EAAoD,IAAI,CAAC;EAE7E,MAAMC,YAAY,GAAG,IAAAC,kBAAW,EAAC,MAAS;IACxC,MAAMC,QAAQ,GAAGX,OAAO,CAACG,WAAW,CAAC,CAAC;IACtC,MAAMS,MAAM,GAAGL,KAAK,CAACM,OAAO;IAC5B,IAAID,MAAM,KAAK,IAAI,IAAIA,MAAM,CAACD,QAAQ,KAAKA,QAAQ,EAAE;MACnD,OAAOC,MAAM,CAACE,KAAK;IACrB;IACA,MAAMA,KAAK,GAAGT,QAAQ,CAACM,QAAQ,CAAC;IAChC,IAAIC,MAAM,KAAK,IAAI,IAAIN,OAAO,GAAGM,MAAM,CAACE,KAAK,EAAEA,KAAK,CAAC,KAAK,IAAI,EAAE;MAC9D;MACA;MACAP,KAAK,CAACM,OAAO,GAAG;QAAEF,QAAQ;QAAEG,KAAK,EAAEF,MAAM,CAACE;MAAM,CAAC;MACjD,OAAOF,MAAM,CAACE,KAAK;IACrB;IACAP,KAAK,CAACM,OAAO,GAAG;MAAEF,QAAQ;MAAEG;IAAM,CAAC;IACnC,OAAOA,KAAK;EACd,CAAC,EAAE,CAACd,OAAO,EAAEK,QAAQ,EAAEC,OAAO,CAAC,CAAC;EAEhC,OAAO,IAAAL,2BAAoB,EAACD,OAAO,CAACE,SAAS,EAAEO,YAAY,EAAEA,YAAY,CAAC;AAC5E","ignoreList":[]}
@@ -28,7 +28,7 @@ Object.defineProperty(exports, "isTimeoutOrNetworkError", {
28
28
  return _errorHandlers.isTimeoutOrNetworkError;
29
29
  }
30
30
  });
31
- exports.useStorage = exports.useOxy = exports.useFollow = exports.useAuthStore = exports.useAuth = exports.useAccountStore = exports.toast = void 0;
31
+ exports.useStorage = exports.useOxy = exports.useFollow = exports.useAuthStore = exports.useAuth = exports.toast = void 0;
32
32
  var _errorHandlers = require("./utils/errorHandlers.js");
33
33
  /**
34
34
  * Server-safe UI exports (noops)
@@ -70,7 +70,6 @@ const ProfileScreen = exports.ProfileScreen = noopComponent;
70
70
 
71
71
  // Stores (return empty objects)
72
72
  const useAuthStore = exports.useAuthStore = noopHook;
73
- const useAccountStore = exports.useAccountStore = noopHook;
74
73
 
75
74
  // Toast (noop)
76
75
  const toast = exports.toast = Object.assign(() => {}, {
@@ -1 +1 @@
1
- {"version":3,"names":["_errorHandlers","require","noopComponent","noopHook","noopStorageResult","storage","isReady","OxyProvider","exports","OxySignInButton","LogoIcon","LogoText","FollowButton","OxyPayButton","useOxy","useAuth","useFollow","useStorage","ProfileScreen","useAuthStore","useAccountStore","toast","Object","assign","success","error","info","warning","loading","dismiss"],"sourceRoot":"../../../src","sources":["ui/server.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoDA,IAAAA,cAAA,GAAAC,OAAA;AApDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAMC,aAAa,GAAGA,CAAA,KAAM,IAAI;AAChC,MAAMC,QAAQ,GAAGA,CAAA,MAAO,CAAC,CAAC,CAAC;AAC3B,MAAMC,iBAAiB,GAAG;EAAEC,OAAO,EAAE,IAAI;EAAEC,OAAO,EAAE;AAAM,CAAC;;AAE3D;AACO,MAAMC,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAGL,aAAa;AACjC,MAAMO,eAAe,GAAAD,OAAA,CAAAC,eAAA,GAAGP,aAAa;AACrC,MAAMQ,QAAQ,GAAAF,OAAA,CAAAE,QAAA,GAAGR,aAAa;AAC9B,MAAMS,QAAQ,GAAAH,OAAA,CAAAG,QAAA,GAAGT,aAAa;AAC9B,MAAMU,YAAY,GAAAJ,OAAA,CAAAI,YAAA,GAAGV,aAAa;AAClC,MAAMW,YAAY,GAAAL,OAAA,CAAAK,YAAA,GAAGX,aAAa;;AAEzC;AACO,MAAMY,MAAM,GAAAN,OAAA,CAAAM,MAAA,GAAGX,QAAQ;;AAE9B;AACO,MAAMY,OAAO,GAAAP,OAAA,CAAAO,OAAA,GAAGZ,QAAQ;AACxB,MAAMa,SAAS,GAAAR,OAAA,CAAAQ,SAAA,GAAGb,QAAQ;AAC1B,MAAMc,UAAU,GAAGA,CAAA,KAAMb,iBAAiB;;AAEjD;AAAAI,OAAA,CAAAS,UAAA,GAAAA,UAAA;AACO,MAAMC,aAAa,GAAAV,OAAA,CAAAU,aAAA,GAAGhB,aAAa;;AAE1C;AACO,MAAMiB,YAAY,GAAAX,OAAA,CAAAW,YAAA,GAAGhB,QAAQ;AAC7B,MAAMiB,eAAe,GAAAZ,OAAA,CAAAY,eAAA,GAAGjB,QAAQ;;AAEvC;AACO,MAAMkB,KAAK,GAAAb,OAAA,CAAAa,KAAA,GAAGC,MAAM,CAACC,MAAM,CAC9B,MAAM,CAAC,CAAC,EACR;EACIC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,KAAK,EAAEA,CAAA,KAAM,CAAC,CAAC;EACfC,IAAI,EAAEA,CAAA,KAAM,CAAC,CAAC;EACdC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,OAAO,EAAEA,CAAA,KAAM,CAAC;AACpB,CACJ,CAAC;;AAED","ignoreList":[]}
1
+ {"version":3,"names":["_errorHandlers","require","noopComponent","noopHook","noopStorageResult","storage","isReady","OxyProvider","exports","OxySignInButton","LogoIcon","LogoText","FollowButton","OxyPayButton","useOxy","useAuth","useFollow","useStorage","ProfileScreen","useAuthStore","toast","Object","assign","success","error","info","warning","loading","dismiss"],"sourceRoot":"../../../src","sources":["ui/server.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmDA,IAAAA,cAAA,GAAAC,OAAA;AAnDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAMC,aAAa,GAAGA,CAAA,KAAM,IAAI;AAChC,MAAMC,QAAQ,GAAGA,CAAA,MAAO,CAAC,CAAC,CAAC;AAC3B,MAAMC,iBAAiB,GAAG;EAAEC,OAAO,EAAE,IAAI;EAAEC,OAAO,EAAE;AAAM,CAAC;;AAE3D;AACO,MAAMC,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAGL,aAAa;AACjC,MAAMO,eAAe,GAAAD,OAAA,CAAAC,eAAA,GAAGP,aAAa;AACrC,MAAMQ,QAAQ,GAAAF,OAAA,CAAAE,QAAA,GAAGR,aAAa;AAC9B,MAAMS,QAAQ,GAAAH,OAAA,CAAAG,QAAA,GAAGT,aAAa;AAC9B,MAAMU,YAAY,GAAAJ,OAAA,CAAAI,YAAA,GAAGV,aAAa;AAClC,MAAMW,YAAY,GAAAL,OAAA,CAAAK,YAAA,GAAGX,aAAa;;AAEzC;AACO,MAAMY,MAAM,GAAAN,OAAA,CAAAM,MAAA,GAAGX,QAAQ;;AAE9B;AACO,MAAMY,OAAO,GAAAP,OAAA,CAAAO,OAAA,GAAGZ,QAAQ;AACxB,MAAMa,SAAS,GAAAR,OAAA,CAAAQ,SAAA,GAAGb,QAAQ;AAC1B,MAAMc,UAAU,GAAGA,CAAA,KAAMb,iBAAiB;;AAEjD;AAAAI,OAAA,CAAAS,UAAA,GAAAA,UAAA;AACO,MAAMC,aAAa,GAAAV,OAAA,CAAAU,aAAA,GAAGhB,aAAa;;AAE1C;AACO,MAAMiB,YAAY,GAAAX,OAAA,CAAAW,YAAA,GAAGhB,QAAQ;;AAEpC;AACO,MAAMiB,KAAK,GAAAZ,OAAA,CAAAY,KAAA,GAAGC,MAAM,CAACC,MAAM,CAC9B,MAAM,CAAC,CAAC,EACR;EACIC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,KAAK,EAAEA,CAAA,KAAM,CAAC,CAAC;EACfC,IAAI,EAAEA,CAAA,KAAM,CAAC,CAAC;EACdC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,OAAO,EAAEA,CAAA,KAAM,CAAC,CAAC;EACjBC,OAAO,EAAEA,CAAA,KAAM,CAAC;AACpB,CACJ,CAAC;;AAED","ignoreList":[]}
@@ -7,20 +7,28 @@ exports.createPlatformAuthStateStore = createPlatformAuthStateStore;
7
7
  var _core = require("@oxyhq/core");
8
8
  var _storageHelpers = require("../utils/storageHelpers.js");
9
9
  var _nativeSecureStorage = require("./nativeSecureStorage.js");
10
+ var _sharedDeviceCredentialStore = require("./sharedDeviceCredentialStore.js");
10
11
  /**
11
12
  * Platform `AuthStateStore` for `@oxyhq/services`.
12
13
  *
13
- * The zero-cookie device model persists the durable device credential
14
- * (`deviceId` + `deviceSecret`) per origin (web) / per device (native), and the
15
- * SDK re-mints the access token from that credential on cold boot. `@oxyhq/core`
16
- * owns the store shape + logic (`createWebAuthStateStore` /
17
- * `createNativeAuthStateStore`); this module only selects the platform storage
18
- * seam:
14
+ * The device model persists the durable device credential (`deviceId` +
15
+ * `deviceSecret`) per origin (web) / per device (native), and the SDK re-mints
16
+ * the access token from that credential on cold boot. `@oxyhq/core` owns the
17
+ * store shape + logic (`createWebAuthStateStore` / `createNativeAuthStateStore` /
18
+ * `createMemoryAuthStateStore`); this module only selects the seam:
19
19
  *
20
+ * - `storage: 'ephemeral'` → `createMemoryAuthStateStore()`, on EVERY platform.
20
21
  * - web → `createWebAuthStateStore()` (localStorage, in-memory fallback).
21
22
  * - native → `createNativeAuthStateStore(secureKV)` for the SESSION blob over
22
23
  * the shared `createNativeSecureKeyValueStorage()` adapter
23
- * (`expo-secure-store`, AsyncStorage fallback).
24
+ * (`expo-secure-store`, AsyncStorage fallback), WRAPPED so every credential
25
+ * it persists is also mirrored into the device-wide shared slot.
26
+ *
27
+ * The native wrapper is how several official apps end up on ONE `DeviceSession`
28
+ * (and therefore one active context): whichever app proves a credential publishes
29
+ * it, and a later-installed sibling adopts it during cold boot instead of asking
30
+ * for the Commons identity key. The mirror is additive — it can neither change
31
+ * nor fail the app's own durable write.
24
32
  */
25
33
 
26
34
  /**
@@ -29,11 +37,39 @@ var _nativeSecureStorage = require("./nativeSecureStorage.js");
29
37
  * Native persists the SESSION blob (`deviceId` + `deviceSecret` + cached access
30
38
  * token) per-app in SecureStore; the SDK re-mints the access token from the
31
39
  * device credential on the next cold boot.
40
+ *
41
+ * ## The ephemeral check is FIRST, and the order is load-bearing
42
+ *
43
+ * It short-circuits above the `isReactNative()` branch so an ephemeral caller can
44
+ * never reach the native path — and therefore can never reach the shared-slot
45
+ * mirroring wrapper. Checked after that branch instead, an origin that has
46
+ * declined to persist a credential would publish one into the device-wide slot
47
+ * every sibling app adopts on cold boot: it would keep nothing itself while
48
+ * deciding which session five other apps boot into.
49
+ *
50
+ * That is unreachable today because the only ephemeral caller is a web origin, so
51
+ * `isReactNative()` is false there anyway. Unreachable today is exactly the kind
52
+ * of guarantee that stops holding when someone adds the second caller, so it is
53
+ * structural here rather than incidental, and
54
+ * `__tests__/session/authStoreEphemeral.test.ts` holds the ordering directly.
32
55
  */
33
- function createPlatformAuthStateStore() {
56
+ function createPlatformAuthStateStore(options = {}) {
57
+ // FIRST, above every platform branch — see the docblock for why the ordering
58
+ // is the guarantee and not a coincidence.
59
+ if (options.storage === 'ephemeral') {
60
+ return (0, _core.createMemoryAuthStateStore)();
61
+ }
34
62
  if (!(0, _storageHelpers.isReactNative)()) {
35
63
  return (0, _core.createWebAuthStateStore)();
36
64
  }
37
- return (0, _core.createNativeAuthStateStore)((0, _nativeSecureStorage.createNativeSecureKeyValueStorage)());
65
+ const local = (0, _core.createNativeAuthStateStore)((0, _nativeSecureStorage.createNativeSecureKeyValueStorage)());
66
+ if (options.sessionMode === 'identity') {
67
+ return local;
68
+ }
69
+ const shared = (0, _sharedDeviceCredentialStore.createPlatformSharedDeviceCredentialStore)();
70
+ return shared ? (0, _core.createSharedMirroringAuthStateStore)({
71
+ local,
72
+ shared
73
+ }) : local;
38
74
  }
39
75
  //# sourceMappingURL=authStore.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_core","require","_storageHelpers","_nativeSecureStorage","createPlatformAuthStateStore","isReactNative","createWebAuthStateStore","createNativeAuthStateStore","createNativeSecureKeyValueStorage"],"sourceRoot":"../../../../src","sources":["ui/session/authStore.ts"],"mappings":";;;;;;AAeA,IAAAA,KAAA,GAAAC,OAAA;AAKA,IAAAC,eAAA,GAAAD,OAAA;AACA,IAAAE,oBAAA,GAAAF,OAAA;AArBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,4BAA4BA,CAAA,EAAmB;EAC7D,IAAI,CAAC,IAAAC,6BAAa,EAAC,CAAC,EAAE;IACpB,OAAO,IAAAC,6BAAuB,EAAC,CAAC;EAClC;EAEA,OAAO,IAAAC,gCAA0B,EAAC,IAAAC,sDAAiC,EAAC,CAAC,CAAC;AACxE","ignoreList":[]}
1
+ {"version":3,"names":["_core","require","_storageHelpers","_nativeSecureStorage","_sharedDeviceCredentialStore","createPlatformAuthStateStore","options","storage","createMemoryAuthStateStore","isReactNative","createWebAuthStateStore","local","createNativeAuthStateStore","createNativeSecureKeyValueStorage","sessionMode","shared","createPlatformSharedDeviceCredentialStore","createSharedMirroringAuthStateStore"],"sourceRoot":"../../../../src","sources":["ui/session/authStore.ts"],"mappings":";;;;;;AAsBA,IAAAA,KAAA,GAAAC,OAAA;AAQA,IAAAC,eAAA,GAAAD,OAAA;AACA,IAAAE,oBAAA,GAAAF,OAAA;AACA,IAAAG,4BAAA,GAAAH,OAAA;AAhCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA2CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASI,4BAA4BA,CAC1CC,OAAsC,GAAG,CAAC,CAAC,EAC3B;EAChB;EACA;EACA,IAAIA,OAAO,CAACC,OAAO,KAAK,WAAW,EAAE;IACnC,OAAO,IAAAC,gCAA0B,EAAC,CAAC;EACrC;EAEA,IAAI,CAAC,IAAAC,6BAAa,EAAC,CAAC,EAAE;IACpB,OAAO,IAAAC,6BAAuB,EAAC,CAAC;EAClC;EAEA,MAAMC,KAAK,GAAG,IAAAC,gCAA0B,EAAC,IAAAC,sDAAiC,EAAC,CAAC,CAAC;EAC7E,IAAIP,OAAO,CAACQ,WAAW,KAAK,UAAU,EAAE;IACtC,OAAOH,KAAK;EACd;EACA,MAAMI,MAAM,GAAG,IAAAC,sEAAyC,EAAC,CAAC;EAC1D,OAAOD,MAAM,GAAG,IAAAE,yCAAmC,EAAC;IAAEN,KAAK;IAAEI;EAAO,CAAC,CAAC,GAAGJ,KAAK;AAChF","ignoreList":[]}
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.SHARED_DEVICE_SESSION_STORAGE_KEY = exports.IOS_KEYCHAIN_ACCESS_GROUP = exports.IOS_DEVICE_SESSION_KEYCHAIN_SERVICE = void 0;
7
+ exports.createPlatformSharedDeviceCredentialStore = createPlatformSharedDeviceCredentialStore;
8
+ var _reactNative = require("react-native");
9
+ var _expoModulesCore = require("expo-modules-core");
10
+ var _core = require("@oxyhq/core");
11
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /**
12
+ * The platform half of the shared native DeviceSession credential.
13
+ *
14
+ * `@oxyhq/core` owns the rules (`sharedDeviceCredential.ts`: when to adopt, when
15
+ * to publish, and above all that an unreadable slot is never an empty one). This
16
+ * module owns only where the bytes live, which is genuinely different per
17
+ * platform:
18
+ *
19
+ * - **iOS** — one `expo-secure-store` item in the approved Keychain Access Group
20
+ * `group.so.oxy.shared`, under its OWN `keychainService`
21
+ * ({@link IOS_DEVICE_SESSION_KEYCHAIN_SERVICE}). Every identity slot uses a
22
+ * different service (`oxy_identity`, `oxy_identity_backup`,
23
+ * `oxy_identity_mnemonic`) and the legacy cross-app identity keypair uses the
24
+ * same group with NO service at all — so this item cannot alias any of them.
25
+ * That separation is the point of the whole phase: the group-shared identity
26
+ * key and the group-shared device-session credential are different secrets
27
+ * with different blast radii and must not be conflated.
28
+ * - **Android** — the signature-protected `OxyDeviceSession` broker (its own
29
+ * EncryptedSharedPreferences file, its own ContentProvider, its own
30
+ * `signature`-level permission). It carries a session credential; it can NOT
31
+ * reach the identity keypair, which lives in a different file behind a
32
+ * different provider.
33
+ * - **web / anything else** — no shared slot. Each origin is its own device by
34
+ * design, so the factory returns `null` and the cold boot simply omits the
35
+ * lane.
36
+ *
37
+ * ## What is written here, and what is not
38
+ *
39
+ * Only `{deviceId, deviceSecret}`. No access token, no account id, no user id,
40
+ * and never any identity key material.
41
+ *
42
+ * ## Accessibility
43
+ *
44
+ * `WHEN_UNLOCKED_THIS_DEVICE_ONLY`: a device credential must not travel to
45
+ * another handset in an iCloud/encrypted backup restore — the restored device is
46
+ * a different device and has to establish its own session. It also keeps the item
47
+ * out of reach while the phone is locked, which is why a read can legitimately
48
+ * fail and why the `unavailable` verdict exists at all.
49
+ */
50
+ /**
51
+ * The iOS Keychain Access Group every official Oxy app declares in its
52
+ * entitlements. Shared with the identity slots — the group is the app-group
53
+ * boundary, not the secret's identity.
54
+ */
55
+ const IOS_KEYCHAIN_ACCESS_GROUP = exports.IOS_KEYCHAIN_ACCESS_GROUP = 'group.so.oxy.shared';
56
+
57
+ /**
58
+ * The iOS `keychainService` for the DEVICE SESSION credential. Deliberately
59
+ * distinct from every identity and recovery service; do not reuse one of those
60
+ * here, and do not drop it (an item written with no service shares the legacy
61
+ * identity slot's namespace inside the group).
62
+ */
63
+ const IOS_DEVICE_SESSION_KEYCHAIN_SERVICE = exports.IOS_DEVICE_SESSION_KEYCHAIN_SERVICE = 'oxy_device_session';
64
+
65
+ /** The single key holding the JSON-encoded `{deviceId, deviceSecret}` pair. */
66
+ const SHARED_DEVICE_SESSION_STORAGE_KEY = exports.SHARED_DEVICE_SESSION_STORAGE_KEY = 'oxy_shared_device_session_v1';
67
+
68
+ // Variable indirection so Metro's static analyzer never traces expo-secure-store
69
+ // into the web bundle; the module is native-only and optional.
70
+ const SECURE_STORE_MODULE = 'expo-secure-store';
71
+
72
+ /**
73
+ * The subset of `expo-secure-store` this module needs. Unlike the adapter in
74
+ * `nativeSecureStorage.ts` it must pass OPTIONS — the access group and the
75
+ * dedicated service are the entire mechanism here, so an options-less wrapper
76
+ * would silently write a package-private item that no sibling app can see.
77
+ */
78
+
79
+ let keychainStorePromise = null;
80
+ function loadKeychainGroupStore() {
81
+ if (!keychainStorePromise) {
82
+ const moduleName = SECURE_STORE_MODULE;
83
+ keychainStorePromise = (specifier => new Promise(r => r(`${specifier}`)).then(s => _interopRequireWildcard(require(s))))(moduleName).then(mod => {
84
+ if (typeof mod.getItemAsync === 'function' && typeof mod.setItemAsync === 'function' && typeof mod.deleteItemAsync === 'function' && typeof mod.WHEN_UNLOCKED_THIS_DEVICE_ONLY === 'number') {
85
+ return {
86
+ getItemAsync: mod.getItemAsync.bind(mod),
87
+ setItemAsync: mod.setItemAsync.bind(mod),
88
+ deleteItemAsync: mod.deleteItemAsync.bind(mod),
89
+ WHEN_UNLOCKED_THIS_DEVICE_ONLY: mod.WHEN_UNLOCKED_THIS_DEVICE_ONLY
90
+ };
91
+ }
92
+ return null;
93
+ }).catch(() => null);
94
+ }
95
+ return keychainStorePromise;
96
+ }
97
+
98
+ /** Parse the stored JSON into a credential, or `null` for anything malformed. */
99
+ function parseStoredCredential(raw) {
100
+ if (!raw) {
101
+ return null;
102
+ }
103
+ let parsed;
104
+ try {
105
+ parsed = JSON.parse(raw);
106
+ } catch {
107
+ return null;
108
+ }
109
+ if (!parsed || typeof parsed !== 'object') {
110
+ return null;
111
+ }
112
+ const candidate = parsed;
113
+ if (typeof candidate.deviceId !== 'string' || candidate.deviceId.length === 0 || typeof candidate.deviceSecret !== 'string' || candidate.deviceSecret.length === 0) {
114
+ return null;
115
+ }
116
+ return {
117
+ deviceId: candidate.deviceId,
118
+ deviceSecret: candidate.deviceSecret
119
+ };
120
+ }
121
+
122
+ /**
123
+ * The iOS store: one keychain item in the shared access group.
124
+ *
125
+ * A THROWN read is `unavailable`, a `null` read is `absent`. That mapping is the
126
+ * whole safety contract — `expo-secure-store` returns `null` for a genuinely
127
+ * missing item and throws when the keychain itself refuses, and collapsing the
128
+ * two is what would let a locked phone look like a device that never had a
129
+ * session.
130
+ */
131
+ function createKeychainGroupCredentialStore() {
132
+ const readOptions = {
133
+ keychainService: IOS_DEVICE_SESSION_KEYCHAIN_SERVICE,
134
+ keychainAccessGroup: IOS_KEYCHAIN_ACCESS_GROUP
135
+ };
136
+ return {
137
+ read: async () => {
138
+ const store = await loadKeychainGroupStore();
139
+ if (!store) {
140
+ return {
141
+ state: 'unsupported'
142
+ };
143
+ }
144
+ let raw;
145
+ try {
146
+ raw = await store.getItemAsync(SHARED_DEVICE_SESSION_STORAGE_KEY, readOptions);
147
+ } catch (error) {
148
+ return {
149
+ state: 'unavailable',
150
+ cause: error
151
+ };
152
+ }
153
+ if (raw === null) {
154
+ return {
155
+ state: 'absent'
156
+ };
157
+ }
158
+ const credential = parseStoredCredential(raw);
159
+ if (!credential) {
160
+ // Something IS stored and we cannot read it. Reporting `absent` would
161
+ // authorise overwriting whatever a newer build put there.
162
+ return {
163
+ state: 'unavailable',
164
+ cause: new Error('shared device session item is present but not parseable')
165
+ };
166
+ }
167
+ return {
168
+ state: 'present',
169
+ credential
170
+ };
171
+ },
172
+ publish: async credential => {
173
+ const store = await loadKeychainGroupStore();
174
+ if (!store) {
175
+ return false;
176
+ }
177
+ const value = JSON.stringify(credential);
178
+ try {
179
+ await store.setItemAsync(SHARED_DEVICE_SESSION_STORAGE_KEY, value, {
180
+ ...readOptions,
181
+ keychainAccessible: store.WHEN_UNLOCKED_THIS_DEVICE_ONLY
182
+ });
183
+ // Read-back verify. A keychain write can resolve without the item having
184
+ // landed under the access group (a missing entitlement is the usual
185
+ // cause), and a phantom credential would send a fresh install into a mint
186
+ // that can never succeed.
187
+ return (await store.getItemAsync(SHARED_DEVICE_SESSION_STORAGE_KEY, readOptions)) === value;
188
+ } catch {
189
+ return false;
190
+ }
191
+ },
192
+ clear: async () => {
193
+ const store = await loadKeychainGroupStore();
194
+ if (!store) {
195
+ return;
196
+ }
197
+ try {
198
+ await store.deleteItemAsync(SHARED_DEVICE_SESSION_STORAGE_KEY, readOptions);
199
+ } catch {
200
+ // Best-effort: the slot is a join point, not a source of truth.
201
+ }
202
+ }
203
+ };
204
+ }
205
+
206
+ /**
207
+ * The Android broker's JS surface. `read` returns an UNTRUSTED payload that
208
+ * {@link normalizeSharedDeviceSessionRead} narrows; `write` reports whether the
209
+ * native read-back confirmed the bytes.
210
+ */
211
+
212
+ let brokerModule;
213
+
214
+ /**
215
+ * Resolve the `OxyDeviceSession` broker, or `null` when it is not autolinked.
216
+ *
217
+ * `requireOptionalNativeModule` (a static import Metro always resolves) rather
218
+ * than a dynamic `import(moduleName)`: the latter compiles to `require(variable)`
219
+ * in the CJS build, which Metro cannot resolve inside a consuming app — it
220
+ * silently returns `null` there, which is exactly how the cross-app identity
221
+ * bridge broke once. Same reasoning as `backgroundSession.ts` next door.
222
+ */
223
+ function loadBrokerModule() {
224
+ if (brokerModule === undefined) {
225
+ const native = (0, _expoModulesCore.requireOptionalNativeModule)('OxyDeviceSession');
226
+ brokerModule = native && typeof native.read === 'function' && typeof native.write === 'function' && typeof native.clear === 'function' ? {
227
+ read: native.read.bind(native),
228
+ write: native.write.bind(native),
229
+ clear: native.clear.bind(native)
230
+ } : null;
231
+ }
232
+ return brokerModule;
233
+ }
234
+
235
+ /**
236
+ * The Android store: the signature-protected `OxyDeviceSession` broker.
237
+ *
238
+ * The broker already answers with an explicit status, so the only work here is
239
+ * narrowing an UNTRUSTED payload — `normalizeSharedDeviceSessionRead` resolves
240
+ * anything it does not recognise to `unavailable`, never `absent`.
241
+ */
242
+ function createBrokerCredentialStore() {
243
+ return {
244
+ read: async () => {
245
+ const broker = loadBrokerModule();
246
+ if (!broker) {
247
+ return {
248
+ state: 'unsupported'
249
+ };
250
+ }
251
+ try {
252
+ return (0, _core.normalizeSharedDeviceSessionRead)(await broker.read());
253
+ } catch (error) {
254
+ return {
255
+ state: 'unavailable',
256
+ cause: error
257
+ };
258
+ }
259
+ },
260
+ publish: async credential => {
261
+ const broker = loadBrokerModule();
262
+ if (!broker) {
263
+ return false;
264
+ }
265
+ try {
266
+ // The broker read-back-verifies natively and returns the verdict.
267
+ return await broker.write(credential.deviceId, credential.deviceSecret);
268
+ } catch {
269
+ return false;
270
+ }
271
+ },
272
+ clear: async () => {
273
+ const broker = loadBrokerModule();
274
+ if (!broker) {
275
+ return;
276
+ }
277
+ try {
278
+ await broker.clear();
279
+ } catch {
280
+ // Best-effort — see the iOS store.
281
+ }
282
+ }
283
+ };
284
+ }
285
+
286
+ /**
287
+ * The shared DeviceSession credential slot for this runtime, or `null` when
288
+ * there is none.
289
+ *
290
+ * The branch is on the PLATFORM, not on which module happens to load, because
291
+ * `expo-secure-store` loads perfectly well on Android — it would just quietly
292
+ * ignore `keychainAccessGroup` and read a package-private item, which looks
293
+ * exactly like an empty shared slot. This is the same iOS-vs-Android split
294
+ * `KeyManager` makes for the shared identity, for the same reason.
295
+ *
296
+ * Any other native platform gets the broker, which answers `unsupported` when
297
+ * the module is not linked — so the lane is simply off, which is the safe
298
+ * direction.
299
+ */
300
+ function createPlatformSharedDeviceCredentialStore() {
301
+ if (_reactNative.Platform.OS === 'web') {
302
+ return null;
303
+ }
304
+ return _reactNative.Platform.OS === 'ios' ? createKeychainGroupCredentialStore() : createBrokerCredentialStore();
305
+ }
306
+ //# sourceMappingURL=sharedDeviceCredentialStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNative","require","_expoModulesCore","_core","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","IOS_KEYCHAIN_ACCESS_GROUP","exports","IOS_DEVICE_SESSION_KEYCHAIN_SERVICE","SHARED_DEVICE_SESSION_STORAGE_KEY","SECURE_STORE_MODULE","keychainStorePromise","loadKeychainGroupStore","moduleName","specifier","Promise","then","s","mod","getItemAsync","setItemAsync","deleteItemAsync","WHEN_UNLOCKED_THIS_DEVICE_ONLY","bind","catch","parseStoredCredential","raw","parsed","JSON","parse","candidate","deviceId","length","deviceSecret","createKeychainGroupCredentialStore","readOptions","keychainService","keychainAccessGroup","read","store","state","error","cause","credential","Error","publish","value","stringify","keychainAccessible","clear","brokerModule","loadBrokerModule","undefined","native","requireOptionalNativeModule","write","createBrokerCredentialStore","broker","normalizeSharedDeviceSessionRead","createPlatformSharedDeviceCredentialStore","Platform","OS"],"sourceRoot":"../../../../src","sources":["ui/session/sharedDeviceCredentialStore.ts"],"mappings":"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","ignoreList":[]}
@@ -3,68 +3,167 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.bindAuthStoreToRuntime = bindAuthStoreToRuntime;
6
7
  exports.useAuthStore = void 0;
7
- var _zustand = require("zustand");
8
- var _core = require("@oxyhq/core");
9
- const log = (0, _core.createLogger)('AuthStore');
10
- const useAuthStore = exports.useAuthStore = (0, _zustand.create)((set, get) => ({
8
+ var _react = require("react");
9
+ /**
10
+ * The signed-in user, as a zustand-shaped read/write surface.
11
+ *
12
+ * It used to BE a zustand store, and that made it a second owner of the
13
+ * session: the provider wrote `user`/`isAuthenticated` here, `SessionClient`
14
+ * wrote the same facts into its device state, and nothing reconciled them —
15
+ * when they disagreed, which one was right was not answerable. It is now a
16
+ * projection of the ONE `OxyRuntime` (ADR 0004): reads come off the runtime
17
+ * snapshot and writes go into the runtime, so there is nothing left to drift.
18
+ *
19
+ * The zustand SHAPE is kept deliberately — `useAuthStore(selector)`,
20
+ * `.getState()`, `.setState()`, `.subscribe()` — because a dozen call sites
21
+ * across this package and the Commons app read the user out of band, from
22
+ * mutation success handlers and cache helpers that are not inside a render.
23
+ * Rewriting them is Phase 8's cut, not this one's.
24
+ *
25
+ * `fetchUser` and `lastUserFetch` are GONE rather than projected: they were a
26
+ * five-minute profile cache with zero readers anywhere in the monorepo, and the
27
+ * Query cache has owned that job since long before this change.
28
+ */
29
+
30
+ /** The subset of `AuthState` a caller may push back in through `setState`. */
31
+
32
+ let boundRuntime = null;
33
+ let unbindRuntime = null;
34
+ const listeners = new Set();
35
+ const loginSuccess = user => {
36
+ boundRuntime?.setAccount(user);
37
+ };
38
+ const loginFailure = error => {
39
+ boundRuntime?.batch(() => {
40
+ boundRuntime?.setLoading(false);
41
+ boundRuntime?.setError(error);
42
+ });
43
+ };
44
+ const logout = () => {
45
+ boundRuntime?.clearSession();
46
+ };
47
+ const setUser = user => {
48
+ boundRuntime?.setAccount(user);
49
+ };
50
+ const SIGNED_OUT = Object.freeze({
11
51
  user: null,
12
52
  isAuthenticated: false,
13
53
  isLoading: false,
14
54
  error: null,
15
- lastUserFetch: null,
16
- loginSuccess: user => set({
17
- isLoading: false,
18
- isAuthenticated: true,
19
- user: (0, _core.normalizeUserIdentity)(user),
20
- lastUserFetch: Date.now()
21
- }),
22
- loginFailure: error => set({
23
- isLoading: false,
24
- error
25
- }),
26
- logout: () => set({
27
- user: null,
28
- isAuthenticated: false,
29
- lastUserFetch: null
30
- }),
31
- setUser: user => set({
32
- user: (0, _core.normalizeUserIdentity)(user),
33
- lastUserFetch: Date.now()
34
- }),
35
- fetchUser: async (oxyServices, forceRefresh = false) => {
36
- const state = get();
37
- const now = Date.now();
38
- const cacheAge = state.lastUserFetch ? now - state.lastUserFetch : Number.POSITIVE_INFINITY;
39
- const cacheValid = cacheAge < 5 * 60 * 1000; // 5 minutes cache
55
+ loginSuccess,
56
+ loginFailure,
57
+ logout,
58
+ setUser
59
+ });
60
+ let state = SIGNED_OUT;
61
+ function project(runtime) {
62
+ if (runtime === null) {
63
+ return SIGNED_OUT;
64
+ }
65
+ const snapshot = runtime.getSnapshot();
66
+ return Object.freeze({
67
+ user: snapshot.account,
68
+ isAuthenticated: snapshot.account !== null,
69
+ isLoading: snapshot.isLoading,
70
+ error: snapshot.error?.message ?? null,
71
+ loginSuccess,
72
+ loginFailure,
73
+ logout,
74
+ setUser
75
+ });
76
+ }
77
+ function republish() {
78
+ const next = project(boundRuntime);
79
+ if (next.user === state.user && next.isAuthenticated === state.isAuthenticated && next.isLoading === state.isLoading && next.error === state.error) {
80
+ return;
81
+ }
82
+ state = next;
83
+ for (const listener of [...listeners]) {
84
+ listener();
85
+ }
86
+ }
40
87
 
41
- // Use cached data if available and not forcing refresh
42
- if (!forceRefresh && state.user && cacheValid) {
43
- log.info('Using cached user data', {
44
- cacheAge
45
- });
88
+ /**
89
+ * Point this surface at the provider's runtime. Called once by
90
+ * `OxyRuntimeProvider`; the returned function detaches it again on unmount.
91
+ *
92
+ * With nothing bound, reads answer signed-out and writes are dropped. That is
93
+ * the honest answer for the two places it happens — the SSR shim, and a unit
94
+ * test poking the store with no provider mounted — and it is why binding is an
95
+ * explicit call rather than a lazily-created default runtime, which is exactly
96
+ * the fabricated-forever-loading runtime ADR 0004 deleted.
97
+ */
98
+ function bindAuthStoreToRuntime(runtime) {
99
+ unbindRuntime?.();
100
+ boundRuntime = runtime;
101
+ unbindRuntime = runtime.subscribe(republish);
102
+ republish();
103
+ return () => {
104
+ if (boundRuntime !== runtime) {
46
105
  return;
47
106
  }
48
- set({
49
- isLoading: true,
50
- error: null
51
- });
52
- try {
53
- const user = (0, _core.normalizeUserIdentity)(await oxyServices.getCurrentUser());
54
- set({
55
- user,
56
- isLoading: false,
57
- isAuthenticated: true,
58
- lastUserFetch: now
59
- });
60
- } catch (error) {
61
- const errorMessage = error instanceof Error ? error.message : 'Failed to fetch user';
62
- log.error('Error fetching user', error);
63
- set({
64
- error: errorMessage,
65
- isLoading: false
66
- });
107
+ unbindRuntime?.();
108
+ unbindRuntime = null;
109
+ boundRuntime = null;
110
+ republish();
111
+ };
112
+ }
113
+ const getState = () => state;
114
+ const setState = patch => {
115
+ boundRuntime?.batch(() => {
116
+ if (patch.isLoading !== undefined) {
117
+ boundRuntime?.setLoading(patch.isLoading);
67
118
  }
68
- }
69
- }));
119
+ if (patch.error !== undefined) {
120
+ boundRuntime?.setError(patch.error);
121
+ }
122
+ if (patch.user !== undefined) {
123
+ if (patch.user === null) {
124
+ boundRuntime?.clearSession();
125
+ } else {
126
+ boundRuntime?.setAccount(patch.user);
127
+ }
128
+ }
129
+ });
130
+ };
131
+ const subscribe = listener => {
132
+ listeners.add(listener);
133
+ return () => {
134
+ listeners.delete(listener);
135
+ };
136
+ };
137
+ function useAuthStoreHook(selector) {
138
+ // The selection is cached against the state object it came from, so a
139
+ // selector returning a fresh object cannot make `useSyncExternalStore` see a
140
+ // new value on every call and loop.
141
+ const cache = (0, _react.useRef)(null);
142
+ const getSelection = (0, _react.useCallback)(() => {
143
+ const cached = cache.current;
144
+ if (cached !== null && cached.state === state) {
145
+ return cached.value;
146
+ }
147
+ const value = selector(state);
148
+ cache.current = {
149
+ state,
150
+ value
151
+ };
152
+ return value;
153
+ }, [selector]);
154
+ return (0, _react.useSyncExternalStore)(subscribe, getSelection, getSelection);
155
+ }
156
+
157
+ /**
158
+ * Read the signed-in user. Zustand-shaped, projected from the runtime.
159
+ *
160
+ * A selector that builds an object must be wrapped in `useShallow` (as every
161
+ * call site here already does) — otherwise a structurally-equal result reads as
162
+ * a change on every publish.
163
+ */
164
+ const useAuthStore = exports.useAuthStore = Object.assign(useAuthStoreHook, {
165
+ getState,
166
+ setState,
167
+ subscribe
168
+ });
70
169
  //# sourceMappingURL=authStore.js.map