@oxy.so/services 4.0.7 → 6.1.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 (403) hide show
  1. package/README.md +2 -2
  2. package/lib/commonjs/assets/assets/signIn/slide-1.jpg +0 -0
  3. package/lib/commonjs/assets/assets/signIn/slide-1.jpg.d.ts +3 -0
  4. package/lib/commonjs/assets/assets/signIn/slide-2.jpg +0 -0
  5. package/lib/commonjs/assets/assets/signIn/slide-2.jpg.d.ts +3 -0
  6. package/lib/commonjs/assets/assets/signIn/slide-3.jpg +0 -0
  7. package/lib/commonjs/assets/assets/signIn/slide-3.jpg.d.ts +3 -0
  8. package/lib/commonjs/assets/assets/signIn/slide-4.jpg +0 -0
  9. package/lib/commonjs/assets/assets/signIn/slide-4.jpg.d.ts +3 -0
  10. package/lib/commonjs/assets/signIn/slide-1.jpg +0 -0
  11. package/lib/commonjs/assets/signIn/slide-2.jpg +0 -0
  12. package/lib/commonjs/assets/signIn/slide-3.jpg +0 -0
  13. package/lib/commonjs/assets/signIn/slide-4.jpg +0 -0
  14. package/lib/commonjs/index.js +77 -8
  15. package/lib/commonjs/index.js.map +1 -1
  16. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +11 -58
  17. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
  18. package/lib/commonjs/ui/components/OxyAuthChooser.js +36 -45
  19. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  20. package/lib/commonjs/ui/components/OxyProvider.js +0 -2
  21. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  22. package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
  23. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +30 -16
  24. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  25. package/lib/commonjs/ui/components/authChooser/primitives.js +7 -52
  26. package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -1
  27. package/lib/commonjs/ui/components/authChooser/signInFailureMessage.js +1 -7
  28. package/lib/commonjs/ui/components/authChooser/signInFailureMessage.js.map +1 -1
  29. package/lib/commonjs/ui/components/authChooser/styles.js +0 -31
  30. package/lib/commonjs/ui/components/authChooser/styles.js.map +1 -1
  31. package/lib/commonjs/ui/components/authChooser/types.js +2 -2
  32. package/lib/commonjs/ui/components/authChooser/types.js.map +1 -1
  33. package/lib/commonjs/ui/components/oauthNavigation.js +1 -1
  34. package/lib/commonjs/ui/components/signIn/InlineCommonsQr.js +161 -0
  35. package/lib/commonjs/ui/components/signIn/InlineCommonsQr.js.map +1 -0
  36. package/lib/commonjs/ui/components/signIn/OxyAccountPicker.js +111 -0
  37. package/lib/commonjs/ui/components/signIn/OxyAccountPicker.js.map +1 -0
  38. package/lib/commonjs/ui/components/signIn/OxyAuthScreen.js +160 -0
  39. package/lib/commonjs/ui/components/signIn/OxyAuthScreen.js.map +1 -0
  40. package/lib/commonjs/ui/components/signIn/OxyCreateAccountPanel.js +236 -0
  41. package/lib/commonjs/ui/components/signIn/OxyCreateAccountPanel.js.map +1 -0
  42. package/lib/commonjs/ui/components/signIn/OxyDeleteAccountPanel.js +114 -0
  43. package/lib/commonjs/ui/components/signIn/OxyDeleteAccountPanel.js.map +1 -0
  44. package/lib/commonjs/ui/components/signIn/OxyLinkCommonsPanel.js +275 -0
  45. package/lib/commonjs/ui/components/signIn/OxyLinkCommonsPanel.js.map +1 -0
  46. package/lib/commonjs/ui/components/signIn/OxyRecoverAccountPanel.js +170 -0
  47. package/lib/commonjs/ui/components/signIn/OxyRecoverAccountPanel.js.map +1 -0
  48. package/lib/commonjs/ui/components/signIn/OxySignInPanel.js +371 -0
  49. package/lib/commonjs/ui/components/signIn/OxySignInPanel.js.map +1 -0
  50. package/lib/commonjs/ui/components/signIn/OxySignUpPanel.js +78 -0
  51. package/lib/commonjs/ui/components/signIn/OxySignUpPanel.js.map +1 -0
  52. package/lib/commonjs/ui/components/signIn/accountFlowParts.js +244 -0
  53. package/lib/commonjs/ui/components/signIn/accountFlowParts.js.map +1 -0
  54. package/lib/commonjs/ui/components/signIn/artwork.js +21 -0
  55. package/lib/commonjs/ui/components/signIn/artwork.js.map +1 -0
  56. package/lib/commonjs/ui/components/signIn/passkeyError.js +46 -0
  57. package/lib/commonjs/ui/components/signIn/passkeyError.js.map +1 -0
  58. package/lib/commonjs/ui/components/signIn/signInMethods.js +46 -0
  59. package/lib/commonjs/ui/components/signIn/signInMethods.js.map +1 -0
  60. package/lib/commonjs/ui/context/OxyContext.js +16 -16
  61. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  62. package/lib/commonjs/ui/context/commitSessionFlow.js +0 -43
  63. package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -1
  64. package/lib/commonjs/ui/context/passkeyFlow.js +22 -0
  65. package/lib/commonjs/ui/context/passkeyFlow.js.map +1 -1
  66. package/lib/commonjs/ui/hooks/accountDialogSnapshot.js +15 -1
  67. package/lib/commonjs/ui/hooks/accountDialogSnapshot.js.map +1 -1
  68. package/lib/commonjs/ui/hooks/useDeviceSwitcher.js +1 -3
  69. package/lib/commonjs/ui/hooks/useDeviceSwitcher.js.map +1 -1
  70. package/lib/commonjs/ui/oauth/browserAuthTransport.js +11 -4
  71. package/lib/commonjs/ui/oauth/browserAuthTransport.js.map +1 -1
  72. package/lib/commonjs/ui/oauth/oauthHandshake.js +3 -0
  73. package/lib/commonjs/ui/oauth/oauthHandshake.js.map +1 -1
  74. package/lib/commonjs/ui/oauth/oauthPopup.js +2 -3
  75. package/lib/commonjs/ui/oauth/oauthPopup.js.map +1 -1
  76. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +0 -23
  77. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  78. package/lib/commonjs/ui/screens/EditProfileScreen.js +0 -8
  79. package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -1
  80. package/lib/commonjs/ui/screens/ManageAccountScreen.js +3 -4
  81. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  82. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +1 -1
  83. package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  84. package/lib/commonjs/ui/session/authStore.js +0 -21
  85. package/lib/commonjs/ui/session/authStore.js.map +1 -1
  86. package/lib/commonjs/ui/utils/accountDeletionHandoff.js +2 -2
  87. package/lib/commonjs/ui/utils/accountDeletionHandoff.js.map +1 -1
  88. package/lib/module/assets/assets/signIn/slide-1.jpg +0 -0
  89. package/lib/module/assets/assets/signIn/slide-1.jpg.d.ts +3 -0
  90. package/lib/module/assets/assets/signIn/slide-2.jpg +0 -0
  91. package/lib/module/assets/assets/signIn/slide-2.jpg.d.ts +3 -0
  92. package/lib/module/assets/assets/signIn/slide-3.jpg +0 -0
  93. package/lib/module/assets/assets/signIn/slide-3.jpg.d.ts +3 -0
  94. package/lib/module/assets/assets/signIn/slide-4.jpg +0 -0
  95. package/lib/module/assets/assets/signIn/slide-4.jpg.d.ts +3 -0
  96. package/lib/module/assets/signIn/slide-1.jpg +0 -0
  97. package/lib/module/assets/signIn/slide-2.jpg +0 -0
  98. package/lib/module/assets/signIn/slide-3.jpg +0 -0
  99. package/lib/module/assets/signIn/slide-4.jpg +0 -0
  100. package/lib/module/index.js +14 -6
  101. package/lib/module/index.js.map +1 -1
  102. package/lib/module/ui/components/OxyAccountDialogScreen.js +14 -59
  103. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
  104. package/lib/module/ui/components/OxyAuthChooser.js +37 -46
  105. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  106. package/lib/module/ui/components/OxyProvider.js +0 -2
  107. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  108. package/lib/module/ui/components/ProfileButton.js.map +1 -1
  109. package/lib/module/ui/components/authChooser/AccountsMenuView.js +22 -10
  110. package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  111. package/lib/module/ui/components/authChooser/primitives.js +1 -44
  112. package/lib/module/ui/components/authChooser/primitives.js.map +1 -1
  113. package/lib/module/ui/components/authChooser/signInFailureMessage.js +1 -7
  114. package/lib/module/ui/components/authChooser/signInFailureMessage.js.map +1 -1
  115. package/lib/module/ui/components/authChooser/styles.js +0 -31
  116. package/lib/module/ui/components/authChooser/styles.js.map +1 -1
  117. package/lib/module/ui/components/authChooser/types.js +2 -2
  118. package/lib/module/ui/components/authChooser/types.js.map +1 -1
  119. package/lib/module/ui/components/oauthNavigation.js +1 -1
  120. package/lib/module/ui/components/signIn/InlineCommonsQr.js +157 -0
  121. package/lib/module/ui/components/signIn/InlineCommonsQr.js.map +1 -0
  122. package/lib/module/ui/components/signIn/OxyAccountPicker.js +106 -0
  123. package/lib/module/ui/components/signIn/OxyAccountPicker.js.map +1 -0
  124. package/lib/module/ui/components/signIn/OxyAuthScreen.js +151 -0
  125. package/lib/module/ui/components/signIn/OxyAuthScreen.js.map +1 -0
  126. package/lib/module/ui/components/signIn/OxyCreateAccountPanel.js +231 -0
  127. package/lib/module/ui/components/signIn/OxyCreateAccountPanel.js.map +1 -0
  128. package/lib/module/ui/components/signIn/OxyDeleteAccountPanel.js +109 -0
  129. package/lib/module/ui/components/signIn/OxyDeleteAccountPanel.js.map +1 -0
  130. package/lib/module/ui/components/signIn/OxyLinkCommonsPanel.js +270 -0
  131. package/lib/module/ui/components/signIn/OxyLinkCommonsPanel.js.map +1 -0
  132. package/lib/module/ui/components/signIn/OxyRecoverAccountPanel.js +165 -0
  133. package/lib/module/ui/components/signIn/OxyRecoverAccountPanel.js.map +1 -0
  134. package/lib/module/ui/components/signIn/OxySignInPanel.js +366 -0
  135. package/lib/module/ui/components/signIn/OxySignInPanel.js.map +1 -0
  136. package/lib/module/ui/components/signIn/OxySignUpPanel.js +75 -0
  137. package/lib/module/ui/components/signIn/OxySignUpPanel.js.map +1 -0
  138. package/lib/module/ui/components/signIn/accountFlowParts.js +235 -0
  139. package/lib/module/ui/components/signIn/accountFlowParts.js.map +1 -0
  140. package/lib/module/ui/components/signIn/artwork.js +16 -0
  141. package/lib/module/ui/components/signIn/artwork.js.map +1 -0
  142. package/lib/module/ui/components/signIn/passkeyError.js +40 -0
  143. package/lib/module/ui/components/signIn/passkeyError.js.map +1 -0
  144. package/lib/module/ui/components/signIn/signInMethods.js +42 -0
  145. package/lib/module/ui/components/signIn/signInMethods.js.map +1 -0
  146. package/lib/module/ui/context/OxyContext.js +17 -17
  147. package/lib/module/ui/context/OxyContext.js.map +1 -1
  148. package/lib/module/ui/context/commitSessionFlow.js +0 -42
  149. package/lib/module/ui/context/commitSessionFlow.js.map +1 -1
  150. package/lib/module/ui/context/passkeyFlow.js +21 -0
  151. package/lib/module/ui/context/passkeyFlow.js.map +1 -1
  152. package/lib/module/ui/hooks/accountDialogSnapshot.js +14 -1
  153. package/lib/module/ui/hooks/accountDialogSnapshot.js.map +1 -1
  154. package/lib/module/ui/hooks/useDeviceSwitcher.js +3 -5
  155. package/lib/module/ui/hooks/useDeviceSwitcher.js.map +1 -1
  156. package/lib/module/ui/oauth/browserAuthTransport.js +11 -4
  157. package/lib/module/ui/oauth/browserAuthTransport.js.map +1 -1
  158. package/lib/module/ui/oauth/oauthHandshake.js +3 -0
  159. package/lib/module/ui/oauth/oauthHandshake.js.map +1 -1
  160. package/lib/module/ui/oauth/oauthPopup.js +2 -3
  161. package/lib/module/ui/oauth/oauthPopup.js.map +1 -1
  162. package/lib/module/ui/screens/EditProfileFieldScreen.js +1 -24
  163. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  164. package/lib/module/ui/screens/EditProfileScreen.js +0 -8
  165. package/lib/module/ui/screens/EditProfileScreen.js.map +1 -1
  166. package/lib/module/ui/screens/ManageAccountScreen.js +4 -5
  167. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  168. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +1 -1
  169. package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
  170. package/lib/module/ui/session/authStore.js +1 -22
  171. package/lib/module/ui/session/authStore.js.map +1 -1
  172. package/lib/module/ui/utils/accountDeletionHandoff.js +3 -3
  173. package/lib/module/ui/utils/accountDeletionHandoff.js.map +1 -1
  174. package/lib/typescript/assets/signIn/slide-1.jpg.d.ts +3 -0
  175. package/lib/typescript/assets/signIn/slide-2.jpg.d.ts +3 -0
  176. package/lib/typescript/assets/signIn/slide-3.jpg.d.ts +3 -0
  177. package/lib/typescript/assets/signIn/slide-4.jpg.d.ts +3 -0
  178. package/lib/typescript/commonjs/index.d.ts +16 -2
  179. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  180. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  181. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts +5 -12
  182. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  183. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  184. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts +1 -1
  185. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
  186. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  187. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +0 -19
  188. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -1
  189. package/lib/typescript/commonjs/ui/components/authChooser/signInFailureMessage.d.ts +1 -5
  190. package/lib/typescript/commonjs/ui/components/authChooser/signInFailureMessage.d.ts.map +1 -1
  191. package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts +0 -31
  192. package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts.map +1 -1
  193. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +2 -7
  194. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -1
  195. package/lib/typescript/commonjs/ui/components/oauthNavigation.d.ts +1 -1
  196. package/lib/typescript/commonjs/ui/components/signIn/InlineCommonsQr.d.ts +20 -0
  197. package/lib/typescript/commonjs/ui/components/signIn/InlineCommonsQr.d.ts.map +1 -0
  198. package/lib/typescript/commonjs/ui/components/signIn/OxyAccountPicker.d.ts +34 -0
  199. package/lib/typescript/commonjs/ui/components/signIn/OxyAccountPicker.d.ts.map +1 -0
  200. package/lib/typescript/commonjs/ui/components/signIn/OxyAuthScreen.d.ts +43 -0
  201. package/lib/typescript/commonjs/ui/components/signIn/OxyAuthScreen.d.ts.map +1 -0
  202. package/lib/typescript/commonjs/ui/components/signIn/OxyCreateAccountPanel.d.ts +24 -0
  203. package/lib/typescript/commonjs/ui/components/signIn/OxyCreateAccountPanel.d.ts.map +1 -0
  204. package/lib/typescript/commonjs/ui/components/signIn/OxyDeleteAccountPanel.d.ts +16 -0
  205. package/lib/typescript/commonjs/ui/components/signIn/OxyDeleteAccountPanel.d.ts.map +1 -0
  206. package/lib/typescript/commonjs/ui/components/signIn/OxyLinkCommonsPanel.d.ts +21 -0
  207. package/lib/typescript/commonjs/ui/components/signIn/OxyLinkCommonsPanel.d.ts.map +1 -0
  208. package/lib/typescript/commonjs/ui/components/signIn/OxyRecoverAccountPanel.d.ts +20 -0
  209. package/lib/typescript/commonjs/ui/components/signIn/OxyRecoverAccountPanel.d.ts.map +1 -0
  210. package/lib/typescript/commonjs/ui/components/signIn/OxySignInPanel.d.ts +43 -0
  211. package/lib/typescript/commonjs/ui/components/signIn/OxySignInPanel.d.ts.map +1 -0
  212. package/lib/typescript/commonjs/ui/components/signIn/OxySignUpPanel.d.ts +17 -0
  213. package/lib/typescript/commonjs/ui/components/signIn/OxySignUpPanel.d.ts.map +1 -0
  214. package/lib/typescript/commonjs/ui/components/signIn/accountFlowParts.d.ts +60 -0
  215. package/lib/typescript/commonjs/ui/components/signIn/accountFlowParts.d.ts.map +1 -0
  216. package/lib/typescript/commonjs/ui/components/signIn/artwork.d.ts +8 -0
  217. package/lib/typescript/commonjs/ui/components/signIn/artwork.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/ui/components/signIn/passkeyError.d.ts +16 -0
  219. package/lib/typescript/commonjs/ui/components/signIn/passkeyError.d.ts.map +1 -0
  220. package/lib/typescript/commonjs/ui/components/signIn/signInMethods.d.ts +39 -0
  221. package/lib/typescript/commonjs/ui/components/signIn/signInMethods.d.ts.map +1 -0
  222. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  223. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts +0 -40
  224. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts.map +1 -1
  225. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +15 -10
  226. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  227. package/lib/typescript/commonjs/ui/context/passkeyFlow.d.ts +16 -1
  228. package/lib/typescript/commonjs/ui/context/passkeyFlow.d.ts.map +1 -1
  229. package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts +7 -1
  230. package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts.map +1 -1
  231. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  232. package/lib/typescript/commonjs/ui/hooks/useDeviceSwitcher.d.ts.map +1 -1
  233. package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts +9 -0
  234. package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts.map +1 -1
  235. package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts +3 -0
  236. package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts.map +1 -1
  237. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts +2 -3
  238. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts.map +1 -1
  239. package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts +1 -1
  240. package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  241. package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -1
  242. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  243. package/lib/typescript/commonjs/ui/session/authStore.d.ts +0 -30
  244. package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
  245. package/lib/typescript/commonjs/ui/types/navigation.d.ts +0 -26
  246. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  247. package/lib/typescript/module/index.d.ts +16 -2
  248. package/lib/typescript/module/index.d.ts.map +1 -1
  249. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  250. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts +5 -12
  251. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  252. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  253. package/lib/typescript/module/ui/components/ProfileButton.d.ts +1 -1
  254. package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
  255. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  256. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +0 -19
  257. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -1
  258. package/lib/typescript/module/ui/components/authChooser/signInFailureMessage.d.ts +1 -5
  259. package/lib/typescript/module/ui/components/authChooser/signInFailureMessage.d.ts.map +1 -1
  260. package/lib/typescript/module/ui/components/authChooser/styles.d.ts +0 -31
  261. package/lib/typescript/module/ui/components/authChooser/styles.d.ts.map +1 -1
  262. package/lib/typescript/module/ui/components/authChooser/types.d.ts +2 -7
  263. package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -1
  264. package/lib/typescript/module/ui/components/oauthNavigation.d.ts +1 -1
  265. package/lib/typescript/module/ui/components/signIn/InlineCommonsQr.d.ts +20 -0
  266. package/lib/typescript/module/ui/components/signIn/InlineCommonsQr.d.ts.map +1 -0
  267. package/lib/typescript/module/ui/components/signIn/OxyAccountPicker.d.ts +34 -0
  268. package/lib/typescript/module/ui/components/signIn/OxyAccountPicker.d.ts.map +1 -0
  269. package/lib/typescript/module/ui/components/signIn/OxyAuthScreen.d.ts +43 -0
  270. package/lib/typescript/module/ui/components/signIn/OxyAuthScreen.d.ts.map +1 -0
  271. package/lib/typescript/module/ui/components/signIn/OxyCreateAccountPanel.d.ts +24 -0
  272. package/lib/typescript/module/ui/components/signIn/OxyCreateAccountPanel.d.ts.map +1 -0
  273. package/lib/typescript/module/ui/components/signIn/OxyDeleteAccountPanel.d.ts +16 -0
  274. package/lib/typescript/module/ui/components/signIn/OxyDeleteAccountPanel.d.ts.map +1 -0
  275. package/lib/typescript/module/ui/components/signIn/OxyLinkCommonsPanel.d.ts +21 -0
  276. package/lib/typescript/module/ui/components/signIn/OxyLinkCommonsPanel.d.ts.map +1 -0
  277. package/lib/typescript/module/ui/components/signIn/OxyRecoverAccountPanel.d.ts +20 -0
  278. package/lib/typescript/module/ui/components/signIn/OxyRecoverAccountPanel.d.ts.map +1 -0
  279. package/lib/typescript/module/ui/components/signIn/OxySignInPanel.d.ts +43 -0
  280. package/lib/typescript/module/ui/components/signIn/OxySignInPanel.d.ts.map +1 -0
  281. package/lib/typescript/module/ui/components/signIn/OxySignUpPanel.d.ts +17 -0
  282. package/lib/typescript/module/ui/components/signIn/OxySignUpPanel.d.ts.map +1 -0
  283. package/lib/typescript/module/ui/components/signIn/accountFlowParts.d.ts +60 -0
  284. package/lib/typescript/module/ui/components/signIn/accountFlowParts.d.ts.map +1 -0
  285. package/lib/typescript/module/ui/components/signIn/artwork.d.ts +8 -0
  286. package/lib/typescript/module/ui/components/signIn/artwork.d.ts.map +1 -0
  287. package/lib/typescript/module/ui/components/signIn/passkeyError.d.ts +16 -0
  288. package/lib/typescript/module/ui/components/signIn/passkeyError.d.ts.map +1 -0
  289. package/lib/typescript/module/ui/components/signIn/signInMethods.d.ts +39 -0
  290. package/lib/typescript/module/ui/components/signIn/signInMethods.d.ts.map +1 -0
  291. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  292. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts +0 -40
  293. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts.map +1 -1
  294. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +15 -10
  295. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  296. package/lib/typescript/module/ui/context/passkeyFlow.d.ts +16 -1
  297. package/lib/typescript/module/ui/context/passkeyFlow.d.ts.map +1 -1
  298. package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts +7 -1
  299. package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts.map +1 -1
  300. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  301. package/lib/typescript/module/ui/hooks/useDeviceSwitcher.d.ts.map +1 -1
  302. package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts +9 -0
  303. package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts.map +1 -1
  304. package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts +3 -0
  305. package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts.map +1 -1
  306. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts +2 -3
  307. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts.map +1 -1
  308. package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts +1 -1
  309. package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  310. package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -1
  311. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  312. package/lib/typescript/module/ui/session/authStore.d.ts +0 -30
  313. package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
  314. package/lib/typescript/module/ui/types/navigation.d.ts +0 -26
  315. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  316. package/package.json +4 -7
  317. package/src/assets/signIn/slide-1.jpg +0 -0
  318. package/src/assets/signIn/slide-1.jpg.d.ts +3 -0
  319. package/src/assets/signIn/slide-2.jpg +0 -0
  320. package/src/assets/signIn/slide-2.jpg.d.ts +3 -0
  321. package/src/assets/signIn/slide-3.jpg +0 -0
  322. package/src/assets/signIn/slide-3.jpg.d.ts +3 -0
  323. package/src/assets/signIn/slide-4.jpg +0 -0
  324. package/src/assets/signIn/slide-4.jpg.d.ts +3 -0
  325. package/src/index.ts +27 -7
  326. package/src/ui/components/OxyAccountDialogScreen.tsx +11 -72
  327. package/src/ui/components/OxyAuthChooser.tsx +37 -54
  328. package/src/ui/components/OxyProvider.tsx +0 -2
  329. package/src/ui/components/ProfileButton.tsx +1 -4
  330. package/src/ui/components/authChooser/AccountsMenuView.tsx +28 -8
  331. package/src/ui/components/authChooser/primitives.tsx +1 -39
  332. package/src/ui/components/authChooser/signInFailureMessage.ts +1 -7
  333. package/src/ui/components/authChooser/styles.ts +0 -31
  334. package/src/ui/components/authChooser/types.ts +2 -7
  335. package/src/ui/components/oauthNavigation.ts +1 -1
  336. package/src/ui/components/signIn/InlineCommonsQr.tsx +135 -0
  337. package/src/ui/components/signIn/OxyAccountPicker.tsx +129 -0
  338. package/src/ui/components/signIn/OxyAuthScreen.tsx +123 -0
  339. package/src/ui/components/signIn/OxyCreateAccountPanel.tsx +207 -0
  340. package/src/ui/components/signIn/OxyDeleteAccountPanel.tsx +106 -0
  341. package/src/ui/components/signIn/OxyLinkCommonsPanel.tsx +222 -0
  342. package/src/ui/components/signIn/OxyRecoverAccountPanel.tsx +154 -0
  343. package/src/ui/components/signIn/OxySignInPanel.tsx +392 -0
  344. package/src/ui/components/signIn/OxySignUpPanel.tsx +86 -0
  345. package/src/ui/components/signIn/accountFlowParts.tsx +204 -0
  346. package/src/ui/components/signIn/artwork.ts +13 -0
  347. package/src/ui/components/signIn/passkeyError.ts +44 -0
  348. package/src/ui/components/signIn/signInMethods.ts +51 -0
  349. package/src/ui/context/OxyContext.tsx +23 -19
  350. package/src/ui/context/__tests__/commitSessionFlow.test.ts +0 -89
  351. package/src/ui/context/__tests__/passkeyFlow.test.ts +59 -1
  352. package/src/ui/context/commitSessionFlow.ts +0 -61
  353. package/src/ui/context/oxyContextTypes.ts +16 -10
  354. package/src/ui/context/passkeyFlow.ts +28 -0
  355. package/src/ui/hooks/accountDialogSnapshot.ts +20 -1
  356. package/src/ui/hooks/useDeviceSwitcher.ts +3 -11
  357. package/src/ui/oauth/__tests__/browserAuthTransport.test.ts +21 -0
  358. package/src/ui/oauth/browserAuthTransport.ts +14 -4
  359. package/src/ui/oauth/oauthHandshake.ts +4 -1
  360. package/src/ui/oauth/oauthPopup.ts +2 -3
  361. package/src/ui/screens/EditProfileFieldScreen.tsx +1 -27
  362. package/src/ui/screens/EditProfileScreen.tsx +0 -6
  363. package/src/ui/screens/ManageAccountScreen.tsx +4 -5
  364. package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +1 -1
  365. package/src/ui/session/authStore.ts +0 -37
  366. package/src/ui/types/navigation.ts +0 -26
  367. package/src/ui/utils/accountDeletionHandoff.ts +3 -3
  368. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +0 -132
  369. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +0 -1
  370. package/lib/commonjs/ui/components/authChooser/SignUpView.js +0 -77
  371. package/lib/commonjs/ui/components/authChooser/SignUpView.js.map +0 -1
  372. package/lib/commonjs/ui/components/passkeyHubPopup.js +0 -33
  373. package/lib/commonjs/ui/components/passkeyHubPopup.js.map +0 -1
  374. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js +0 -48
  375. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js.map +0 -1
  376. package/lib/module/ui/components/authChooser/SignInEntryView.js +0 -127
  377. package/lib/module/ui/components/authChooser/SignInEntryView.js.map +0 -1
  378. package/lib/module/ui/components/authChooser/SignUpView.js +0 -73
  379. package/lib/module/ui/components/authChooser/SignUpView.js.map +0 -1
  380. package/lib/module/ui/components/passkeyHubPopup.js +0 -29
  381. package/lib/module/ui/components/passkeyHubPopup.js.map +0 -1
  382. package/lib/module/ui/oauth/legacyRedirectLanes.js +0 -44
  383. package/lib/module/ui/oauth/legacyRedirectLanes.js.map +0 -1
  384. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +0 -39
  385. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +0 -1
  386. package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts +0 -31
  387. package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts.map +0 -1
  388. package/lib/typescript/commonjs/ui/components/passkeyHubPopup.d.ts +0 -23
  389. package/lib/typescript/commonjs/ui/components/passkeyHubPopup.d.ts.map +0 -1
  390. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts +0 -40
  391. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts.map +0 -1
  392. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +0 -39
  393. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +0 -1
  394. package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts +0 -31
  395. package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts.map +0 -1
  396. package/lib/typescript/module/ui/components/passkeyHubPopup.d.ts +0 -23
  397. package/lib/typescript/module/ui/components/passkeyHubPopup.d.ts.map +0 -1
  398. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts +0 -40
  399. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts.map +0 -1
  400. package/src/ui/components/authChooser/SignInEntryView.tsx +0 -157
  401. package/src/ui/components/authChooser/SignUpView.tsx +0 -76
  402. package/src/ui/components/passkeyHubPopup.ts +0 -28
  403. package/src/ui/oauth/legacyRedirectLanes.ts +0 -43
