@oxyhq/services 22.12.5 → 22.13.1

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 (464) hide show
  1. package/README.md +16 -46
  2. package/lib/commonjs/index.js +90 -10
  3. package/lib/commonjs/index.js.map +1 -1
  4. package/lib/commonjs/notifications/deviceNotifications.js +424 -0
  5. package/lib/commonjs/notifications/deviceNotifications.js.map +1 -0
  6. package/lib/commonjs/ui/boot/runProviderColdBoot.js +51 -9
  7. package/lib/commonjs/ui/boot/runProviderColdBoot.js.map +1 -1
  8. package/lib/commonjs/ui/client.js +0 -13
  9. package/lib/commonjs/ui/client.js.map +1 -1
  10. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +27 -4
  11. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
  12. package/lib/commonjs/ui/components/OxyAuthChooser.js +74 -1124
  13. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  14. package/lib/commonjs/ui/components/OxyConsentScreen.js +50 -12
  15. package/lib/commonjs/ui/components/OxyConsentScreen.js.map +1 -1
  16. package/lib/commonjs/ui/components/OxyProvider.js +4 -4
  17. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  18. package/lib/commonjs/ui/components/OxySignInButton.js +74 -40
  19. package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
  20. package/lib/commonjs/ui/components/OxySignInRequestSurface.js +147 -0
  21. package/lib/commonjs/ui/components/OxySignInRequestSurface.js.map +1 -0
  22. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +527 -0
  23. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -0
  24. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +90 -0
  25. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +1 -0
  26. package/lib/commonjs/ui/components/authChooser/SignInRequestView.js +106 -0
  27. package/lib/commonjs/ui/components/authChooser/SignInRequestView.js.map +1 -0
  28. package/lib/commonjs/ui/components/authChooser/SignUpView.js +188 -0
  29. package/lib/commonjs/ui/components/authChooser/SignUpView.js.map +1 -0
  30. package/lib/commonjs/ui/components/authChooser/TroubleDisclosure.js +61 -0
  31. package/lib/commonjs/ui/components/authChooser/TroubleDisclosure.js.map +1 -0
  32. package/lib/commonjs/ui/components/authChooser/primitives.js +169 -0
  33. package/lib/commonjs/ui/components/authChooser/primitives.js.map +1 -0
  34. package/lib/commonjs/ui/components/authChooser/requestSurfaces.js +153 -0
  35. package/lib/commonjs/ui/components/authChooser/requestSurfaces.js.map +1 -0
  36. package/lib/commonjs/ui/components/authChooser/signInProgress.js +54 -0
  37. package/lib/commonjs/ui/components/authChooser/signInProgress.js.map +1 -0
  38. package/lib/commonjs/ui/components/{oxyAuthChooserStyles.js → authChooser/styles.js} +19 -1
  39. package/lib/commonjs/ui/components/authChooser/styles.js.map +1 -0
  40. package/lib/commonjs/ui/components/authChooser/types.js +70 -0
  41. package/lib/commonjs/ui/components/authChooser/types.js.map +1 -0
  42. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js +50 -0
  43. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js.map +1 -0
  44. package/lib/commonjs/ui/context/OxyContext.js +205 -30
  45. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  46. package/lib/commonjs/ui/context/commitSessionFlow.js +46 -0
  47. package/lib/commonjs/ui/context/commitSessionFlow.js.map +1 -1
  48. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +15 -2
  49. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  50. package/lib/commonjs/ui/context/useOxyAccountGraph.js +13 -5
  51. package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
  52. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js +6 -1
  53. package/lib/commonjs/ui/hooks/useSwitchableAccounts.js.map +1 -1
  54. package/lib/commonjs/ui/index.js +0 -13
  55. package/lib/commonjs/ui/index.js.map +1 -1
  56. package/lib/commonjs/ui/oauth/browserAuthTransport.js +170 -0
  57. package/lib/commonjs/ui/oauth/browserAuthTransport.js.map +1 -0
  58. package/lib/commonjs/ui/oauth/completeOAuthCode.js +78 -0
  59. package/lib/commonjs/ui/oauth/completeOAuthCode.js.map +1 -0
  60. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js +48 -0
  61. package/lib/commonjs/ui/oauth/legacyRedirectLanes.js.map +1 -0
  62. package/lib/commonjs/ui/oauth/oauthHandshake.js +53 -0
  63. package/lib/commonjs/ui/oauth/oauthHandshake.js.map +1 -0
  64. package/lib/commonjs/ui/oauth/oauthPopup.js +276 -0
  65. package/lib/commonjs/ui/oauth/oauthPopup.js.map +1 -0
  66. package/lib/commonjs/ui/oauth/oauthPopupMessages.js +141 -0
  67. package/lib/commonjs/ui/oauth/oauthPopupMessages.js.map +1 -0
  68. package/lib/commonjs/ui/oauth/types.js +2 -0
  69. package/lib/commonjs/ui/oauth/types.js.map +1 -0
  70. package/lib/commonjs/ui/server.js +2 -5
  71. package/lib/commonjs/ui/server.js.map +1 -1
  72. package/lib/commonjs/ui/session/authStore.js +6 -75
  73. package/lib/commonjs/ui/session/authStore.js.map +1 -1
  74. package/lib/commonjs/ui/session/createSessionClient.js +11 -3
  75. package/lib/commonjs/ui/session/createSessionClient.js.map +1 -1
  76. package/lib/commonjs/ui/session/identityBinding.js +95 -0
  77. package/lib/commonjs/ui/session/identityBinding.js.map +1 -0
  78. package/lib/commonjs/ui/session/index.js +13 -0
  79. package/lib/commonjs/ui/session/index.js.map +1 -1
  80. package/lib/commonjs/ui/session/nativeSecureStorage.js +90 -0
  81. package/lib/commonjs/ui/session/nativeSecureStorage.js.map +1 -0
  82. package/lib/commonjs/ui/session/tokenTransport.js +11 -1
  83. package/lib/commonjs/ui/session/tokenTransport.js.map +1 -1
  84. package/lib/commonjs/ui/utils/crossOriginRestore.js +3 -2
  85. package/lib/commonjs/ui/utils/crossOriginRestore.js.map +1 -1
  86. package/lib/commonjs/ui/utils/deliveryPlatform.js +58 -0
  87. package/lib/commonjs/ui/utils/deliveryPlatform.js.map +1 -0
  88. package/lib/commonjs/ui/utils/oauthReturn.js +33 -49
  89. package/lib/commonjs/ui/utils/oauthReturn.js.map +1 -1
  90. package/lib/module/index.js +27 -4
  91. package/lib/module/index.js.map +1 -1
  92. package/lib/module/notifications/deviceNotifications.js +414 -0
  93. package/lib/module/notifications/deviceNotifications.js.map +1 -0
  94. package/lib/module/ui/boot/runProviderColdBoot.js +51 -9
  95. package/lib/module/ui/boot/runProviderColdBoot.js.map +1 -1
  96. package/lib/module/ui/client.js +0 -1
  97. package/lib/module/ui/client.js.map +1 -1
  98. package/lib/module/ui/components/OxyAccountDialogScreen.js +27 -4
  99. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
  100. package/lib/module/ui/components/OxyAuthChooser.js +78 -1129
  101. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  102. package/lib/module/ui/components/OxyConsentScreen.js +50 -12
  103. package/lib/module/ui/components/OxyConsentScreen.js.map +1 -1
  104. package/lib/module/ui/components/OxyProvider.js +4 -4
  105. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  106. package/lib/module/ui/components/OxySignInButton.js +76 -42
  107. package/lib/module/ui/components/OxySignInButton.js.map +1 -1
  108. package/lib/module/ui/components/OxySignInRequestSurface.js +141 -0
  109. package/lib/module/ui/components/OxySignInRequestSurface.js.map +1 -0
  110. package/lib/module/ui/components/authChooser/AccountsMenuView.js +523 -0
  111. package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -0
  112. package/lib/module/ui/components/authChooser/SignInEntryView.js +85 -0
  113. package/lib/module/ui/components/authChooser/SignInEntryView.js.map +1 -0
  114. package/lib/module/ui/components/authChooser/SignInRequestView.js +101 -0
  115. package/lib/module/ui/components/authChooser/SignInRequestView.js.map +1 -0
  116. package/lib/module/ui/components/authChooser/SignUpView.js +184 -0
  117. package/lib/module/ui/components/authChooser/SignUpView.js.map +1 -0
  118. package/lib/module/ui/components/authChooser/TroubleDisclosure.js +57 -0
  119. package/lib/module/ui/components/authChooser/TroubleDisclosure.js.map +1 -0
  120. package/lib/module/ui/components/authChooser/primitives.js +163 -0
  121. package/lib/module/ui/components/authChooser/primitives.js.map +1 -0
  122. package/lib/module/ui/components/authChooser/requestSurfaces.js +143 -0
  123. package/lib/module/ui/components/authChooser/requestSurfaces.js.map +1 -0
  124. package/lib/module/ui/components/authChooser/signInProgress.js +50 -0
  125. package/lib/module/ui/components/authChooser/signInProgress.js.map +1 -0
  126. package/lib/module/ui/components/{oxyAuthChooserStyles.js → authChooser/styles.js} +19 -1
  127. package/lib/module/ui/components/authChooser/styles.js.map +1 -0
  128. package/lib/module/ui/components/authChooser/types.js +66 -0
  129. package/lib/module/ui/components/authChooser/types.js.map +1 -0
  130. package/lib/module/ui/components/authChooser/useUsernameAvailability.js +46 -0
  131. package/lib/module/ui/components/authChooser/useUsernameAvailability.js.map +1 -0
  132. package/lib/module/ui/context/OxyContext.js +208 -33
  133. package/lib/module/ui/context/OxyContext.js.map +1 -1
  134. package/lib/module/ui/context/commitSessionFlow.js +45 -0
  135. package/lib/module/ui/context/commitSessionFlow.js.map +1 -1
  136. package/lib/module/ui/context/hooks/useAuthOperations.js +15 -2
  137. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  138. package/lib/module/ui/context/useOxyAccountGraph.js +13 -5
  139. package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
  140. package/lib/module/ui/hooks/useSwitchableAccounts.js +6 -1
  141. package/lib/module/ui/hooks/useSwitchableAccounts.js.map +1 -1
  142. package/lib/module/ui/index.js +0 -1
  143. package/lib/module/ui/index.js.map +1 -1
  144. package/lib/module/ui/oauth/browserAuthTransport.js +167 -0
  145. package/lib/module/ui/oauth/browserAuthTransport.js.map +1 -0
  146. package/lib/module/ui/oauth/completeOAuthCode.js +75 -0
  147. package/lib/module/ui/oauth/completeOAuthCode.js.map +1 -0
  148. package/lib/module/ui/oauth/legacyRedirectLanes.js +44 -0
  149. package/lib/module/ui/oauth/legacyRedirectLanes.js.map +1 -0
  150. package/lib/module/ui/oauth/oauthHandshake.js +50 -0
  151. package/lib/module/ui/oauth/oauthHandshake.js.map +1 -0
  152. package/lib/module/ui/oauth/oauthPopup.js +268 -0
  153. package/lib/module/ui/oauth/oauthPopup.js.map +1 -0
  154. package/lib/module/ui/oauth/oauthPopupMessages.js +135 -0
  155. package/lib/module/ui/oauth/oauthPopupMessages.js.map +1 -0
  156. package/lib/module/ui/oauth/types.js +2 -0
  157. package/lib/module/ui/oauth/types.js.map +1 -0
  158. package/lib/module/ui/server.js +0 -2
  159. package/lib/module/ui/server.js.map +1 -1
  160. package/lib/module/ui/session/authStore.js +5 -75
  161. package/lib/module/ui/session/authStore.js.map +1 -1
  162. package/lib/module/ui/session/createSessionClient.js +11 -3
  163. package/lib/module/ui/session/createSessionClient.js.map +1 -1
  164. package/lib/module/ui/session/identityBinding.js +89 -0
  165. package/lib/module/ui/session/identityBinding.js.map +1 -0
  166. package/lib/module/ui/session/index.js +5 -2
  167. package/lib/module/ui/session/index.js.map +1 -1
  168. package/lib/module/ui/session/nativeSecureStorage.js +88 -0
  169. package/lib/module/ui/session/nativeSecureStorage.js.map +1 -0
  170. package/lib/module/ui/session/tokenTransport.js +11 -1
  171. package/lib/module/ui/session/tokenTransport.js.map +1 -1
  172. package/lib/module/ui/utils/crossOriginRestore.js +4 -3
  173. package/lib/module/ui/utils/crossOriginRestore.js.map +1 -1
  174. package/lib/module/ui/utils/deliveryPlatform.js +55 -0
  175. package/lib/module/ui/utils/deliveryPlatform.js.map +1 -0
  176. package/lib/module/ui/utils/oauthReturn.js +35 -50
  177. package/lib/module/ui/utils/oauthReturn.js.map +1 -1
  178. package/lib/typescript/commonjs/index.d.ts +9 -1
  179. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  180. package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts +173 -0
  181. package/lib/typescript/commonjs/notifications/deviceNotifications.d.ts.map +1 -0
  182. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts +34 -2
  183. package/lib/typescript/commonjs/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  184. package/lib/typescript/commonjs/ui/client.d.ts +0 -1
  185. package/lib/typescript/commonjs/ui/client.d.ts.map +1 -1
  186. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  187. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts +23 -29
  188. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  189. package/lib/typescript/commonjs/ui/components/OxyConsentScreen.d.ts.map +1 -1
  190. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  191. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts +17 -12
  192. package/lib/typescript/commonjs/ui/components/OxySignInButton.d.ts.map +1 -1
  193. package/lib/typescript/commonjs/ui/components/OxySignInRequestSurface.d.ts +108 -0
  194. package/lib/typescript/commonjs/ui/components/OxySignInRequestSurface.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts +38 -0
  196. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +32 -0
  198. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/ui/components/authChooser/SignInRequestView.d.ts +34 -0
  200. package/lib/typescript/commonjs/ui/components/authChooser/SignInRequestView.d.ts.map +1 -0
  201. package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts +34 -0
  202. package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/ui/components/authChooser/TroubleDisclosure.d.ts +36 -0
  204. package/lib/typescript/commonjs/ui/components/authChooser/TroubleDisclosure.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts +55 -0
  206. package/lib/typescript/commonjs/ui/components/authChooser/primitives.d.ts.map +1 -0
  207. package/lib/typescript/commonjs/ui/components/authChooser/requestSurfaces.d.ts +58 -0
  208. package/lib/typescript/commonjs/ui/components/authChooser/requestSurfaces.d.ts.map +1 -0
  209. package/lib/typescript/commonjs/ui/components/authChooser/signInProgress.d.ts +26 -0
  210. package/lib/typescript/commonjs/ui/components/authChooser/signInProgress.d.ts.map +1 -0
  211. package/lib/typescript/{module/ui/components/oxyAuthChooserStyles.d.ts → commonjs/ui/components/authChooser/styles.d.ts} +19 -1
  212. package/lib/typescript/commonjs/ui/components/authChooser/styles.d.ts.map +1 -0
  213. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +103 -0
  214. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -0
  215. package/lib/typescript/commonjs/ui/components/authChooser/useUsernameAvailability.d.ts +16 -0
  216. package/lib/typescript/commonjs/ui/components/authChooser/useUsernameAvailability.d.ts.map +1 -0
  217. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  218. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts +40 -0
  219. package/lib/typescript/commonjs/ui/context/commitSessionFlow.d.ts.map +1 -1
  220. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +11 -2
  221. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  222. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +44 -1
  223. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  224. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts +7 -1
  225. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  226. package/lib/typescript/commonjs/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
  227. package/lib/typescript/commonjs/ui/index.d.ts +0 -1
  228. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  229. package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts +56 -0
  230. package/lib/typescript/commonjs/ui/oauth/browserAuthTransport.d.ts.map +1 -0
  231. package/lib/typescript/commonjs/ui/oauth/completeOAuthCode.d.ts +49 -0
  232. package/lib/typescript/commonjs/ui/oauth/completeOAuthCode.d.ts.map +1 -0
  233. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts +40 -0
  234. package/lib/typescript/commonjs/ui/oauth/legacyRedirectLanes.d.ts.map +1 -0
  235. package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts +50 -0
  236. package/lib/typescript/commonjs/ui/oauth/oauthHandshake.d.ts.map +1 -0
  237. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts +83 -0
  238. package/lib/typescript/commonjs/ui/oauth/oauthPopup.d.ts.map +1 -0
  239. package/lib/typescript/commonjs/ui/oauth/oauthPopupMessages.d.ts +67 -0
  240. package/lib/typescript/commonjs/ui/oauth/oauthPopupMessages.d.ts.map +1 -0
  241. package/lib/typescript/commonjs/ui/oauth/types.d.ts +176 -0
  242. package/lib/typescript/commonjs/ui/oauth/types.d.ts.map +1 -0
  243. package/lib/typescript/commonjs/ui/server.d.ts +0 -2
  244. package/lib/typescript/commonjs/ui/server.d.ts.map +1 -1
  245. package/lib/typescript/commonjs/ui/session/authStore.d.ts +3 -7
  246. package/lib/typescript/commonjs/ui/session/authStore.d.ts.map +1 -1
  247. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts +8 -1
  248. package/lib/typescript/commonjs/ui/session/createSessionClient.d.ts.map +1 -1
  249. package/lib/typescript/commonjs/ui/session/identityBinding.d.ts +66 -0
  250. package/lib/typescript/commonjs/ui/session/identityBinding.d.ts.map +1 -0
  251. package/lib/typescript/commonjs/ui/session/index.d.ts +6 -2
  252. package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
  253. package/lib/typescript/commonjs/ui/session/nativeSecureStorage.d.ts +25 -0
  254. package/lib/typescript/commonjs/ui/session/nativeSecureStorage.d.ts.map +1 -0
  255. package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts +8 -1
  256. package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts.map +1 -1
  257. package/lib/typescript/commonjs/ui/types/navigation.d.ts +44 -0
  258. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  259. package/lib/typescript/commonjs/ui/utils/crossOriginRestore.d.ts.map +1 -1
  260. package/lib/typescript/commonjs/ui/utils/deliveryPlatform.d.ts +33 -0
  261. package/lib/typescript/commonjs/ui/utils/deliveryPlatform.d.ts.map +1 -0
  262. package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts +11 -16
  263. package/lib/typescript/commonjs/ui/utils/oauthReturn.d.ts.map +1 -1
  264. package/lib/typescript/module/index.d.ts +9 -1
  265. package/lib/typescript/module/index.d.ts.map +1 -1
  266. package/lib/typescript/module/notifications/deviceNotifications.d.ts +173 -0
  267. package/lib/typescript/module/notifications/deviceNotifications.d.ts.map +1 -0
  268. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts +34 -2
  269. package/lib/typescript/module/ui/boot/runProviderColdBoot.d.ts.map +1 -1
  270. package/lib/typescript/module/ui/client.d.ts +0 -1
  271. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  272. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  273. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts +23 -29
  274. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  275. package/lib/typescript/module/ui/components/OxyConsentScreen.d.ts.map +1 -1
  276. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  277. package/lib/typescript/module/ui/components/OxySignInButton.d.ts +17 -12
  278. package/lib/typescript/module/ui/components/OxySignInButton.d.ts.map +1 -1
  279. package/lib/typescript/module/ui/components/OxySignInRequestSurface.d.ts +108 -0
  280. package/lib/typescript/module/ui/components/OxySignInRequestSurface.d.ts.map +1 -0
  281. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts +38 -0
  282. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -0
  283. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +32 -0
  284. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +1 -0
  285. package/lib/typescript/module/ui/components/authChooser/SignInRequestView.d.ts +34 -0
  286. package/lib/typescript/module/ui/components/authChooser/SignInRequestView.d.ts.map +1 -0
  287. package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts +34 -0
  288. package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts.map +1 -0
  289. package/lib/typescript/module/ui/components/authChooser/TroubleDisclosure.d.ts +36 -0
  290. package/lib/typescript/module/ui/components/authChooser/TroubleDisclosure.d.ts.map +1 -0
  291. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts +55 -0
  292. package/lib/typescript/module/ui/components/authChooser/primitives.d.ts.map +1 -0
  293. package/lib/typescript/module/ui/components/authChooser/requestSurfaces.d.ts +58 -0
  294. package/lib/typescript/module/ui/components/authChooser/requestSurfaces.d.ts.map +1 -0
  295. package/lib/typescript/module/ui/components/authChooser/signInProgress.d.ts +26 -0
  296. package/lib/typescript/module/ui/components/authChooser/signInProgress.d.ts.map +1 -0
  297. package/lib/typescript/{commonjs/ui/components/oxyAuthChooserStyles.d.ts → module/ui/components/authChooser/styles.d.ts} +19 -1
  298. package/lib/typescript/module/ui/components/authChooser/styles.d.ts.map +1 -0
  299. package/lib/typescript/module/ui/components/authChooser/types.d.ts +103 -0
  300. package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -0
  301. package/lib/typescript/module/ui/components/authChooser/useUsernameAvailability.d.ts +16 -0
  302. package/lib/typescript/module/ui/components/authChooser/useUsernameAvailability.d.ts.map +1 -0
  303. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  304. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts +40 -0
  305. package/lib/typescript/module/ui/context/commitSessionFlow.d.ts.map +1 -1
  306. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +11 -2
  307. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  308. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +44 -1
  309. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  310. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts +7 -1
  311. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  312. package/lib/typescript/module/ui/hooks/useSwitchableAccounts.d.ts.map +1 -1
  313. package/lib/typescript/module/ui/index.d.ts +0 -1
  314. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  315. package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts +56 -0
  316. package/lib/typescript/module/ui/oauth/browserAuthTransport.d.ts.map +1 -0
  317. package/lib/typescript/module/ui/oauth/completeOAuthCode.d.ts +49 -0
  318. package/lib/typescript/module/ui/oauth/completeOAuthCode.d.ts.map +1 -0
  319. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts +40 -0
  320. package/lib/typescript/module/ui/oauth/legacyRedirectLanes.d.ts.map +1 -0
  321. package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts +50 -0
  322. package/lib/typescript/module/ui/oauth/oauthHandshake.d.ts.map +1 -0
  323. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts +83 -0
  324. package/lib/typescript/module/ui/oauth/oauthPopup.d.ts.map +1 -0
  325. package/lib/typescript/module/ui/oauth/oauthPopupMessages.d.ts +67 -0
  326. package/lib/typescript/module/ui/oauth/oauthPopupMessages.d.ts.map +1 -0
  327. package/lib/typescript/module/ui/oauth/types.d.ts +176 -0
  328. package/lib/typescript/module/ui/oauth/types.d.ts.map +1 -0
  329. package/lib/typescript/module/ui/server.d.ts +0 -2
  330. package/lib/typescript/module/ui/server.d.ts.map +1 -1
  331. package/lib/typescript/module/ui/session/authStore.d.ts +3 -7
  332. package/lib/typescript/module/ui/session/authStore.d.ts.map +1 -1
  333. package/lib/typescript/module/ui/session/createSessionClient.d.ts +8 -1
  334. package/lib/typescript/module/ui/session/createSessionClient.d.ts.map +1 -1
  335. package/lib/typescript/module/ui/session/identityBinding.d.ts +66 -0
  336. package/lib/typescript/module/ui/session/identityBinding.d.ts.map +1 -0
  337. package/lib/typescript/module/ui/session/index.d.ts +6 -2
  338. package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
  339. package/lib/typescript/module/ui/session/nativeSecureStorage.d.ts +25 -0
  340. package/lib/typescript/module/ui/session/nativeSecureStorage.d.ts.map +1 -0
  341. package/lib/typescript/module/ui/session/tokenTransport.d.ts +8 -1
  342. package/lib/typescript/module/ui/session/tokenTransport.d.ts.map +1 -1
  343. package/lib/typescript/module/ui/types/navigation.d.ts +44 -0
  344. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  345. package/lib/typescript/module/ui/utils/crossOriginRestore.d.ts.map +1 -1
  346. package/lib/typescript/module/ui/utils/deliveryPlatform.d.ts +33 -0
  347. package/lib/typescript/module/ui/utils/deliveryPlatform.d.ts.map +1 -0
  348. package/lib/typescript/module/ui/utils/oauthReturn.d.ts +11 -16
  349. package/lib/typescript/module/ui/utils/oauthReturn.d.ts.map +1 -1
  350. package/package.json +18 -10
  351. package/src/index.ts +51 -5
  352. package/src/notifications/deviceNotifications.ts +458 -0
  353. package/src/ui/boot/__tests__/coldBootWebAuthMode.test.ts +281 -0
  354. package/src/ui/boot/runProviderColdBoot.ts +83 -13
  355. package/src/ui/client.ts +0 -1
  356. package/src/ui/components/OxyAccountDialogScreen.tsx +33 -4
  357. package/src/ui/components/OxyAuthChooser.tsx +102 -1231
  358. package/src/ui/components/OxyConsentScreen.tsx +56 -13
  359. package/src/ui/components/OxyProvider.tsx +4 -4
  360. package/src/ui/components/OxySignInButton.tsx +119 -78
  361. package/src/ui/components/OxySignInRequestSurface.tsx +202 -0
  362. package/src/ui/components/__tests__/OxyConsentScreen.test.tsx +27 -0
  363. package/src/ui/components/authChooser/AccountsMenuView.tsx +569 -0
  364. package/src/ui/components/authChooser/SignInEntryView.tsx +121 -0
  365. package/src/ui/components/authChooser/SignInRequestView.tsx +130 -0
  366. package/src/ui/components/authChooser/SignUpView.tsx +174 -0
  367. package/src/ui/components/authChooser/TroubleDisclosure.tsx +73 -0
  368. package/src/ui/components/authChooser/primitives.tsx +144 -0
  369. package/src/ui/components/authChooser/requestSurfaces.tsx +120 -0
  370. package/src/ui/components/authChooser/signInProgress.ts +54 -0
  371. package/src/ui/components/{oxyAuthChooserStyles.ts → authChooser/styles.ts} +18 -0
  372. package/src/ui/components/authChooser/types.ts +120 -0
  373. package/src/ui/components/authChooser/useUsernameAvailability.ts +60 -0
  374. package/src/ui/context/OxyContext.tsx +226 -24
  375. package/src/ui/context/__tests__/commitSessionFlow.test.ts +102 -0
  376. package/src/ui/context/commitSessionFlow.ts +64 -0
  377. package/src/ui/context/hooks/useAuthOperations.ts +26 -1
  378. package/src/ui/context/oxyContextTypes.ts +45 -1
  379. package/src/ui/context/useOxyAccountGraph.ts +19 -5
  380. package/src/ui/hooks/useSwitchableAccounts.ts +12 -1
  381. package/src/ui/index.ts +0 -1
  382. package/src/ui/oauth/__tests__/browserAuthTransport.test.ts +335 -0
  383. package/src/ui/oauth/__tests__/completeOAuthCode.test.ts +142 -0
  384. package/src/ui/oauth/__tests__/oauthPopup.test.ts +352 -0
  385. package/src/ui/oauth/__tests__/oauthPopupMessages.test.ts +189 -0
  386. package/src/ui/oauth/__tests__/sharedCompletionPath.test.ts +174 -0
  387. package/src/ui/oauth/browserAuthTransport.ts +193 -0
  388. package/src/ui/oauth/completeOAuthCode.ts +93 -0
  389. package/src/ui/oauth/legacyRedirectLanes.ts +43 -0
  390. package/src/ui/oauth/oauthHandshake.ts +74 -0
  391. package/src/ui/oauth/oauthPopup.ts +277 -0
  392. package/src/ui/oauth/oauthPopupMessages.ts +136 -0
  393. package/src/ui/oauth/types.ts +150 -0
  394. package/src/ui/server.ts +0 -2
  395. package/src/ui/session/__tests__/createSessionClient.test.ts +26 -0
  396. package/src/ui/session/__tests__/tokenTransport.test.ts +34 -0
  397. package/src/ui/session/authStore.ts +5 -89
  398. package/src/ui/session/createSessionClient.ts +15 -2
  399. package/src/ui/session/identityBinding.ts +116 -0
  400. package/src/ui/session/index.ts +6 -2
  401. package/src/ui/session/nativeSecureStorage.ts +98 -0
  402. package/src/ui/session/tokenTransport.ts +14 -1
  403. package/src/ui/types/navigation.ts +44 -1
  404. package/src/ui/utils/__tests__/crossOriginRestore.test.ts +17 -0
  405. package/src/ui/utils/crossOriginRestore.ts +7 -6
  406. package/src/ui/utils/deliveryPlatform.ts +65 -0
  407. package/src/ui/utils/oauthReturn.ts +38 -62
  408. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  409. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  410. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  411. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  412. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  413. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  414. package/lib/commonjs/assets/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  415. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  416. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  417. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  418. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  419. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  420. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  421. package/lib/commonjs/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  422. package/lib/commonjs/ui/components/FontLoader.js +0 -35
  423. package/lib/commonjs/ui/components/FontLoader.js.map +0 -1
  424. package/lib/commonjs/ui/components/FontLoader.native.js +0 -88
  425. package/lib/commonjs/ui/components/FontLoader.native.js.map +0 -1
  426. package/lib/commonjs/ui/components/oxyAuthChooserStyles.js.map +0 -1
  427. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  428. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  429. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  430. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  431. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  432. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  433. package/lib/module/assets/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  434. package/lib/module/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  435. package/lib/module/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  436. package/lib/module/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  437. package/lib/module/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  438. package/lib/module/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  439. package/lib/module/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  440. package/lib/module/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  441. package/lib/module/ui/components/FontLoader.js +0 -29
  442. package/lib/module/ui/components/FontLoader.js.map +0 -1
  443. package/lib/module/ui/components/FontLoader.native.js +0 -83
  444. package/lib/module/ui/components/FontLoader.native.js.map +0 -1
  445. package/lib/module/ui/components/oxyAuthChooserStyles.js.map +0 -1
  446. package/lib/typescript/commonjs/ui/components/FontLoader.d.ts +0 -24
  447. package/lib/typescript/commonjs/ui/components/FontLoader.d.ts.map +0 -1
  448. package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts +0 -13
  449. package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts.map +0 -1
  450. package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts.map +0 -1
  451. package/lib/typescript/module/ui/components/FontLoader.d.ts +0 -24
  452. package/lib/typescript/module/ui/components/FontLoader.d.ts.map +0 -1
  453. package/lib/typescript/module/ui/components/FontLoader.native.d.ts +0 -13
  454. package/lib/typescript/module/ui/components/FontLoader.native.d.ts.map +0 -1
  455. package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts.map +0 -1
  456. package/src/assets/fonts/Inter/Inter_18pt-Black.ttf +0 -0
  457. package/src/assets/fonts/Inter/Inter_18pt-Bold.ttf +0 -0
  458. package/src/assets/fonts/Inter/Inter_18pt-ExtraBold.ttf +0 -0
  459. package/src/assets/fonts/Inter/Inter_18pt-Light.ttf +0 -0
  460. package/src/assets/fonts/Inter/Inter_18pt-Medium.ttf +0 -0
  461. package/src/assets/fonts/Inter/Inter_18pt-Regular.ttf +0 -0
  462. package/src/assets/fonts/Inter/Inter_18pt-SemiBold.ttf +0 -0
  463. package/src/ui/components/FontLoader.native.tsx +0 -88
  464. package/src/ui/components/FontLoader.tsx +0 -27
