@oxyhq/services 14.1.0 → 16.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 (292) hide show
  1. package/lib/commonjs/index.js +4 -21
  2. package/lib/commonjs/index.js.map +1 -1
  3. package/lib/commonjs/ui/components/SignInAccountChooser.js +189 -0
  4. package/lib/commonjs/ui/components/SignInAccountChooser.js.map +1 -0
  5. package/lib/commonjs/ui/components/SignInModal.js +350 -131
  6. package/lib/commonjs/ui/components/SignInModal.js.map +1 -1
  7. package/lib/commonjs/ui/context/OxyContext.js +340 -1547
  8. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  9. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +61 -64
  10. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  11. package/lib/commonjs/ui/hooks/mutations/mutationKeys.js +1 -1
  12. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js +9 -9
  13. package/lib/commonjs/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  14. package/lib/commonjs/ui/hooks/queries/queryKeys.js +1 -1
  15. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +7 -8
  16. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
  17. package/lib/commonjs/ui/hooks/useAuth.js +14 -33
  18. package/lib/commonjs/ui/hooks/useAuth.js.map +1 -1
  19. package/lib/commonjs/ui/hooks/usePasswordSignIn.js +170 -0
  20. package/lib/commonjs/ui/hooks/usePasswordSignIn.js.map +1 -0
  21. package/lib/commonjs/ui/hooks/useProfileEditing.js +2 -5
  22. package/lib/commonjs/ui/hooks/useProfileEditing.js.map +1 -1
  23. package/lib/commonjs/ui/hooks/useSessionManagement.js +2 -2
  24. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  25. package/lib/commonjs/ui/navigation/routes.js +1 -0
  26. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  27. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js +17 -18
  28. package/lib/commonjs/ui/screens/ConnectedAppsScreen.js.map +1 -1
  29. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +93 -68
  30. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  31. package/lib/commonjs/ui/screens/EditProfileScreen.js +187 -0
  32. package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -0
  33. package/lib/commonjs/ui/screens/ManageAccountScreen.js +3 -7
  34. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  35. package/lib/commonjs/ui/screens/OxyAuthScreen.js +231 -95
  36. package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/ProfileScreen.js +15 -2
  38. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/linkFormat.js +38 -0
  40. package/lib/commonjs/ui/screens/linkFormat.js.map +1 -0
  41. package/lib/commonjs/ui/session/authStore.js +146 -0
  42. package/lib/commonjs/ui/session/authStore.js.map +1 -0
  43. package/lib/commonjs/ui/session/createSessionClient.js +23 -17
  44. package/lib/commonjs/ui/session/createSessionClient.js.map +1 -1
  45. package/lib/commonjs/ui/session/index.js +13 -7
  46. package/lib/commonjs/ui/session/index.js.map +1 -1
  47. package/lib/commonjs/ui/session/tokenTransport.js +19 -31
  48. package/lib/commonjs/ui/session/tokenTransport.js.map +1 -1
  49. package/lib/commonjs/ui/utils/isWebBrowser.js +13 -0
  50. package/lib/commonjs/ui/utils/isWebBrowser.js.map +1 -0
  51. package/lib/commonjs/utils/deviceFlowSignIn.js +13 -16
  52. package/lib/commonjs/utils/deviceFlowSignIn.js.map +1 -1
  53. package/lib/module/index.js +2 -7
  54. package/lib/module/index.js.map +1 -1
  55. package/lib/module/ui/components/SignInAccountChooser.js +183 -0
  56. package/lib/module/ui/components/SignInAccountChooser.js.map +1 -0
  57. package/lib/module/ui/components/SignInModal.js +352 -134
  58. package/lib/module/ui/components/SignInModal.js.map +1 -1
  59. package/lib/module/ui/context/OxyContext.js +342 -1551
  60. package/lib/module/ui/context/OxyContext.js.map +1 -1
  61. package/lib/module/ui/context/hooks/useAuthOperations.js +60 -63
  62. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  63. package/lib/module/ui/hooks/mutations/mutationKeys.js +1 -1
  64. package/lib/module/ui/hooks/mutations/useAccountMutations.js +7 -7
  65. package/lib/module/ui/hooks/mutations/useAccountMutations.js.map +1 -1
  66. package/lib/module/ui/hooks/queries/queryKeys.js +1 -1
  67. package/lib/module/ui/hooks/queries/useAccountQueries.js +5 -6
  68. package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
  69. package/lib/module/ui/hooks/useAuth.js +14 -33
  70. package/lib/module/ui/hooks/useAuth.js.map +1 -1
  71. package/lib/module/ui/hooks/usePasswordSignIn.js +165 -0
  72. package/lib/module/ui/hooks/usePasswordSignIn.js.map +1 -0
  73. package/lib/module/ui/hooks/useProfileEditing.js +2 -5
  74. package/lib/module/ui/hooks/useProfileEditing.js.map +1 -1
  75. package/lib/module/ui/hooks/useSessionManagement.js +1 -1
  76. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  77. package/lib/module/ui/navigation/routes.js +1 -0
  78. package/lib/module/ui/navigation/routes.js.map +1 -1
  79. package/lib/module/ui/screens/ConnectedAppsScreen.js +19 -20
  80. package/lib/module/ui/screens/ConnectedAppsScreen.js.map +1 -1
  81. package/lib/module/ui/screens/EditProfileFieldScreen.js +91 -66
  82. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  83. package/lib/module/ui/screens/EditProfileScreen.js +182 -0
  84. package/lib/module/ui/screens/EditProfileScreen.js.map +1 -0
  85. package/lib/module/ui/screens/ManageAccountScreen.js +3 -7
  86. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  87. package/lib/module/ui/screens/OxyAuthScreen.js +233 -97
  88. package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
  89. package/lib/module/ui/screens/ProfileScreen.js +15 -2
  90. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  91. package/lib/module/ui/screens/linkFormat.js +31 -0
  92. package/lib/module/ui/screens/linkFormat.js.map +1 -0
  93. package/lib/module/ui/session/authStore.js +143 -0
  94. package/lib/module/ui/session/authStore.js.map +1 -0
  95. package/lib/module/ui/session/createSessionClient.js +22 -16
  96. package/lib/module/ui/session/createSessionClient.js.map +1 -1
  97. package/lib/module/ui/session/index.js +9 -9
  98. package/lib/module/ui/session/index.js.map +1 -1
  99. package/lib/module/ui/session/tokenTransport.js +20 -33
  100. package/lib/module/ui/session/tokenTransport.js.map +1 -1
  101. package/lib/module/ui/utils/isWebBrowser.js +11 -0
  102. package/lib/module/ui/utils/isWebBrowser.js.map +1 -0
  103. package/lib/module/utils/deviceFlowSignIn.js +14 -17
  104. package/lib/module/utils/deviceFlowSignIn.js.map +1 -1
  105. package/lib/typescript/commonjs/index.d.ts +2 -3
  106. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  107. package/lib/typescript/commonjs/ui/components/SignInAccountChooser.d.ts +29 -0
  108. package/lib/typescript/commonjs/ui/components/SignInAccountChooser.d.ts.map +1 -0
  109. package/lib/typescript/commonjs/ui/components/SignInModal.d.ts +15 -10
  110. package/lib/typescript/commonjs/ui/components/SignInModal.d.ts.map +1 -1
  111. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +36 -42
  112. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  113. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +18 -23
  114. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  115. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +4 -6
  116. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  117. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts +6 -7
  118. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  119. package/lib/typescript/commonjs/ui/hooks/useAuth.d.ts.map +1 -1
  120. package/lib/typescript/commonjs/ui/hooks/usePasswordSignIn.d.ts +31 -0
  121. package/lib/typescript/commonjs/ui/hooks/usePasswordSignIn.d.ts.map +1 -0
  122. package/lib/typescript/commonjs/ui/hooks/useProfileEditing.d.ts +0 -1
  123. package/lib/typescript/commonjs/ui/hooks/useProfileEditing.d.ts.map +1 -1
  124. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
  125. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  126. package/lib/typescript/commonjs/ui/screens/ConnectedAppsScreen.d.ts.map +1 -1
  127. package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  128. package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts +14 -0
  129. package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -0
  130. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts +1 -1
  131. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  132. package/lib/typescript/commonjs/ui/screens/OxyAuthScreen.d.ts +13 -12
  133. package/lib/typescript/commonjs/ui/screens/OxyAuthScreen.d.ts.map +1 -1
  134. package/lib/typescript/commonjs/ui/screens/ProfileScreen.d.ts.map +1 -1
  135. package/lib/typescript/commonjs/ui/screens/linkFormat.d.ts +23 -0
  136. package/lib/typescript/commonjs/ui/screens/linkFormat.d.ts.map +1 -0
  137. package/lib/typescript/commonjs/ui/session/authStore.d.ts +33 -0
  138. package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -0
  139. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts +19 -15
  140. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts.map +1 -1
  141. package/lib/typescript/commonjs/ui/session/index.d.ts +9 -9
  142. package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
  143. package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts +13 -19
  144. package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts.map +1 -1
  145. package/lib/typescript/commonjs/ui/utils/isWebBrowser.d.ts +9 -0
  146. package/lib/typescript/commonjs/ui/utils/isWebBrowser.d.ts.map +1 -0
  147. package/lib/typescript/commonjs/ui/utils/storageHelpers.d.ts +7 -7
  148. package/lib/typescript/commonjs/utils/deviceFlowSignIn.d.ts +15 -13
  149. package/lib/typescript/commonjs/utils/deviceFlowSignIn.d.ts.map +1 -1
  150. package/lib/typescript/module/index.d.ts +2 -3
  151. package/lib/typescript/module/index.d.ts.map +1 -1
  152. package/lib/typescript/module/ui/components/SignInAccountChooser.d.ts +29 -0
  153. package/lib/typescript/module/ui/components/SignInAccountChooser.d.ts.map +1 -0
  154. package/lib/typescript/module/ui/components/SignInModal.d.ts +15 -10
  155. package/lib/typescript/module/ui/components/SignInModal.d.ts.map +1 -1
  156. package/lib/typescript/module/ui/context/OxyContext.d.ts +36 -42
  157. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  158. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +18 -23
  159. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  160. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +4 -6
  161. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  162. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts +6 -7
  163. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  164. package/lib/typescript/module/ui/hooks/useAuth.d.ts.map +1 -1
  165. package/lib/typescript/module/ui/hooks/usePasswordSignIn.d.ts +31 -0
  166. package/lib/typescript/module/ui/hooks/usePasswordSignIn.d.ts.map +1 -0
  167. package/lib/typescript/module/ui/hooks/useProfileEditing.d.ts +0 -1
  168. package/lib/typescript/module/ui/hooks/useProfileEditing.d.ts.map +1 -1
  169. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  170. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  171. package/lib/typescript/module/ui/screens/ConnectedAppsScreen.d.ts.map +1 -1
  172. package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  173. package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts +14 -0
  174. package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -0
  175. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts +1 -1
  176. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  177. package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts +13 -12
  178. package/lib/typescript/module/ui/screens/OxyAuthScreen.d.ts.map +1 -1
  179. package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
  180. package/lib/typescript/module/ui/screens/linkFormat.d.ts +23 -0
  181. package/lib/typescript/module/ui/screens/linkFormat.d.ts.map +1 -0
  182. package/lib/typescript/module/ui/session/authStore.d.ts +33 -0
  183. package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -0
  184. package/lib/typescript/module/ui/session/createSessionClient.d.ts +19 -15
  185. package/lib/typescript/module/ui/session/createSessionClient.d.ts.map +1 -1
  186. package/lib/typescript/module/ui/session/index.d.ts +9 -9
  187. package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
  188. package/lib/typescript/module/ui/session/tokenTransport.d.ts +13 -19
  189. package/lib/typescript/module/ui/session/tokenTransport.d.ts.map +1 -1
  190. package/lib/typescript/module/ui/utils/isWebBrowser.d.ts +9 -0
  191. package/lib/typescript/module/ui/utils/isWebBrowser.d.ts.map +1 -0
  192. package/lib/typescript/module/ui/utils/storageHelpers.d.ts +7 -7
  193. package/lib/typescript/module/utils/deviceFlowSignIn.d.ts +15 -13
  194. package/lib/typescript/module/utils/deviceFlowSignIn.d.ts.map +1 -1
  195. package/package.json +4 -4
  196. package/src/index.ts +2 -6
  197. package/src/ui/components/SignInAccountChooser.tsx +162 -0
  198. package/src/ui/components/SignInModal.tsx +309 -139
  199. package/src/ui/context/OxyContext.tsx +532 -1785
  200. package/src/ui/context/hooks/useAuthOperations.ts +65 -76
  201. package/src/ui/hooks/mutations/mutationKeys.ts +1 -1
  202. package/src/ui/hooks/mutations/useAccountMutations.ts +7 -7
  203. package/src/ui/hooks/queries/queryKeys.ts +1 -1
  204. package/src/ui/hooks/queries/useAccountQueries.ts +8 -9
  205. package/src/ui/hooks/useAuth.ts +14 -35
  206. package/src/ui/hooks/usePasswordSignIn.ts +207 -0
  207. package/src/ui/hooks/useProfileEditing.ts +2 -8
  208. package/src/ui/hooks/useSessionManagement.ts +1 -1
  209. package/src/ui/navigation/routes.ts +3 -1
  210. package/src/ui/screens/ConnectedAppsScreen.tsx +23 -24
  211. package/src/ui/screens/EditProfileFieldScreen.tsx +102 -66
  212. package/src/ui/screens/EditProfileScreen.tsx +155 -0
  213. package/src/ui/screens/ManageAccountScreen.tsx +3 -7
  214. package/src/ui/screens/OxyAuthScreen.tsx +259 -112
  215. package/src/ui/screens/ProfileScreen.tsx +15 -2
  216. package/src/ui/screens/__tests__/linkFormat.test.ts +73 -0
  217. package/src/ui/screens/linkFormat.ts +37 -0
  218. package/src/ui/session/__tests__/createSessionClient.test.ts +22 -7
  219. package/src/ui/session/__tests__/tokenTransport.test.ts +37 -49
  220. package/src/ui/session/authStore.ts +164 -0
  221. package/src/ui/session/createSessionClient.ts +30 -17
  222. package/src/ui/session/index.ts +10 -9
  223. package/src/ui/session/tokenTransport.ts +26 -36
  224. package/src/ui/utils/isWebBrowser.ts +8 -0
  225. package/src/ui/utils/storageHelpers.ts +7 -7
  226. package/src/utils/__tests__/deviceFlowSignIn.test.ts +50 -131
  227. package/src/utils/deviceFlowSignIn.ts +19 -26
  228. package/lib/commonjs/ui/context/inSessionTokenRefresh.js +0 -243
  229. package/lib/commonjs/ui/context/inSessionTokenRefresh.js.map +0 -1
  230. package/lib/commonjs/ui/context/silentSessionRestore.js +0 -56
  231. package/lib/commonjs/ui/context/silentSessionRestore.js.map +0 -1
  232. package/lib/commonjs/ui/hooks/useWebSSO.js +0 -28
  233. package/lib/commonjs/ui/hooks/useWebSSO.js.map +0 -1
  234. package/lib/commonjs/ui/session/projectSessionState.js +0 -86
  235. package/lib/commonjs/ui/session/projectSessionState.js.map +0 -1
  236. package/lib/commonjs/ui/session/sessionClientHost.js +0 -30
  237. package/lib/commonjs/ui/session/sessionClientHost.js.map +0 -1
  238. package/lib/commonjs/ui/utils/activeAuthuser.js +0 -142
  239. package/lib/commonjs/ui/utils/activeAuthuser.js.map +0 -1
  240. package/lib/commonjs/utils/crossApex.js +0 -74
  241. package/lib/commonjs/utils/crossApex.js.map +0 -1
  242. package/lib/module/ui/context/inSessionTokenRefresh.js +0 -238
  243. package/lib/module/ui/context/inSessionTokenRefresh.js.map +0 -1
  244. package/lib/module/ui/context/silentSessionRestore.js +0 -53
  245. package/lib/module/ui/context/silentSessionRestore.js.map +0 -1
  246. package/lib/module/ui/hooks/useWebSSO.js +0 -24
  247. package/lib/module/ui/hooks/useWebSSO.js.map +0 -1
  248. package/lib/module/ui/session/projectSessionState.js +0 -79
  249. package/lib/module/ui/session/projectSessionState.js.map +0 -1
  250. package/lib/module/ui/session/sessionClientHost.js +0 -26
  251. package/lib/module/ui/session/sessionClientHost.js.map +0 -1
  252. package/lib/module/ui/utils/activeAuthuser.js +0 -134
  253. package/lib/module/ui/utils/activeAuthuser.js.map +0 -1
  254. package/lib/module/utils/crossApex.js +0 -69
  255. package/lib/module/utils/crossApex.js.map +0 -1
  256. package/lib/typescript/commonjs/ui/context/inSessionTokenRefresh.d.ts +0 -106
  257. package/lib/typescript/commonjs/ui/context/inSessionTokenRefresh.d.ts.map +0 -1
  258. package/lib/typescript/commonjs/ui/context/silentSessionRestore.d.ts +0 -36
  259. package/lib/typescript/commonjs/ui/context/silentSessionRestore.d.ts.map +0 -1
  260. package/lib/typescript/commonjs/ui/hooks/useWebSSO.d.ts +0 -19
  261. package/lib/typescript/commonjs/ui/hooks/useWebSSO.d.ts.map +0 -1
  262. package/lib/typescript/commonjs/ui/session/projectSessionState.d.ts +0 -45
  263. package/lib/typescript/commonjs/ui/session/projectSessionState.d.ts.map +0 -1
  264. package/lib/typescript/commonjs/ui/session/sessionClientHost.d.ts +0 -14
  265. package/lib/typescript/commonjs/ui/session/sessionClientHost.d.ts.map +0 -1
  266. package/lib/typescript/commonjs/ui/utils/activeAuthuser.d.ts +0 -67
  267. package/lib/typescript/commonjs/ui/utils/activeAuthuser.d.ts.map +0 -1
  268. package/lib/typescript/commonjs/utils/crossApex.d.ts +0 -55
  269. package/lib/typescript/commonjs/utils/crossApex.d.ts.map +0 -1
  270. package/lib/typescript/module/ui/context/inSessionTokenRefresh.d.ts +0 -106
  271. package/lib/typescript/module/ui/context/inSessionTokenRefresh.d.ts.map +0 -1
  272. package/lib/typescript/module/ui/context/silentSessionRestore.d.ts +0 -36
  273. package/lib/typescript/module/ui/context/silentSessionRestore.d.ts.map +0 -1
  274. package/lib/typescript/module/ui/hooks/useWebSSO.d.ts +0 -19
  275. package/lib/typescript/module/ui/hooks/useWebSSO.d.ts.map +0 -1
  276. package/lib/typescript/module/ui/session/projectSessionState.d.ts +0 -45
  277. package/lib/typescript/module/ui/session/projectSessionState.d.ts.map +0 -1
  278. package/lib/typescript/module/ui/session/sessionClientHost.d.ts +0 -14
  279. package/lib/typescript/module/ui/session/sessionClientHost.d.ts.map +0 -1
  280. package/lib/typescript/module/ui/utils/activeAuthuser.d.ts +0 -67
  281. package/lib/typescript/module/ui/utils/activeAuthuser.d.ts.map +0 -1
  282. package/lib/typescript/module/utils/crossApex.d.ts +0 -55
  283. package/lib/typescript/module/utils/crossApex.d.ts.map +0 -1
  284. package/src/ui/context/inSessionTokenRefresh.ts +0 -264
  285. package/src/ui/context/silentSessionRestore.ts +0 -53
  286. package/src/ui/hooks/useWebSSO.ts +0 -23
  287. package/src/ui/session/__tests__/projectSessionState.test.ts +0 -114
  288. package/src/ui/session/__tests__/sessionClientHost.test.ts +0 -43
  289. package/src/ui/session/projectSessionState.ts +0 -85
  290. package/src/ui/session/sessionClientHost.ts +0 -27
  291. package/src/ui/utils/activeAuthuser.ts +0 -142
  292. package/src/utils/crossApex.ts +0 -75
