@oxyhq/services 16.0.0 → 18.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 (278) hide show
  1. package/README.md +77 -98
  2. package/lib/commonjs/index.js +40 -51
  3. package/lib/commonjs/index.js.map +1 -1
  4. package/lib/commonjs/ui/client.js +0 -14
  5. package/lib/commonjs/ui/client.js.map +1 -1
  6. package/lib/commonjs/ui/components/OxyAccountDialog.js +742 -0
  7. package/lib/commonjs/ui/components/OxyAccountDialog.js.map +1 -0
  8. package/lib/commonjs/ui/components/OxyConsentScreen.js +461 -0
  9. package/lib/commonjs/ui/components/OxyConsentScreen.js.map +1 -0
  10. package/lib/commonjs/ui/components/OxyProvider.js +13 -6
  11. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  12. package/lib/commonjs/ui/components/OxySignInButton.js +180 -22
  13. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
  14. package/lib/commonjs/ui/components/ProfileButton.js +25 -112
  15. package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
  16. package/lib/commonjs/ui/components/RequireOxyAuth.js +299 -0
  17. package/lib/commonjs/ui/components/RequireOxyAuth.js.map +1 -0
  18. package/lib/commonjs/ui/components/oauthNavigation.js +73 -0
  19. package/lib/commonjs/ui/components/oauthNavigation.js.map +1 -0
  20. package/lib/commonjs/ui/context/OxyContext.js +122 -4
  21. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  22. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +1 -1
  23. package/lib/commonjs/ui/hooks/useAuth.js +19 -30
  24. package/lib/commonjs/ui/hooks/useAuth.js.map +1 -1
  25. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +37 -267
  26. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +1 -1
  27. package/lib/commonjs/ui/index.js +5 -40
  28. package/lib/commonjs/ui/index.js.map +1 -1
  29. package/lib/commonjs/ui/navigation/accountDialogManager.js +91 -0
  30. package/lib/commonjs/ui/navigation/accountDialogManager.js.map +1 -0
  31. package/lib/commonjs/ui/navigation/routes.js +0 -2
  32. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  33. package/lib/commonjs/ui/screens/ManageAccountScreen.js +4 -3
  34. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  35. package/lib/commonjs/ui/session/createSessionClient.js +10 -2
  36. package/lib/commonjs/ui/session/createSessionClient.js.map +1 -1
  37. package/lib/module/index.js +19 -16
  38. package/lib/module/index.js.map +1 -1
  39. package/lib/module/ui/client.js +1 -2
  40. package/lib/module/ui/client.js.map +1 -1
  41. package/lib/module/ui/components/OxyAccountDialog.js +739 -0
  42. package/lib/module/ui/components/OxyAccountDialog.js.map +1 -0
  43. package/lib/module/ui/components/OxyConsentScreen.js +454 -0
  44. package/lib/module/ui/components/OxyConsentScreen.js.map +1 -0
  45. package/lib/module/ui/components/OxyProvider.js +13 -6
  46. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  47. package/lib/module/ui/components/OxySignInButton.js +181 -22
  48. package/lib/module/ui/components/OxySignInButton.js.map +1 -1
  49. package/lib/module/ui/components/ProfileButton.js +26 -112
  50. package/lib/module/ui/components/ProfileButton.js.map +1 -1
  51. package/lib/module/ui/components/RequireOxyAuth.js +294 -0
  52. package/lib/module/ui/components/RequireOxyAuth.js.map +1 -0
  53. package/lib/module/ui/components/oauthNavigation.js +70 -0
  54. package/lib/module/ui/components/oauthNavigation.js.map +1 -0
  55. package/lib/module/ui/context/OxyContext.js +123 -5
  56. package/lib/module/ui/context/OxyContext.js.map +1 -1
  57. package/lib/module/ui/hooks/mutations/useAccountMutations.js +1 -1
  58. package/lib/module/ui/hooks/useAuth.js +19 -30
  59. package/lib/module/ui/hooks/useAuth.js.map +1 -1
  60. package/lib/module/ui/hooks/useSwitchableAccounts.js +38 -267
  61. package/lib/module/ui/hooks/useSwitchableAccounts.js.map +1 -1
  62. package/lib/module/ui/index.js +1 -5
  63. package/lib/module/ui/index.js.map +1 -1
  64. package/lib/module/ui/navigation/accountDialogManager.js +81 -0
  65. package/lib/module/ui/navigation/accountDialogManager.js.map +1 -0
  66. package/lib/module/ui/navigation/routes.js +0 -2
  67. package/lib/module/ui/navigation/routes.js.map +1 -1
  68. package/lib/module/ui/screens/ManageAccountScreen.js +4 -3
  69. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  70. package/lib/module/ui/session/createSessionClient.js +10 -2
  71. package/lib/module/ui/session/createSessionClient.js.map +1 -1
  72. package/lib/typescript/commonjs/index.d.ts +8 -12
  73. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  74. package/lib/typescript/commonjs/ui/client.d.ts +0 -4
  75. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/ui/components/OxyAccountDialog.d.ts +51 -0
  77. package/lib/typescript/commonjs/ui/components/OxyAccountDialog.d.ts.map +1 -0
  78. package/lib/typescript/commonjs/ui/components/OxyConsentScreen.d.ts +45 -0
  79. package/lib/typescript/commonjs/ui/components/OxyConsentScreen.d.ts.map +1 -0
  80. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts +2 -2
  81. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts +56 -0
  83. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts +11 -23
  85. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/ui/components/RequireOxyAuth.d.ts +55 -0
  87. package/lib/typescript/commonjs/ui/components/RequireOxyAuth.d.ts.map +1 -0
  88. package/lib/typescript/commonjs/ui/components/oauthNavigation.d.ts +36 -0
  89. package/lib/typescript/commonjs/ui/components/oauthNavigation.d.ts.map +1 -0
  90. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +27 -1
  91. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  93. package/lib/typescript/commonjs/ui/hooks/queries/useServicesQueries.d.ts +1 -1
  94. package/lib/typescript/commonjs/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
  95. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -1
  96. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts +13 -152
  97. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
  98. package/lib/typescript/commonjs/ui/index.d.ts +2 -5
  99. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  100. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts +49 -0
  101. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts.map +1 -0
  102. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
  103. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  104. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts +1 -1
  105. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  106. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts +9 -2
  107. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts.map +1 -1
  108. package/lib/typescript/commonjs/ui/types/navigation.d.ts +27 -0
  109. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  110. package/lib/typescript/module/index.d.ts +8 -12
  111. package/lib/typescript/module/index.d.ts.map +1 -1
  112. package/lib/typescript/module/ui/client.d.ts +0 -4
  113. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  114. package/lib/typescript/module/ui/components/OxyAccountDialog.d.ts +51 -0
  115. package/lib/typescript/module/ui/components/OxyAccountDialog.d.ts.map +1 -0
  116. package/lib/typescript/module/ui/components/OxyConsentScreen.d.ts +45 -0
  117. package/lib/typescript/module/ui/components/OxyConsentScreen.d.ts.map +1 -0
  118. package/lib/typescript/module/ui/components/OxyProvider.d.ts +2 -2
  119. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  120. package/lib/typescript/module/ui/components/OxySignInButton.d.ts +56 -0
  121. package/lib/typescript/module/ui/components/OxySignInButton.d.ts.map +1 -1
  122. package/lib/typescript/module/ui/components/ProfileButton.d.ts +11 -23
  123. package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
  124. package/lib/typescript/module/ui/components/RequireOxyAuth.d.ts +55 -0
  125. package/lib/typescript/module/ui/components/RequireOxyAuth.d.ts.map +1 -0
  126. package/lib/typescript/module/ui/components/oauthNavigation.d.ts +36 -0
  127. package/lib/typescript/module/ui/components/oauthNavigation.d.ts.map +1 -0
  128. package/lib/typescript/module/ui/context/OxyContext.d.ts +27 -1
  129. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  130. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  131. package/lib/typescript/module/ui/hooks/queries/useServicesQueries.d.ts +1 -1
  132. package/lib/typescript/module/ui/hooks/queries/useServicesQueries.d.ts.map +1 -1
  133. package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
  134. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts +13 -152
  135. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
  136. package/lib/typescript/module/ui/index.d.ts +2 -5
  137. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  138. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts +49 -0
  139. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts.map +1 -0
  140. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  141. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  142. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts +1 -1
  143. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  144. package/lib/typescript/module/ui/session/createSessionClient.d.ts +9 -2
  145. package/lib/typescript/module/ui/session/createSessionClient.d.ts.map +1 -1
  146. package/lib/typescript/module/ui/types/navigation.d.ts +27 -0
  147. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  148. package/package.json +4 -4
  149. package/src/index.ts +33 -27
  150. package/src/ui/client.ts +0 -4
  151. package/src/ui/components/OxyAccountDialog.tsx +735 -0
  152. package/src/ui/components/OxyConsentScreen.tsx +456 -0
  153. package/src/ui/components/OxyProvider.tsx +14 -6
  154. package/src/ui/components/OxySignInButton.tsx +227 -22
  155. package/src/ui/components/ProfileButton.tsx +23 -126
  156. package/src/ui/components/RequireOxyAuth.tsx +266 -0
  157. package/src/ui/components/__tests__/OxyConsentScreen.test.tsx +130 -0
  158. package/src/ui/components/oauthNavigation.ts +89 -0
  159. package/src/ui/context/OxyContext.tsx +176 -9
  160. package/src/ui/context/__tests__/OxyContext.coldBoot.test.tsx +165 -0
  161. package/src/ui/hooks/mutations/useAccountMutations.ts +1 -1
  162. package/src/ui/hooks/useAuth.ts +19 -31
  163. package/src/ui/hooks/useSwitchableAccounts.ts +42 -376
  164. package/src/ui/index.ts +2 -5
  165. package/src/ui/navigation/accountDialogManager.ts +84 -0
  166. package/src/ui/navigation/routes.ts +0 -4
  167. package/src/ui/screens/ManageAccountScreen.tsx +3 -2
  168. package/src/ui/session/createSessionClient.ts +9 -1
  169. package/src/ui/types/navigation.ts +27 -0
  170. package/lib/commonjs/ui/components/AccountMenu.js +0 -598
  171. package/lib/commonjs/ui/components/AccountMenu.js.map +0 -1
  172. package/lib/commonjs/ui/components/AccountMenuButton.js +0 -135
  173. package/lib/commonjs/ui/components/AccountMenuButton.js.map +0 -1
  174. package/lib/commonjs/ui/components/AccountSwitcher.js +0 -780
  175. package/lib/commonjs/ui/components/AccountSwitcher.js.map +0 -1
  176. package/lib/commonjs/ui/components/AnotherDeviceQR.js +0 -116
  177. package/lib/commonjs/ui/components/AnotherDeviceQR.js.map +0 -1
  178. package/lib/commonjs/ui/components/ProfileMenu.js +0 -518
  179. package/lib/commonjs/ui/components/ProfileMenu.js.map +0 -1
  180. package/lib/commonjs/ui/components/SignInAccountChooser.js +0 -189
  181. package/lib/commonjs/ui/components/SignInAccountChooser.js.map +0 -1
  182. package/lib/commonjs/ui/components/SignInModal.js +0 -600
  183. package/lib/commonjs/ui/components/SignInModal.js.map +0 -1
  184. package/lib/commonjs/ui/hooks/useOxyAuthSession.js +0 -501
  185. package/lib/commonjs/ui/hooks/useOxyAuthSession.js.map +0 -1
  186. package/lib/commonjs/ui/hooks/usePasswordSignIn.js +0 -170
  187. package/lib/commonjs/ui/hooks/usePasswordSignIn.js.map +0 -1
  188. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +0 -51
  189. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +0 -1
  190. package/lib/commonjs/ui/screens/OxyAuthScreen.js +0 -312
  191. package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +0 -1
  192. package/lib/commonjs/utils/deviceFlowSignIn.js +0 -109
  193. package/lib/commonjs/utils/deviceFlowSignIn.js.map +0 -1
  194. package/lib/module/ui/components/AccountMenu.js +0 -593
  195. package/lib/module/ui/components/AccountMenu.js.map +0 -1
  196. package/lib/module/ui/components/AccountMenuButton.js +0 -130
  197. package/lib/module/ui/components/AccountMenuButton.js.map +0 -1
  198. package/lib/module/ui/components/AccountSwitcher.js +0 -774
  199. package/lib/module/ui/components/AccountSwitcher.js.map +0 -1
  200. package/lib/module/ui/components/AnotherDeviceQR.js +0 -110
  201. package/lib/module/ui/components/AnotherDeviceQR.js.map +0 -1
  202. package/lib/module/ui/components/ProfileMenu.js +0 -514
  203. package/lib/module/ui/components/ProfileMenu.js.map +0 -1
  204. package/lib/module/ui/components/SignInAccountChooser.js +0 -183
  205. package/lib/module/ui/components/SignInAccountChooser.js.map +0 -1
  206. package/lib/module/ui/components/SignInModal.js +0 -591
  207. package/lib/module/ui/components/SignInModal.js.map +0 -1
  208. package/lib/module/ui/hooks/useOxyAuthSession.js +0 -495
  209. package/lib/module/ui/hooks/useOxyAuthSession.js.map +0 -1
  210. package/lib/module/ui/hooks/usePasswordSignIn.js +0 -165
  211. package/lib/module/ui/hooks/usePasswordSignIn.js.map +0 -1
  212. package/lib/module/ui/screens/AccountSwitcherScreen.js +0 -48
  213. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +0 -1
  214. package/lib/module/ui/screens/OxyAuthScreen.js +0 -306
  215. package/lib/module/ui/screens/OxyAuthScreen.js.map +0 -1
  216. package/lib/module/utils/deviceFlowSignIn.js +0 -106
  217. package/lib/module/utils/deviceFlowSignIn.js.map +0 -1
  218. package/lib/typescript/commonjs/ui/components/AccountMenu.d.ts +0 -47
  219. package/lib/typescript/commonjs/ui/components/AccountMenu.d.ts.map +0 -1
  220. package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts +0 -26
  221. package/lib/typescript/commonjs/ui/components/AccountMenuButton.d.ts.map +0 -1
  222. package/lib/typescript/commonjs/ui/components/AccountSwitcher.d.ts +0 -46
  223. package/lib/typescript/commonjs/ui/components/AccountSwitcher.d.ts.map +0 -1
  224. package/lib/typescript/commonjs/ui/components/AnotherDeviceQR.d.ts +0 -34
  225. package/lib/typescript/commonjs/ui/components/AnotherDeviceQR.d.ts.map +0 -1
  226. package/lib/typescript/commonjs/ui/components/ProfileMenu.d.ts +0 -49
  227. package/lib/typescript/commonjs/ui/components/ProfileMenu.d.ts.map +0 -1
  228. package/lib/typescript/commonjs/ui/components/SignInAccountChooser.d.ts +0 -29
  229. package/lib/typescript/commonjs/ui/components/SignInAccountChooser.d.ts.map +0 -1
  230. package/lib/typescript/commonjs/ui/components/SignInModal.d.ts +0 -28
  231. package/lib/typescript/commonjs/ui/components/SignInModal.d.ts.map +0 -1
  232. package/lib/typescript/commonjs/ui/hooks/useOxyAuthSession.d.ts +0 -105
  233. package/lib/typescript/commonjs/ui/hooks/useOxyAuthSession.d.ts.map +0 -1
  234. package/lib/typescript/commonjs/ui/hooks/usePasswordSignIn.d.ts +0 -31
  235. package/lib/typescript/commonjs/ui/hooks/usePasswordSignIn.d.ts.map +0 -1
  236. package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts +0 -11
  237. package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts.map +0 -1
  238. package/lib/typescript/commonjs/ui/screens/OxyAuthScreen.d.ts +0 -22
  239. package/lib/typescript/commonjs/ui/screens/OxyAuthScreen.d.ts.map +0 -1
  240. package/lib/typescript/commonjs/utils/deviceFlowSignIn.d.ts +0 -97
  241. package/lib/typescript/commonjs/utils/deviceFlowSignIn.d.ts.map +0 -1
  242. package/lib/typescript/module/ui/components/AccountMenu.d.ts +0 -47
  243. package/lib/typescript/module/ui/components/AccountMenu.d.ts.map +0 -1
  244. package/lib/typescript/module/ui/components/AccountMenuButton.d.ts +0 -26
  245. package/lib/typescript/module/ui/components/AccountMenuButton.d.ts.map +0 -1
  246. package/lib/typescript/module/ui/components/AccountSwitcher.d.ts +0 -46
  247. package/lib/typescript/module/ui/components/AccountSwitcher.d.ts.map +0 -1
  248. package/lib/typescript/module/ui/components/AnotherDeviceQR.d.ts +0 -34
  249. package/lib/typescript/module/ui/components/AnotherDeviceQR.d.ts.map +0 -1
  250. package/lib/typescript/module/ui/components/ProfileMenu.d.ts +0 -49
  251. package/lib/typescript/module/ui/components/ProfileMenu.d.ts.map +0 -1
  252. package/lib/typescript/module/ui/components/SignInAccountChooser.d.ts +0 -29
  253. package/lib/typescript/module/ui/components/SignInAccountChooser.d.ts.map +0 -1
  254. package/lib/typescript/module/ui/components/SignInModal.d.ts +0 -28
  255. package/lib/typescript/module/ui/components/SignInModal.d.ts.map +0 -1
  256. package/lib/typescript/module/ui/hooks/useOxyAuthSession.d.ts +0 -105
  257. package/lib/typescript/module/ui/hooks/useOxyAuthSession.d.ts.map +0 -1
  258. package/lib/typescript/module/ui/hooks/usePasswordSignIn.d.ts +0 -31
  259. package/lib/typescript/module/ui/hooks/usePasswordSignIn.d.ts.map +0 -1
  260. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts +0 -11
  261. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +0 -1
  262. package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts +0 -22
  263. package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts.map +0 -1
  264. package/lib/typescript/module/utils/deviceFlowSignIn.d.ts +0 -97
  265. package/lib/typescript/module/utils/deviceFlowSignIn.d.ts.map +0 -1
  266. package/src/ui/components/AccountMenu.tsx +0 -645
  267. package/src/ui/components/AccountMenuButton.tsx +0 -126
  268. package/src/ui/components/AccountSwitcher.tsx +0 -751
  269. package/src/ui/components/AnotherDeviceQR.tsx +0 -119
  270. package/src/ui/components/ProfileMenu.tsx +0 -564
  271. package/src/ui/components/SignInAccountChooser.tsx +0 -162
  272. package/src/ui/components/SignInModal.tsx +0 -530
  273. package/src/ui/hooks/useOxyAuthSession.ts +0 -635
  274. package/src/ui/hooks/usePasswordSignIn.ts +0 -207
  275. package/src/ui/screens/AccountSwitcherScreen.tsx +0 -43
  276. package/src/ui/screens/OxyAuthScreen.tsx +0 -324
  277. package/src/utils/__tests__/deviceFlowSignIn.test.ts +0 -231
  278. package/src/utils/deviceFlowSignIn.ts +0 -152
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * RequireOxyAuth — the optional signed-out gate primitive (React Native).
5
+ *
6
+ * ONE shared way for any Oxy app to opt into a signed-out gate. It is entirely
7
+ * OPTIONAL: a public app renders its children untouched (`prompt="off"`); an
8
+ * auth-required app blocks them behind a signed-out state (`prompt="hard"`); an
9
+ * app that mostly works signed-out but wants a nudge shows a dismissible banner
10
+ * (`prompt="soft"`). Every mode reuses the ONE account dialog the provider
11
+ * already mounts — opening the sign-in surface is always
12
+ * `useOxy().openAccountDialog('signin')`; there is NO second dialog.
13
+ *
14
+ * Readiness gating (CRITICAL): the gate keys on the SDK's own readiness state
15
+ * (`useOxy().canUsePrivateApi` / `isPrivateApiPending`), NEVER on app-local
16
+ * hooks. While auth is still resolving (`isPrivateApiPending`) it renders a
17
+ * neutral loading state so the signed-out wall never flashes before the
18
+ * device-first cold boot concludes (the documented cold-boot race).
19
+ *
20
+ * Styling follows the sibling `OxyAccountDialog`/`OxySignInButton` pattern —
21
+ * `useTheme()` + `StyleSheet` (NOT NativeWind), so the gate renders correctly in
22
+ * EVERY consumer, including apps that do not run NativeWind (e.g. the accounts
23
+ * app).
24
+ */
25
+
26
+ import { useState } from 'react';
27
+ import { ActivityIndicator, Pressable, StyleSheet, View } from 'react-native';
28
+ import { useTheme } from '@oxyhq/bloom/theme';
29
+ import { Text } from '@oxyhq/bloom/typography';
30
+ import { useOxy } from "../context/OxyContext.js";
31
+ import { OxySignInButton } from "./OxySignInButton.js";
32
+ import OxyLogo from "./OxyLogo.js";
33
+
34
+ /**
35
+ * How `RequireOxyAuth` treats a signed-out (or still-resolving) session.
36
+ * - `off` — always render children (public app; a no-op provided for symmetry).
37
+ * - `soft` — render children, plus a dismissible sign-in banner when signed out.
38
+ * - `hard` — block children behind a centered signed-out state until signed in.
39
+ */
40
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
41
+ const DEFAULT_TITLE = 'Sign in to continue';
42
+ const DEFAULT_SUBTITLE = 'Sign in with your Oxy account to continue.';
43
+ const DEFAULT_BANNER_MESSAGE = "You're browsing signed out.";
44
+ const DEFAULT_BANNER_ACTION = 'Sign in';
45
+
46
+ /**
47
+ * Optional signed-out gate. Wrap any subtree (or the whole app via the
48
+ * provider's `requireAuth` prop) to opt into a shared, readiness-safe wall.
49
+ */
50
+ export const RequireOxyAuth = ({
51
+ children,
52
+ prompt = 'hard',
53
+ loadingFallback,
54
+ signedOutFallback,
55
+ title,
56
+ subtitle,
57
+ bannerMessage,
58
+ bannerActionLabel
59
+ }) => {
60
+ const {
61
+ canUsePrivateApi,
62
+ isPrivateApiPending,
63
+ openAccountDialog
64
+ } = useOxy();
65
+
66
+ // Public app: render straight through. Cheap enough to short-circuit before
67
+ // touching any gate UI.
68
+ if (prompt === 'off') {
69
+ return /*#__PURE__*/_jsx(_Fragment, {
70
+ children: children
71
+ });
72
+ }
73
+
74
+ // Signed in (and token ready): render the protected subtree in every mode.
75
+ if (canUsePrivateApi) {
76
+ return /*#__PURE__*/_jsx(_Fragment, {
77
+ children: children
78
+ });
79
+ }
80
+ if (prompt === 'soft') {
81
+ return /*#__PURE__*/_jsx(SoftGate, {
82
+ pending: isPrivateApiPending,
83
+ message: bannerMessage ?? DEFAULT_BANNER_MESSAGE,
84
+ actionLabel: bannerActionLabel ?? DEFAULT_BANNER_ACTION,
85
+ onSignIn: () => openAccountDialog('signin'),
86
+ children: children
87
+ });
88
+ }
89
+
90
+ // prompt === 'hard'
91
+ if (isPrivateApiPending) {
92
+ return loadingFallback ? /*#__PURE__*/_jsx(_Fragment, {
93
+ children: loadingFallback
94
+ }) : /*#__PURE__*/_jsx(NeutralLoading, {});
95
+ }
96
+ if (signedOutFallback) {
97
+ return /*#__PURE__*/_jsx(_Fragment, {
98
+ children: signedOutFallback
99
+ });
100
+ }
101
+ return /*#__PURE__*/_jsx(HardWall, {
102
+ title: title ?? DEFAULT_TITLE,
103
+ subtitle: subtitle ?? DEFAULT_SUBTITLE
104
+ });
105
+ };
106
+
107
+ // ---------------------------------------------------------------------------
108
+ // Soft gate — children + a dismissible sign-in banner while signed out.
109
+ // ---------------------------------------------------------------------------
110
+
111
+ const SoftGate = ({
112
+ children,
113
+ pending,
114
+ message,
115
+ actionLabel,
116
+ onSignIn
117
+ }) => {
118
+ const theme = useTheme();
119
+ const [dismissed, setDismissed] = useState(false);
120
+
121
+ // Never surface the nudge while auth is still resolving — only once the boot
122
+ // has concluded signed out and the user has not dismissed it.
123
+ const showBanner = !pending && !dismissed;
124
+ return /*#__PURE__*/_jsxs(View, {
125
+ style: styles.softRoot,
126
+ children: [showBanner ? /*#__PURE__*/_jsxs(View, {
127
+ style: [styles.banner, {
128
+ backgroundColor: theme.colors.card,
129
+ borderColor: theme.colors.border
130
+ }],
131
+ children: [/*#__PURE__*/_jsx(OxyLogo, {
132
+ variant: "icon",
133
+ size: 20,
134
+ fillColor: theme.colors.primary
135
+ }), /*#__PURE__*/_jsx(Text, {
136
+ style: [styles.bannerText, {
137
+ color: theme.colors.text
138
+ }],
139
+ numberOfLines: 2,
140
+ children: message
141
+ }), /*#__PURE__*/_jsx(Pressable, {
142
+ onPress: onSignIn,
143
+ style: [styles.bannerCta, {
144
+ backgroundColor: theme.colors.primary
145
+ }],
146
+ accessibilityRole: "button",
147
+ accessibilityLabel: actionLabel,
148
+ children: /*#__PURE__*/_jsx(Text, {
149
+ style: styles.bannerCtaText,
150
+ children: actionLabel
151
+ })
152
+ }), /*#__PURE__*/_jsx(Pressable, {
153
+ onPress: () => setDismissed(true),
154
+ style: styles.bannerDismiss,
155
+ accessibilityRole: "button",
156
+ accessibilityLabel: "Dismiss",
157
+ hitSlop: 8,
158
+ children: /*#__PURE__*/_jsx(Text, {
159
+ style: [styles.bannerDismissText, {
160
+ color: theme.colors.textSecondary
161
+ }],
162
+ children: "\u2715"
163
+ })
164
+ })]
165
+ }) : null, /*#__PURE__*/_jsx(View, {
166
+ style: styles.softBody,
167
+ children: children
168
+ })]
169
+ });
170
+ };
171
+
172
+ // ---------------------------------------------------------------------------
173
+ // Hard wall — centered signed-out state with the "Sign in with Oxy" CTA.
174
+ // ---------------------------------------------------------------------------
175
+
176
+ const HardWall = ({
177
+ title,
178
+ subtitle
179
+ }) => {
180
+ const theme = useTheme();
181
+ return /*#__PURE__*/_jsxs(View, {
182
+ style: [styles.wallRoot, {
183
+ backgroundColor: theme.colors.background
184
+ }],
185
+ children: [/*#__PURE__*/_jsx(View, {
186
+ style: [styles.logoBadge, {
187
+ backgroundColor: theme.colors.primarySubtle
188
+ }],
189
+ children: /*#__PURE__*/_jsx(OxyLogo, {
190
+ variant: "icon",
191
+ size: 44,
192
+ fillColor: theme.colors.primary
193
+ })
194
+ }), /*#__PURE__*/_jsx(Text, {
195
+ style: [styles.wallTitle, {
196
+ color: theme.colors.text
197
+ }],
198
+ children: title
199
+ }), /*#__PURE__*/_jsx(Text, {
200
+ style: [styles.wallSubtitle, {
201
+ color: theme.colors.textSecondary
202
+ }],
203
+ children: subtitle
204
+ }), /*#__PURE__*/_jsx(OxySignInButton, {
205
+ variant: "contained",
206
+ style: styles.wallCta
207
+ })]
208
+ });
209
+ };
210
+ const NeutralLoading = () => {
211
+ const theme = useTheme();
212
+ return /*#__PURE__*/_jsx(View, {
213
+ style: [styles.wallRoot, {
214
+ backgroundColor: theme.colors.background
215
+ }],
216
+ children: /*#__PURE__*/_jsx(ActivityIndicator, {
217
+ color: theme.colors.primary
218
+ })
219
+ });
220
+ };
221
+ const styles = StyleSheet.create({
222
+ softRoot: {
223
+ flex: 1
224
+ },
225
+ softBody: {
226
+ flex: 1
227
+ },
228
+ banner: {
229
+ flexDirection: 'row',
230
+ alignItems: 'center',
231
+ gap: 10,
232
+ paddingVertical: 8,
233
+ paddingHorizontal: 12,
234
+ borderBottomWidth: StyleSheet.hairlineWidth
235
+ },
236
+ bannerText: {
237
+ flex: 1,
238
+ fontSize: 13.5
239
+ },
240
+ bannerCta: {
241
+ paddingVertical: 6,
242
+ paddingHorizontal: 14,
243
+ borderRadius: 999
244
+ },
245
+ bannerCtaText: {
246
+ color: '#FFFFFF',
247
+ fontSize: 13,
248
+ fontWeight: '700'
249
+ },
250
+ bannerDismiss: {
251
+ width: 28,
252
+ height: 28,
253
+ alignItems: 'center',
254
+ justifyContent: 'center'
255
+ },
256
+ bannerDismissText: {
257
+ fontSize: 15,
258
+ fontWeight: '600'
259
+ },
260
+ wallRoot: {
261
+ flex: 1,
262
+ alignItems: 'center',
263
+ justifyContent: 'center',
264
+ padding: 24,
265
+ gap: 16
266
+ },
267
+ logoBadge: {
268
+ width: 88,
269
+ height: 88,
270
+ borderRadius: 44,
271
+ alignItems: 'center',
272
+ justifyContent: 'center',
273
+ marginBottom: 4
274
+ },
275
+ wallTitle: {
276
+ fontSize: 24,
277
+ fontWeight: '800',
278
+ letterSpacing: -0.4,
279
+ textAlign: 'center'
280
+ },
281
+ wallSubtitle: {
282
+ fontSize: 15,
283
+ lineHeight: 21,
284
+ textAlign: 'center',
285
+ maxWidth: 340
286
+ },
287
+ wallCta: {
288
+ marginTop: 8,
289
+ width: '100%',
290
+ maxWidth: 320
291
+ }
292
+ });
293
+ export default RequireOxyAuth;
294
+ //# sourceMappingURL=RequireOxyAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useState","ActivityIndicator","Pressable","StyleSheet","View","useTheme","Text","useOxy","OxySignInButton","OxyLogo","Fragment","_Fragment","jsx","_jsx","jsxs","_jsxs","DEFAULT_TITLE","DEFAULT_SUBTITLE","DEFAULT_BANNER_MESSAGE","DEFAULT_BANNER_ACTION","RequireOxyAuth","children","prompt","loadingFallback","signedOutFallback","title","subtitle","bannerMessage","bannerActionLabel","canUsePrivateApi","isPrivateApiPending","openAccountDialog","SoftGate","pending","message","actionLabel","onSignIn","NeutralLoading","HardWall","theme","dismissed","setDismissed","showBanner","style","styles","softRoot","banner","backgroundColor","colors","card","borderColor","border","variant","size","fillColor","primary","bannerText","color","text","numberOfLines","onPress","bannerCta","accessibilityRole","accessibilityLabel","bannerCtaText","bannerDismiss","hitSlop","bannerDismissText","textSecondary","softBody","wallRoot","background","logoBadge","primarySubtle","wallTitle","wallSubtitle","wallCta","create","flex","flexDirection","alignItems","gap","paddingVertical","paddingHorizontal","borderBottomWidth","hairlineWidth","fontSize","borderRadius","fontWeight","width","height","justifyContent","padding","marginBottom","letterSpacing","textAlign","lineHeight","maxWidth","marginTop"],"sourceRoot":"../../../../src","sources":["ui/components/RequireOxyAuth.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Platform navigation for the third-party "Sign in with Oxy" OAuth flow.
5
+ *
6
+ * Kept out of `OxySignInButton` so the button's routing logic can be unit-tested
7
+ * without driving a real browser navigation (jsdom's `location.assign` is
8
+ * non-configurable and cannot be spied). Both entry points hand a fully-built
9
+ * `auth.oxy.so/authorize` URL to the platform — never FedCM, an SSO bounce, or
10
+ * an Oxy session cookie.
11
+ */
12
+
13
+ import { Linking } from 'react-native';
14
+ import { logger } from '@oxyhq/core';
15
+
16
+ /** Minimal shape of the optional `expo-web-browser` auth-session result. */
17
+
18
+ /** Minimal shape of the optional `expo-web-browser` native module we depend on. */
19
+
20
+ /** Outcome of opening the authorize URL on native. */
21
+
22
+ /**
23
+ * Web: hand the TOP-LEVEL document to the OAuth authorize URL (a full-page
24
+ * redirect, not a popup) so the RP returns to its registered `redirect_uri`.
25
+ * No-op where `location` is unavailable (SSR / non-browser hosts).
26
+ */
27
+ export function redirectToAuthorize(url) {
28
+ globalThis.location?.assign(url);
29
+ }
30
+
31
+ /**
32
+ * Native: open the authorize URL in an in-app auth session via the optional
33
+ * `expo-web-browser` module (`openAuthSessionAsync` returns to `redirectUri`),
34
+ * degrading to `Linking.openURL` when the module is not installed — the same
35
+ * dynamic-import-with-fallback pattern services uses for haptics/netinfo.
36
+ *
37
+ * Returns the deep-link URL the session came back to when it can be observed, so
38
+ * the caller can hand `?code=…&state=…` back to the RP for the token exchange.
39
+ */
40
+ export async function openAuthorizeUrlNative(url, redirectUri) {
41
+ try {
42
+ const mod = await import('expo-web-browser');
43
+ if (mod && typeof mod.openAuthSessionAsync === 'function') {
44
+ const result = await mod.openAuthSessionAsync(url, redirectUri);
45
+ const redirectUrl = result && result.type === 'success' && typeof result.url === 'string' ? result.url : null;
46
+ return {
47
+ redirectUrl
48
+ };
49
+ }
50
+ } catch (error) {
51
+ logger.warn('OxySignInButton: expo-web-browser auth session failed; falling back to Linking.openURL', {
52
+ component: 'oauthNavigation'
53
+ }, error);
54
+ }
55
+
56
+ // Fallback: Linking cannot observe the return URL, so the RP completes the
57
+ // exchange from its own deep-link handler. A rejected openURL (e.g. an
58
+ // unregistered scheme) must not throw out of the sign-in flow.
59
+ try {
60
+ await Linking.openURL(url);
61
+ } catch (error) {
62
+ logger.warn('OxySignInButton: Linking.openURL rejected the authorize URL', {
63
+ component: 'oauthNavigation'
64
+ }, error);
65
+ }
66
+ return {
67
+ redirectUrl: null
68
+ };
69
+ }
70
+ //# sourceMappingURL=oauthNavigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Linking","logger","redirectToAuthorize","url","globalThis","location","assign","openAuthorizeUrlNative","redirectUri","mod","openAuthSessionAsync","result","redirectUrl","type","error","warn","component","openURL"],"sourceRoot":"../../../../src","sources":["ui/components/oauthNavigation.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,OAAO,QAAQ,cAAc;AACtC,SAASC,MAAM,QAAQ,aAAa;;AAEpC;;AAMA;;AAKA;;AAWA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CAACC,GAAW,EAAQ;EAClDC,UAAU,CAA6BC,QAAQ,EAAEC,MAAM,CAACH,GAAG,CAAC;AACjE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,eAAeI,sBAAsBA,CACxCJ,GAAW,EACXK,WAAmB,EACS;EAC5B,IAAI;IACA,MAAMC,GAAG,GAAI,MAAM,MAAM,CAAC,kBAAkB,CAAiC;IAC7E,IAAIA,GAAG,IAAI,OAAOA,GAAG,CAACC,oBAAoB,KAAK,UAAU,EAAE;MACvD,MAAMC,MAAM,GAAG,MAAMF,GAAG,CAACC,oBAAoB,CAACP,GAAG,EAAEK,WAAW,CAAC;MAC/D,MAAMI,WAAW,GACbD,MAAM,IAAIA,MAAM,CAACE,IAAI,KAAK,SAAS,IAAI,OAAOF,MAAM,CAACR,GAAG,KAAK,QAAQ,GAC/DQ,MAAM,CAACR,GAAG,GACV,IAAI;MACd,OAAO;QAAES;MAAY,CAAC;IAC1B;EACJ,CAAC,CAAC,OAAOE,KAAK,EAAE;IACZb,MAAM,CAACc,IAAI,CACP,wFAAwF,EACxF;MAAEC,SAAS,EAAE;IAAkB,CAAC,EAChCF,KACJ,CAAC;EACL;;EAEA;EACA;EACA;EACA,IAAI;IACA,MAAMd,OAAO,CAACiB,OAAO,CAACd,GAAG,CAAC;EAC9B,CAAC,CAAC,OAAOW,KAAK,EAAE;IACZb,MAAM,CAACc,IAAI,CACP,6DAA6D,EAC7D;MAAEC,SAAS,EAAE;IAAkB,CAAC,EAChCF,KACJ,CAAC;EACL;EACA,OAAO;IAAEF,WAAW,EAAE;EAAK,CAAC;AAChC","ignoreList":[]}
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
 