@@ -0,0 +1,281 @@
1
+ /**
2
+ * `runProviderColdBoot` — the `webAuthMode` transport gate (#691 phase 7).
3
+ *
4
+ * `webAuthMode: 'popup'` must never let the boot navigate the RP's top-level
5
+ * window: no silent `prompt=none` restore, no authorize redirect, a signed-out
6
+ * domain simply resolves signed out. `'redirect'` — still the default and the
7
+ * compatibility path — must behave exactly as before.
8
+ *
9
+ * Unlike `__tests__/boot/runProviderColdBoot.test.ts` (deadline + connectivity
10
+ * wiring, with `crossOriginRestore` stubbed out), this suite keeps the restore
11
+ * lane REAL so the redirect-mode assertions reach the actual navigation
12
+ * primitive — the thing popup mode has to suppress.
13
+ */
14
+
15
+ import type { AuthStateStore, PersistedAuthState, SessionClient } from '@oxyhq/core';
16
+
17
+ // Only `runSessionColdBoot` and the origin-CLASSIFICATION predicates are faked.
18
+ // jsdom's `location` is non-configurable, so origin eligibility has to be driven
19
+ // through the predicates (their real behaviour is covered by core's own tests);
20
+ // everything else in core (PKCE, authorize-URL builder, handshake store) stays
21
+ // real so the redirect-mode lane is exercised end to end.
22
+ jest.mock('@oxyhq/core', () => {
23
+ const actual = jest.requireActual('@oxyhq/core');
24
+ return {
25
+ __esModule: true,
26
+ ...actual,
27
+ runSessionColdBoot: jest.fn(),
28
+ isLoopbackOrigin: jest.fn(() => false),
29
+ isOfficialWebOrigin: jest.fn(() => true),
30
+ isIdpHubOrigin: jest.fn(() => false),
31
+ };
32
+ });
33
+
34
+ // The ONLY top-level-window navigation primitive either lane can reach.
35
+ jest.mock('../../components/oauthNavigation', () => ({
36
+ redirectToAuthorize: jest.fn(),
37
+ }));
38
+
39
+ // Spied but REAL: redirect mode must still perform the actual restore.
40
+ jest.mock('../../utils/crossOriginRestore', () => {
41
+ const actual = jest.requireActual('../../utils/crossOriginRestore');
42
+ return {
43
+ __esModule: true,
44
+ ...actual,
45
+ maybeStartSilentOAuthRestore: jest.fn(actual.maybeStartSilentOAuthRestore),
46
+ consumeSilentOAuthError: jest.fn(actual.consumeSilentOAuthError),
47
+ };
48
+ });
49
+
50
+ jest.mock('../../utils/oauthReturn', () => {
51
+ const actual = jest.requireActual('../../utils/oauthReturn');
52
+ return {
53
+ __esModule: true,
54
+ ...actual,
55
+ tryCompleteOAuthReturn: jest.fn(async () => false),
56
+ consumeHubSyncFailure: jest.fn(actual.consumeHubSyncFailure),
57
+ };
58
+ });
59
+
60
+ import { runSessionColdBoot } from '@oxyhq/core';
61
+ import { redirectToAuthorize } from '../../components/oauthNavigation';
62
+ import {
63
+ clearCrossOriginRestoreGuards,
64
+ consumeSilentOAuthError,
65
+ maybeStartSilentOAuthRestore,
66
+ } from '../../utils/crossOriginRestore';
67
+ import { consumeHubSyncFailure, tryCompleteOAuthReturn } from '../../utils/oauthReturn';
68
+ import { runProviderColdBoot, type RunProviderColdBootOptions } from '../runProviderColdBoot';
69
+
70
+ const mockRunSessionColdBoot = runSessionColdBoot as jest.Mock;
71
+ const mockRedirectToAuthorize = redirectToAuthorize as jest.Mock;
72
+ const mockSilentRestore = maybeStartSilentOAuthRestore as jest.Mock;
73
+ const mockConsumeSilentOAuthError = consumeSilentOAuthError as jest.Mock;
74
+ const mockConsumeHubSyncFailure = consumeHubSyncFailure as jest.Mock;
75
+ const mockTryCompleteOAuthReturn = tryCompleteOAuthReturn as jest.Mock;
76
+
77
+ const CLIENT_ID = 'oxy_dk_test';
78
+
79
+ /** An auth store holding no device credential — the signed-out domain case. */
80
+ function makeEmptyAuthStore(): AuthStateStore {
81
+ return {
82
+ load: jest.fn(async (): Promise<PersistedAuthState | null> => null),
83
+ save: jest.fn(async () => undefined),
84
+ clear: jest.fn(async () => undefined),
85
+ } as unknown as AuthStateStore;
86
+ }
87
+
88
+ interface Harness {
89
+ options: RunProviderColdBootOptions;
90
+ commitSession: jest.Mock;
91
+ markAuthResolved: jest.Mock;
92
+ setTokenReady: jest.Mock;
93
+ sessionClientStart: jest.Mock;
94
+ }
95
+
96
+ function makeHarness(overrides: Partial<RunProviderColdBootOptions> = {}): Harness {
97
+ const commitSession = jest.fn(async () => undefined);
98
+ const markAuthResolved = jest.fn();
99
+ const setTokenReady = jest.fn();
100
+ const sessionClientStart = jest.fn(async () => undefined);
101
+
102
+ const options: RunProviderColdBootOptions = {
103
+ oxyServices: {} as RunProviderColdBootOptions['oxyServices'],
104
+ authStore: makeEmptyAuthStore(),
105
+ clientId: CLIENT_ID,
106
+ sessionClient: { start: sessionClientStart } as unknown as SessionClient,
107
+ syncDeviceCredentialToHost: jest.fn(async () => undefined),
108
+ commitSession,
109
+ markAuthResolved,
110
+ setTokenReady,
111
+ ...overrides,
112
+ };
113
+
114
+ return { options, commitSession, markAuthResolved, setTokenReady, sessionClientStart };
115
+ }
116
+
117
+ /** `runSessionColdBoot` finding no session at all — the signed-out domain. */
118
+ function stubSignedOutBoot(): void {
119
+ mockRunSessionColdBoot.mockImplementation(async (opts: Parameters<typeof runSessionColdBoot>[0]) => {
120
+ await opts.onSignedOut?.('no_session');
121
+ return { kind: 'unauthenticated' } as const;
122
+ });
123
+ }
124
+
125
+ describe('runProviderColdBoot — webAuthMode transport gate (#691 phase 7)', () => {
126
+ beforeEach(() => {
127
+ mockRunSessionColdBoot.mockReset();
128
+ mockRedirectToAuthorize.mockClear();
129
+ mockSilentRestore.mockClear();
130
+ mockConsumeSilentOAuthError.mockClear();
131
+ mockConsumeHubSyncFailure.mockClear();
132
+ mockTryCompleteOAuthReturn.mockClear();
133
+ mockTryCompleteOAuthReturn.mockImplementation(async () => false);
134
+ globalThis.sessionStorage?.clear();
135
+ clearCrossOriginRestoreGuards();
136
+ });
137
+
138
+ describe("webAuthMode: 'popup'", () => {
139
+ it('never starts the silent restore and never navigates the top-level window', async () => {
140
+ stubSignedOutBoot();
141
+ const { options } = makeHarness({ webAuthMode: 'popup' });
142
+
143
+ await runProviderColdBoot(options);
144
+
145
+ expect(mockSilentRestore).not.toHaveBeenCalled();
146
+ expect(mockRedirectToAuthorize).not.toHaveBeenCalled();
147
+ });
148
+
149
+ it('resolves a domain with no local credential SIGNED OUT instead of bouncing', async () => {
150
+ stubSignedOutBoot();
151
+ const { options, markAuthResolved, commitSession, sessionClientStart } = makeHarness({
152
+ webAuthMode: 'popup',
153
+ });
154
+
155
+ await runProviderColdBoot(options);
156
+
157
+ // Auth resolution concluded (routing can settle), nothing was committed,
158
+ // and with no persisted credential the device socket is not started.
159
+ expect(markAuthResolved).toHaveBeenCalled();
160
+ expect(commitSession).not.toHaveBeenCalled();
161
+ expect(sessionClientStart).not.toHaveBeenCalled();
162
+ expect(mockRedirectToAuthorize).not.toHaveBeenCalled();
163
+ });
164
+
165
+ it('still completes an authorization code already on the URL (blocked-popup fallback)', async () => {
166
+ // A popup-mode app lands here whenever the browser blocked the popup and
167
+ // `startWebOAuthSignIn` fell back to a full-page redirect.
168
+ mockTryCompleteOAuthReturn.mockImplementation(async () => true);
169
+ const { options, markAuthResolved, setTokenReady } = makeHarness({ webAuthMode: 'popup' });
170
+
171
+ await runProviderColdBoot(options);
172
+
173
+ expect(mockTryCompleteOAuthReturn).toHaveBeenCalledTimes(1);
174
+ expect(setTokenReady).toHaveBeenLastCalledWith(true);
175
+ expect(markAuthResolved).toHaveBeenCalled();
176
+ // The device mint is short-circuited by the completed return leg.
177
+ expect(mockRunSessionColdBoot).not.toHaveBeenCalled();
178
+ expect(mockRedirectToAuthorize).not.toHaveBeenCalled();
179
+ });
180
+
181
+ it('commits the OAuth return WITHOUT hub sync', async () => {
182
+ mockTryCompleteOAuthReturn.mockImplementation(async () => true);
183
+ const { options } = makeHarness({ webAuthMode: 'popup' });
184
+
185
+ await runProviderColdBoot(options);
186
+
187
+ const commit = mockTryCompleteOAuthReturn.mock.calls[0][0] as {
188
+ commitSession: (input: unknown) => Promise<void>;
189
+ };
190
+ await commit.commitSession({ sessionId: 's1', userId: 'u1' });
191
+ expect(options.commitSession).toHaveBeenCalledWith(
192
+ { sessionId: 's1', userId: 'u1' },
193
+ { activate: true, hubSync: false },
194
+ );
195
+ });
196
+ });
197
+
198
+ describe("webAuthMode: 'redirect' (unchanged compatibility path)", () => {
199
+ it('starts the silent restore and navigates to the IdP with prompt=none', async () => {
200
+ stubSignedOutBoot();
201
+ const { options } = makeHarness({ webAuthMode: 'redirect' });
202
+
203
+ await runProviderColdBoot(options);
204
+
205
+ expect(mockSilentRestore).toHaveBeenCalledTimes(1);
206
+ expect(mockRedirectToAuthorize).toHaveBeenCalledTimes(1);
207
+ const url = new URL(mockRedirectToAuthorize.mock.calls[0][0] as string);
208
+ expect(url.origin + url.pathname).toBe('https://auth.oxy.so/authorize');
209
+ expect(url.searchParams.get('client_id')).toBe(CLIENT_ID);
210
+ expect(url.searchParams.get('prompt')).toBe('none');
211
+ });
212
+
213
+ it('is the DEFAULT when no webAuthMode is supplied', async () => {
214
+ stubSignedOutBoot();
215
+ const { options } = makeHarness();
216
+
217
+ await runProviderColdBoot(options);
218
+
219
+ expect(mockSilentRestore).toHaveBeenCalledTimes(1);
220
+ expect(mockRedirectToAuthorize).toHaveBeenCalledTimes(1);
221
+ });
222
+
223
+ it('does NOT restore when the mint already resolved a session', async () => {
224
+ mockRunSessionColdBoot.mockImplementation(async (opts: Parameters<typeof runSessionColdBoot>[0]) => {
225
+ const session = { sessionId: 's1', userId: 'u1', accessToken: 'at', via: 'device-secret-mint' };
226
+ await opts.onSession?.(session);
227
+ return { kind: 'session', via: session.via, session } as const;
228
+ });
229
+ const { options, commitSession } = makeHarness({ webAuthMode: 'redirect' });
230
+
231
+ await runProviderColdBoot(options);
232
+
233
+ expect(commitSession).toHaveBeenCalledWith(
234
+ { sessionId: 's1', accessToken: 'at', userId: 'u1' },
235
+ { activate: false },
236
+ );
237
+ expect(mockSilentRestore).not.toHaveBeenCalled();
238
+ expect(mockRedirectToAuthorize).not.toHaveBeenCalled();
239
+ });
240
+ });
241
+
242
+ describe('URL-cleanup consumers run in BOTH modes', () => {
243
+ it.each(['popup', 'redirect'] as const)(
244
+ 'consumes the silent-OAuth error and hub-sync failure params (%s)',
245
+ async (webAuthMode) => {
246
+ stubSignedOutBoot();
247
+ const { options } = makeHarness({ webAuthMode });
248
+
249
+ await runProviderColdBoot(options);
250
+
251
+ expect(mockConsumeSilentOAuthError).toHaveBeenCalledTimes(1);
252
+ expect(mockConsumeHubSyncFailure).toHaveBeenCalledTimes(1);
253
+ },
254
+ );
255
+
256
+ it.each(['popup', 'redirect'] as const)(
257
+ 'consumes an authorization code left on the URL (%s)',
258
+ async (webAuthMode) => {
259
+ stubSignedOutBoot();
260
+ const { options } = makeHarness({ webAuthMode });
261
+
262
+ await runProviderColdBoot(options);
263
+
264
+ expect(mockTryCompleteOAuthReturn).toHaveBeenCalledTimes(1);
265
+ },
266
+ );
267
+ });
268
+
269
+ describe('identity mode still skips both web OAuth lanes in either transport', () => {
270
+ it.each(['popup', 'redirect'] as const)('skips the return leg and the restore (%s)', async (webAuthMode) => {
271
+ stubSignedOutBoot();
272
+ const { options } = makeHarness({ webAuthMode, sessionMode: 'identity' });
273
+
274
+ await runProviderColdBoot(options);
275
+
276
+ expect(mockTryCompleteOAuthReturn).not.toHaveBeenCalled();
277
+ expect(mockSilentRestore).not.toHaveBeenCalled();
278
+ expect(mockRedirectToAuthorize).not.toHaveBeenCalled();
279
+ });
280
+ });
281
+ });
@@ -2,7 +2,9 @@ import {
2
2
  logger as loggerUtil,
3
3
  runSessionColdBoot,
4
4
  type AuthStateStore,
5
+ type IdentityBinding,
5
6
  type OxyServices,
7
+ type SessionMode,
6
8
  } from '@oxyhq/core';