@@ -1,33 +1,43 @@
1
1
  "use strict";
2
2
 
3
3
  /**
4
- * SignInModal - Web-first centered sign-in modal (Continue with Oxy)
4
+ * SignInModal web-first centered sign-in modal.
5
5
  *
6
- * A semi-transparent full-screen modal whose primary action is the one-tap
7
- * "Continue with Oxy" approval flow. The QR code is demoted to a collapsed
8
- * "Sign in on another device" disclosure (you can't scan your own screen).
6
+ * Two phases, Google-style:
7
+ * 1. Account chooser (FRONT screen, shown when the device/user already has
8
+ * accounts): pick an account to continue as one tap switches through the
9
+ * SAME `switchToAccount` path the account switcher uses — or "Use another
10
+ * account" to reveal the sign-in options.
11
+ * 2. Sign-in options: the first-party password flow (identifier → password →
12
+ * optional 2FA, `usePasswordSignIn`) as the PRIMARY action, with the
13
+ * cross-app device flow (same-device deep-link + "sign in on another device"
14
+ * QR) as a SECONDARY option below an "or" divider.
9
15
  *
10
- * ALL of the auth-session machinery (session-token creation, QR data, socket +
11
- * polling, waiting/error/retry state, the open-auth handler, deep-link return,
12
- * and cleanup) lives in the shared `useOxyAuthSession` hook, which the native
13
- * `OxyAuthScreen` also consumes neither container re-implements the transport.
14
- *
15
- * Animates with a fade + scale effect.
16
+ * When there are no accounts the modal opens straight on the sign-in options.
17
+ * The device-flow machinery lives in the shared `useOxyAuthSession` hook (the
18
+ * native `OxyAuthScreen` consumes it too neither container re-implements the
19
+ * transport). Animates with a fade + scale; per-phase content cross-fades and
20
+ * respects reduced motion.
16
21
  */
