@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,106 @@
1
+ /**
2
+ * Deleting a passkey account (ADR 0029 D3), auth.oxy.so's `/delete-account`.
3
+ *
4
+ * A passkey account has no key to sign its deletion with, so the person types
5
+ * the username and asserts one of the account's passkeys — on auth.oxy.so, the
6
+ * one origin that asserts them — over a challenge the API minted for the
7
+ * account. An account with a Commons key is deleted in Commons, with its key.
8
+ * The page must be signed in as the account; the host renders sign-in first.
9
+ */
10
+
11
+ import type React from 'react';
12
+ import { useState } from 'react';
13
+ import { useOxy } from '../../context/OxyContext';
14
+ import { useI18n } from '../../hooks/useI18n';
15
+ import { isPasskeySupported, runAuthenticationCeremony } from '../../../webauthn/passkeyClient';
16
+ import { PASSKEY_UNSUPPORTED_MESSAGE } from '../../context/passkeyFlow';
17
+ import { OxyAuthScreen, OxyAuthScreenHeader } from './OxyAuthScreen';
18
+ import {
19
+ AccountFlowAction,
20
+ AccountFlowErrorLine,
21
+ AccountFlowField,
22
+ AccountFlowNote,
23
+ describeAccountFlowError,
24
+ } from './accountFlowParts';
25
+
26
+ export interface OxyDeleteAccountPanelProps {
27
+ /** The account is gone and this origin signed out of it. */
28
+ onDeleted?: () => void;
29
+ }
30
+
31
+ export const OxyDeleteAccountPanel: React.FC<OxyDeleteAccountPanelProps> = ({ onDeleted }) => {
32
+ const { t } = useI18n();
33
+ const { user, oxyServices, logout } = useOxy();
34
+ const [confirmText, setConfirmText] = useState('');
35
+ const [pending, setPending] = useState(false);
36
+ const [error, setError] = useState<string | null>(null);
37
+ const [deleted, setDeleted] = useState(false);
38
+
39
+ if (deleted) {
40
+ return (
41
+ <OxyAuthScreen>
42
+ <OxyAuthScreenHeader title={t('deleteAccount.passkey.done')} description={t('deleteAccount.passkey.closeWindow')} />
43
+ </OxyAuthScreen>
44
+ );
45
+ }
46
+
47
+ const username = user?.username ?? '';
48
+ if (user?.publicKey) {
49
+ return (
50
+ <OxyAuthScreen>
51
+ <OxyAuthScreenHeader title={t('deleteAccount.handoff.commonsTitle')} description={t('deleteAccount.passkey.commons')} />
52
+ </OxyAuthScreen>
53
+ );
54
+ }
55
+
56
+ // The ceremony opens the browser's passkey prompt, so it starts from the press.
57
+ const remove = () => {
58
+ if (pending) return;
59
+ if (confirmText.trim() !== username) {
60
+ setError(t('deleteAccount.confirmLabel', { username }));
61
+ return;
62
+ }
63
+ setError(null);
64
+ setPending(true);
65
+ (async () => {
66
+ if (!isPasskeySupported()) throw new Error(PASSKEY_UNSUPPORTED_MESSAGE);
67
+ const options = await oxyServices.getAccountDeletionOptions();
68
+ const assertion = await runAuthenticationCeremony(options);
69
+ await oxyServices.deleteAccountWithPasskey(confirmText.trim(), assertion);
70
+ await logout().catch(() => undefined);
71
+ setDeleted(true);
72
+ onDeleted?.();
73
+ })()
74
+ .catch((reason: unknown) => setError(describeAccountFlowError(reason, t)))
75
+ .finally(() => setPending(false));
76
+ };
77
+
78
+ return (
79
+ <OxyAuthScreen>
80
+ <OxyAuthScreenHeader title={t('deleteAccount.title')} description={t('deleteAccount.passkey.subtitle', { username })} />
81
+ <AccountFlowNote>{t('deleteAccount.warning')}</AccountFlowNote>
82
+ <AccountFlowField
83
+ label={t('deleteAccount.confirmLabel', { username })}
84
+ value={confirmText}
85
+ onChange={(value) => {
86
+ setConfirmText(value);
87
+ if (error) setError(null);
88
+ }}
89
+ onSubmit={remove}
90
+ error={null}
91
+ disabled={pending}
92
+ placeholder={username}
93
+ autoComplete="off"
94
+ testID="delete-account-confirm"
95
+ />
96
+ {error ? <AccountFlowErrorLine message={error} /> : null}
97
+ <AccountFlowAction
98
+ label={t('deleteAccount.passkey.action')}
99
+ onPress={remove}
100
+ pending={pending}
101
+ disabled={confirmText.trim() !== username}
102
+ testID="delete-account-passkey"
103
+ />
104
+ </OxyAuthScreen>
105
+ );
106
+ };
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Linking Commons to a passkey account (ADR 0029 D3), auth.oxy.so's
3
+ * `/link-commons`:
4
+ *
5
+ * QR → Commons scans and signs with its key → both screens show the same
6
+ * code → the person confirms here with the passkey → linked
7
+ *
8
+ * Afterwards the account is self-custodied: its root is the key Commons holds,
9
+ * its recovery email is deleted, and its phrase in Commons is how it gets back
10
+ * in. The passkey keeps signing in on the web. The page must be signed in as
11
+ * the account; the host renders sign-in first.
12
+ */
13
+
14
+ import type React from 'react';
15
+ import { useCallback, useEffect, useRef, useState } from 'react';
16
+ import { ActivityIndicator, StyleSheet, View } from 'react-native';
17
+ import QRCode from 'react-native-qrcode-svg';
18
+ import { Button } from '@oxy.so/bloom/button';
19
+ import { useTheme } from '@oxy.so/bloom/theme';
20
+ import { Text } from '@oxy.so/bloom/typography';
21
+ import { deriveIdentityLinkCode } from '@oxy.so/core';
22
+ import type { IdentityLinkCreateResponse } from '@oxy.so/contracts';
23
+ import { useOxy } from '../../context/OxyContext';
24
+ import { PASSKEY_UNSUPPORTED_MESSAGE } from '../../context/passkeyFlow';
25
+ import { useI18n } from '../../hooks/useI18n';
26
+ import { isPasskeySupported, runAuthenticationCeremony } from '../../../webauthn/passkeyClient';
27
+ import { OxyAuthScreen, OxyAuthScreenHeader } from './OxyAuthScreen';
28
+ import { AccountFlowAction, AccountFlowErrorLine, AccountFlowNote, describeAccountFlowError } from './accountFlowParts';
29
+
30
+ /** How often the page asks whether Commons has signed. */
31
+ export const IDENTITY_LINK_POLL_MS = 2000;
32
+
33
+ /** High-contrast, un-themed on purpose: scan reliability. */
34
+ const QR_PLATE_BG = '#FFFFFF';
35
+ const QR_FOREGROUND = '#000000';
36
+ const QR_SIZE = 200;
37
+
38
+ type Step =
39
+ | { name: 'opening' }
40
+ | { name: 'qr'; link: IdentityLinkCreateResponse }
41
+ | { name: 'matching'; link: IdentityLinkCreateResponse; code: string }
42
+ | { name: 'expired' }
43
+ | { name: 'done' };
44
+
45
+ export interface OxyLinkCommonsPanelProps {
46
+ /** Commons is linked. */
47
+ onLinked?: () => void;
48
+ }
49
+
50
+ export const OxyLinkCommonsPanel: React.FC<OxyLinkCommonsPanelProps> = ({ onLinked }) => {
51
+ const theme = useTheme();
52
+ const { t } = useI18n();
53
+ const { user, oxyServices } = useOxy();
54
+ const [step, setStep] = useState<Step>({ name: 'opening' });
55
+ const [pending, setPending] = useState(false);
56
+ const [error, setError] = useState<string | null>(null);
57
+ const alreadyLinked = Boolean(user?.publicKey);
58
+
59
+ const open = useCallback(() => {
60
+ setError(null);
61
+ setStep({ name: 'opening' });
62
+ oxyServices
63
+ .createIdentityLink()
64
+ .then((link) => setStep({ name: 'qr', link }))
65
+ .catch((reason: unknown) => {
66
+ setError(describeAccountFlowError(reason, t));
67
+ setStep({ name: 'expired' });
68
+ });
69
+ }, [oxyServices, t]);
70
+
71
+ // One request per visit, opened once the page knows the account has no root.
72
+ const opened = useRef(false);
73
+ useEffect(() => {
74
+ if (alreadyLinked || opened.current) return;
75
+ opened.current = true;
76
+ open();
77
+ }, [alreadyLinked, open]);
78
+
79
+ // While the QR shows, ask whether Commons has signed; a request only lives a
80
+ // few minutes, and an expired one says so instead of waiting forever.
81
+ const link = step.name === 'qr' ? step.link : null;
82
+ useEffect(() => {
83
+ if (!link) return;
84
+ let stopped = false;
85
+ const poll = async () => {
86
+ if (stopped) return;
87
+ if (Date.now() >= link.expiresAt) {
88
+ setStep({ name: 'expired' });
89
+ return;
90
+ }
91
+ try {
92
+ const state = await oxyServices.getIdentityLink(link.linkId);
93
+ if (stopped) return;
94
+ if (state.status === 'signed' && state.publicKey) {
95
+ setStep({ name: 'matching', link, code: deriveIdentityLinkCode(link.linkId, state.publicKey) });
96
+ return;
97
+ }
98
+ if (state.status === 'cancelled') {
99
+ setStep({ name: 'expired' });
100
+ return;
101
+ }
102
+ } catch {
103
+ // A missed poll is retried on the next tick.
104
+ }
105
+ if (!stopped) timer = setTimeout(() => void poll(), IDENTITY_LINK_POLL_MS);
106
+ };
107
+ let timer = setTimeout(() => void poll(), IDENTITY_LINK_POLL_MS);
108
+ return () => {
109
+ stopped = true;
110
+ clearTimeout(timer);
111
+ };
112
+ }, [link, oxyServices]);
113
+
114
+ // The ceremony opens the browser's passkey prompt, so it starts from the press.
115
+ const confirm = (confirmed: IdentityLinkCreateResponse) => {
116
+ if (pending) return;
117
+ setError(null);
118
+ setPending(true);
119
+ (async () => {
120
+ if (!isPasskeySupported()) throw new Error(PASSKEY_UNSUPPORTED_MESSAGE);
121
+ const options = await oxyServices.getIdentityLinkAssertionOptions(confirmed.linkId, confirmed.challenge);
122
+ const assertion = await runAuthenticationCeremony(options);
123
+ await oxyServices.completeIdentityLink(confirmed.linkId, assertion);
124
+ setStep({ name: 'done' });
125
+ onLinked?.();
126
+ })()
127
+ .catch((reason: unknown) => setError(describeAccountFlowError(reason, t)))
128
+ .finally(() => setPending(false));
129
+ };
130
+
131
+ const cancel = (cancelled: IdentityLinkCreateResponse) => {
132
+ void oxyServices.cancelIdentityLink(cancelled.linkId).catch(() => undefined);
133
+ setStep({ name: 'expired' });
134
+ };
135
+
136
+ if (alreadyLinked) {
137
+ return (
138
+ <OxyAuthScreen>
139
+ <OxyAuthScreenHeader title={t('linkCommons.title')} description={t('linkCommons.already')} />
140
+ </OxyAuthScreen>
141
+ );
142
+ }
143
+
144
+ switch (step.name) {
145
+ case 'done':
146
+ return (
147
+ <OxyAuthScreen>
148
+ <OxyAuthScreenHeader title={t('linkCommons.doneTitle')} description={t('linkCommons.done')} />
149
+ </OxyAuthScreen>
150
+ );
151
+ case 'expired':
152
+ return (
153
+ <OxyAuthScreen>
154
+ <OxyAuthScreenHeader title={t('linkCommons.title')} description={t('linkCommons.expired')} />
155
+ {error ? <AccountFlowErrorLine message={error} /> : null}
156
+ <AccountFlowAction label={t('linkCommons.renew')} onPress={open} pending={false} testID="link-commons-renew" />
157
+ </OxyAuthScreen>
158
+ );
159
+ case 'matching':
160
+ return (
161
+ <OxyAuthScreen>
162
+ <OxyAuthScreenHeader title={t('linkCommons.compareTitle')} description={t('linkCommons.compare')} />
163
+ <Text
164
+ accessibilityLabel={step.code.split('').join(' ')}
165
+ style={[styles.code, { color: theme.colors.text }]}
166
+ testID="link-commons-code"
167
+ >
168
+ {`${step.code.slice(0, 3)} ${step.code.slice(3)}`}
169
+ </Text>
170
+ {error ? <AccountFlowErrorLine message={error} /> : null}
171
+ <AccountFlowAction label={t('linkCommons.confirm')} onPress={() => confirm(step.link)} pending={pending} testID="link-commons-confirm" />
172
+ <Button appearance="plain" tone="neutral" size="lg" fullWidth disabled={pending} onPress={() => cancel(step.link)} testID="link-commons-cancel">
173
+ {t('linkCommons.cancel')}
174
+ </Button>
175
+ </OxyAuthScreen>
176
+ );
177
+ case 'qr':
178
+ return (
179
+ <OxyAuthScreen>
180
+ <OxyAuthScreenHeader title={t('linkCommons.title')} description={t('linkCommons.subtitle')} />
181
+ <View style={styles.plateRow}>
182
+ <View style={[styles.plate, { borderColor: theme.colors.border }]} testID="link-commons-qr">
183
+ <QRCode value={step.link.qrPayload} size={QR_SIZE} backgroundColor={QR_PLATE_BG} color={QR_FOREGROUND} />
184
+ </View>
185
+ </View>
186
+ <AccountFlowNote>{t('linkCommons.scan')}</AccountFlowNote>
187
+ <AccountFlowNote>{t('linkCommons.waiting')}</AccountFlowNote>
188
+ <Button appearance="plain" tone="neutral" size="lg" fullWidth onPress={() => cancel(step.link)} testID="link-commons-cancel">
189
+ {t('linkCommons.cancel')}
190
+ </Button>
191
+ </OxyAuthScreen>
192
+ );
193
+ default:
194
+ return (
195
+ <OxyAuthScreen>
196
+ <OxyAuthScreenHeader title={t('linkCommons.title')} description={t('linkCommons.subtitle')} />
197
+ <View style={styles.plateRow}>
198
+ <ActivityIndicator size="large" color={theme.colors.primary} />
199
+ </View>
200
+ </OxyAuthScreen>
201
+ );
202
+ }
203
+ };
204
+
205
+ const styles = StyleSheet.create({
206
+ plateRow: {
207
+ alignItems: 'center',
208
+ },
209
+ plate: {
210
+ padding: 12,
211
+ borderRadius: 16,
212
+ borderWidth: StyleSheet.hairlineWidth,
213
+ backgroundColor: QR_PLATE_BG,
214
+ },
215
+ code: {
216
+ fontSize: 40,
217
+ lineHeight: 48,
218
+ fontWeight: '700',
219
+ letterSpacing: 4,
220
+ textAlign: 'center',
221
+ },
222
+ });
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Recovering a passkey account (ADR 0029 D3), auth.oxy.so's `/recover`:
3
+ *
4
+ * username or email → the code sent to the recovery email → new passkey → signed in
5
+ *
6
+ * The first step answers the same whether or not the account exists, so it
7
+ * never says who has one. An account that uses Commons has no recovery email:
8
+ * it recovers in Commons with its phrase, and the first step says so. The new
9
+ * passkey joins the ones the account has; lost ones are removed afterwards in
10
+ * the account's security settings.
11
+ */
12
+
13
+ import type React from 'react';
14
+ import { useState } from 'react';
15
+ import { useTheme } from '@oxy.so/bloom/theme';
16
+ import { DeviceManager } from '@oxy.so/core';
17
+ import { useOxy } from '../../context/OxyContext';
18
+ import { runPasskeyRegisterSignIn } from '../../context/passkeyFlow';
19
+ import { useI18n } from '../../hooks/useI18n';
20
+ import { isPasskeySupported, runRegistrationCeremony } from '../../../webauthn/passkeyClient';
21
+ import { SubtleLink } from '../authChooser/primitives';
22
+ import { OxyAuthScreen, OxyAuthScreenHeader, OxyAuthTerms } from './OxyAuthScreen';
23
+ import {
24
+ AccountFlowAction,
25
+ AccountFlowErrorLine,
26
+ AccountFlowField,
27
+ AccountFlowNote,
28
+ EmailCodeStep,
29
+ describeAccountFlowError,
30
+ isTicketExpired,
31
+ } from './accountFlowParts';
32
+
33
+ type Step =
34
+ | { name: 'entry' }
35
+ | { name: 'code'; verificationId: string }
36
+ | { name: 'passkey'; recoveryTicket: string; username: string | null };
37
+
38
+ export interface OxyRecoverAccountPanelProps {
39
+ /** The account has a new passkey and this origin is signed in as it. */
40
+ onRecovered: () => void;
41
+ /** "Back to sign in". */
42
+ onSignIn: () => void;
43
+ }
44
+
45
+ export const OxyRecoverAccountPanel: React.FC<OxyRecoverAccountPanelProps> = ({ onRecovered, onSignIn }) => {
46
+ const theme = useTheme();
47
+ const { t } = useI18n();
48
+ const { oxyServices, handleWebSession } = useOxy();
49
+ const [step, setStep] = useState<Step>({ name: 'entry' });
50
+ const [identifier, setIdentifier] = useState('');
51
+ const [pending, setPending] = useState(false);
52
+ const [error, setError] = useState<string | null>(null);
53
+
54
+ const run = (work: () => Promise<void>) => {
55
+ if (pending) return;
56
+ setError(null);
57
+ setPending(true);
58
+ work()
59
+ .catch((reason: unknown) => {
60
+ if (isTicketExpired(reason)) setStep({ name: 'entry' });
61
+ setError(describeAccountFlowError(reason, t));
62
+ })
63
+ .finally(() => setPending(false));
64
+ };
65
+
66
+ const sendCode = async () => {
67
+ const { verificationId } = await oxyServices.startEmailVerification({ purpose: 'recovery', identifier: identifier.trim() });
68
+ setStep({ name: 'code', verificationId });
69
+ };
70
+
71
+ const submitIdentifier = () => {
72
+ if (!identifier.trim()) {
73
+ setError(t('recover.identifier.required'));
74
+ return;
75
+ }
76
+ run(sendCode);
77
+ };
78
+
79
+ // The ceremony opens the browser's passkey prompt, so it starts from the press.
80
+ const addPasskey = (recoveryTicket: string) =>
81
+ run(() =>
82
+ runPasskeyRegisterSignIn({
83
+ isSupported: isPasskeySupported,
84
+ getRegisterOptions: () => oxyServices.webauthnRegisterOptions({ recoveryTicket }),
85
+ runCeremony: runRegistrationCeremony,
86
+ registerVerify: (response) =>
87
+ oxyServices.webauthnRegisterVerify(response, {
88
+ recoveryTicket,
89
+ deviceFingerprint: JSON.stringify(DeviceManager.getDeviceFingerprint()),
90
+ }),
91
+ commit: async (session) => {
92
+ await handleWebSession(session);
93
+ onRecovered();
94
+ },
95
+ }),
96
+ );
97
+
98
+ switch (step.name) {
99
+ case 'code':
100
+ return (
101
+ <EmailCodeStep
102
+ description={t('emailCode.sentIfAccount')}
103
+ verificationId={step.verificationId}
104
+ onConfirmed={({ ticket, username }) => {
105
+ setError(null);
106
+ setStep({ name: 'passkey', recoveryTicket: ticket, username });
107
+ }}
108
+ onResend={sendCode}
109
+ back={{ label: t('signin.actions.back'), onPress: () => setStep({ name: 'entry' }) }}
110
+ />
111
+ );
112
+ case 'passkey':
113
+ return (
114
+ <OxyAuthScreen>
115
+ <OxyAuthScreenHeader
116
+ title={t('recover.passkey.title')}
117
+ description={t('recover.passkey.subtitle', { username: step.username ?? '' })}
118
+ />
119
+ {error ? <AccountFlowErrorLine message={error} /> : null}
120
+ <AccountFlowAction
121
+ label={t('recover.passkey.action')}
122
+ onPress={() => addPasskey(step.recoveryTicket)}
123
+ pending={pending}
124
+ testID="recover-create-passkey"
125
+ />
126
+ <OxyAuthTerms />
127
+ </OxyAuthScreen>
128
+ );
129
+ default:
130
+ return (
131
+ <OxyAuthScreen>
132
+ <OxyAuthScreenHeader title={t('recover.title')} description={t('recover.subtitle')} />
133
+ <AccountFlowField
134
+ label={t('recover.identifier.label')}
135
+ value={identifier}
136
+ onChange={(value) => {
137
+ setIdentifier(value);
138
+ if (error) setError(null);
139
+ }}
140
+ onSubmit={submitIdentifier}
141
+ error={error}
142
+ disabled={pending}
143
+ placeholder={t('recover.identifier.placeholder')}
144
+ autoComplete="username"
145
+ testID="recover-identifier"
146
+ />
147
+ <AccountFlowNote>{t('recover.commonsNote')}</AccountFlowNote>
148
+ <AccountFlowAction label={t('signin.actions.continue')} onPress={submitIdentifier} pending={pending} testID="recover-continue" />
149
+ <SubtleLink label={t('recover.backToSignIn')} theme={theme} onPress={onSignIn} testID="back-to-sign-in" />
150
+ <OxyAuthTerms />
151
+ </OxyAuthScreen>
152
+ );
153
+ }
154
+ };