7
9
  import type { SessionClient } from '@oxyhq/core';
8
10
  import { loadPersistedDeviceCredential } from '../utils/deviceCredential';
@@ -13,6 +15,8 @@ import {
13
15
  } from '../utils/crossOriginRestore';
14
16
  import { tryCompleteOAuthReturn, consumeHubSyncFailure } from '../utils/oauthReturn';
15
17
  import { isWebBrowser } from '../utils/isWebBrowser';
18
+ import { allowsAutomaticIdpRedirect } from '../oauth/legacyRedirectLanes';
19
+ import type { WebAuthMode } from '../oauth/types';
16
20
  import type { CommitInput } from '../context/oxyContextTypes';
17
21
 
18
22
  /** How long the cold boot waits for the post-boot SessionClient handoff (ms). */
@@ -82,6 +86,27 @@ export interface RunProviderColdBootOptions {
82
86
  * silent-restore redirect targets its own IdP, never production.
83
87
  */
84
88
  authorizeBaseUrl?: string;
89
+ /**
90
+ * Who owns the session this boot resolves. `'account'` (the default) is the
91
+ * device's active account — every ordinary Oxy app. `'identity'` binds the
92
+ * boot to the owner of this device's PRIMARY identity key and REQUIRES
93
+ * {@link identity}; it also disables the two web OAuth lanes below, which
94
+ * commit whatever account the IdP hands back.
95
+ */
96
+ sessionMode?: SessionMode;
97
+ /** The identity binding required by `sessionMode: 'identity'`. */
98
+ identity?: IdentityBinding;
99
+ /**
100
+ * How this provider's WEB sign-in reaches the IdP
101
+ * (`OxyProviderProps.webAuthMode`).
102
+ *
103
+ * A first-class INPUT to the boot, not a UI-only concern: `'popup'` forbids
104
+ * the automatic full-page `prompt=none` restore in step 3, so a domain with no
105
+ * local credential resolves SIGNED OUT instead of bouncing the top-level
106
+ * window to `auth.oxy.so`. See `allowsAutomaticIdpRedirect`.
107
+ * @default 'redirect'
108
+ */
109
+ webAuthMode?: WebAuthMode;
85
110
  sessionClient: SessionClient;
86
111
  syncDeviceCredentialToHost: () => Promise<void>;
87
112
  commitSession: (
@@ -97,8 +122,18 @@ export interface RunProviderColdBootOptions {
97
122
  *
98
123
  * Ordered pipeline:
99
124
  * 1. Complete OAuth authorization-code return (web)
100
- * 2. `runSessionColdBoot` — device-secret mint (+ native shared-key)
125
+ * 2. `runSessionColdBoot` — device-secret mint (+ native shared-key, or the
126
+ * primary-identity-key lane in `sessionMode: 'identity'`)
101
127
  * 3. Silent OAuth for all web apps when mint finds no session
128
+ *
129
+ * Steps 1 and 3 are ACCOUNT-MODE ONLY: both commit whichever account the IdP
130
+ * resolves, which for an identity-bound client is somebody else's account by
131
+ * construction. In `'identity'` mode the boot is exactly step 2.
132
+ *
133
+ * Step 3 is additionally REDIRECT-MODE ONLY: it navigates the top-level window
134
+ * with no user gesture behind it, which `webAuthMode: 'popup'` exists to
135
+ * eliminate. In popup mode the boot is steps 1 and 2, and a domain with no local
136
+ * credential simply resolves signed out. See `allowsAutomaticIdpRedirect`.
102
137
  */
103
138
  export async function runProviderColdBoot(opts: RunProviderColdBootOptions): Promise<void> {
104
139
  const {
@@ -107,6 +142,9 @@ export async function runProviderColdBoot(opts: RunProviderColdBootOptions): Pro
107
142
  clientId,
108
143
  authRedirectUri,
109
144
  authorizeBaseUrl,
145
+ sessionMode = 'account',
146
+ identity,
147
+ webAuthMode = 'redirect',
110
148
  sessionClient,
111
149
  syncDeviceCredentialToHost,
112
150
  commitSession,
@@ -114,18 +152,34 @@ export async function runProviderColdBoot(opts: RunProviderColdBootOptions): Pro
114
152
  setTokenReady,
115
153
  } = opts;
116
154
 
155
+ const identityBound = sessionMode === 'identity';
156
+
117
157
  setTokenReady(false);
118
158
 
119
159
  try {
160
+ // MODE-INDEPENDENT URL cleanup, deliberately so: both consume query params a
161
+ // PREVIOUS redirect-mode session left in the address bar (`?error=login_required`
162
+ // from a silent authorize, `?hub_sync=failed` from the hub) and restore the
163
+ // page the visit started on. Flipping an app to popup mode must not strand
164
+ // those params, so neither is gated on `webAuthMode`. Neither starts a
165
+ // navigation — they only rewrite the URL via `history.replaceState`.
120
166
  consumeSilentOAuthError();
121
167
  consumeHubSyncFailure();
122
168
 
123
- const oauthCompleted = await tryCompleteOAuthReturn({
124
- oxyServices,
125
- clientId,
126
- authRedirectUri,
127
- commitSession: (input) => commitSession(input, { activate: true, hubSync: false }),
128
- });
169
+ // The redirect transport's RETURN leg — also NOT gated on `webAuthMode`. A
170
+ // popup-mode app legitimately lands here with `?code=` whenever the browser
171
+ // blocked the popup and `startWebOAuthSignIn` fell back to a full-page
172
+ // redirect (`popup-blocked` / `popup-navigation-failed`), and an app that
173
+ // switched modes mid-flight must not be stranded with a dead `?code=`
174
+ // either. It consumes a code already on the URL; it never starts one.
175
+ const oauthCompleted = identityBound
176
+ ? false
177
+ : await tryCompleteOAuthReturn({
178
+ oxyServices,
179
+ clientId,
180
+ authRedirectUri,
181
+ commitSession: (input) => commitSession(input, { activate: true, hubSync: false }),
182
+ });
129
183
  if (oauthCompleted) {
130
184
  setTokenReady(true);
131
185
  markAuthResolved();
@@ -142,6 +196,8 @@ export async function runProviderColdBoot(opts: RunProviderColdBootOptions): Pro
142
196
  oxy: oxyServices,
143
197
  store: authStore,
144
198
  platform: { isWeb: isWebBrowser(), isNative: !isWebBrowser() },
199
+ sessionMode,
200
+ identity,
145
201
  overallDeadlineMs: COLD_BOOT_OVERALL_DEADLINE_MS,
146
202
  isOffline: () => offline,
147
203
  onStepDeadline: (stepId) => {
@@ -204,16 +260,30 @@ export async function runProviderColdBoot(opts: RunProviderColdBootOptions): Pro
204
260
  },
205
261
  });
206
262
 
207
- // Silent cross-origin OAuth restore (web cross-app SSO). Gate it the SAME
208
- // way the hub-sync WRITE side (`syncHubAfterSignIn`) gates: official web
209
- // origins only, never the IdP hub itself, and — unlike the write side —
210
- // never a loopback / local-dev origin (which must not be bounced to a hosted
211
- // IdP on cold boot). The authorize endpoint is env-configurable so a
212
- // local/staging app targets its own IdP instead of production.
263
+ // Silent cross-origin OAuth restore (web cross-app SSO): a full-page
264
+ // `prompt=none` bounce to the IdP when the mint found no local session.
265
+ //
266
+ // TRANSPORT gate (`allowsAutomaticIdpRedirect`): `webAuthMode: 'popup'`
267
+ // FORBIDS this lane. It navigates the top-level window with no user gesture
268
+ // behind it, which is precisely what popup mode exists to eliminate — a
269
+ // popup-mode domain without a local credential resolves signed out right
270
+ // here and waits for the user's next explicit "Continue with Oxy" (issue
271
+ // #691, "Cold boot and cross-domain behavior"). `'redirect'` — still the
272
+ // default and the compatibility path — reaches this lane unchanged, and this
273
+ // whole block disappears with the transport in phase 7b.
274
+ //
275
+ // ORIGIN gate: same as the hub-sync WRITE side (`syncHubAfterSignIn`) —
276
+ // official web origins only, never the IdP hub itself, and — unlike the
277
+ // write side — never a loopback / local-dev origin (which must not be
278
+ // bounced to a hosted IdP on cold boot). The authorize endpoint is
279
+ // env-configurable so a local/staging app targets its own IdP instead of
280
+ // production.
213
281
  const webOrigin = isWebBrowser()
214
282
  ? (globalThis as { location?: Location }).location?.origin
215
283
  : undefined;
216
284
  if (
285
+ !identityBound &&
286
+ allowsAutomaticIdpRedirect(webAuthMode) &&
217
287
  clientId &&
218
288
  outcome.kind !== 'session' &&
219
289
  webOrigin &&
package/src/ui/client.ts CHANGED
@@ -17,7 +17,6 @@ export { LogoIcon } from './components/logo/LogoIcon';
17
17
  export { LogoText } from './components/logo/LogoText';
18
18
  export { default as FollowButton } from './components/FollowButton';
19
19
  export { default as OxyPayButton } from './components/OxyPayButton';
20
- export { FontLoader, setupFonts } from './components/FontLoader';
21
20
 
22
21
  // Context
23
22
  export { useOxy } from './context/OxyContext';
@@ -75,7 +75,19 @@ const OxyAccountDialogScreen: React.FC<BaseScreenProps> = ({ canGoBack }) => {
75
75
  const { view } = snapshot;
76
76
  const showBack =
77
77
  view === 'qr' || view === 'signup' || (view === 'add' && snapshot.accounts.length > 0);
78
- const goToAccounts = useCallback(() => controller?.setView('accounts'), [controller]);
78
+ const goToAccounts = useCallback(() => {
79
+ if (!controller) return;
80
+ const { view: currentView, signIn } = controller.getSnapshot();
81
+ // Backing out of an active request must withdraw it — otherwise the
82
+ // authorizeCode stays approvable until expiry (issue #691 phase 5).
83
+ if (
84
+ (currentView === 'qr' || currentView === 'add') &&
85
+ (signIn.phase === 'starting' || signIn.phase === 'waiting')
86
+ ) {
87
+ controller.cancelSignIn();
88
+ }
89
+ controller.setView('accounts');
90
+ }, [controller]);
79
91
  // An ENTRY view (accounts / signin — no in-dialog back of its own) that is
80
92
  // MORPHED into a host surface (ManageAccount → switcher) has a frame beneath it,
81
93
  // so its back CLOSES the dialog and reshapes back to the host — routed through
@@ -118,10 +130,16 @@ function headerCopy(
118
130
  t: Translate,
119
131
  ): { title: string; subtitle: string | null } {
120
132
  switch (view) {
133
+ // The ACTIVE REQUEST. Its header is deliberately route-AGNOSTIC: Oxy picks
134
+ // the delivery route (QR here, a push to the user's phone, or opening
135
+ // Commons on this device — issue #691), so naming one of them in the bar
136
+ // would contradict the other two. The route-specific status line lives in
137
+ // the body, derived from `signIn.progress`, and is the only thing that
138
+ // describes HOW the request is travelling.
121
139
  case 'qr':
122
140
  return {
123
- title: t('accountSwitcher.scanTitle') || 'Sign in with Oxy',
124
- subtitle: t('accountSwitcher.scanSubtitle') || 'Scan with Commons on your phone.',
141
+ title: t('accountSwitcher.signInWithOxy') || 'Sign in with Oxy',
142
+ subtitle: null,
125
143
  };
126
144
  case 'signup':
127
145
  return {
@@ -148,7 +166,18 @@ const EMPTY_SNAPSHOT: AccountDialogSnapshot = {
148
166
  loading: false,
149
167
  error: null,
150
168
  switchingAccountId: null,
151
- signIn: { phase: 'idle', authorizeCode: null, qrPayload: null, expiresAt: null, error: null },
169
+ signIn: {
170
+ phase: 'idle',
171
+ authorizeCode: null,
172
+ qrPayload: null,
173
+ expiresAt: null,
174
+ error: null,
175
+ route: null,
176
+ routeFailed: false,
177
+ pushSentAt: null,
178
+ openedAt: null,
179
+ progress: 'idle',
180
+ },
152
181
  commonsAvailability: 'unknown',
153
182
  };
154
183