17
22
 
18
23
  import { useState, useEffect, useCallback } from 'react';
19
- import { View, Text, TouchableOpacity, StyleSheet, Modal } from 'react-native';
20
- import Animated, { useSharedValue, useAnimatedStyle, withTiming } from 'react-native-reanimated';
24
+ import { View, Text, TextInput, TouchableOpacity, StyleSheet, Modal, Linking, AccessibilityInfo } from 'react-native';
25
+ import Animated, { useSharedValue, useAnimatedStyle, withTiming, FadeIn } from 'react-native-reanimated';
21
26
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
22
27
  import { useTheme } from '@oxyhq/bloom/theme';
23
28
  import { Button } from '@oxyhq/bloom/button';
24
29
  import { Loading } from '@oxyhq/bloom/loading';
25
- import { Linking } from 'react-native';
30
+ import { toast } from '@oxyhq/bloom';
31
+ import { Ionicons } from '@expo/vector-icons';
32
+ import { isDev, logger as loggerUtil } from '@oxyhq/core';
26
33
  import { useOxy } from "../context/OxyContext.js";
27
34
  import OxyLogo from "./OxyLogo.js";
28
35
  import AnotherDeviceQR from "./AnotherDeviceQR.js";
36
+ import SignInAccountChooser from "./SignInAccountChooser.js";
37
+ import { useSwitchableAccounts } from "../hooks/useSwitchableAccounts.js";
38
+ import { useI18n } from "../hooks/useI18n.js";
29
39
  import { useOxyAuthSession, OXY_ACCOUNTS_WEB_URL } from "../hooks/useOxyAuthSession.js";