3
3
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
4
+ import { Linking } from 'react-native';
4
5
  import { OxyServices, oxyClient } from '@oxyhq/core';
5
- import { KeyManager, runSessionColdBoot, installAuthRefreshHandler, startTokenRefreshScheduler, logger as loggerUtil } from '@oxyhq/core';
6
+ import { KeyManager, runSessionColdBoot, installAuthRefreshHandler, startTokenRefreshScheduler, createAccountDialogController, logger as loggerUtil } from '@oxyhq/core';
7
+ import { registerAccountDialogControls, notifyAccountDialogVisibility } from "../navigation/accountDialogManager.js";
6
8
  import { useAuthStore } from "../stores/authStore.js";
7
9
  import { useShallow } from 'zustand/react/shallow';
8
10
  import { useLanguageManagement } from "../hooks/useLanguageManagement.js";
@@ -113,6 +115,7 @@ export const OxyProvider = ({
113
115
  authRedirectUri,
114
116
  storageKeyPrefix = 'oxy_session',
115
117
  clientId: clientIdProp,
118
+ coldBoot = true,
116
119
  onAuthStateChange,
117
120
  onError
118
121
  }) => {
@@ -168,6 +171,7 @@ export const OxyProvider = ({
168
171
  userRef.current = user;
169
172
  isAuthenticatedRef.current = isAuthenticated;
170
173
  const [initialized, setInitialized] = useState(false);
174
+ const [accountDialogOpen, setAccountDialogOpen] = useState(false);
171
175
  const setAuthState = useAuthStore.setState;
172
176
 
173
177
  // Keep the shared `oxyClient` singleton's token store in lockstep with the
@@ -308,10 +312,19 @@ export const OxyProvider = ({
308
312
  const markAuthResolvedRef = useRef(markAuthResolved);
309
313
  markAuthResolvedRef.current = markAuthResolved;
310
314
 
315
+ // Re-boot indirection: the SessionClient is built in the ref initializer below
316
+ // (before `runColdBoot` is defined), but its `onSessionAppeared` must re-run the
317
+ // cold boot to self-acquire when a sibling signs in on this device. A ref bridges
318
+ // the ordering; it is assigned right after `runColdBoot` is declared.
319
+ const runColdBootRef = useRef(null);
320
+
311
321
  // Server-authoritative device session client. Built ONCE per `oxyServices`
312
322
  // instance. `onUnauthenticated` (a device signout-all pushed over the socket,
313
323
  // or bootstrapped as zero-account) clears the persisted store + local state so
314
324
  // a reload does not try to restore a session the device no longer has.
325
+ // `signedOutSocketAuth` + `onSessionAppeared` power the signed-out sync channel:
326
+ // an idle tab joins its `device:<id>` room (web via the `oxy_device` cookie,
327
+ // native via the shared device token) and self-acquires on a sibling sign-in.
315
328
  const sessionClientPairRef = useRef(null);
316
329
  if (!sessionClientPairRef.current) {
317
330
  sessionClientPairRef.current = createSessionClient(oxyServices, authStore, () => {
@@ -319,6 +332,21 @@ export const OxyProvider = ({
319
332
  void clearSessionStateRef.current().catch(clearError => {
320
333
  logger('Failed to clear local state on remote sign-out', clearError);
321
334
  });
335
+ }, {
336
+ signedOutSocketAuth: async () => {
337
+ // Web (`*.oxy.so`): the first-party `oxy_device` cookie rides the
338
+ // same-site handshake automatically — just connect.
339
+ if (isWebBrowser()) return true;
340
+ // Native (no cookie jar): present the shared device token if we have one.
341
+ try {
342
+ return (await authStore.loadDeviceToken()) ?? false;
343
+ } catch {
344
+ return false;
345
+ }
346
+ },
347
+ onSessionAppeared: () => {
348
+ void runColdBootRef.current?.();
349
+ }
322
350
  });
323
351
  }
324
352
  const {
@@ -598,6 +626,58 @@ export const OxyProvider = ({
598
626
  });
599
627
  }, [commitSession]);
600
628
 
629
+ // ── Unified account dialog ─────────────────────────────────────────────────
630
+ // The single account-chooser + sign-in surface. Built ONCE per provider mount
631
+ // and bound to the live `oxyServices` + `sessionClient` + this provider's
632
+ // `handleWebSession` commit funnel. `handleWebSession` is threaded through a ref
633
+ // so the controller keeps a STABLE `commitSession` (rebuilding the controller
634
+ // on every commit-identity change would drop its subscription + state).
635
+ const handleWebSessionRef = useRef(handleWebSession);
636
+ handleWebSessionRef.current = handleWebSession;
637
+ const accountDialogControllerRef = useRef(null);
638
+ if (!accountDialogControllerRef.current) {
639
+ accountDialogControllerRef.current = createAccountDialogController({
640
+ oxyServices,
641
+ sessionClient,
642
+ clientId,
643
+ locale: currentLanguage,
644
+ commitSession: session => handleWebSessionRef.current(session),
645
+ onSignedIn: () => setAccountDialogOpen(false),
646
+ openUrl: url => {
647
+ void Linking.openURL(url);
648
+ }
649
+ });
650
+ }
651
+ const accountDialogController = accountDialogControllerRef.current;
652
+ const openAccountDialog = useCallback(view => {
653
+ accountDialogControllerRef.current?.setView(view ?? 'accounts');
654
+ setAccountDialogOpen(true);
655
+ }, []);
656
+ const closeAccountDialog = useCallback(() => {
657
+ accountDialogControllerRef.current?.cancelSignIn();
658
+ setAccountDialogOpen(false);
659
+ }, []);
660
+
661
+ // Start driving the dialog on mount; tear it down on unmount.
662
+ useEffect(() => {
663
+ const controller = accountDialogControllerRef.current;
664
+ controller?.start();
665
+ return () => controller?.destroy();
666
+ }, []);
667
+
668
+ // Expose the live open/close controls to the imperative manager so
669
+ // `showSignInModal()` (and any app-level imperative "sign in" handler) works.
670
+ useEffect(() => registerAccountDialogControls({
671
+ open: openAccountDialog,
672
+ close: closeAccountDialog
673
+ }), [openAccountDialog, closeAccountDialog]);
674
+
675
+ // Broadcast visibility so `OxySignInButton`'s "Signing in…" affordance stays
676
+ // accurate regardless of what opened or dismissed the dialog.
677
+ useEffect(() => {
678
+ notifyAccountDialogVisibility(accountDialogOpen);
679
+ }, [accountDialogOpen]);
680
+
601
681
  // Keyless password sign-in: username/email + password.
602
682
  const signInWithPassword = useCallback(async (identifier, password, opts) => {
603
683
  const deviceToken = (await authStore.loadDeviceToken()) ?? undefined;
@@ -692,6 +772,17 @@ export const OxyProvider = ({
692
772
  },
693
773
  onSignedOut: () => {
694
774
  markAuthResolvedRef.current();
775
+ // Open the signed-out realtime channel so this idle tab joins its
776
+ // `device:<id>` room (web `oxy_device` cookie / native device token)
777
+ // and self-acquires when a sibling signs in. Idempotent, best-effort.
778
+ void sessionClient.start().catch(startError => {
779
+ if (__DEV__) {
780
+ loggerUtil.debug('signed-out socket start failed (non-fatal)', {
781
+ component: 'OxyContext',
782
+ method: 'runColdBoot'
783
+ }, startError);
784
+ }
785
+ });
695
786
  },
696
787
  onStepError: (id, error) => {
697
788
  if (__DEV__) {
@@ -713,9 +804,25 @@ export const OxyProvider = ({
713
804
  // Backstop: resolve on every exit path so the gate can never hang.
714
805
  markAuthResolvedRef.current();
715
806
  }
716
- }, [oxyServices, authStore]);
807
+ }, [oxyServices, authStore, sessionClient]);
808
+ // Bridge for `onSessionAppeared` (SessionClient) → re-run the cold boot to
809
+ // self-acquire when a sibling signs in on this device while this tab is idle.
810
+ runColdBootRef.current = runColdBoot;
717
811
  useEffect(() => {
718
- if (!storage || initialized) {
812
+ if (initialized) {
813
+ return;
814
+ }
815
+ // IdP mode (`coldBoot={false}`): this provider is NOT the ecosystem session
816
+ // authority, so it never runs the device-first restore and never opens the
817
+ // signed-out device-state socket (`runColdBoot` → `onSignedOut` is the sole
818
+ // place that socket starts). Resolve auth immediately as signed out so there
819
+ // is no boot spinner; a deliberate sign-in still commits a normal session.
820
+ if (!coldBoot) {
821
+ setInitialized(true);
822
+ markAuthResolved();
823
+ return;
824
+ }
825
+ if (!storage) {
719
826
  return;
720
827
  }
721
828
  setInitialized(true);
@@ -724,7 +831,7 @@ export const OxyProvider = ({
724
831
  logger('Cold boot failed', error);
725
832
  }
726
833
  });
727
- }, [runColdBoot, storage, initialized, logger]);
834
+ }, [coldBoot, runColdBoot, storage, initialized, logger, markAuthResolved]);
728
835
 
729
836
  // Exposed `refreshSessions`: re-bootstrap the server-authoritative device
730
837
  // state and reproject — the manual counterpart to the realtime socket.
@@ -790,6 +897,9 @@ export const OxyProvider = ({
790
897
  useEffect(() => {
791
898
  if (isAuthenticated && initialized && tokenReady) {
792
899
  refreshAccounts();
900
+ // Reload the dialog's own account graph too, so a session restored OUTSIDE
901
+ // the dialog (cold boot / password sign-in) surfaces its graph accounts.
902
+ void accountDialogControllerRef.current?.refresh();
793
903
  }
794
904
  }, [isAuthenticated, initialized, tokenReady, refreshAccounts]);
795
905
  const runPostAccountSwitchSideEffects = useCallback(async () => {
@@ -874,11 +984,15 @@ export const OxyProvider = ({
874
984
  useFollow: useFollowHook,
875
985
  showBottomSheet: showBottomSheetForContext,
876
986
  openAvatarPicker,
987
+ accountDialogController,
988
+ isAccountDialogOpen: accountDialogOpen,
989
+ openAccountDialog,
990
+ closeAccountDialog,
877
991
  accounts,
878
992
  switchToAccount,
879
993
  refreshAccounts,
880
994
  createAccount: createAccountFn
881
- }), [user, sessions, activeSessionId, isAuthenticated, isLoading, tokenReady, hasAccessToken, canUsePrivateApi, isPrivateApiPending, authResolved, storage, error, currentLanguage, currentLanguageMetadata, currentLanguageName, currentNativeLanguageName, hasIdentity, getPublicKey, signIn, signInWithPassword, completeTwoFactorSignIn, handleWebSession, logout, logoutAll, switchSessionForContext, refreshSessionsForContext, setLanguage, getDeviceSessions, logoutAllDeviceSessions, updateDeviceName, clearSessionState, clearAllAccountData, storageKeyPrefix, clientId, oxyServices, useFollowHook, showBottomSheetForContext, openAvatarPicker, accounts, switchToAccount, refreshAccounts, createAccountFn]);
995
+ }), [user, sessions, activeSessionId, isAuthenticated, isLoading, tokenReady, hasAccessToken, canUsePrivateApi, isPrivateApiPending, authResolved, storage, error, currentLanguage, currentLanguageMetadata, currentLanguageName, currentNativeLanguageName, hasIdentity, getPublicKey, signIn, signInWithPassword, completeTwoFactorSignIn, handleWebSession, logout, logoutAll, switchSessionForContext, refreshSessionsForContext, setLanguage, getDeviceSessions, logoutAllDeviceSessions, updateDeviceName, clearSessionState, clearAllAccountData, storageKeyPrefix, clientId, oxyServices, useFollowHook, showBottomSheetForContext, openAvatarPicker, accountDialogController, accountDialogOpen, openAccountDialog, closeAccountDialog, accounts, switchToAccount, refreshAccounts, createAccountFn]);
882
996
  return /*#__PURE__*/_jsx(OxyContext.Provider, {
883
997
  value: contextValue,
884
998
  children: children
@@ -933,6 +1047,10 @@ const LOADING_STATE = {
933
1047
  clientId: null,
934
1048
  oxyServices: LOADING_STATE_OXY_SERVICES,
935
1049
  openAvatarPicker: () => {},
1050
+ accountDialogController: null,
1051
+ isAccountDialogOpen: false,
1052
+ openAccountDialog: () => {},
1053
+ closeAccountDialog: () => {},
936
1054
  accounts: [],
937
1055
  switchToAccount: () => rejectMissingProvider(),
938
1056
  refreshAccounts: () => rejectMissingProvider(),