@@ -0,0 +1,392 @@
1
+ /**
2
+ * THE Oxy sign-in screen. The account dialog every Oxy app opens and the
3
+ * auth.oxy.so page render this one component; only where it is mounted
4
+ * differs (`host`).
5
+ *
6
+ * picker a returning device: "Choose an account", then "Use another account"
7
+ * entry the header, the Commons way in, and the way in for someone with no
8
+ * account. On auth.oxy.so (`page`) also the username with its
9
+ * Continue — a username-first passkey sign-in, which takes a
10
+ * platform passkey AND a hardware security key with no resident
11
+ * credential (a U2F key such as a Titan) — and "or continue with" the
12
+ * discoverable passkey. From `md` that page is Bloom `AuthCard`'s
13
+ * split card, with the embedded QR over its photo carousel in the
14
+ * right column; below `md` it is "Continue with Oxy" at the top.
15
+ * In an app's dialog on the web, "Continue with Oxy" opens that page
16
+ * in a window over the app, like "Sign in with Google": the browser's
17
+ * session lives on auth.oxy.so, so every Oxy app shares it. On
18
+ * native it is "Continue with Oxy" ("Get Commons" without Commons).
19
+ *
20
+ * `signInMethods.ts` owns which blocks a platform gets.
21
+ */
22
+
23
+ import type React from 'react';
24
+ import { useCallback, useEffect, useState } from 'react';
25
+ import { Linking, Platform, Text as RNText, StyleSheet, View } from 'react-native';
26
+ import { View as CssView } from 'react-native-css/components';
27
+ import { AuthMediaCarousel } from '@oxy.so/bloom/auth-card';
28
+ import { Button } from '@oxy.so/bloom/button';
29
+ import { Divider } from '@oxy.so/bloom/divider';
30
+ import { RiKey2Line } from '@oxy.so/bloom/icons/RiKey2Line';
31
+ import { RiQrCodeLine } from '@oxy.so/bloom/icons/RiQrCodeLine';
32
+ import { useTheme } from '@oxy.so/bloom/theme';
33
+ import { TextField, TextFieldHint, TextFieldInput, TextFieldLabel } from '@oxy.so/bloom/text-field';
34
+ import { toast } from '@oxy.so/bloom/toast';
35
+ import { Text } from '@oxy.so/bloom/typography';
36
+ import type { SwitcherContextRow } from '@oxy.so/core';
37
+ import { useQueryClient } from '@tanstack/react-query';
38
+ import { useOxy } from '../../context/OxyContext';
39
+ import { useAccountDialogSnapshot } from '../../hooks/accountDialogSnapshot';
40
+ import { useDeviceSwitcher } from '../../hooks/useDeviceSwitcher';
41
+ import { useI18n } from '../../hooks/useI18n';
42
+ import { getCommonsAcquisitionUrl } from '../../utils/commonsStoreLinks';
43
+ import { isWebBrowser } from '../../utils/isWebBrowser';
44
+ import { SubtleLink } from '../authChooser/primitives';
45
+ import { SIGN_IN_SLIDES } from './artwork';
46
+ import { InlineCommonsQr } from './InlineCommonsQr';
47
+ import { OxyAccountPicker } from './OxyAccountPicker';
48
+ import { OxyAuthScreen, OxyAuthScreenHeader, OxyAuthSplit, OxyAuthTerms } from './OxyAuthScreen';
49
+ import { RATE_LIMIT_SECONDS, describePasskeyError, isRateLimited } from './passkeyError';
50
+ import { resolveSignInMethods } from './signInMethods';
51
+
52
+ export interface OxySignInPanelProps {
53
+ /** This screen signed the origin in. */
54
+ onSignedIn: () => void;
55
+ /** "New to Oxy? Create one". */
56
+ onCreateAccount: () => void;
57
+ /** "Lost your passkey? Recover your account" — auth.oxy.so's page only. */
58
+ onRecover?: () => void;
59
+ /** A handle to pre-fill, skipping the picker (a re-authentication). */
60
+ loginHint?: string;
61
+ /** The app being continued to, when there is one. */
62
+ appName?: string | null;
63
+ /**
64
+ * `dialog` — inside the account dialog, which the controller closes itself
65
+ * once a request it runs signs in, and where a request shows in place.
66
+ * `page` — a page of its own (auth.oxy.so): a request opens the dialog to
67
+ * show it, and its completion is reported through `onSignedIn` too.
68
+ */
69
+ host?: 'dialog' | 'page';
70
+ }
71
+
72
+ export const OxySignInPanel: React.FC<OxySignInPanelProps> = ({
73
+ onSignedIn,
74
+ onCreateAccount,
75
+ onRecover,
76
+ loginHint,
77
+ appName = null,
78
+ host = 'page',
79
+ }) => {
80
+ const theme = useTheme();
81
+ const { t } = useI18n();
82
+ const queryClient = useQueryClient();
83
+ const { accountDialogController: controller, openAccountDialog, signInWithPasskey, continueOnAuth } = useOxy();
84
+ const snapshot = useAccountDialogSnapshot(controller);
85
+ const { principals, activeContext } = useDeviceSwitcher();
86
+
87
+ const methods = resolveSignInMethods({
88
+ web: isWebBrowser(),
89
+ host,
90
+ commonsAvailability: snapshot.commonsAvailability,
91
+ });
92
+
93
+ const [showForm, setShowForm] = useState(Boolean(loginHint));
94
+ const [identifier, setIdentifier] = useState(loginHint ?? '');
95
+ const [pending, setPending] = useState(false);
96
+ const [error, setError] = useState<string | null>(null);
97
+ const [rateLimitSeconds, setRateLimitSeconds] = useState(0);
98
+ const blocked = pending || rateLimitSeconds > 0;
99
+
100
+ // The countdown after a 429: one tick a second until the person may retry.
101
+ useEffect(() => {
102
+ if (rateLimitSeconds <= 0) return;
103
+ const timer = setTimeout(() => setRateLimitSeconds((seconds) => Math.max(0, seconds - 1)), 1000);
104
+ return () => clearTimeout(timer);
105
+ }, [rateLimitSeconds]);
106
+
107
+ // On a page, a request the controller runs (the embedded QR, or one shown in
108
+ // the dialog opened over it) finishes the page's sign-in too. Only one that
109
+ // STARTED here: a completion already on the controller is somebody else's.
110
+ const [mountedAttempt] = useState(snapshot.signIn.attempt);
111
+ const completedHere = snapshot.signIn.phase === 'completed' && snapshot.signIn.attempt !== mountedAttempt;
112
+ useEffect(() => {
113
+ if (host === 'page' && completedHere) onSignedIn();
114
+ }, [host, completedHere, onSignedIn]);
115
+
116
+ /** Show the request a controller call just started — the dialog is where it lives. */
117
+ const showRequest = useCallback(() => {
118
+ if (host === 'page') openAccountDialog('qr');
119
+ }, [host, openAccountDialog]);
120
+
121
+ // These open a window or leave the page, so they run straight from the
122
+ // press, before any await.
123
+ const continueWithOxy = () => {
124
+ void controller?.signInWithOxy();
125
+ showRequest();
126
+ };
127
+ const signInOnOxy = () => {
128
+ void continueOnAuth('signin').then((result) => {
129
+ if (result.status === 'signed-in') onSignedIn();
130
+ else if (result.status === 'failed') toast.error(t('signin.errors.failed'));
131
+ });
132
+ };
133
+ const useAnotherDevice = () => {
134
+ void controller?.showQr();
135
+ showRequest();
136
+ };
137
+ const getCommons = () => {
138
+ Promise.resolve()
139
+ .then(() => Linking.openURL(getCommonsAcquisitionUrl(Platform.OS)))
140
+ .catch(() => toast.error(t('accountSwitcher.linkOpenFailed')));
141
+ };
142
+
143
+ const runPasskey = async (username: string | undefined, failToast: string) => {
144
+ if (blocked) return;
145
+ setError(null);
146
+ setPending(true);
147
+ try {
148
+ await signInWithPasskey({ username });
149
+ onSignedIn();
150
+ } catch (err) {
151
+ if (isRateLimited(err)) {
152
+ setRateLimitSeconds(RATE_LIMIT_SECONDS);
153
+ } else {
154
+ const message = describePasskeyError(err, t);
155
+ setError(message);
156
+ toast.error(failToast, { description: message });
157
+ }
158
+ } finally {
159
+ setPending(false);
160
+ }
161
+ };
162
+ const submitUsername = () => {
163
+ const username = identifier.trim();
164
+ if (username) void runPasskey(username, t('signin.errors.failed'));
165
+ else setError(t('signin.username.required'));
166
+ };
167
+
168
+ // A returning device starts at WHO. Not while adding an account from inside
169
+ // a signed-in app: the rows are the accounts it would add.
170
+ const pickerAllowed = host === 'dialog' ? !snapshot.hasSession : activeContext !== null;
171
+ const reauthenticate = (context: SwitcherContextRow) => {
172
+ setIdentifier(context.handle ?? '');
173
+ setShowForm(true);
174
+ };
175
+ const selectContext = async (context: SwitcherContextRow) => {
176
+ const outcome = await controller?.chooseContext(context.contextId).catch(() => 'failed' as const);
177
+ switch (outcome) {
178
+ case 'switched':
179
+ // Every account-scoped query now describes somebody else.
180
+ void queryClient.invalidateQueries();
181
+ onSignedIn();
182
+ return;
183
+ case 'current':
184
+ onSignedIn();
185
+ return;
186
+ case 'signing-in':
187
+ // The request for that account is running; it shows where requests do.
188
+ showRequest();
189
+ return;
190
+ case 'failed':
191
+ // The pair could not be activated as it stands: sign in as it explicitly.
192
+ if (methods.passkey && context.handle) reauthenticate(context);
193
+ else toast.error(t('accountSwitcher.toasts.activateFailed'));
194
+ return;
195
+ default:
196
+ return;
197
+ }
198
+ };
199
+
200
+ const showsPicker = pickerAllowed && !showForm && principals.length > 0;
201
+ // auth.oxy.so's page is the split card from `md`.
202
+ const splits = methods.commons === 'qr';
203
+
204
+ if (showsPicker) {
205
+ return (
206
+ <OxyAccountPicker
207
+ principals={principals}
208
+ appName={appName}
209
+ signedOut={!snapshot.hasSession}
210
+ pendingContextId={snapshot.activatingContextId}
211
+ isLoading={snapshot.activatingContextId !== null}
212
+ onSelectContext={(context) => void selectContext(context)}
213
+ onUseAnother={() => {
214
+ setIdentifier('');
215
+ setShowForm(true);
216
+ }}
217
+ />
218
+ );
219
+ }
220
+
221
+ const shownError = rateLimitSeconds > 0 ? t('signin.errors.rateLimited', { seconds: rateLimitSeconds }) : error;
222
+
223
+ const adding = host === 'dialog' && snapshot.hasSession;
224
+ const title = adding ? t('signin.addAccountTitle') : t('signin.title');
225
+ const description = adding
226
+ ? t('signin.addAccountSubtitle')
227
+ : appName
228
+ ? t('signin.subtitleToApp', { app: appName })
229
+ : t('signin.subtitle');
230
+ const noAccount = (
231
+ <Text style={[styles.note, styles.noAccount, { color: theme.colors.textSecondary }]}>
232
+ {t('signin.noAccount')}{' '}
233
+ <RNText
234
+ accessibilityRole="link"
235
+ onPress={onCreateAccount}
236
+ style={[styles.noAccountLink, { color: theme.colors.text }]}
237
+ testID="create-account-link"
238
+ >
239
+ {t('signin.createAccount')}
240
+ </RNText>
241
+ </Text>
242
+ );
243
+ // One solid action per screen: the username's Continue when there is one.
244
+ const commonsAppearance = methods.passkey ? 'outline' : 'solid';
245
+
246
+ const continueWithOxyButton = (
247
+ <Button
248
+ appearance={commonsAppearance}
249
+ tone={commonsAppearance === 'solid' ? 'action' : 'neutral'}
250
+ size="lg"
251
+ fullWidth
252
+ onPress={methods.commons === 'window' ? signInOnOxy : continueWithOxy}
253
+ testID="continue-with-oxy"
254
+ >
255
+ {t('accountSwitcher.continueWithOxy')}
256
+ </Button>
257
+ );
258
+
259
+ const form = (
260
+ <OxyAuthScreen className={splits ? 'md:max-w-none' : undefined}>
261
+ <OxyAuthScreenHeader title={title} description={description} />
262
+
263
+ {/* Below `md` this screen is the phone a QR would be scanned with. */}
264
+ {splits ? <CssView className="md:hidden">{continueWithOxyButton}</CssView> : null}
265
+
266
+ {methods.commons === 'continue' || methods.commons === 'window' ? continueWithOxyButton : null}
267
+ {methods.commons === 'get-commons' ? (
268
+ <View style={styles.stack}>
269
+ <Text style={[styles.note, { color: theme.colors.textSecondary }]}>{t('accountSwitcher.commonsNotInstalled')}</Text>
270
+ <Button appearance="solid" tone="action" size="lg" fullWidth onPress={getCommons} testID="get-commons-button">
271
+ {t('accountSwitcher.getCommons')}
272
+ </Button>
273
+ </View>
274
+ ) : null}
275
+
276
+ {methods.passkey ? (
277
+ <View style={styles.stack}>
278
+ <View style={styles.field}>
279
+ <TextFieldLabel nativeID="username-label">{t('signin.username.label')}</TextFieldLabel>
280
+ <TextField invalid={shownError !== null} disabled={blocked} radius={999} style={styles.input}>
281
+ <TextFieldInput
282
+ testID="username"
283
+ label={t('signin.username.label')}
284
+ value={identifier}
285
+ onValueChange={(value) => {
286
+ setIdentifier(value);
287
+ if (error) setError(null);
288
+ }}
289
+ placeholder={t('signin.username.placeholder')}
290
+ autoComplete="username"
291
+ autoCapitalize="none"
292
+ autoCorrect={false}
293
+ autoFocus={Platform.OS === 'web'}
294
+ returnKeyType="go"
295
+ onSubmitEditing={submitUsername}
296
+ aria-required
297
+ />
298
+ </TextField>
299
+ {shownError ? <TextFieldHint invalid>{shownError}</TextFieldHint> : null}
300
+ </View>
301
+ {noAccount}
302
+ <Button
303
+ appearance="solid"
304
+ tone="action"
305
+ size="lg"
306
+ fullWidth
307
+ loading={pending}
308
+ disabled={blocked}
309
+ onPress={submitUsername}
310
+ testID="username-continue"
311
+ >
312
+ {t('signin.actions.continue')}
313
+ </Button>
314
+ </View>
315
+ ) : null}
316
+
317
+ {/* The alternatives to the screen's primary way in, always under it. The
318
+ window an app opens on the web is where they all are. */}
319
+ {methods.commons === 'window' ? null : <Divider>{t('signin.orContinueWith')}</Divider>}
320
+
321
+ {methods.passkey ? (
322
+ <Button
323
+ appearance="outline"
324
+ tone="neutral"
325
+ size="lg"
326
+ fullWidth
327
+ leadingIcon={RiKey2Line}
328
+ disabled={blocked}
329
+ onPress={() => void runPasskey(undefined, t('signin.errors.failed'))}
330
+ testID="passkey-sign-in"
331
+ >
332
+ {t('signin.methods.passkey')}
333
+ </Button>
334
+ ) : methods.commons === 'window' ? null : (
335
+ <Button
336
+ appearance="outline"
337
+ tone="neutral"
338
+ size="lg"
339
+ fullWidth
340
+ leadingIcon={RiQrCodeLine}
341
+ onPress={useAnotherDevice}
342
+ testID="scan-qr"
343
+ >
344
+ {t('accountSwitcher.scanQr')}
345
+ </Button>
346
+ )}
347
+
348
+ {methods.passkey ? null : noAccount}
349
+ {onRecover ? (
350
+ <SubtleLink label={t('signin.recoverLink')} theme={theme} onPress={onRecover} testID="recover-link" />
351
+ ) : null}
352
+ <OxyAuthTerms />
353
+ </OxyAuthScreen>
354
+ );
355
+
356
+ if (!splits) return form;
357
+ return (
358
+ <OxyAuthSplit
359
+ aside={
360
+ <>
361
+ <AuthMediaCarousel slides={SIGN_IN_SLIDES} style={StyleSheet.absoluteFill} />
362
+ <InlineCommonsQr controller={controller} />
363
+ </>
364
+ }
365
+ >
366
+ {form}
367
+ </OxyAuthSplit>
368
+ );
369
+ };
370
+
371
+ const styles = StyleSheet.create({
372
+ stack: {
373
+ gap: 12,
374
+ },
375
+ field: {
376
+ gap: 6,
377
+ },
378
+ note: {
379
+ fontSize: 14,
380
+ lineHeight: 20,
381
+ textAlign: 'center',
382
+ },
383
+ noAccount: {
384
+ textAlign: 'left',
385
+ },
386
+ noAccountLink: {
387
+ textDecorationLine: 'underline',
388
+ },
389
+ input: {
390
+ height: 40,
391
+ },
392
+ });
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Account creation in the account dialog.
3
+ *
4
+ * On the web the account is made on auth.oxy.so, in its window over the app
5
+ * (`onCreateOnWeb`), and this app is signed in as it. On native, Commons
6
+ * creates the identity: straight in when it is installed, "Get Commons"
7
+ * otherwise.
8
+ */
9
+
10
+ import type React from 'react';
11
+ import { useCallback } from 'react';
12
+ import { Linking, Platform } from 'react-native';
13
+ import { Button } from '@oxy.so/bloom/button';
14
+ import { RiKey2Line } from '@oxy.so/bloom/icons/RiKey2Line';
15
+ import { useTheme } from '@oxy.so/bloom/theme';
16
+ import { toast } from '@oxy.so/bloom/toast';
17
+ import { useOxy } from '../../context/OxyContext';
18
+ import { useAccountDialogSnapshot } from '../../hooks/accountDialogSnapshot';
19
+ import { useI18n } from '../../hooks/useI18n';
20
+ import { getCommonsAcquisitionUrl } from '../../utils/commonsStoreLinks';
21
+ import { isWebBrowser } from '../../utils/isWebBrowser';
22
+ import { SubtleLink } from '../authChooser/primitives';
23
+ import { OxyAuthScreen, OxyAuthScreenHeader, OxyAuthTerms } from './OxyAuthScreen';
24
+
25
+ /** Commons' own identity-creation deep link. */
26
+ const COMMONS_CREATE_IDENTITY_URL = 'oxycommons://create-identity';
27
+
28
+ export interface OxySignUpPanelProps {
29
+ /** "Already have an account? Sign in". */
30
+ onSignIn: () => void;
31
+ /** The web's one action: auth.oxy.so's sign-up, in its window. */
32
+ onCreateOnWeb: () => void;
33
+ }
34
+
35
+ export const OxySignUpPanel: React.FC<OxySignUpPanelProps> = ({ onSignIn, onCreateOnWeb }) => {
36
+ const theme = useTheme();
37
+ const { t } = useI18n();
38
+ const { accountDialogController: controller } = useOxy();
39
+ const snapshot = useAccountDialogSnapshot(controller);
40
+ const web = isWebBrowser();
41
+
42
+ const openExternal = useCallback(
43
+ (url: string) => {
44
+ Promise.resolve()
45
+ .then(() => Linking.openURL(url))
46
+ .catch(() => toast.error(t('accountSwitcher.linkOpenFailed')));
47
+ },
48
+ [t],
49
+ );
50
+
51
+ const commonsInstalled = snapshot.commonsAvailability === 'available';
52
+
53
+ return (
54
+ <OxyAuthScreen>
55
+ <OxyAuthScreenHeader title={t('signup.title')} description={web ? t('signup.webSubtitle') : t('signup.subtitle')} />
56
+ {web ? (
57
+ <Button
58
+ appearance="solid"
59
+ tone="action"
60
+ size="lg"
61
+ fullWidth
62
+ leadingIcon={RiKey2Line}
63
+ onPress={onCreateOnWeb}
64
+ testID="signup-open-identity"
65
+ >
66
+ {t('signup.createAccount')}
67
+ </Button>
68
+ ) : (
69
+ <Button
70
+ appearance="solid"
71
+ tone="action"
72
+ size="lg"
73
+ fullWidth
74
+ onPress={() =>
75
+ openExternal(commonsInstalled ? COMMONS_CREATE_IDENTITY_URL : getCommonsAcquisitionUrl(Platform.OS))
76
+ }
77
+ testID="signup-commons"
78
+ >
79
+ {commonsInstalled ? t('signup.createInCommons') : t('accountSwitcher.getCommons')}
80
+ </Button>
81
+ )}
82
+ <SubtleLink label={t('signup.backToSignInLink')} theme={theme} onPress={onSignIn} testID="back-to-sign-in" />
83
+ <OxyAuthTerms />
84
+ </OxyAuthScreen>
85
+ );
86
+ };
@@ -0,0 +1,204 @@
1
+ /**
2
+ * The pieces auth.oxy.so's account pages share (ADR 0029 D3): creating a
3
+ * passkey account, recovering one, deleting one. Each is a page of the IdP
4
+ * built from the same sign-in shell as `OxySignInPanel`, so they read as one
5
+ * product; the passkey belongs to auth.oxy.so, so none of them runs anywhere
6
+ * else.
7
+ */
8
+
9
+ import type React from 'react';
10
+ import { useState } from 'react';
11
+ import { StyleSheet, View } from 'react-native';
12
+ import { Button } from '@oxy.so/bloom/button';
13
+ import { useTheme } from '@oxy.so/bloom/theme';
14
+ import { TextField, TextFieldHint, TextFieldInput, TextFieldLabel } from '@oxy.so/bloom/text-field';
15
+ import { Text } from '@oxy.so/bloom/typography';
16
+ import { EMAIL_CODE_LENGTH, EMAIL_VERIFICATION_ERROR_CODES, type EmailVerificationConfirmResponse } from '@oxy.so/contracts';
17
+ import { useOxy } from '../../context/OxyContext';
18
+ import { useI18n } from '../../hooks/useI18n';
19
+ import type { Translate } from '../authChooser/types';
20
+ import { SubtleLink } from '../authChooser/primitives';
21
+ import { OxyAuthScreen, OxyAuthScreenHeader } from './OxyAuthScreen';
22
+ import { describePasskeyError, isRateLimited } from './passkeyError';
23
+
24
+ /** The API error code a thrown SDK error carries (`error.code`), if any. */
25
+ function errorCode(error: unknown): string | undefined {
26
+ const code = (error as { code?: unknown } | null)?.code;
27
+ return typeof code === 'string' ? code : undefined;
28
+ }
29
+
30
+ /** A failure of an account page, in the person's language. */
31
+ export function describeAccountFlowError(error: unknown, t: Translate): string {
32
+ switch (errorCode(error)) {
33
+ case EMAIL_VERIFICATION_ERROR_CODES.codeInvalid:
34
+ return t('emailCode.errors.codeInvalid');
35
+ case EMAIL_VERIFICATION_ERROR_CODES.tooManyAttempts:
36
+ return t('emailCode.errors.tooManyAttempts');
37
+ case EMAIL_VERIFICATION_ERROR_CODES.ticketInvalid:
38
+ case EMAIL_VERIFICATION_ERROR_CODES.ticketRequired:
39
+ return t('emailCode.errors.expired');
40
+ case EMAIL_VERIFICATION_ERROR_CODES.unavailable:
41
+ return t('emailCode.errors.unavailable');
42
+ default:
43
+ if (isRateLimited(error)) return t('emailCode.errors.rateLimited');
44
+ return describePasskeyError(error, t);
45
+ }
46
+ }
47
+
48
+ /** Whether the confirmation this flow holds is gone and it must start again. */
49
+ export function isTicketExpired(error: unknown): boolean {
50
+ const code = errorCode(error);
51
+ return code === EMAIL_VERIFICATION_ERROR_CODES.ticketInvalid || code === EMAIL_VERIFICATION_ERROR_CODES.ticketRequired;
52
+ }
53
+
54
+ /** One labelled input, the way the sign-in screen draws its username. */
55
+ export const AccountFlowField: React.FC<{
56
+ label: string;
57
+ value: string;
58
+ onChange: (value: string) => void;
59
+ onSubmit: () => void;
60
+ error: string | null;
61
+ disabled?: boolean;
62
+ placeholder?: string;
63
+ autoComplete?: 'username' | 'email' | 'one-time-code' | 'off';
64
+ keyboardType?: 'default' | 'email-address' | 'number-pad';
65
+ maxLength?: number;
66
+ testID: string;
67
+ }> = ({ label, value, onChange, onSubmit, error, disabled, placeholder, autoComplete, keyboardType, maxLength, testID }) => (
68
+ <View style={styles.field}>
69
+ <TextFieldLabel>{label}</TextFieldLabel>
70
+ <TextField invalid={error !== null} disabled={disabled} radius={999} style={styles.input}>
71
+ <TextFieldInput
72
+ testID={testID}
73
+ label={label}
74
+ value={value}
75
+ onValueChange={onChange}
76
+ placeholder={placeholder}
77
+ autoComplete={autoComplete}
78
+ keyboardType={keyboardType}
79
+ maxLength={maxLength}
80
+ autoCapitalize="none"
81
+ autoCorrect={false}
82
+ autoFocus
83
+ returnKeyType="go"
84
+ onSubmitEditing={onSubmit}
85
+ aria-required
86
+ />
87
+ </TextField>
88
+ {error ? <TextFieldHint invalid>{error}</TextFieldHint> : null}
89
+ </View>
90
+ );
91
+
92
+ /** The screen's one primary action. */
93
+ export const AccountFlowAction: React.FC<{
94
+ label: string;
95
+ onPress: () => void;
96
+ pending: boolean;
97
+ disabled?: boolean;
98
+ testID: string;
99
+ }> = ({ label, onPress, pending, disabled, testID }) => (
100
+ <Button appearance="solid" tone="action" size="lg" fullWidth loading={pending} disabled={pending || disabled} onPress={onPress} testID={testID}>
101
+ {label}
102
+ </Button>
103
+ );
104
+
105
+ /** A line of body copy under the header. */
106
+ export const AccountFlowNote: React.FC<{ children: React.ReactNode }> = ({ children }) => {
107
+ const theme = useTheme();
108
+ return <Text style={[styles.note, { color: theme.colors.textSecondary }]}>{children}</Text>;
109
+ };
110
+
111
+ /** Why a step failed, where it happened. */
112
+ export const AccountFlowErrorLine: React.FC<{ message: string }> = ({ message }) => {
113
+ const theme = useTheme();
114
+ return (
115
+ <Text accessibilityRole="alert" style={[styles.note, { color: theme.colors.error }]}>
116
+ {message}
117
+ </Text>
118
+ );
119
+ };
120
+
121
+ export interface EmailCodeStepProps {
122
+ /** What was sent, and where (or, for a recovery, where it may have gone). */
123
+ description: string;
124
+ verificationId: string;
125
+ onConfirmed: (confirmed: EmailVerificationConfirmResponse) => void;
126
+ /** Send a new code; resolves once it is on its way. */
127
+ onResend: () => Promise<void>;
128
+ /** "Use another email" / "Back" — the step before. */
129
+ back: { label: string; onPress: () => void };
130
+ }
131
+
132
+ /** "Check your email": the 6-digit code a verification sent. */
133
+ export const EmailCodeStep: React.FC<EmailCodeStepProps> = ({ description, verificationId, onConfirmed, onResend, back }) => {
134
+ const theme = useTheme();
135
+ const { t } = useI18n();
136
+ const { oxyServices } = useOxy();
137
+ const [code, setCode] = useState('');
138
+ const [pending, setPending] = useState(false);
139
+ const [error, setError] = useState<string | null>(null);
140
+ const [notice, setNotice] = useState<string | null>(null);
141
+
142
+ const confirm = () => {
143
+ const digits = code.replace(/\D/g, '');
144
+ if (digits.length !== EMAIL_CODE_LENGTH || pending) {
145
+ setError(t('emailCode.errors.codeInvalid'));
146
+ return;
147
+ }
148
+ setError(null);
149
+ setPending(true);
150
+ oxyServices
151
+ .confirmEmailVerification(verificationId, digits)
152
+ .then(onConfirmed)
153
+ .catch((reason: unknown) => setError(describeAccountFlowError(reason, t)))
154
+ .finally(() => setPending(false));
155
+ };
156
+
157
+ const resend = () => {
158
+ setError(null);
159
+ setNotice(null);
160
+ setCode('');
161
+ onResend()
162
+ .then(() => setNotice(t('emailCode.resent')))
163
+ .catch((reason: unknown) => setError(describeAccountFlowError(reason, t)));
164
+ };
165
+
166
+ return (
167
+ <OxyAuthScreen>
168
+ <OxyAuthScreenHeader title={t('emailCode.title')} description={description} />
169
+ <AccountFlowField
170
+ label={t('emailCode.label')}
171
+ value={code}
172
+ onChange={(value) => {
173
+ setCode(value);
174
+ if (error) setError(null);
175
+ }}
176
+ onSubmit={confirm}
177
+ error={error}
178
+ disabled={pending}
179
+ placeholder="000000"
180
+ autoComplete="one-time-code"
181
+ keyboardType="number-pad"
182
+ maxLength={EMAIL_CODE_LENGTH}
183
+ testID="email-code"
184
+ />
185
+ {notice ? <Text style={[styles.note, { color: theme.colors.textSecondary }]}>{notice}</Text> : null}
186
+ <AccountFlowAction label={t('signin.actions.continue')} onPress={confirm} pending={pending} testID="email-code-continue" />
187
+ <SubtleLink label={t('emailCode.resend')} theme={theme} onPress={resend} disabled={pending} testID="email-code-resend" />
188
+ <SubtleLink label={back.label} theme={theme} onPress={back.onPress} disabled={pending} testID="email-code-back" />
189
+ </OxyAuthScreen>
190
+ );
191
+ };
192
+
193
+ const styles = StyleSheet.create({
194
+ field: {
195
+ gap: 6,
196
+ },
197
+ input: {
198
+ height: 40,
199
+ },
200
+ note: {
201
+ fontSize: 16,
202
+ lineHeight: 24,
203
+ },
204
+ });
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The photos the sign-in split card's carousel turns through. Shipped with the
3
+ * SDK and imported like its icon fonts, so every host serves them from its own
4
+ * origin — nothing to allow in anyone's CSP.
5
+ */
6
+
7
+ import type { AuthMediaSlide } from '@oxy.so/bloom/auth-card';
8
+ import slide1 from '../../../assets/signIn/slide-1.jpg';
9
+ import slide2 from '../../../assets/signIn/slide-2.jpg';
10
+ import slide3 from '../../../assets/signIn/slide-3.jpg';
11
+ import slide4 from '../../../assets/signIn/slide-4.jpg';
12
+
13
+ export const SIGN_IN_SLIDES: AuthMediaSlide[] = [slide1, slide2, slide3, slide4].map((source) => ({ source }));