30
- import { isCrossApexWeb } from "../../utils/crossApex.js";
40
+ import { usePasswordSignIn } from "../hooks/usePasswordSignIn.js";
31
41
 
32
42
  // Store for modal visibility with subscription support
33
43
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
@@ -55,11 +65,6 @@ const SignInModal = () => {
55
65
  const [visible, setVisible] = useState(false);
56
66
  const insets = useSafeAreaInsets();
57
67
  const theme = useTheme();
58
- const {
59
- oxyServices,
60
- handleWebSession,
61
- clientId
62
- } = useOxy();
63
68
 
64
69
  // Register the imperative visibility callback.
65
70
  useEffect(() => {
@@ -70,56 +75,71 @@ const SignInModal = () => {
70
75
  }, []);
71
76
  if (!visible) return null;
72
77
 
73
- // The hook owns the whole auth-session lifecycle. Mounting it only while the
74
- // modal is visible matches the previous behavior (session created on open,
75
- // cleaned up on close) — the inner component is unmounted when `visible`
76
- // flips false, which runs the hook's unmount cleanup.
78
+ // Mounting the content only while visible preserves the session-created-on-open
79
+ // / cleaned-up-on-close behaviour and resets the phase state on every reopen.
77
80
  return /*#__PURE__*/_jsx(SignInModalContent, {
78
81
  theme: theme,
79
- insets: insets,
80
- oxyServices: oxyServices,
81
- handleWebSession: handleWebSession,
82
- clientId: clientId
82
+ insets: insets
83
83
  });
84
84
  };
85
85
  const SignInModalContent = ({
86
86
  theme,
87
- insets,
88
- oxyServices,
89
- handleWebSession,
90
- clientId
87
+ insets
91
88
  }) => {
89
+ const {
90
+ oxyServices,
91
+ handleWebSession,
92
+ clientId,
93
+ switchToAccount
94
+ } = useOxy();
95
+ const {
96
+ t
97
+ } = useI18n();
98
+ const {
99
+ accounts
100
+ } = useSwitchableAccounts();
101
+
102
+ // Phase: the chooser is the front screen whenever accounts exist AND the user
103
+ // has not tapped "Use another account" this session.
104
+ const [useAnother, setUseAnother] = useState(false);
105
+ const [switchingId, setSwitchingId] = useState(null);
106
+ const showChooser = !useAnother && accounts.length > 0;
92
107
  const {
93
108
  qrData,
94
109
  qrPayload,
95
110
  isLoading,
96
111
  error,
97
112
  isWaiting,
98
- openAuthApproval,
99
113
  openSameDeviceApproval,
100
114
  retry
101
115
  } = useOxyAuthSession(oxyServices, clientId, handleWebSession, {
102
116
  onSignedIn: hideSignInModal
103
117
  });
104
118
 
105
- // On a cross-apex web RP, only the "Continue with Oxy" IdP popup establishes
106
- // a durable `fedcm_session`. The Commons-app handoffs (same-device deep-link
107
- // + cross-device QR) approve OUTSIDE the browser, so they leave no IdP
108
- // session and the user would be logged out on reload — hide them there.
109
- const crossApexWeb = isCrossApexWeb();
119
+ // First-party password sign-in the PRIMARY option once past the chooser.
120
+ const pw = usePasswordSignIn({
121
+ onSignedIn: hideSignInModal
122
+ });
110
123
 
111
- // Entrance animation.
124
+ // Entrance animation (respects reduced motion).
112
125
  const opacity = useSharedValue(0);
113
126
  const scale = useSharedValue(0.96);
114
-
115
- // biome-ignore lint/correctness/useExhaustiveDependencies: opacity/scale are Reanimated SharedValues (stable refs) and must not be listed as deps; this runs once on mount to play the entrance.
127
+ // biome-ignore lint/correctness/useExhaustiveDependencies: opacity/scale are Reanimated SharedValues (stable refs), not deps; runs once on mount.
116
128
  useEffect(() => {
117
- opacity.value = withTiming(1, {
118
- duration: 250
119
- });
120
- scale.value = withTiming(1, {
121
- duration: 250
129
+ let cancelled = false;
130
+ AccessibilityInfo.isReduceMotionEnabled().then(reduced => {
131
+ if (cancelled) return;
132
+ const duration = reduced ? 0 : 250;
133
+ opacity.value = withTiming(1, {
134
+ duration
135
+ });
136
+ scale.value = withTiming(1, {
137
+ duration
138
+ });
122
139
  });
140
+ return () => {
141
+ cancelled = true;
142
+ };
123
143
  }, []);
124
144
  const backdropStyle = useAnimatedStyle(() => ({
125
145
  opacity: opacity.value
@@ -130,12 +150,32 @@ const SignInModalContent = ({
130
150
  scale: scale.value
131
151
  }]
132
152
  }));
133
- const handleClose = useCallback(() => {
134
- hideSignInModal();
135
- }, []);
136
- const handleCreateAccount = useCallback(() => {
137
- Linking.openURL(OXY_ACCOUNTS_WEB_URL);
138
- }, []);
153
+ const handleClose = useCallback(() => hideSignInModal(), []);
154
+ const handleCreateAccount = useCallback(() => Linking.openURL(OXY_ACCOUNTS_WEB_URL), []);
155
+ const handleSelectAccount = useCallback(async account => {
156
+ // The active account is already signed in — selecting it just continues.
157
+ if (account.isCurrent) {
158
+ hideSignInModal();
159
+ return;
160
+ }
161
+ if (switchingId) return;
162
+ setSwitchingId(account.accountId);
163
+ try {
164
+ await switchToAccount(account.accountId);
165
+ hideSignInModal();
166
+ } catch (switchError) {
167
+ if (isDev()) {
168
+ loggerUtil.warn('SignInModal: switch account failed', {
169
+ component: 'SignInModal'
170
+ }, switchError);
171
+ }
172
+ toast.error(t('accountSwitcher.toasts.switchFailed') || 'Failed to switch account');
173
+ } finally {
174
+ setSwitchingId(null);
175
+ }
176
+ }, [switchingId, switchToAccount, t]);
177
+ const title = showChooser ? t('signin.chooser.title') : 'Sign in to Oxy';
178
+ const subtitle = showChooser ? t('signin.chooser.subtitle') : 'Continue with your Oxy identity to sign in securely.';
139
179
  return /*#__PURE__*/_jsx(Modal, {
140
180
  visible: true,
141
181
  transparent: true,
@@ -153,7 +193,7 @@ const SignInModalContent = ({
153
193
  }), /*#__PURE__*/_jsxs(Animated.View, {
154
194
  style: [styles.card, {
155
195
  backgroundColor: theme.colors.card,
156
- paddingTop: insets.top + 24,
196
+ paddingTop: insets.top + 28,
157
197
  paddingBottom: insets.bottom + 24
158
198
  }, contentStyle],
159
199
  children: [/*#__PURE__*/_jsx(TouchableOpacity, {
@@ -163,72 +203,159 @@ const SignInModalContent = ({
163
203
  onPress: handleClose,
164
204
  accessibilityRole: "button",
165
205
  accessibilityLabel: "Close sign in",
166
- children: /*#__PURE__*/_jsx(Text, {
167
- style: [styles.closeButtonText, {
168
- color: theme.colors.textSecondary
169
- }],
170
- children: "\xD7"
206
+ children: /*#__PURE__*/_jsx(Ionicons, {
207
+ name: "close",
208
+ size: 22,
209
+ color: theme.colors.textSecondary
171
210
  })
172
211
  }), /*#__PURE__*/_jsxs(View, {
173
212
  style: styles.header,
174
213
  children: [/*#__PURE__*/_jsx(OxyLogo, {
175
214
  variant: "icon",
176
- size: 56
215
+ size: 52
177
216
  }), /*#__PURE__*/_jsx(Text, {
178
217
  className: "text-foreground",
179
218
  style: styles.title,
180
- children: "Sign in to Oxy"
219
+ children: title
181
220
  }), /*#__PURE__*/_jsx(Text, {
182
221
  className: "text-muted-foreground",
183
222
  style: styles.subtitle,
184
- children: "Continue with your Oxy identity to sign in securely"
223
+ children: subtitle
185
224
  })]
186
- }), isLoading ? /*#__PURE__*/_jsxs(View, {
187
- style: styles.loadingContainer,
188
- children: [/*#__PURE__*/_jsx(Loading, {
189
- size: "large"
190
- }), /*#__PURE__*/_jsx(Text, {
191
- className: "text-muted-foreground",
192
- style: styles.loadingText,
193
- children: "Preparing sign in..."
194
- })]
195
- }) : error ? /*#__PURE__*/_jsxs(View, {
196
- style: styles.errorContainer,
197
- children: [/*#__PURE__*/_jsx(Text, {
198
- className: "text-destructive",
199
- style: styles.errorText,
200
- children: error
201
- }), /*#__PURE__*/_jsx(Button, {
202
- variant: "primary",
203
- onPress: retry,
204
- style: styles.primaryButton,
205
- children: "Try Again"
206
- })]
207
- }) : /*#__PURE__*/_jsxs(_Fragment, {
208
- children: [/*#__PURE__*/_jsx(Button, {
209
- variant: "primary",
210
- onPress: openAuthApproval,
211
- icon: /*#__PURE__*/_jsx(OxyLogo, {
212
- variant: "icon",
213
- size: 20,
214
- fillColor: theme.colors.primaryForeground,
215
- style: styles.buttonIcon
216
- }),
217
- style: styles.primaryButton,
218
- children: "Continue with Oxy"
219
- }), !crossApexWeb && qrPayload && /*#__PURE__*/_jsx(Button, {
220
- variant: "secondary",
221
- onPress: openSameDeviceApproval,
222
- icon: /*#__PURE__*/_jsx(OxyLogo, {
223
- variant: "icon",
224
- size: 20,
225
- fillColor: theme.colors.text,
226
- style: styles.buttonIcon
227
- }),
228
- style: styles.secondaryButton,
229
- children: "Sign in with the Oxy app"
230
- }), isWaiting && /*#__PURE__*/_jsxs(View, {
231
- style: styles.statusContainer,
225
+ }), showChooser ? /*#__PURE__*/_jsx(Animated.View, {
226
+ entering: FadeIn.duration(180),
227
+ style: styles.phase,
228
+ children: /*#__PURE__*/_jsx(SignInAccountChooser, {
229
+ accounts: accounts,
230
+ onSelectAccount: handleSelectAccount,
231
+ onUseAnother: () => setUseAnother(true),
232
+ pendingAccountId: switchingId,
233
+ disabled: switchingId !== null
234
+ })
235
+ }, "chooser") : /*#__PURE__*/_jsxs(Animated.View, {
236
+ entering: FadeIn.duration(180),
237
+ style: styles.phase,
238
+ children: [accounts.length > 0 && /*#__PURE__*/_jsxs(TouchableOpacity, {
239
+ onPress: () => setUseAnother(false),
240
+ accessibilityRole: "button",
241
+ style: styles.backRow,
242
+ children: [/*#__PURE__*/_jsx(Ionicons, {
243
+ name: "chevron-back",
244
+ size: 18,
245
+ color: theme.colors.textSecondary
246
+ }), /*#__PURE__*/_jsx(Text, {
247
+ style: [styles.backText, {
248
+ color: theme.colors.textSecondary
249
+ }],
250
+ children: t('signin.chooser.title')
251
+ })]
252
+ }), /*#__PURE__*/_jsxs(View, {
253
+ style: styles.form,
254
+ children: [pw.step === 'identifier' && /*#__PURE__*/_jsx(TextInput, {
255
+ style: [styles.input, {
256
+ borderColor: theme.colors.border,
257
+ color: theme.colors.text,
258
+ backgroundColor: theme.colors.backgroundSecondary
259
+ }],
260
+ value: pw.identifier,
261
+ onChangeText: pw.setIdentifier,
262
+ onSubmitEditing: pw.submitIdentifier,
263
+ placeholder: "Username or email",
264
+ placeholderTextColor: theme.colors.textSecondary,
265
+ autoCapitalize: "none",
266
+ autoCorrect: false,
267
+ keyboardType: "email-address",
268
+ returnKeyType: "next",
269
+ accessibilityLabel: "Username or email"
270
+ }), pw.step === 'password' && /*#__PURE__*/_jsxs(_Fragment, {
271
+ children: [/*#__PURE__*/_jsx(Text, {
272
+ style: [styles.contextText, {
273
+ color: theme.colors.textSecondary
274
+ }],
275
+ children: pw.identifier
276
+ }), /*#__PURE__*/_jsx(TextInput, {
277
+ style: [styles.input, {
278
+ borderColor: theme.colors.border,
279
+ color: theme.colors.text,
280
+ backgroundColor: theme.colors.backgroundSecondary
281
+ }],
282
+ value: pw.password,
283
+ onChangeText: pw.setPassword,
284
+ onSubmitEditing: pw.submitPassword,
285
+ placeholder: "Password",
286
+ placeholderTextColor: theme.colors.textSecondary,
287
+ secureTextEntry: true,
288
+ autoCapitalize: "none",
289
+ autoCorrect: false,
290
+ returnKeyType: "go",
291
+ accessibilityLabel: "Password"
292
+ })]
293
+ }), pw.step === 'twoFactor' && /*#__PURE__*/_jsx(TextInput, {
294
+ style: [styles.input, {
295
+ borderColor: theme.colors.border,
296
+ color: theme.colors.text,
297
+ backgroundColor: theme.colors.backgroundSecondary
298
+ }],
299
+ value: pw.code,
300
+ onChangeText: pw.setCode,
301
+ onSubmitEditing: pw.submitTwoFactor,
302
+ placeholder: pw.useBackupCode ? 'Backup code' : '6-digit code',
303
+ placeholderTextColor: theme.colors.textSecondary,
304
+ autoCapitalize: "none",
305
+ autoCorrect: false,
306
+ keyboardType: pw.useBackupCode ? 'default' : 'number-pad',
307
+ returnKeyType: "go",
308
+ accessibilityLabel: pw.useBackupCode ? 'Backup code' : 'Two-factor code'
309
+ }), /*#__PURE__*/_jsx(Button, {
310
+ variant: "primary",
311
+ onPress: pw.step === 'identifier' ? pw.submitIdentifier : pw.step === 'password' ? pw.submitPassword : pw.submitTwoFactor,
312
+ loading: pw.isSubmitting,
313
+ disabled: pw.isSubmitting,
314
+ style: styles.primaryButton,
315
+ children: pw.step === 'identifier' ? 'Continue' : pw.step === 'password' ? 'Sign in' : 'Verify'
316
+ }), pw.error && /*#__PURE__*/_jsx(Text, {
317
+ className: "text-destructive",
318
+ style: styles.formError,
319
+ children: pw.error
320
+ }), pw.step === 'twoFactor' && /*#__PURE__*/_jsx(TouchableOpacity, {
321
+ onPress: () => pw.setUseBackupCode(!pw.useBackupCode),
322
+ accessibilityRole: "button",
323
+ style: styles.linkButton,
324
+ children: /*#__PURE__*/_jsx(Text, {
325
+ style: [styles.linkText, {
326
+ color: theme.colors.primary
327
+ }],
328
+ children: pw.useBackupCode ? 'Use authenticator code' : 'Use a backup code'
329
+ })
330
+ }), pw.step !== 'identifier' && /*#__PURE__*/_jsx(TouchableOpacity, {
331
+ onPress: pw.back,
332
+ accessibilityRole: "button",
333
+ style: styles.linkButton,
334
+ children: /*#__PURE__*/_jsx(Text, {
335
+ style: [styles.linkText, {
336
+ color: theme.colors.textSecondary
337
+ }],
338
+ children: "Back"
339
+ })
340
+ })]
341
+ }), /*#__PURE__*/_jsxs(View, {
342
+ style: styles.dividerRow,
343
+ children: [/*#__PURE__*/_jsx(View, {
344
+ style: [styles.dividerLine, {
345
+ backgroundColor: theme.colors.border
346
+ }]
347
+ }), /*#__PURE__*/_jsx(Text, {
348
+ style: [styles.dividerText, {
349
+ color: theme.colors.textSecondary
350
+ }],
351
+ children: "or"
352
+ }), /*#__PURE__*/_jsx(View, {
353
+ style: [styles.dividerLine, {
354
+ backgroundColor: theme.colors.border
355
+ }]
356
+ })]
357
+ }), isLoading ? /*#__PURE__*/_jsxs(View, {
358
+ style: styles.deviceLoading,
232
359
  children: [/*#__PURE__*/_jsx(Loading, {
233
360
  size: "small",
234
361
  style: styles.statusSpinner
@@ -236,16 +363,52 @@ const SignInModalContent = ({
236
363
  style: [styles.statusText, {
237
364
  color: theme.colors.textSecondary
238
365
  }],
239
- children: "Waiting for authorization..."
366
+ children: "Preparing sign in\u2026"
367
+ })]
368
+ }) : error ? /*#__PURE__*/_jsxs(View, {
369
+ style: styles.errorContainer,
370
+ children: [/*#__PURE__*/_jsx(Text, {
371
+ className: "text-destructive",
372
+ style: styles.errorText,
373
+ children: error
374
+ }), /*#__PURE__*/_jsx(Button, {
375
+ variant: "secondary",
376
+ onPress: retry,
377
+ style: styles.secondaryButton,
378
+ children: "Try Again"
379
+ })]
380
+ }) : /*#__PURE__*/_jsxs(_Fragment, {
381
+ children: [qrPayload && /*#__PURE__*/_jsx(Button, {
382
+ variant: "secondary",
383
+ onPress: openSameDeviceApproval,
384
+ icon: /*#__PURE__*/_jsx(OxyLogo, {
385
+ variant: "icon",
386
+ size: 20,
387
+ fillColor: theme.colors.text,
388
+ style: styles.buttonIcon
389
+ }),
390
+ style: styles.secondaryButton,
391
+ children: "Sign in with the Oxy app"
392
+ }), isWaiting && /*#__PURE__*/_jsxs(View, {
393
+ style: styles.statusContainer,
394
+ children: [/*#__PURE__*/_jsx(Loading, {
395
+ size: "small",
396
+ style: styles.statusSpinner
397
+ }), /*#__PURE__*/_jsx(Text, {
398
+ style: [styles.statusText, {
399
+ color: theme.colors.textSecondary
400
+ }],
401
+ children: "Waiting for authorization\u2026"
402
+ })]
403
+ }), /*#__PURE__*/_jsx(View, {
404
+ style: styles.qrSection,
405
+ children: /*#__PURE__*/_jsx(AnotherDeviceQR, {
406
+ qrData: qrData,
407
+ qrPayload: qrPayload
408
+ })
240
409
  })]
241
- }), !crossApexWeb && /*#__PURE__*/_jsx(View, {
242
- style: styles.qrSection,
243
- children: /*#__PURE__*/_jsx(AnotherDeviceQR, {
244
- qrData: qrData,
245
- qrPayload: qrPayload
246
- })
247
410
  })]
248
- }), /*#__PURE__*/_jsxs(View, {
411
+ }, "signIn"), /*#__PURE__*/_jsxs(View, {
249
412
  style: styles.footer,
250
413
  children: [/*#__PURE__*/_jsxs(Text, {
251
414
  style: styles.footerText,
@@ -273,42 +436,54 @@ const styles = StyleSheet.create({
273
436
  },
274
437
  card: {
275
438
  width: '100%',
276
- maxWidth: 400,
439
+ maxWidth: 420,
277
440
  alignItems: 'center',
278
441
  paddingHorizontal: 24,
279
- borderRadius: 24
442
+ borderRadius: 28
280
443
  },
281
444
  closeButton: {
282
445
  position: 'absolute',
283
446
  top: 16,
284
447
  right: 16,
285
- width: 40,
286
- height: 40,
287
- borderRadius: 20,
448
+ width: 36,
449
+ height: 36,
450
+ borderRadius: 18,
288
451
  justifyContent: 'center',
289
452
  alignItems: 'center',
290
453
  zIndex: 10
291
454
  },
292
- closeButtonText: {
293
- fontSize: 28,
294
- fontWeight: '300',
295
- lineHeight: 32
296
- },
297
455
  header: {
298
456
  alignItems: 'center',
299
- marginBottom: 28
457
+ marginBottom: 24
300
458
  },
301
459
  title: {
302
460
  fontSize: 26,
303
- fontWeight: 'bold',
461
+ fontWeight: '800',
462
+ letterSpacing: -0.5,
304
463
  marginTop: 16,
305
464
  textAlign: 'center'
306
465
  },
307
466
  subtitle: {
308
467
  fontSize: 15,
468
+ lineHeight: 21,
309
469
  marginTop: 8,
310
470
  textAlign: 'center'
311
471
  },
472
+ phase: {
473
+ width: '100%'
474
+ },
475
+ backRow: {
476
+ flexDirection: 'row',
477
+ alignItems: 'center',
478
+ gap: 4,
479
+ alignSelf: 'flex-start',
480
+ paddingVertical: 6,
481
+ marginBottom: 8
482
+ },
483
+ backText: {
484
+ fontSize: 14,
485
+ fontWeight: '600'
486
+ },
312
487
  primaryButton: {
313
488
  width: '100%',
314
489
  borderRadius: 12
@@ -321,6 +496,57 @@ const styles = StyleSheet.create({
321
496
  buttonIcon: {
322
497
  marginRight: 10
323
498
  },
499
+ form: {
500
+ width: '100%'
501
+ },
502
+ input: {
503
+ width: '100%',
504
+ borderWidth: 1,
505
+ borderRadius: 12,
506
+ paddingHorizontal: 16,
507
+ paddingVertical: 13,
508
+ fontSize: 15,
509
+ marginBottom: 12
510
+ },
511
+ contextText: {
512
+ fontSize: 14,
513
+ textAlign: 'center',
514
+ marginBottom: 12
515
+ },
516
+ formError: {
517
+ fontSize: 14,
518
+ textAlign: 'center',
519
+ marginTop: 12
520
+ },
521
+ linkButton: {
522
+ alignSelf: 'center',
523
+ paddingVertical: 8,
524
+ marginTop: 8
525
+ },
526
+ linkText: {
527
+ fontSize: 14,
528
+ fontWeight: '600'
529
+ },
530
+ dividerRow: {
531
+ flexDirection: 'row',
532
+ alignItems: 'center',
533
+ width: '100%',
534
+ marginVertical: 20
535
+ },
536
+ dividerLine: {
537
+ flex: 1,
538
+ height: 1
539
+ },
540
+ dividerText: {
541
+ marginHorizontal: 12,
542
+ fontSize: 13
543
+ },
544
+ deviceLoading: {
545
+ flexDirection: 'row',
546
+ alignItems: 'center',
547
+ justifyContent: 'center',
548
+ paddingVertical: 12
549
+ },
324
550
  statusContainer: {
325
551
  flexDirection: 'row',
326
552
  alignItems: 'center',
@@ -337,14 +563,6 @@ const styles = StyleSheet.create({
337
563
  width: '100%',
338
564
  marginTop: 24
339
565
  },
340
- loadingContainer: {
341
- alignItems: 'center',
342
- paddingVertical: 40
343
- },
344
- loadingText: {
345
- marginTop: 16,
346
- fontSize: 14
347
- },
348
566
  errorContainer: {
349
567
  alignItems: 'center',
350
568
  paddingVertical: 20,