@tempoxyz/id 0.0.0-stage → 0.0.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 (1096) hide show
  1. package/README.md +121 -2
  2. package/dist/App.d.ts +121 -0
  3. package/dist/App.d.ts.map +1 -0
  4. package/dist/App.js +132 -0
  5. package/dist/App.js.map +1 -0
  6. package/dist/app/client/.assetsignore +2 -0
  7. package/dist/app/client/_headers +4 -0
  8. package/dist/app/client/assets/Account-BYLpNFf3.css +1 -0
  9. package/dist/app/client/assets/Account-BllJah07.js +1 -0
  10. package/dist/app/client/assets/Amount-E_7snI0-.js +1 -0
  11. package/dist/app/client/assets/Amount-ZdtluGf-.css +1 -0
  12. package/dist/app/client/assets/Approval-CgV5JHlb.css +1 -0
  13. package/dist/app/client/assets/Approval-yKflypU2.js +1 -0
  14. package/dist/app/client/assets/ArrowUp-CRvqfMNU.js +1 -0
  15. package/dist/app/client/assets/Authentication-BAXhOh_4.js +2 -0
  16. package/dist/app/client/assets/BRLA-CZvVDNYr.png +0 -0
  17. package/dist/app/client/assets/BRZ-Cn3jEi9t.svg +1 -0
  18. package/dist/app/client/assets/CHFAU-DCedc4aH.png +0 -0
  19. package/dist/app/client/assets/Callout-B736759d.js +1 -0
  20. package/dist/app/client/assets/Callout-DBfEmP7q.css +1 -0
  21. package/dist/app/client/assets/Check-DVgD8tDG.js +1 -0
  22. package/dist/app/client/assets/ChevronRight-CsXtIZCB.js +1 -0
  23. package/dist/app/client/assets/ChooseAccount-BjxfQjPK.js +1 -0
  24. package/dist/app/client/assets/ChooseAccount-DL3wgJhE.css +1 -0
  25. package/dist/app/client/assets/Client-JrABNovb.js +1 -0
  26. package/dist/app/client/assets/Close-CRvWlhqc.js +1 -0
  27. package/dist/app/client/assets/Cloud-DgJsrqpQ.js +1 -0
  28. package/dist/app/client/assets/CodeInput-79Ctx8ZA.js +1 -0
  29. package/dist/app/client/assets/CodeInput-BqRteSwD.css +1 -0
  30. package/dist/app/client/assets/DLUSD-BnRXm3EI.png +0 -0
  31. package/dist/app/client/assets/Deposit-CclrAoXL.css +1 -0
  32. package/dist/app/client/assets/Deposit-c7uYn2Eb.js +1 -0
  33. package/dist/app/client/assets/DevTools-BYkmtuV5.css +1 -0
  34. package/dist/app/client/assets/DevTools-BgnzDGo2.js +1 -0
  35. package/dist/app/client/assets/DeviceApproval-BBUVv58e.js +1 -0
  36. package/dist/app/client/assets/DeviceApproval-BffFLD8F.css +1 -0
  37. package/dist/app/client/assets/EURAU-sjieTTB9.svg +1 -0
  38. package/dist/app/client/assets/EURC.e-CxYiiwkz.svg +1 -0
  39. package/dist/app/client/assets/Fingerprint-BNCA6qOJ.js +1 -0
  40. package/dist/app/client/assets/GBPA-DI_25xSG.svg +4 -0
  41. package/dist/app/client/assets/GUSD-BDEP2Qb-.svg +1 -0
  42. package/dist/app/client/assets/GeistMono-Variable-BRXCGrxA.woff2 +0 -0
  43. package/dist/app/client/assets/Globe-f0eWzcEI.js +1 -0
  44. package/dist/app/client/assets/Grant-5a-n1gJH.css +1 -0
  45. package/dist/app/client/assets/Grant-Dp7mpcEi.js +1 -0
  46. package/dist/app/client/assets/Hex-C9KeV7_9.css +1 -0
  47. package/dist/app/client/assets/Hex-CSp2U46W.js +10 -0
  48. package/dist/app/client/assets/IconChip-DpZHa1JW.js +1 -0
  49. package/dist/app/client/assets/IconChip-yqaQ2y_d.css +1 -0
  50. package/dist/app/client/assets/InputGroup-BlZvt9In.css +1 -0
  51. package/dist/app/client/assets/InputGroup-CsOeBnpB.js +1 -0
  52. package/dist/app/client/assets/Inter-cyrillic-e3OmmzmJ.woff2 +0 -0
  53. package/dist/app/client/assets/Inter-cyrillic-ext-DOWZeO4Q.woff2 +0 -0
  54. package/dist/app/client/assets/Inter-greek-BD3ujQlX.woff2 +0 -0
  55. package/dist/app/client/assets/Inter-greek-ext-CXEwbus4.woff2 +0 -0
  56. package/dist/app/client/assets/Inter-latin-BDFm4vTb.woff2 +0 -0
  57. package/dist/app/client/assets/Inter-latin-ext-E7a9JEPe.woff2 +0 -0
  58. package/dist/app/client/assets/Inter-symbols-DEch7Rxr.woff2 +0 -0
  59. package/dist/app/client/assets/Inter-vietnamese-Bg9723vR.woff2 +0 -0
  60. package/dist/app/client/assets/Loader-Cm9YJNNJ.js +1 -0
  61. package/dist/app/client/assets/MACH-sK0r79kQ.svg +4 -0
  62. package/dist/app/client/assets/OUSD-BFXgVo-Z.svg +5 -0
  63. package/dist/app/client/assets/OUSD.dark-BbbjMvA1.svg +17 -0
  64. package/dist/app/client/assets/OUSD.light-B_zpSz_c.svg +17 -0
  65. package/dist/app/client/assets/PRIME-CiFp2-3e.svg +14 -0
  66. package/dist/app/client/assets/PopoverPopup-DprRXRQe.js +1 -0
  67. package/dist/app/client/assets/Rows-DPGTUdA8.css +1 -0
  68. package/dist/app/client/assets/Rows-Qqo3evtk.js +1 -0
  69. package/dist/app/client/assets/SBC-BTYkbkiD.svg +1 -0
  70. package/dist/app/client/assets/SEKAU-CB5Fc6o8.svg +5 -0
  71. package/dist/app/client/assets/Separator-CZUjVQOL.js +1 -0
  72. package/dist/app/client/assets/SignIn-HdaDzFmq.js +1 -0
  73. package/dist/app/client/assets/SignIn-mlBTwUq4.css +1 -0
  74. package/dist/app/client/assets/Stack-CkkvkOzj.js +1 -0
  75. package/dist/app/client/assets/Stack-D7Yt22Ed.css +1 -0
  76. package/dist/app/client/assets/Tag-BMh6ajrW.css +1 -0
  77. package/dist/app/client/assets/Tag-CLOVANTX.js +1 -0
  78. package/dist/app/client/assets/ToolbarRootContext-Zty_Dh3J.js +1 -0
  79. package/dist/app/client/assets/Tooltip-CLATV6YU.js +1 -0
  80. package/dist/app/client/assets/Tooltip-d3y9ESUJ.css +1 -0
  81. package/dist/app/client/assets/USD1-COVcO_PB.svg +30 -0
  82. package/dist/app/client/assets/USDB-Ckwb6UQw.svg +11 -0
  83. package/dist/app/client/assets/USDC.e-3nMsKAMC.svg +1 -0
  84. package/dist/app/client/assets/USDT0-ia60Dw0e.svg +1 -0
  85. package/dist/app/client/assets/USDY-CB4iet2q.svg +16 -0
  86. package/dist/app/client/assets/USDe-BXHQCd92.svg +1 -0
  87. package/dist/app/client/assets/Upgrade-D0_aO5AP.js +1 -0
  88. package/dist/app/client/assets/WalletUpgrade-BPsPNQsd.js +1 -0
  89. package/dist/app/client/assets/WalletUpgrade-C04kW0Jl.css +1 -0
  90. package/dist/app/client/assets/YLDS-CRh8Zw0g.svg +3 -0
  91. package/dist/app/client/assets/___-I98bns4o.css +1 -0
  92. package/dist/app/client/assets/___.flows-XOlLwMIy.js +5 -0
  93. package/dist/app/client/assets/alphaUSD-CpCFoVuh.svg +1 -0
  94. package/dist/app/client/assets/authorize-C-MlCyaM.js +1 -0
  95. package/dist/app/client/assets/betaUSD-9A8AjgYg.svg +1 -0
  96. package/dist/app/client/assets/cUSD-WsQfa-iC.svg +1 -0
  97. package/dist/app/client/assets/cbBTC-DvUDqrDi.svg +1 -0
  98. package/dist/app/client/assets/choose-account-nXR-SKa2.js +1 -0
  99. package/dist/app/client/assets/deposit-G8tiLPN4.js +1 -0
  100. package/dist/app/client/assets/device-BojBF7hZ.js +1 -0
  101. package/dist/app/client/assets/error-KiOpX7GD.js +1 -0
  102. package/dist/app/client/assets/frxUSD-n9pTpinR.svg +1 -0
  103. package/dist/app/client/assets/getPseudoElementBounds-BsLy4zf_.js +1 -0
  104. package/dist/app/client/assets/goUSD-D9kUvHsF.svg +5 -0
  105. package/dist/app/client/assets/iUSD-CWCJAq9X.svg +1 -0
  106. package/dist/app/client/assets/index-BZH0M7Nf.js +13 -0
  107. package/dist/app/client/assets/index-CIYxHmYA.css +1 -0
  108. package/dist/app/client/assets/login-DUjpk60p.js +1 -0
  109. package/dist/app/client/assets/pathUSD-BvaO6ooS.svg +25 -0
  110. package/dist/app/client/assets/preload-helper-Bs9KvdYl.js +1 -0
  111. package/dist/app/client/assets/rUSD-B-xuFS7T.svg +1 -0
  112. package/dist/app/client/assets/reUSD-CkIUs0Lx.svg +1 -0
  113. package/dist/app/client/assets/removable-DMiA3t_o.js +1 -0
  114. package/dist/app/client/assets/reset-co-CHrff.css +1 -0
  115. package/dist/app/client/assets/rolldown-runtime-WkwZ5CU-.js +1 -0
  116. package/dist/app/client/assets/routes-CK8cthzA.js +1 -0
  117. package/dist/app/client/assets/sUSDe-j9GOnH7I.svg +1 -0
  118. package/dist/app/client/assets/siUSD-C10QUNYS.svg +1 -0
  119. package/dist/app/client/assets/stcUSD-DIntDJeh.svg +1 -0
  120. package/dist/app/client/assets/syrupUSDC-DhYwZqdM.svg +5 -0
  121. package/dist/app/client/assets/thetaUSD-Dgmksf6G.svg +1 -0
  122. package/dist/app/client/assets/useNavigate-CB6S2u4J.js +1 -0
  123. package/dist/app/client/assets/useQuery-BpHfPhTT.js +1 -0
  124. package/dist/app/client/assets/useRegisterFieldControl-DsslqY-V.js +1 -0
  125. package/dist/app/client/assets/wYLDS-CaCKDrO-.svg +10 -0
  126. package/dist/app/client/assets/wsrUSD-B2Ey0bDQ.svg +1 -0
  127. package/dist/app/client/assets/zyzz-DYC-X0_B.css +1 -0
  128. package/dist/app/client/assets/zyzz.config-DX_D_7j3.js +2 -0
  129. package/dist/app/db/auth.d.ts +3412 -0
  130. package/dist/app/db/auth.d.ts.map +1 -0
  131. package/dist/app/db/auth.js +349 -0
  132. package/dist/app/db/auth.js.map +1 -0
  133. package/dist/app/db/schema.d.ts +1091 -0
  134. package/dist/app/db/schema.d.ts.map +1 -0
  135. package/dist/app/db/schema.js +183 -0
  136. package/dist/app/db/schema.js.map +1 -0
  137. package/dist/app/db/table.d.ts +8 -0
  138. package/dist/app/db/table.d.ts.map +1 -0
  139. package/dist/app/db/table.js +28 -0
  140. package/dist/app/db/table.js.map +1 -0
  141. package/dist/app/server/.vite/manifest.json +2093 -0
  142. package/dist/app/server/assets/Account-BYLpNFf3.css +1 -0
  143. package/dist/app/server/assets/Account-G_SUeRU3.js +2 -0
  144. package/dist/app/server/assets/Account-G_SUeRU3.js.map +1 -0
  145. package/dist/app/server/assets/Amount-Cgwdr3Xt.js +2 -0
  146. package/dist/app/server/assets/Amount-Cgwdr3Xt.js.map +1 -0
  147. package/dist/app/server/assets/Amount-ZdtluGf-.css +1 -0
  148. package/dist/app/server/assets/Approval-CgV5JHlb.css +1 -0
  149. package/dist/app/server/assets/Approval-DvkB9tWA.js +2 -0
  150. package/dist/app/server/assets/Approval-DvkB9tWA.js.map +1 -0
  151. package/dist/app/server/assets/ArrowUp-DpK_zNgZ.js +2 -0
  152. package/dist/app/server/assets/ArrowUp-DpK_zNgZ.js.map +1 -0
  153. package/dist/app/server/assets/Authentication-BOkhlNQu.js +2 -0
  154. package/dist/app/server/assets/Authentication-BOkhlNQu.js.map +1 -0
  155. package/dist/app/server/assets/Authentication-C3oNZAVX.js +2 -0
  156. package/dist/app/server/assets/Authentication-C3oNZAVX.js.map +1 -0
  157. package/dist/app/server/assets/BRLA-CZvVDNYr.png +0 -0
  158. package/dist/app/server/assets/BRZ-Cn3jEi9t.svg +1 -0
  159. package/dist/app/server/assets/Bytes-C7CRVS3J.js +4 -0
  160. package/dist/app/server/assets/Bytes-C7CRVS3J.js.map +1 -0
  161. package/dist/app/server/assets/CHFAU-DCedc4aH.png +0 -0
  162. package/dist/app/server/assets/Callout-DBfEmP7q.css +1 -0
  163. package/dist/app/server/assets/Callout-tQoAitWq.js +2 -0
  164. package/dist/app/server/assets/Callout-tQoAitWq.js.map +1 -0
  165. package/dist/app/server/assets/ChainList-C4A_7e-9.js +6 -0
  166. package/dist/app/server/assets/ChainList-C4A_7e-9.js.map +1 -0
  167. package/dist/app/server/assets/ChainName-BMnJyJrd.js +2 -0
  168. package/dist/app/server/assets/ChainName-BMnJyJrd.js.map +1 -0
  169. package/dist/app/server/assets/Check-DU_oR3Ev.js +2 -0
  170. package/dist/app/server/assets/Check-DU_oR3Ev.js.map +1 -0
  171. package/dist/app/server/assets/ChevronRight-DTBnw-W6.js +2 -0
  172. package/dist/app/server/assets/ChevronRight-DTBnw-W6.js.map +1 -0
  173. package/dist/app/server/assets/ChooseAccount-BizJvMrY.js +2 -0
  174. package/dist/app/server/assets/ChooseAccount-BizJvMrY.js.map +1 -0
  175. package/dist/app/server/assets/ChooseAccount-DL3wgJhE.css +1 -0
  176. package/dist/app/server/assets/Client-Dx3KrpJZ.js +2 -0
  177. package/dist/app/server/assets/Client-Dx3KrpJZ.js.map +1 -0
  178. package/dist/app/server/assets/ClientOnly-CKLiu67O.js +2 -0
  179. package/dist/app/server/assets/ClientOnly-CKLiu67O.js.map +1 -0
  180. package/dist/app/server/assets/Close-DUeE37ev.js +2 -0
  181. package/dist/app/server/assets/Close-DUeE37ev.js.map +1 -0
  182. package/dist/app/server/assets/Cloud-CLB3rTTy.js +2 -0
  183. package/dist/app/server/assets/Cloud-CLB3rTTy.js.map +1 -0
  184. package/dist/app/server/assets/CodeInput-BqRteSwD.css +1 -0
  185. package/dist/app/server/assets/CodeInput-FsPzVuLU.js +2 -0
  186. package/dist/app/server/assets/CodeInput-FsPzVuLU.js.map +1 -0
  187. package/dist/app/server/assets/Credential-DFjcrdyI.js +2 -0
  188. package/dist/app/server/assets/Credential-DFjcrdyI.js.map +1 -0
  189. package/dist/app/server/assets/DLUSD-BnRXm3EI.png +0 -0
  190. package/dist/app/server/assets/Deposit-CclrAoXL.css +1 -0
  191. package/dist/app/server/assets/Deposit-ChYGRfW2.js +2 -0
  192. package/dist/app/server/assets/Deposit-ChYGRfW2.js.map +1 -0
  193. package/dist/app/server/assets/DevTools-BYkmtuV5.css +1 -0
  194. package/dist/app/server/assets/DevTools-ZJVXqrIK.js +2 -0
  195. package/dist/app/server/assets/DevTools-ZJVXqrIK.js.map +1 -0
  196. package/dist/app/server/assets/DeviceApproval-BffFLD8F.css +1 -0
  197. package/dist/app/server/assets/DeviceApproval-Bqe3Mi78.js +2 -0
  198. package/dist/app/server/assets/DeviceApproval-Bqe3Mi78.js.map +1 -0
  199. package/dist/app/server/assets/EURAU-sjieTTB9.svg +1 -0
  200. package/dist/app/server/assets/EURC.e-CxYiiwkz.svg +1 -0
  201. package/dist/app/server/assets/ExecutionError-CDszGSF1.js +9 -0
  202. package/dist/app/server/assets/ExecutionError-CDszGSF1.js.map +1 -0
  203. package/dist/app/server/assets/Fingerprint-DhOPOdRr.js +2 -0
  204. package/dist/app/server/assets/Fingerprint-DhOPOdRr.js.map +1 -0
  205. package/dist/app/server/assets/GBPA-DI_25xSG.svg +4 -0
  206. package/dist/app/server/assets/GUSD-BDEP2Qb-.svg +1 -0
  207. package/dist/app/server/assets/GeistMono-Variable-BRXCGrxA.woff2 +0 -0
  208. package/dist/app/server/assets/Globe-2CxqxU-7.js +2 -0
  209. package/dist/app/server/assets/Globe-2CxqxU-7.js.map +1 -0
  210. package/dist/app/server/assets/Grant-5a-n1gJH.css +1 -0
  211. package/dist/app/server/assets/Grant-D_tun0mF.js +2 -0
  212. package/dist/app/server/assets/Grant-D_tun0mF.js.map +1 -0
  213. package/dist/app/server/assets/Hex-C9KeV7_9.css +1 -0
  214. package/dist/app/server/assets/Hex-Z6m_0Y0m.js +11 -0
  215. package/dist/app/server/assets/Hex-Z6m_0Y0m.js.map +1 -0
  216. package/dist/app/server/assets/IconChip-C9ZrmGB5.js +2 -0
  217. package/dist/app/server/assets/IconChip-C9ZrmGB5.js.map +1 -0
  218. package/dist/app/server/assets/IconChip-yqaQ2y_d.css +1 -0
  219. package/dist/app/server/assets/InputGroup-BlZvt9In.css +1 -0
  220. package/dist/app/server/assets/InputGroup-hpjuLuR7.js +2 -0
  221. package/dist/app/server/assets/InputGroup-hpjuLuR7.js.map +1 -0
  222. package/dist/app/server/assets/Inter-cyrillic-e3OmmzmJ.woff2 +0 -0
  223. package/dist/app/server/assets/Inter-cyrillic-ext-DOWZeO4Q.woff2 +0 -0
  224. package/dist/app/server/assets/Inter-greek-BD3ujQlX.woff2 +0 -0
  225. package/dist/app/server/assets/Inter-greek-ext-CXEwbus4.woff2 +0 -0
  226. package/dist/app/server/assets/Inter-latin-BDFm4vTb.woff2 +0 -0
  227. package/dist/app/server/assets/Inter-latin-ext-E7a9JEPe.woff2 +0 -0
  228. package/dist/app/server/assets/Inter-symbols-DEch7Rxr.woff2 +0 -0
  229. package/dist/app/server/assets/Inter-vietnamese-Bg9723vR.woff2 +0 -0
  230. package/dist/app/server/assets/Loader-DnKC9P5p.js +2 -0
  231. package/dist/app/server/assets/Loader-DnKC9P5p.js.map +1 -0
  232. package/dist/app/server/assets/MACH-sK0r79kQ.svg +4 -0
  233. package/dist/app/server/assets/Match-CyVdYcSf.js +2 -0
  234. package/dist/app/server/assets/Match-CyVdYcSf.js.map +1 -0
  235. package/dist/app/server/assets/OUSD-BFXgVo-Z.svg +5 -0
  236. package/dist/app/server/assets/OUSD.dark-BbbjMvA1.svg +17 -0
  237. package/dist/app/server/assets/OUSD.light-B_zpSz_c.svg +17 -0
  238. package/dist/app/server/assets/PRIME-CiFp2-3e.svg +14 -0
  239. package/dist/app/server/assets/PopoverPopup-CwqeQelI.js +2 -0
  240. package/dist/app/server/assets/PopoverPopup-CwqeQelI.js.map +1 -0
  241. package/dist/app/server/assets/Rows-CQKQwTI1.js +2 -0
  242. package/dist/app/server/assets/Rows-CQKQwTI1.js.map +1 -0
  243. package/dist/app/server/assets/Rows-DPGTUdA8.css +1 -0
  244. package/dist/app/server/assets/SBC-BTYkbkiD.svg +1 -0
  245. package/dist/app/server/assets/SEKAU-CB5Fc6o8.svg +5 -0
  246. package/dist/app/server/assets/Separator-DrI7KRAs.js +2 -0
  247. package/dist/app/server/assets/Separator-DrI7KRAs.js.map +1 -0
  248. package/dist/app/server/assets/SignIn-DfeeLEmN.js +2 -0
  249. package/dist/app/server/assets/SignIn-DfeeLEmN.js.map +1 -0
  250. package/dist/app/server/assets/SignIn-mlBTwUq4.css +1 -0
  251. package/dist/app/server/assets/Stack-D7Yt22Ed.css +1 -0
  252. package/dist/app/server/assets/Stack-DGktaLZc.js +2 -0
  253. package/dist/app/server/assets/Stack-DGktaLZc.js.map +1 -0
  254. package/dist/app/server/assets/Tag-9vSRBpph.js +2 -0
  255. package/dist/app/server/assets/Tag-9vSRBpph.js.map +1 -0
  256. package/dist/app/server/assets/Tag-BMh6ajrW.css +1 -0
  257. package/dist/app/server/assets/ToolbarRootContext-BH_CFSWd.js +2 -0
  258. package/dist/app/server/assets/ToolbarRootContext-BH_CFSWd.js.map +1 -0
  259. package/dist/app/server/assets/Tooltip-DLX41peb.js +2 -0
  260. package/dist/app/server/assets/Tooltip-DLX41peb.js.map +1 -0
  261. package/dist/app/server/assets/Tooltip-d3y9ESUJ.css +1 -0
  262. package/dist/app/server/assets/USD1-COVcO_PB.svg +30 -0
  263. package/dist/app/server/assets/USDB-Ckwb6UQw.svg +11 -0
  264. package/dist/app/server/assets/USDC.e-3nMsKAMC.svg +1 -0
  265. package/dist/app/server/assets/USDT0-ia60Dw0e.svg +1 -0
  266. package/dist/app/server/assets/USDY-CB4iet2q.svg +16 -0
  267. package/dist/app/server/assets/USDe-BXHQCd92.svg +1 -0
  268. package/dist/app/server/assets/Upgrade-Dbfm2nm0.js +2 -0
  269. package/dist/app/server/assets/Upgrade-Dbfm2nm0.js.map +1 -0
  270. package/dist/app/server/assets/WalletUpgrade-C04kW0Jl.css +1 -0
  271. package/dist/app/server/assets/WalletUpgrade-CWKc5fYt.js +2 -0
  272. package/dist/app/server/assets/WalletUpgrade-CWKc5fYt.js.map +1 -0
  273. package/dist/app/server/assets/YLDS-CRh8Zw0g.svg +3 -0
  274. package/dist/app/server/assets/___-I98bns4o.css +1 -0
  275. package/dist/app/server/assets/___.flows-Cc-awUoC.js +6 -0
  276. package/dist/app/server/assets/___.flows-Cc-awUoC.js.map +1 -0
  277. package/dist/app/server/assets/_tanstack-start-manifest_v-U7TrtUSA.js +1 -0
  278. package/dist/app/server/assets/_zyzz__2Fhome_2Frunner_2Fwork_2Fid_2Fid_2Fsrc_2Fapp_2Froutes_2F_5B__5D.flows-B1pPOqsM.css +1 -0
  279. package/dist/app/server/assets/_zyzz__2Fhome_2Frunner_2Fwork_2Fid_2Fid_2Fsrc_2Fapp_2Froutes_2F_5B__5D.flows.tsx-CKALi9oD.js +2 -0
  280. package/dist/app/server/assets/_zyzz__2Fhome_2Frunner_2Fwork_2Fid_2Fid_2Fsrc_2Fapp_2Froutes_2F_5B__5D.flows.tsx-CKALi9oD.js.map +1 -0
  281. package/dist/app/server/assets/_zyzz_shared-BbDIEd_j.css +1 -0
  282. package/dist/app/server/assets/alphaUSD-CpCFoVuh.svg +1 -0
  283. package/dist/app/server/assets/arktype-aI7TBD0R-D1R3Byo5.js +2 -0
  284. package/dist/app/server/assets/arktype-aI7TBD0R-D1R3Byo5.js.map +1 -0
  285. package/dist/app/server/assets/async-local-storage-DlOvwxXd.js +2 -0
  286. package/dist/app/server/assets/async-local-storage-DlOvwxXd.js.map +1 -0
  287. package/dist/app/server/assets/authorize-BXzTo2Pb.js +2 -0
  288. package/dist/app/server/assets/authorize-BXzTo2Pb.js.map +1 -0
  289. package/dist/app/server/assets/authorize-BzoUqOdA.js +2 -0
  290. package/dist/app/server/assets/authorize-BzoUqOdA.js.map +1 -0
  291. package/dist/app/server/assets/authorize-DXYo-K2n-rmQQ42x1.js +56 -0
  292. package/dist/app/server/assets/authorize-DXYo-K2n-rmQQ42x1.js.map +1 -0
  293. package/dist/app/server/assets/authorize-DfjPYJqS.css +1 -0
  294. package/dist/app/server/assets/betaUSD-9A8AjgYg.svg +1 -0
  295. package/dist/app/server/assets/bun-sqlite-dialect-DoOVo4ja-CtyBkVMb.js +2 -0
  296. package/dist/app/server/assets/bun-sqlite-dialect-DoOVo4ja-CtyBkVMb.js.map +1 -0
  297. package/dist/app/server/assets/cUSD-WsQfa-iC.svg +1 -0
  298. package/dist/app/server/assets/call-dzi0xjZd.js +31 -0
  299. package/dist/app/server/assets/call-dzi0xjZd.js.map +1 -0
  300. package/dist/app/server/assets/cbBTC-DvUDqrDi.svg +1 -0
  301. package/dist/app/server/assets/ccip-DjD8z_3B.js +2 -0
  302. package/dist/app/server/assets/ccip-DjD8z_3B.js.map +1 -0
  303. package/dist/app/server/assets/choose-account-_X7xq5am.js +2 -0
  304. package/dist/app/server/assets/choose-account-_X7xq5am.js.map +1 -0
  305. package/dist/app/server/assets/choose-account-lqA5SLx9.css +1 -0
  306. package/dist/app/server/assets/choose-account-zm-5Qs3e.js +2 -0
  307. package/dist/app/server/assets/choose-account-zm-5Qs3e.js.map +1 -0
  308. package/dist/app/server/assets/compiled-query-Ds2NVcFT.js +2 -0
  309. package/dist/app/server/assets/compiled-query-Ds2NVcFT.js.map +1 -0
  310. package/dist/app/server/assets/convert-BIC8n32x.js +2 -0
  311. package/dist/app/server/assets/convert-BIC8n32x.js.map +1 -0
  312. package/dist/app/server/assets/cookie-DxViaO10.js +2 -0
  313. package/dist/app/server/assets/cookie-DxViaO10.js.map +1 -0
  314. package/dist/app/server/assets/core-BBrZXfrB.js +56 -0
  315. package/dist/app/server/assets/core-BBrZXfrB.js.map +1 -0
  316. package/dist/app/server/assets/d1-sqlite-dialect-m0f01-4z-Cv-csE1u.js +2 -0
  317. package/dist/app/server/assets/d1-sqlite-dialect-m0f01-4z-Cv-csE1u.js.map +1 -0
  318. package/dist/app/server/assets/decodeFunctionData-bP6V2ai4.js +2 -0
  319. package/dist/app/server/assets/decodeFunctionData-bP6V2ai4.js.map +1 -0
  320. package/dist/app/server/assets/default-u_dwuiYb-DOrMMcg9.js +2 -0
  321. package/dist/app/server/assets/default-u_dwuiYb-DOrMMcg9.js.map +1 -0
  322. package/dist/app/server/assets/deposit-BBaNI01u.js +2 -0
  323. package/dist/app/server/assets/deposit-BBaNI01u.js.map +1 -0
  324. package/dist/app/server/assets/deposit-LWS6ZTuf.js +2 -0
  325. package/dist/app/server/assets/deposit-LWS6ZTuf.js.map +1 -0
  326. package/dist/app/server/assets/deposit-oFx15XCA.css +1 -0
  327. package/dist/app/server/assets/device-CrXlusjr.js +2 -0
  328. package/dist/app/server/assets/device-CrXlusjr.js.map +1 -0
  329. package/dist/app/server/assets/device-DdFMgYe2.js +2 -0
  330. package/dist/app/server/assets/device-DdFMgYe2.js.map +1 -0
  331. package/dist/app/server/assets/device-tMCpu5zk.css +1 -0
  332. package/dist/app/server/assets/dist-CR6FW-yS.js +1 -0
  333. package/dist/app/server/assets/dist-CoH0hD1s.js +15 -0
  334. package/dist/app/server/assets/dist-CoH0hD1s.js.map +1 -0
  335. package/dist/app/server/assets/dist-DcICI3fd.js +2 -0
  336. package/dist/app/server/assets/dist-DcICI3fd.js.map +1 -0
  337. package/dist/app/server/assets/effect-QlVUlMFu-mXPkuQTb.js +2 -0
  338. package/dist/app/server/assets/effect-QlVUlMFu-mXPkuQTb.js.map +1 -0
  339. package/dist/app/server/assets/empty-plugin-adapters-BaGcmrjC.js +2 -0
  340. package/dist/app/server/assets/empty-plugin-adapters-BaGcmrjC.js.map +1 -0
  341. package/dist/app/server/assets/error-CXy8gqdE.css +1 -0
  342. package/dist/app/server/assets/error-DXDT2AHy.js +2 -0
  343. package/dist/app/server/assets/error-DXDT2AHy.js.map +1 -0
  344. package/dist/app/server/assets/error-bnVzy9tx.js +2 -0
  345. package/dist/app/server/assets/error-bnVzy9tx.js.map +1 -0
  346. package/dist/app/server/assets/esm-C6SW--yt.js +4 -0
  347. package/dist/app/server/assets/esm-C6SW--yt.js.map +1 -0
  348. package/dist/app/server/assets/factory-dvoOlKer.js +5 -0
  349. package/dist/app/server/assets/factory-dvoOlKer.js.map +1 -0
  350. package/dist/app/server/assets/frxUSD-n9pTpinR.svg +1 -0
  351. package/dist/app/server/assets/get-id-field-OwLpfjj2.js +6 -0
  352. package/dist/app/server/assets/get-id-field-OwLpfjj2.js.map +1 -0
  353. package/dist/app/server/assets/getPseudoElementBounds-PkWU72kn.js +2 -0
  354. package/dist/app/server/assets/getPseudoElementBounds-PkWU72kn.js.map +1 -0
  355. package/dist/app/server/assets/goUSD-D9kUvHsF.svg +5 -0
  356. package/dist/app/server/assets/iUSD-CWCJAq9X.svg +1 -0
  357. package/dist/app/server/assets/index-CLddUTqr-CC33CMvS.js +2 -0
  358. package/dist/app/server/assets/index-CLddUTqr-CC33CMvS.js.map +1 -0
  359. package/dist/app/server/assets/index-DZEfthgZ-Ec2MMQ_e.js +2 -0
  360. package/dist/app/server/assets/index-DZEfthgZ-Ec2MMQ_e.js.map +1 -0
  361. package/dist/app/server/assets/kysely-adapter-B8tQwTcu.js +1 -0
  362. package/dist/app/server/assets/lazyRouteComponent-DPOOPZw_.js +2 -0
  363. package/dist/app/server/assets/lazyRouteComponent-DPOOPZw_.js.map +1 -0
  364. package/dist/app/server/assets/load-server-Dr0IlySo.js +3 -0
  365. package/dist/app/server/assets/load-server-Dr0IlySo.js.map +1 -0
  366. package/dist/app/server/assets/login-BLq3tEEr.js +2 -0
  367. package/dist/app/server/assets/login-BLq3tEEr.js.map +1 -0
  368. package/dist/app/server/assets/login-DCIrAbED.js +2 -0
  369. package/dist/app/server/assets/login-DCIrAbED.js.map +1 -0
  370. package/dist/app/server/assets/login-msDnt3yT.css +1 -0
  371. package/dist/app/server/assets/matchContext-ByrIUj4L.js +2 -0
  372. package/dist/app/server/assets/matchContext-ByrIUj4L.js.map +1 -0
  373. package/dist/app/server/assets/node-sqlite-dialect-BowWLXvK.js +2 -0
  374. package/dist/app/server/assets/node-sqlite-dialect-BowWLXvK.js.map +1 -0
  375. package/dist/app/server/assets/pathUSD-BvaO6ooS.svg +25 -0
  376. package/dist/app/server/assets/rUSD-B-xuFS7T.svg +1 -0
  377. package/dist/app/server/assets/reUSD-CkIUs0Lx.svg +1 -0
  378. package/dist/app/server/assets/react-dom-DYzj0HXX.js +2 -0
  379. package/dist/app/server/assets/react-dom-DYzj0HXX.js.map +1 -0
  380. package/dist/app/server/assets/removable-BCLTvPOx.js +2 -0
  381. package/dist/app/server/assets/removable-BCLTvPOx.js.map +1 -0
  382. package/dist/app/server/assets/reset-DZWeTZeQ.js +2 -0
  383. package/dist/app/server/assets/reset-DZWeTZeQ.js.map +1 -0
  384. package/dist/app/server/assets/reset-co-CHrff.css +1 -0
  385. package/dist/app/server/assets/resolveError-CZXXvCJR.js +2 -0
  386. package/dist/app/server/assets/resolveError-CZXXvCJR.js.map +1 -0
  387. package/dist/app/server/assets/rolldown-runtime-BWaJ3C7D.js +1 -0
  388. package/dist/app/server/assets/router-Bqz5X4Qw.js +2 -0
  389. package/dist/app/server/assets/router-Bqz5X4Qw.js.map +1 -0
  390. package/dist/app/server/assets/router-CclzitkY.css +1 -0
  391. package/dist/app/server/assets/routes-BLQdKqcZ.js +2 -0
  392. package/dist/app/server/assets/routes-BLQdKqcZ.js.map +1 -0
  393. package/dist/app/server/assets/routes-BgiIzrOt.css +1 -0
  394. package/dist/app/server/assets/routes-Bv6WzsSR.js +2 -0
  395. package/dist/app/server/assets/routes-Bv6WzsSR.js.map +1 -0
  396. package/dist/app/server/assets/sUSDe-j9GOnH7I.svg +1 -0
  397. package/dist/app/server/assets/schema-check-oLqvHR8y.js +9 -0
  398. package/dist/app/server/assets/schema-check-oLqvHR8y.js.map +1 -0
  399. package/dist/app/server/assets/secp256k1-yg8eeIYU.js +2 -0
  400. package/dist/app/server/assets/secp256k1-yg8eeIYU.js.map +1 -0
  401. package/dist/app/server/assets/server-RRUiOef2.js +76 -0
  402. package/dist/app/server/assets/server-RRUiOef2.js.map +1 -0
  403. package/dist/app/server/assets/siUSD-C10QUNYS.svg +1 -0
  404. package/dist/app/server/assets/sqlite-adapter-C_LAV4e3.js +2 -0
  405. package/dist/app/server/assets/sqlite-adapter-C_LAV4e3.js.map +1 -0
  406. package/dist/app/server/assets/sqlite-introspector-DSCAP82F-Crx7Ny14.js +6 -0
  407. package/dist/app/server/assets/sqlite-introspector-DSCAP82F-Crx7Ny14.js.map +1 -0
  408. package/dist/app/server/assets/standard-json-DY77efq0.js +2 -0
  409. package/dist/app/server/assets/standard-json-DY77efq0.js.map +1 -0
  410. package/dist/app/server/assets/standard-json-ig2t0wRt.js +2 -0
  411. package/dist/app/server/assets/standard-json-ig2t0wRt.js.map +1 -0
  412. package/dist/app/server/assets/standard-json-t-LNckA6.js +2 -0
  413. package/dist/app/server/assets/standard-json-t-LNckA6.js.map +1 -0
  414. package/dist/app/server/assets/standard-openapi-CONmVRl8.js +2 -0
  415. package/dist/app/server/assets/standard-openapi-CONmVRl8.js.map +1 -0
  416. package/dist/app/server/assets/start-C63VetBp.js +2 -0
  417. package/dist/app/server/assets/start-C63VetBp.js.map +1 -0
  418. package/dist/app/server/assets/stcUSD-DIntDJeh.svg +1 -0
  419. package/dist/app/server/assets/sury-CWZTCd75-CDaOS2oM.js +2 -0
  420. package/dist/app/server/assets/sury-CWZTCd75-CDaOS2oM.js.map +1 -0
  421. package/dist/app/server/assets/syrupUSDC-DhYwZqdM.svg +5 -0
  422. package/dist/app/server/assets/thetaUSD-Dgmksf6G.svg +1 -0
  423. package/dist/app/server/assets/typebox-Dei93FPO-D_lCVdAz.js +2 -0
  424. package/dist/app/server/assets/typebox-Dei93FPO-D_lCVdAz.js.map +1 -0
  425. package/dist/app/server/assets/useNavigate-D6d1w7KE.js +2 -0
  426. package/dist/app/server/assets/useNavigate-D6d1w7KE.js.map +1 -0
  427. package/dist/app/server/assets/useQuery-BRpCr5vj.js +2 -0
  428. package/dist/app/server/assets/useQuery-BRpCr5vj.js.map +1 -0
  429. package/dist/app/server/assets/useRegisterFieldControl-cJesrOWK.js +2 -0
  430. package/dist/app/server/assets/useRegisterFieldControl-cJesrOWK.js.map +1 -0
  431. package/dist/app/server/assets/utils-C4ZXZIZW.js +2 -0
  432. package/dist/app/server/assets/utils-C4ZXZIZW.js.map +1 -0
  433. package/dist/app/server/assets/utils-D57zfcg-.js +2 -0
  434. package/dist/app/server/assets/utils-D57zfcg-.js.map +1 -0
  435. package/dist/app/server/assets/valibot--1zFm7rT-CIKoH3MS.js +2 -0
  436. package/dist/app/server/assets/valibot--1zFm7rT-CIKoH3MS.js.map +1 -0
  437. package/dist/app/server/assets/valibot-D_HTw1Gn-BdPyLkXt.js +2 -0
  438. package/dist/app/server/assets/valibot-D_HTw1Gn-BdPyLkXt.js.map +1 -0
  439. package/dist/app/server/assets/wYLDS-CaCKDrO-.svg +10 -0
  440. package/dist/app/server/assets/wsrUSD-B2Ey0bDQ.svg +1 -0
  441. package/dist/app/server/assets/zod-Bwrt9trS-BezI5Gi1.js +2 -0
  442. package/dist/app/server/assets/zod-Bwrt9trS-BezI5Gi1.js.map +1 -0
  443. package/dist/app/server/assets/zod-DSgpEGAE-DZ7M_Q33.js +2 -0
  444. package/dist/app/server/assets/zod-DSgpEGAE-DZ7M_Q33.js.map +1 -0
  445. package/dist/app/server/assets/zyzz-6R2K52xP.css +1 -0
  446. package/dist/app/server/assets/zyzz.config-CJRpjn0E.js +3 -0
  447. package/dist/app/server/assets/zyzz.config-CJRpjn0E.js.map +1 -0
  448. package/dist/app/server/index.js +532 -0
  449. package/dist/app/server/index.js.map +1 -0
  450. package/dist/app/server/wrangler.json +1 -0
  451. package/dist/cli/Admin.d.ts +34 -0
  452. package/dist/cli/Admin.d.ts.map +1 -0
  453. package/dist/cli/Admin.js +61 -0
  454. package/dist/cli/Admin.js.map +1 -0
  455. package/dist/cli/Apps.d.ts +9 -0
  456. package/dist/cli/Apps.d.ts.map +1 -0
  457. package/dist/cli/Apps.js +34 -0
  458. package/dist/cli/Apps.js.map +1 -0
  459. package/dist/cli/Cli.d.ts +13 -0
  460. package/dist/cli/Cli.d.ts.map +1 -0
  461. package/dist/cli/Cli.js +26 -0
  462. package/dist/cli/Cli.js.map +1 -0
  463. package/dist/cli/Project.d.ts +17 -0
  464. package/dist/cli/Project.d.ts.map +1 -0
  465. package/dist/cli/Project.js +90 -0
  466. package/dist/cli/Project.js.map +1 -0
  467. package/dist/cli/Realms.d.ts +24 -0
  468. package/dist/cli/Realms.d.ts.map +1 -0
  469. package/dist/cli/Realms.js +48 -0
  470. package/dist/cli/Realms.js.map +1 -0
  471. package/dist/cli/Session.d.ts +79 -0
  472. package/dist/cli/Session.d.ts.map +1 -0
  473. package/dist/cli/Session.js +229 -0
  474. package/dist/cli/Session.js.map +1 -0
  475. package/dist/cli/User.d.ts +24 -0
  476. package/dist/cli/User.d.ts.map +1 -0
  477. package/dist/cli/User.js +34 -0
  478. package/dist/cli/User.js.map +1 -0
  479. package/dist/cli/V1.d.ts +32 -0
  480. package/dist/cli/V1.d.ts.map +1 -0
  481. package/dist/cli/V1.js +38 -0
  482. package/dist/cli/V1.js.map +1 -0
  483. package/dist/cli/bin.d.ts +3 -0
  484. package/dist/cli/bin.d.ts.map +1 -0
  485. package/dist/cli/bin.js +46 -0
  486. package/dist/cli/bin.js.map +1 -0
  487. package/dist/cli/commands/admin/apps/create.d.ts +23 -0
  488. package/dist/cli/commands/admin/apps/create.d.ts.map +1 -0
  489. package/dist/cli/commands/admin/apps/create.js +84 -0
  490. package/dist/cli/commands/admin/apps/create.js.map +1 -0
  491. package/dist/cli/commands/admin/apps/delete.d.ts +15 -0
  492. package/dist/cli/commands/admin/apps/delete.d.ts.map +1 -0
  493. package/dist/cli/commands/admin/apps/delete.js +41 -0
  494. package/dist/cli/commands/admin/apps/delete.js.map +1 -0
  495. package/dist/cli/commands/admin/apps/index.d.ts +5 -0
  496. package/dist/cli/commands/admin/apps/index.d.ts.map +1 -0
  497. package/dist/cli/commands/admin/apps/index.js +14 -0
  498. package/dist/cli/commands/admin/apps/index.js.map +1 -0
  499. package/dist/cli/commands/admin/apps/list.d.ts +10 -0
  500. package/dist/cli/commands/admin/apps/list.d.ts.map +1 -0
  501. package/dist/cli/commands/admin/apps/list.js +26 -0
  502. package/dist/cli/commands/admin/apps/list.js.map +1 -0
  503. package/dist/cli/commands/admin/apps/rotate-secret.d.ts +17 -0
  504. package/dist/cli/commands/admin/apps/rotate-secret.d.ts.map +1 -0
  505. package/dist/cli/commands/admin/apps/rotate-secret.js +47 -0
  506. package/dist/cli/commands/admin/apps/rotate-secret.js.map +1 -0
  507. package/dist/cli/commands/admin/apps/update.d.ts +20 -0
  508. package/dist/cli/commands/admin/apps/update.d.ts.map +1 -0
  509. package/dist/cli/commands/admin/apps/update.js +71 -0
  510. package/dist/cli/commands/admin/apps/update.js.map +1 -0
  511. package/dist/cli/commands/admin/index.d.ts +5 -0
  512. package/dist/cli/commands/admin/index.d.ts.map +1 -0
  513. package/dist/cli/commands/admin/index.js +13 -0
  514. package/dist/cli/commands/admin/index.js.map +1 -0
  515. package/dist/cli/commands/admin/migrate.d.ts +10 -0
  516. package/dist/cli/commands/admin/migrate.d.ts.map +1 -0
  517. package/dist/cli/commands/admin/migrate.js +20 -0
  518. package/dist/cli/commands/admin/migrate.js.map +1 -0
  519. package/dist/cli/commands/admin/realms/add.d.ts +13 -0
  520. package/dist/cli/commands/admin/realms/add.d.ts.map +1 -0
  521. package/dist/cli/commands/admin/realms/add.js +42 -0
  522. package/dist/cli/commands/admin/realms/add.js.map +1 -0
  523. package/dist/cli/commands/admin/realms/index.d.ts +5 -0
  524. package/dist/cli/commands/admin/realms/index.d.ts.map +1 -0
  525. package/dist/cli/commands/admin/realms/index.js +13 -0
  526. package/dist/cli/commands/admin/realms/index.js.map +1 -0
  527. package/dist/cli/commands/admin/realms/list.d.ts +14 -0
  528. package/dist/cli/commands/admin/realms/list.d.ts.map +1 -0
  529. package/dist/cli/commands/admin/realms/list.js +36 -0
  530. package/dist/cli/commands/admin/realms/list.js.map +1 -0
  531. package/dist/cli/commands/admin/realms/passkeys/index.d.ts +5 -0
  532. package/dist/cli/commands/admin/realms/passkeys/index.d.ts.map +1 -0
  533. package/dist/cli/commands/admin/realms/passkeys/index.js +13 -0
  534. package/dist/cli/commands/admin/realms/passkeys/index.js.map +1 -0
  535. package/dist/cli/commands/admin/realms/passkeys/set.d.ts +17 -0
  536. package/dist/cli/commands/admin/realms/passkeys/set.d.ts.map +1 -0
  537. package/dist/cli/commands/admin/realms/passkeys/set.js +46 -0
  538. package/dist/cli/commands/admin/realms/passkeys/set.js.map +1 -0
  539. package/dist/cli/commands/admin/realms/privy/index.d.ts +5 -0
  540. package/dist/cli/commands/admin/realms/privy/index.d.ts.map +1 -0
  541. package/dist/cli/commands/admin/realms/privy/index.js +13 -0
  542. package/dist/cli/commands/admin/realms/privy/index.js.map +1 -0
  543. package/dist/cli/commands/admin/realms/privy/set.d.ts +19 -0
  544. package/dist/cli/commands/admin/realms/privy/set.d.ts.map +1 -0
  545. package/dist/cli/commands/admin/realms/privy/set.js +66 -0
  546. package/dist/cli/commands/admin/realms/privy/set.js.map +1 -0
  547. package/dist/cli/commands/admin/realms/remove.d.ts +12 -0
  548. package/dist/cli/commands/admin/realms/remove.d.ts.map +1 -0
  549. package/dist/cli/commands/admin/realms/remove.js +35 -0
  550. package/dist/cli/commands/admin/realms/remove.js.map +1 -0
  551. package/dist/cli/commands/admin/realms/secp256k1/disable.d.ts +16 -0
  552. package/dist/cli/commands/admin/realms/secp256k1/disable.d.ts.map +1 -0
  553. package/dist/cli/commands/admin/realms/secp256k1/disable.js +42 -0
  554. package/dist/cli/commands/admin/realms/secp256k1/disable.js.map +1 -0
  555. package/dist/cli/commands/admin/realms/secp256k1/enable.d.ts +16 -0
  556. package/dist/cli/commands/admin/realms/secp256k1/enable.d.ts.map +1 -0
  557. package/dist/cli/commands/admin/realms/secp256k1/enable.js +42 -0
  558. package/dist/cli/commands/admin/realms/secp256k1/enable.js.map +1 -0
  559. package/dist/cli/commands/admin/realms/secp256k1/index.d.ts +9 -0
  560. package/dist/cli/commands/admin/realms/secp256k1/index.d.ts.map +1 -0
  561. package/dist/cli/commands/admin/realms/secp256k1/index.js +17 -0
  562. package/dist/cli/commands/admin/realms/secp256k1/index.js.map +1 -0
  563. package/dist/cli/commands/admin/realms/set.d.ts +17 -0
  564. package/dist/cli/commands/admin/realms/set.d.ts.map +1 -0
  565. package/dist/cli/commands/admin/realms/set.js +46 -0
  566. package/dist/cli/commands/admin/realms/set.js.map +1 -0
  567. package/dist/cli/commands/admin/rotate-key.d.ts +16 -0
  568. package/dist/cli/commands/admin/rotate-key.d.ts.map +1 -0
  569. package/dist/cli/commands/admin/rotate-key.js +46 -0
  570. package/dist/cli/commands/admin/rotate-key.js.map +1 -0
  571. package/dist/cli/commands/init.d.ts +11 -0
  572. package/dist/cli/commands/init.d.ts.map +1 -0
  573. package/dist/cli/commands/init.js +34 -0
  574. package/dist/cli/commands/init.js.map +1 -0
  575. package/dist/cli/commands/login.d.ts +12 -0
  576. package/dist/cli/commands/login.d.ts.map +1 -0
  577. package/dist/cli/commands/login.js +29 -0
  578. package/dist/cli/commands/login.js.map +1 -0
  579. package/dist/cli/commands/logout.d.ts +8 -0
  580. package/dist/cli/commands/logout.d.ts.map +1 -0
  581. package/dist/cli/commands/logout.js +19 -0
  582. package/dist/cli/commands/logout.js.map +1 -0
  583. package/dist/cli/commands/whoami.d.ts +12 -0
  584. package/dist/cli/commands/whoami.d.ts.map +1 -0
  585. package/dist/cli/commands/whoami.js +24 -0
  586. package/dist/cli/commands/whoami.js.map +1 -0
  587. package/dist/client/Actions.d.ts +108 -0
  588. package/dist/client/Actions.d.ts.map +1 -0
  589. package/dist/client/Actions.js +94 -0
  590. package/dist/client/Actions.js.map +1 -0
  591. package/dist/client/Auth.d.ts +143 -0
  592. package/dist/client/Auth.d.ts.map +1 -0
  593. package/dist/client/Auth.js +106 -0
  594. package/dist/client/Auth.js.map +1 -0
  595. package/dist/client/Authorization.d.ts +29 -0
  596. package/dist/client/Authorization.d.ts.map +1 -0
  597. package/dist/client/Authorization.js +12 -0
  598. package/dist/client/Authorization.js.map +1 -0
  599. package/dist/client/Decorator.d.ts +172 -0
  600. package/dist/client/Decorator.d.ts.map +1 -0
  601. package/dist/client/Decorator.js +241 -0
  602. package/dist/client/Decorator.js.map +1 -0
  603. package/dist/client/Key.d.ts +82 -0
  604. package/dist/client/Key.d.ts.map +1 -0
  605. package/dist/client/Key.js +81 -0
  606. package/dist/client/Key.js.map +1 -0
  607. package/dist/client/Pending.d.ts +38 -0
  608. package/dist/client/Pending.d.ts.map +1 -0
  609. package/dist/client/Pending.js +12 -0
  610. package/dist/client/Pending.js.map +1 -0
  611. package/dist/client/Permissions.d.ts +36 -0
  612. package/dist/client/Permissions.d.ts.map +1 -0
  613. package/dist/client/Permissions.js +16 -0
  614. package/dist/client/Permissions.js.map +1 -0
  615. package/dist/client/Storage.d.ts +27 -0
  616. package/dist/client/Storage.d.ts.map +1 -0
  617. package/dist/client/Storage.js +16 -0
  618. package/dist/client/Storage.js.map +1 -0
  619. package/dist/client/TempoAccount.d.ts +52 -0
  620. package/dist/client/TempoAccount.d.ts.map +1 -0
  621. package/dist/client/TempoAccount.js +17 -0
  622. package/dist/client/TempoAccount.js.map +1 -0
  623. package/dist/client/Tokens.d.ts +25 -0
  624. package/dist/client/Tokens.d.ts.map +1 -0
  625. package/dist/client/Tokens.js +12 -0
  626. package/dist/client/Tokens.js.map +1 -0
  627. package/dist/client/User.d.ts +21 -0
  628. package/dist/client/User.d.ts.map +1 -0
  629. package/dist/client/User.js +12 -0
  630. package/dist/client/User.js.map +1 -0
  631. package/dist/client/actions/account.d.ts +75 -0
  632. package/dist/client/actions/account.d.ts.map +1 -0
  633. package/dist/client/actions/account.js +102 -0
  634. package/dist/client/actions/account.js.map +1 -0
  635. package/dist/client/actions/device.d.ts +52 -0
  636. package/dist/client/actions/device.d.ts.map +1 -0
  637. package/dist/client/actions/device.js +103 -0
  638. package/dist/client/actions/device.js.map +1 -0
  639. package/dist/client/actions/email.d.ts +89 -0
  640. package/dist/client/actions/email.d.ts.map +1 -0
  641. package/dist/client/actions/email.js +86 -0
  642. package/dist/client/actions/email.js.map +1 -0
  643. package/dist/client/actions/oauth.d.ts +112 -0
  644. package/dist/client/actions/oauth.d.ts.map +1 -0
  645. package/dist/client/actions/oauth.js +103 -0
  646. package/dist/client/actions/oauth.js.map +1 -0
  647. package/dist/client/actions/passkey.d.ts +140 -0
  648. package/dist/client/actions/passkey.d.ts.map +1 -0
  649. package/dist/client/actions/passkey.js +170 -0
  650. package/dist/client/actions/passkey.js.map +1 -0
  651. package/dist/client/actions/realm.d.ts +25 -0
  652. package/dist/client/actions/realm.d.ts.map +1 -0
  653. package/dist/client/actions/realm.js +16 -0
  654. package/dist/client/actions/realm.js.map +1 -0
  655. package/dist/client/actions/redirect.d.ts +152 -0
  656. package/dist/client/actions/redirect.d.ts.map +1 -0
  657. package/dist/client/actions/redirect.js +311 -0
  658. package/dist/client/actions/redirect.js.map +1 -0
  659. package/dist/client/internal/accessKey.d.ts +21 -0
  660. package/dist/client/internal/accessKey.d.ts.map +1 -0
  661. package/dist/client/internal/accessKey.js +38 -0
  662. package/dist/client/internal/accessKey.js.map +1 -0
  663. package/dist/client/internal/account.d.ts +17 -0
  664. package/dist/client/internal/account.d.ts.map +1 -0
  665. package/dist/client/internal/account.js +3 -0
  666. package/dist/client/internal/account.js.map +1 -0
  667. package/dist/client/internal/api.d.ts +110 -0
  668. package/dist/client/internal/api.d.ts.map +1 -0
  669. package/dist/client/internal/api.js +136 -0
  670. package/dist/client/internal/api.js.map +1 -0
  671. package/dist/client/internal/headless.d.ts +159 -0
  672. package/dist/client/internal/headless.d.ts.map +1 -0
  673. package/dist/client/internal/headless.js +196 -0
  674. package/dist/client/internal/headless.js.map +1 -0
  675. package/dist/client/internal/indexedDb.d.ts +8 -0
  676. package/dist/client/internal/indexedDb.d.ts.map +1 -0
  677. package/dist/client/internal/indexedDb.js +32 -0
  678. package/dist/client/internal/indexedDb.js.map +1 -0
  679. package/dist/client/internal/request.d.ts +56 -0
  680. package/dist/client/internal/request.d.ts.map +1 -0
  681. package/dist/client/internal/request.js +44 -0
  682. package/dist/client/internal/request.js.map +1 -0
  683. package/dist/client/internal/store.d.ts +12 -0
  684. package/dist/client/internal/store.d.ts.map +1 -0
  685. package/dist/client/internal/store.js +15 -0
  686. package/dist/client/internal/store.js.map +1 -0
  687. package/dist/client/internal/verifier.d.ts +25 -0
  688. package/dist/client/internal/verifier.d.ts.map +1 -0
  689. package/dist/client/internal/verifier.js +52 -0
  690. package/dist/client/internal/verifier.js.map +1 -0
  691. package/dist/client.d.ts +18 -0
  692. package/dist/client.d.ts.map +1 -0
  693. package/dist/client.js +18 -0
  694. package/dist/client.js.map +1 -0
  695. package/dist/index.d.ts +6 -0
  696. package/dist/index.d.ts.map +1 -0
  697. package/dist/index.js +6 -0
  698. package/dist/index.js.map +1 -0
  699. package/dist/internal/Apps.d.ts +3169 -0
  700. package/dist/internal/Apps.d.ts.map +1 -0
  701. package/dist/internal/Apps.js +948 -0
  702. package/dist/internal/Apps.js.map +1 -0
  703. package/dist/internal/Auth.d.ts +4287 -0
  704. package/dist/internal/Auth.d.ts.map +1 -0
  705. package/dist/internal/Auth.js +185 -0
  706. package/dist/internal/Auth.js.map +1 -0
  707. package/dist/internal/Authorize.d.ts +526 -0
  708. package/dist/internal/Authorize.d.ts.map +1 -0
  709. package/dist/internal/Authorize.js +330 -0
  710. package/dist/internal/Authorize.js.map +1 -0
  711. package/dist/internal/Cache.d.ts +56 -0
  712. package/dist/internal/Cache.d.ts.map +1 -0
  713. package/dist/internal/Cache.js +65 -0
  714. package/dist/internal/Cache.js.map +1 -0
  715. package/dist/internal/Chain.d.ts +738 -0
  716. package/dist/internal/Chain.d.ts.map +1 -0
  717. package/dist/internal/Chain.js +65 -0
  718. package/dist/internal/Chain.js.map +1 -0
  719. package/dist/internal/ChainList.d.ts +117 -0
  720. package/dist/internal/ChainList.d.ts.map +1 -0
  721. package/dist/internal/ChainList.js +148 -0
  722. package/dist/internal/ChainList.js.map +1 -0
  723. package/dist/internal/ChainName.d.ts +11 -0
  724. package/dist/internal/ChainName.d.ts.map +1 -0
  725. package/dist/internal/ChainName.js +13 -0
  726. package/dist/internal/ChainName.js.map +1 -0
  727. package/dist/internal/CodeEmail.d.ts +38 -0
  728. package/dist/internal/CodeEmail.d.ts.map +1 -0
  729. package/dist/internal/CodeEmail.js +85 -0
  730. package/dist/internal/CodeEmail.js.map +1 -0
  731. package/dist/internal/ConfigurableAccount.d.ts +600 -0
  732. package/dist/internal/ConfigurableAccount.d.ts.map +1 -0
  733. package/dist/internal/ConfigurableAccount.js +795 -0
  734. package/dist/internal/ConfigurableAccount.js.map +1 -0
  735. package/dist/internal/Device.d.ts +246 -0
  736. package/dist/internal/Device.d.ts.map +1 -0
  737. package/dist/internal/Device.js +257 -0
  738. package/dist/internal/Device.js.map +1 -0
  739. package/dist/internal/Env.d.ts +97 -0
  740. package/dist/internal/Env.d.ts.map +1 -0
  741. package/dist/internal/Env.js +2 -0
  742. package/dist/internal/Env.js.map +1 -0
  743. package/dist/internal/ErrorResponse.d.ts +608 -0
  744. package/dist/internal/ErrorResponse.d.ts.map +1 -0
  745. package/dist/internal/ErrorResponse.js +701 -0
  746. package/dist/internal/ErrorResponse.js.map +1 -0
  747. package/dist/internal/Id.d.ts +10 -0
  748. package/dist/internal/Id.d.ts.map +1 -0
  749. package/dist/internal/Id.js +34 -0
  750. package/dist/internal/Id.js.map +1 -0
  751. package/dist/internal/KeyAuthorization.d.ts +1650 -0
  752. package/dist/internal/KeyAuthorization.d.ts.map +1 -0
  753. package/dist/internal/KeyAuthorization.js +1187 -0
  754. package/dist/internal/KeyAuthorization.js.map +1 -0
  755. package/dist/internal/Limits.d.ts +70 -0
  756. package/dist/internal/Limits.d.ts.map +1 -0
  757. package/dist/internal/Limits.js +36 -0
  758. package/dist/internal/Limits.js.map +1 -0
  759. package/dist/internal/Log.d.ts +34 -0
  760. package/dist/internal/Log.d.ts.map +1 -0
  761. package/dist/internal/Log.js +99 -0
  762. package/dist/internal/Log.js.map +1 -0
  763. package/dist/internal/LogLine.d.ts +29 -0
  764. package/dist/internal/LogLine.d.ts.map +1 -0
  765. package/dist/internal/LogLine.js +50 -0
  766. package/dist/internal/LogLine.js.map +1 -0
  767. package/dist/internal/Migrations.d.ts +28 -0
  768. package/dist/internal/Migrations.d.ts.map +1 -0
  769. package/dist/internal/Migrations.js +82 -0
  770. package/dist/internal/Migrations.js.map +1 -0
  771. package/dist/internal/Owner.d.ts +230 -0
  772. package/dist/internal/Owner.d.ts.map +1 -0
  773. package/dist/internal/Owner.js +101 -0
  774. package/dist/internal/Owner.js.map +1 -0
  775. package/dist/internal/Passkey.d.ts +901 -0
  776. package/dist/internal/Passkey.d.ts.map +1 -0
  777. package/dist/internal/Passkey.js +1185 -0
  778. package/dist/internal/Passkey.js.map +1 -0
  779. package/dist/internal/PendingKey.d.ts +49 -0
  780. package/dist/internal/PendingKey.d.ts.map +1 -0
  781. package/dist/internal/PendingKey.js +58 -0
  782. package/dist/internal/PendingKey.js.map +1 -0
  783. package/dist/internal/Privy.d.ts +138 -0
  784. package/dist/internal/Privy.d.ts.map +1 -0
  785. package/dist/internal/Privy.js +285 -0
  786. package/dist/internal/Privy.js.map +1 -0
  787. package/dist/internal/RateLimit.d.ts +218 -0
  788. package/dist/internal/RateLimit.d.ts.map +1 -0
  789. package/dist/internal/RateLimit.js +209 -0
  790. package/dist/internal/RateLimit.js.map +1 -0
  791. package/dist/internal/Realm.d.ts +290 -0
  792. package/dist/internal/Realm.d.ts.map +1 -0
  793. package/dist/internal/Realm.js +502 -0
  794. package/dist/internal/Realm.js.map +1 -0
  795. package/dist/internal/RequestId.d.ts +16 -0
  796. package/dist/internal/RequestId.d.ts.map +1 -0
  797. package/dist/internal/RequestId.js +78 -0
  798. package/dist/internal/RequestId.js.map +1 -0
  799. package/dist/internal/SigningKey.d.ts +126 -0
  800. package/dist/internal/SigningKey.d.ts.map +1 -0
  801. package/dist/internal/SigningKey.js +221 -0
  802. package/dist/internal/SigningKey.js.map +1 -0
  803. package/dist/internal/TempoAccount.d.ts +181 -0
  804. package/dist/internal/TempoAccount.d.ts.map +1 -0
  805. package/dist/internal/TempoAccount.js +369 -0
  806. package/dist/internal/TempoAccount.js.map +1 -0
  807. package/dist/internal/TestInbox.d.ts +42 -0
  808. package/dist/internal/TestInbox.d.ts.map +1 -0
  809. package/dist/internal/TestInbox.js +20 -0
  810. package/dist/internal/TestInbox.js.map +1 -0
  811. package/dist/internal/Timing.d.ts +52 -0
  812. package/dist/internal/Timing.d.ts.map +1 -0
  813. package/dist/internal/Timing.js +116 -0
  814. package/dist/internal/Timing.js.map +1 -0
  815. package/dist/internal/Validation.d.ts +52 -0
  816. package/dist/internal/Validation.d.ts.map +1 -0
  817. package/dist/internal/Validation.js +22 -0
  818. package/dist/internal/Validation.js.map +1 -0
  819. package/dist/internal/Verification.d.ts +24 -0
  820. package/dist/internal/Verification.d.ts.map +1 -0
  821. package/dist/internal/Verification.js +37 -0
  822. package/dist/internal/Verification.js.map +1 -0
  823. package/dist/internal/Wallet.d.ts +66 -0
  824. package/dist/internal/Wallet.d.ts.map +1 -0
  825. package/dist/internal/Wallet.js +59 -0
  826. package/dist/internal/Wallet.js.map +1 -0
  827. package/dist/internal/owners/Passkey.d.ts +9 -0
  828. package/dist/internal/owners/Passkey.d.ts.map +1 -0
  829. package/dist/internal/owners/Passkey.js +58 -0
  830. package/dist/internal/owners/Passkey.js.map +1 -0
  831. package/dist/internal/owners/Privy.d.ts +13 -0
  832. package/dist/internal/owners/Privy.d.ts.map +1 -0
  833. package/dist/internal/owners/Privy.js +59 -0
  834. package/dist/internal/owners/Privy.js.map +1 -0
  835. package/dist/internal/owners/Secp256k1.d.ts +12 -0
  836. package/dist/internal/owners/Secp256k1.d.ts.map +1 -0
  837. package/dist/internal/owners/Secp256k1.js +99 -0
  838. package/dist/internal/owners/Secp256k1.js.map +1 -0
  839. package/dist/worker.d.ts +18 -0
  840. package/dist/worker.d.ts.map +1 -0
  841. package/dist/worker.js +18 -0
  842. package/dist/worker.js.map +1 -0
  843. package/package.json +83 -3
  844. package/src/Api.ts +157 -0
  845. package/src/App.ts +316 -0
  846. package/src/api/account.ts +2266 -0
  847. package/src/api/authenticate.ts +1662 -0
  848. package/src/api/authorize.ts +1086 -0
  849. package/src/api/device.ts +516 -0
  850. package/src/api/health.ts +72 -0
  851. package/src/api/lib/AccountStep.ts +485 -0
  852. package/src/api/lib/Auth.ts +164 -0
  853. package/src/api/lib/Configure.ts +921 -0
  854. package/src/api/lib/Consent.ts +388 -0
  855. package/src/api/lib/Cors.ts +160 -0
  856. package/src/api/lib/Database.ts +10 -0
  857. package/src/api/lib/DeviceRequest.ts +244 -0
  858. package/src/api/lib/FirstAccount.ts +136 -0
  859. package/src/api/lib/Headless.ts +616 -0
  860. package/src/api/lib/IsolateCache.ts +28 -0
  861. package/src/api/lib/KeySigner.ts +690 -0
  862. package/src/api/lib/PasskeyLink.ts +162 -0
  863. package/src/api/lib/Session.ts +64 -0
  864. package/src/api/lib/SignInConsent.ts +393 -0
  865. package/src/api/oauth.ts +1796 -0
  866. package/src/app/components/CodeInput.tsx +153 -0
  867. package/src/app/components/DevTools.tsx +1071 -0
  868. package/src/app/components/Grant.tsx +476 -0
  869. package/src/app/components/icons/BRLA.png +0 -0
  870. package/src/app/components/icons/BRZ.svg +1 -0
  871. package/src/app/components/icons/CHFAU.png +0 -0
  872. package/src/app/components/icons/DLUSD.png +0 -0
  873. package/src/app/components/icons/EURAU.svg +1 -0
  874. package/src/app/components/icons/EURC.e.svg +1 -0
  875. package/src/app/components/icons/GBPA.svg +4 -0
  876. package/src/app/components/icons/GUSD.svg +1 -0
  877. package/src/app/components/icons/MACH.svg +4 -0
  878. package/src/app/components/icons/OUSD.svg +5 -0
  879. package/src/app/components/icons/PRIME.svg +14 -0
  880. package/src/app/components/icons/SBC.svg +1 -0
  881. package/src/app/components/icons/SEKAU.svg +5 -0
  882. package/src/app/components/icons/USD1.svg +30 -0
  883. package/src/app/components/icons/USDB.svg +11 -0
  884. package/src/app/components/icons/USDC.e.svg +1 -0
  885. package/src/app/components/icons/USDT0.svg +1 -0
  886. package/src/app/components/icons/USDY.svg +16 -0
  887. package/src/app/components/icons/USDe.svg +1 -0
  888. package/src/app/components/icons/YLDS.svg +3 -0
  889. package/src/app/components/icons/alphaUSD.svg +1 -0
  890. package/src/app/components/icons/betaUSD.svg +1 -0
  891. package/src/app/components/icons/cUSD.svg +1 -0
  892. package/src/app/components/icons/cbBTC.svg +1 -0
  893. package/src/app/components/icons/frxUSD.svg +1 -0
  894. package/src/app/components/icons/goUSD.svg +5 -0
  895. package/src/app/components/icons/iUSD.svg +1 -0
  896. package/src/app/components/icons/pathUSD.svg +25 -0
  897. package/src/app/components/icons/rUSD.svg +1 -0
  898. package/src/app/components/icons/reUSD.svg +1 -0
  899. package/src/app/components/icons/sUSDe.svg +1 -0
  900. package/src/app/components/icons/siUSD.svg +1 -0
  901. package/src/app/components/icons/stcUSD.svg +1 -0
  902. package/src/app/components/icons/syrupUSDC.svg +5 -0
  903. package/src/app/components/icons/thetaUSD.svg +1 -0
  904. package/src/app/components/icons/wYLDS.svg +10 -0
  905. package/src/app/components/icons/wsrUSD.svg +1 -0
  906. package/src/app/components/logos/OUSD.dark.svg +17 -0
  907. package/src/app/components/logos/OUSD.light.svg +17 -0
  908. package/src/app/coverage.server.ts +73 -0
  909. package/src/app/coverage.ts +69 -0
  910. package/src/app/crons/cleanup.ts +104 -0
  911. package/src/app/db/auth.ts +440 -0
  912. package/src/app/db/migrations/0000_better_auth.sql +53 -0
  913. package/src/app/db/migrations/0001_oauth_provider.sql +162 -0
  914. package/src/app/db/migrations/0002_device_code.sql +17 -0
  915. package/src/app/db/migrations/0003_realms.sql +27 -0
  916. package/src/app/db/migrations/0004_default_realm.sql +2 -0
  917. package/src/app/db/migrations/0005_passkeys.sql +30 -0
  918. package/src/app/db/migrations/0006_first_accounts.sql +9 -0
  919. package/src/app/db/migrations/0007_pending_keys.sql +13 -0
  920. package/src/app/db/migrations/0008_secp256k1_owners.sql +18 -0
  921. package/src/app/db/migrations/0009_device_requests.sql +8 -0
  922. package/src/app/db/migrations/0010_device_keys.sql +4 -0
  923. package/src/app/db/migrations/0011_registered_passkeys.sql +2 -0
  924. package/src/app/db/migrations/0012_passkey_accounts.sql +7 -0
  925. package/src/app/db/migrations/0013_first_party_apps.sql +4 -0
  926. package/src/app/db/migrations/0014_logout_revokes_tokens.sql +17 -0
  927. package/src/app/db/migrations/0015_expiry_indexes.sql +9 -0
  928. package/src/app/db/migrations/0016_configurable_accounts.sql +15 -0
  929. package/src/app/db/migrations/0017_account_config_keys.sql +3 -0
  930. package/src/app/db/migrations/0018_better_auth_1_8.sql +9 -0
  931. package/src/app/db/migrations/0019_drop_provider_account_index.sql +1 -0
  932. package/src/app/db/migrations/meta/0000_snapshot.json +362 -0
  933. package/src/app/db/migrations/meta/0001_snapshot.json +1487 -0
  934. package/src/app/db/migrations/meta/0002_snapshot.json +1603 -0
  935. package/src/app/db/migrations/meta/0003_snapshot.json +1760 -0
  936. package/src/app/db/migrations/meta/0004_snapshot.json +1760 -0
  937. package/src/app/db/migrations/meta/0005_snapshot.json +1911 -0
  938. package/src/app/db/migrations/meta/0006_snapshot.json +1967 -0
  939. package/src/app/db/migrations/meta/0007_snapshot.json +2047 -0
  940. package/src/app/db/migrations/meta/0008_snapshot.json +2157 -0
  941. package/src/app/db/migrations/meta/0009_snapshot.json +2207 -0
  942. package/src/app/db/migrations/meta/0010_snapshot.json +2231 -0
  943. package/src/app/db/migrations/meta/0011_snapshot.json +2231 -0
  944. package/src/app/db/migrations/meta/0012_snapshot.json +2231 -0
  945. package/src/app/db/migrations/meta/0013_snapshot.json +2231 -0
  946. package/src/app/db/migrations/meta/0014_snapshot.json +2231 -0
  947. package/src/app/db/migrations/meta/0015_snapshot.json +2375 -0
  948. package/src/app/db/migrations/meta/0016_snapshot.json +2475 -0
  949. package/src/app/db/migrations/meta/0017_snapshot.json +2481 -0
  950. package/src/app/db/migrations/meta/0018_snapshot.json +2535 -0
  951. package/src/app/db/migrations/meta/0019_snapshot.json +2514 -0
  952. package/src/app/db/migrations/meta/_journal.json +146 -0
  953. package/src/app/db/schema.ts +241 -0
  954. package/src/app/db/table.ts +31 -0
  955. package/src/app/env.ts +57 -0
  956. package/src/app/inbox.ts +190 -0
  957. package/src/app/lib/Client.ts +82 -0
  958. package/src/app/lib/Inbox.ts +11 -0
  959. package/src/app/lib/Loader.ts +21 -0
  960. package/src/app/lib/Upgrade.ts +221 -0
  961. package/src/app/package.json +8 -0
  962. package/src/app/public/_headers +4 -0
  963. package/src/app/routeTree.gen.ts +219 -0
  964. package/src/app/router.tsx +47 -0
  965. package/src/app/routes/[_].flows.tsx +4254 -0
  966. package/src/app/routes/__root.tsx +172 -0
  967. package/src/app/routes/authorize.tsx +379 -0
  968. package/src/app/routes/choose-account.tsx +144 -0
  969. package/src/app/routes/deposit.tsx +107 -0
  970. package/src/app/routes/device.tsx +273 -0
  971. package/src/app/routes/error.tsx +62 -0
  972. package/src/app/routes/index.tsx +511 -0
  973. package/src/app/routes/login.tsx +577 -0
  974. package/src/app/screens/Account.tsx +559 -0
  975. package/src/app/screens/Approval.tsx +444 -0
  976. package/src/app/screens/ChooseAccount.tsx +206 -0
  977. package/src/app/screens/Deposit.tsx +523 -0
  978. package/src/app/screens/DeviceApproval.tsx +500 -0
  979. package/src/app/screens/NotFound.tsx +62 -0
  980. package/src/app/screens/SignIn.tsx +372 -0
  981. package/src/app/screens/WalletUpgrade.tsx +121 -0
  982. package/src/app/screens/chains/base.svg +3 -0
  983. package/src/app/screens/chains/ethereum.svg +11 -0
  984. package/src/app/screens/chains/solana.svg +4 -0
  985. package/src/app/screens/chains/tempo.svg +4 -0
  986. package/src/app/server.ts +342 -0
  987. package/src/app/vite.config.ts +128 -0
  988. package/src/app/void.config.ts +36 -0
  989. package/src/app/wallet.ts +69 -0
  990. package/src/app/zyzz.config.ts +52 -0
  991. package/src/cli/Admin.ts +74 -0
  992. package/src/cli/Apps.ts +27 -0
  993. package/src/cli/Cli.ts +41 -0
  994. package/src/cli/Project.ts +119 -0
  995. package/src/cli/Realms.ts +49 -0
  996. package/src/cli/Session.ts +290 -0
  997. package/src/cli/User.ts +40 -0
  998. package/src/cli/V1.ts +54 -0
  999. package/src/cli/bin.ts +44 -0
  1000. package/src/cli/commands/admin/apps/create.ts +96 -0
  1001. package/src/cli/commands/admin/apps/delete.ts +38 -0
  1002. package/src/cli/commands/admin/apps/index.ts +15 -0
  1003. package/src/cli/commands/admin/apps/list.ts +25 -0
  1004. package/src/cli/commands/admin/apps/rotate-secret.ts +47 -0
  1005. package/src/cli/commands/admin/apps/update.ts +79 -0
  1006. package/src/cli/commands/admin/index.ts +14 -0
  1007. package/src/cli/commands/admin/migrate.ts +19 -0
  1008. package/src/cli/commands/admin/realms/add.ts +40 -0
  1009. package/src/cli/commands/admin/realms/index.ts +14 -0
  1010. package/src/cli/commands/admin/realms/list.ts +38 -0
  1011. package/src/cli/commands/admin/realms/passkeys/index.ts +15 -0
  1012. package/src/cli/commands/admin/realms/passkeys/set.ts +44 -0
  1013. package/src/cli/commands/admin/realms/privy/index.ts +14 -0
  1014. package/src/cli/commands/admin/realms/privy/set.ts +69 -0
  1015. package/src/cli/commands/admin/realms/remove.ts +33 -0
  1016. package/src/cli/commands/admin/realms/secp256k1/disable.ts +40 -0
  1017. package/src/cli/commands/admin/realms/secp256k1/enable.ts +40 -0
  1018. package/src/cli/commands/admin/realms/secp256k1/index.ts +19 -0
  1019. package/src/cli/commands/admin/realms/set.ts +46 -0
  1020. package/src/cli/commands/admin/rotate-key.ts +47 -0
  1021. package/src/cli/commands/init.ts +42 -0
  1022. package/src/cli/commands/login.ts +32 -0
  1023. package/src/cli/commands/logout.ts +19 -0
  1024. package/src/cli/commands/whoami.ts +23 -0
  1025. package/src/client/Actions.ts +180 -0
  1026. package/src/client/Auth.ts +267 -0
  1027. package/src/client/Authorization.ts +34 -0
  1028. package/src/client/Decorator.ts +444 -0
  1029. package/src/client/Key.ts +137 -0
  1030. package/src/client/Pending.ts +45 -0
  1031. package/src/client/Permissions.ts +41 -0
  1032. package/src/client/Storage.ts +29 -0
  1033. package/src/client/TempoAccount.ts +55 -0
  1034. package/src/client/Tokens.ts +27 -0
  1035. package/src/client/User.ts +23 -0
  1036. package/src/client/actions/account.ts +171 -0
  1037. package/src/client/actions/device.ts +166 -0
  1038. package/src/client/actions/email.ts +164 -0
  1039. package/src/client/actions/oauth.ts +179 -0
  1040. package/src/client/actions/passkey.ts +333 -0
  1041. package/src/client/actions/realm.ts +37 -0
  1042. package/src/client/actions/redirect.ts +502 -0
  1043. package/src/client/internal/accessKey.ts +54 -0
  1044. package/src/client/internal/account.ts +18 -0
  1045. package/src/client/internal/api.ts +242 -0
  1046. package/src/client/internal/headless.ts +308 -0
  1047. package/src/client/internal/indexedDb.ts +44 -0
  1048. package/src/client/internal/request.ts +70 -0
  1049. package/src/client/internal/store.ts +20 -0
  1050. package/src/client/internal/verifier.ts +75 -0
  1051. package/src/client.ts +17 -0
  1052. package/src/index.ts +5 -0
  1053. package/src/internal/Apps.ts +1283 -0
  1054. package/src/internal/Auth.ts +273 -0
  1055. package/src/internal/Authorize.ts +433 -0
  1056. package/src/internal/Balance.ts +144 -0
  1057. package/src/internal/BodyLimit.ts +31 -0
  1058. package/src/internal/Cache.ts +119 -0
  1059. package/src/internal/Chain.ts +99 -0
  1060. package/src/internal/ChainList.ts +270 -0
  1061. package/src/internal/ChainName.ts +14 -0
  1062. package/src/internal/ChainStatus.ts +65 -0
  1063. package/src/internal/CodeEmail.ts +138 -0
  1064. package/src/internal/ConfigurableAccount.ts +1315 -0
  1065. package/src/internal/Device.ts +471 -0
  1066. package/src/internal/Env.ts +92 -0
  1067. package/src/internal/ErrorResponse.ts +896 -0
  1068. package/src/internal/Faucet.ts +43 -0
  1069. package/src/internal/Id.ts +41 -0
  1070. package/src/internal/KeyAuthorization.ts +1536 -0
  1071. package/src/internal/Limits.ts +40 -0
  1072. package/src/internal/Log.ts +166 -0
  1073. package/src/internal/LogLine.ts +81 -0
  1074. package/src/internal/Logout.ts +356 -0
  1075. package/src/internal/Migrations.ts +120 -0
  1076. package/src/internal/OpenApi.ts +300 -0
  1077. package/src/internal/Owner.ts +310 -0
  1078. package/src/internal/Passkey.ts +1904 -0
  1079. package/src/internal/PendingKey.ts +104 -0
  1080. package/src/internal/Privy.ts +536 -0
  1081. package/src/internal/RateLimit.ts +346 -0
  1082. package/src/internal/Realm.ts +814 -0
  1083. package/src/internal/RequestId.ts +118 -0
  1084. package/src/internal/SignInGrant.ts +175 -0
  1085. package/src/internal/SigningKey.ts +319 -0
  1086. package/src/internal/TempoAccount.ts +545 -0
  1087. package/src/internal/TestInbox.ts +51 -0
  1088. package/src/internal/Timing.ts +172 -0
  1089. package/src/internal/Validation.ts +52 -0
  1090. package/src/internal/Verification.ts +58 -0
  1091. package/src/internal/Wallet.ts +101 -0
  1092. package/src/internal/owners/Passkey.ts +76 -0
  1093. package/src/internal/owners/Privy.ts +82 -0
  1094. package/src/internal/owners/Secp256k1.ts +139 -0
  1095. package/src/types/app.d.ts +39 -0
  1096. package/src/worker.ts +17 -0
@@ -0,0 +1,1283 @@
1
+ /**
2
+ * OAuth apps: the Better Auth plugins that serve them, and the `tempo-id admin apps` operations on
3
+ * `oauth_client`. Every registered app is first-party. A third-party app's client ID is its
4
+ * metadata document's URL or its origin.
5
+ * @module
6
+ */
7
+ import {
8
+ createCimdClientDiscovery,
9
+ isCimdClientIdUrlCandidate,
10
+ } from '@better-auth/cimd'
11
+ import {
12
+ isLoopbackHost,
13
+ isPublicRoutableHost,
14
+ } from '@better-auth/core/utils/host'
15
+ import { isNativePrivateUseRedirectUri } from '@better-auth/core/utils/redirect-uri'
16
+ import type {
17
+ ClientDiscovery,
18
+ ClientMetadataResourceFetch,
19
+ } from '@better-auth/oauth-provider'
20
+ import {
21
+ getOAuthProviderApi,
22
+ getOAuthProviderState,
23
+ oauthProvider,
24
+ } from '@better-auth/oauth-provider'
25
+ import { registerClientMetadataDocument } from '@better-auth/oauth-provider/internal'
26
+ import type { BetterAuthPlugin } from 'better-auth'
27
+ import {
28
+ APIError,
29
+ createAuthEndpoint,
30
+ createAuthMiddleware,
31
+ getSessionFromCtx,
32
+ setShouldSkipSessionRefresh,
33
+ } from 'better-auth/api'
34
+ import { generateRandomString } from 'better-auth/crypto'
35
+ import { jwt } from 'better-auth/plugins/jwt'
36
+ import { and, asc, eq, inArray, isNull, or } from 'drizzle-orm'
37
+ import { Base64, Bytes } from 'ox'
38
+ import { z } from 'zod'
39
+ import * as Schema from '../app/db/schema.js'
40
+ import type * as Cache from './Cache.js'
41
+ import type * as PendingKey from './PendingKey.js'
42
+ import type * as Realm from './Realm.js'
43
+ import * as SigningKey from './SigningKey.js'
44
+
45
+ /** Another app already has the client ID. */
46
+ export class ExistsError extends Error {
47
+ override readonly name = 'Apps.ExistsError'
48
+
49
+ constructor(options: { clientId: string }) {
50
+ super(
51
+ `App ${options.clientId} already exists. Update it, or choose another client ID.`,
52
+ )
53
+ }
54
+ }
55
+
56
+ /** A name, a redirect URI, or another value of an app is not valid. */
57
+ export class InvalidError extends Error {
58
+ override readonly name = 'Apps.InvalidError'
59
+ }
60
+
61
+ /** No OAuth app has the client ID. */
62
+ export class NotFoundError extends Error {
63
+ override readonly name = 'Apps.NotFoundError'
64
+
65
+ constructor(options: { clientId: string }) {
66
+ super(`Unknown app ${options.clientId}. Name a registered OAuth app.`)
67
+ }
68
+ }
69
+
70
+ /** The app redeems codes with PKCE alone, so it has no client secret to rotate. */
71
+ export class PublicError extends Error {
72
+ override readonly name = 'Apps.PublicError'
73
+
74
+ constructor(options: { clientId: string }) {
75
+ super(
76
+ `App ${options.clientId} has no client secret. Rotate the secret of an app with a backend.`,
77
+ )
78
+ }
79
+ }
80
+
81
+ /** An OAuth app, as `tempo-id admin apps` returns it. */
82
+ export type App = {
83
+ /** Sent as `client_id`. */
84
+ clientId: string
85
+ /** When the app was created. */
86
+ createdAt: Date | null
87
+ /** Whether the app signs in through the device grant, as a CLI does. */
88
+ device: boolean
89
+ /** Whether `tempo-id admin apps` registered the app, which then skips consent for keyless requests. */
90
+ firstParty: boolean
91
+ /** The logo as a `data:` URL. Only an app with an origin client ID has one. */
92
+ logo: string | null
93
+ /** The display name on the approval page. */
94
+ name: string | null
95
+ /** The URIs that `GET /oauth2/end-session` may return to. */
96
+ postLogoutRedirectUris: readonly string[]
97
+ /** The URIs that the app returns to. */
98
+ redirectUris: readonly string[]
99
+ /** Whether the app holds a client secret for its backend. */
100
+ secret: boolean
101
+ /** Whether the app holds the `tempo-id:sign` scope. */
102
+ sign: boolean
103
+ /** `web` for a browser app or a backend, and `native` for a mobile app. */
104
+ type: 'native' | 'web'
105
+ }
106
+
107
+ /** The grant type of the device grant (RFC 8628 §3.4). */
108
+ export const deviceGrant = 'urn:ietf:params:oauth:grant-type:device_code'
109
+
110
+ /** Lets an app bind its own challenge, and request unknown key calls headlessly. */
111
+ export const signScope = 'tempo-id:sign'
112
+
113
+ /** The scopes that every app may request. */
114
+ const scopes = ['openid', 'profile', 'email', 'offline_access'] as const
115
+
116
+ /** Returns whether `clientSecret` matches the enabled app, which selects a rate limit's app. */
117
+ export async function authenticate(
118
+ db: Realm.Database,
119
+ options: authenticate.Options,
120
+ ) {
121
+ const [row] = await db
122
+ .select({
123
+ clientSecret: Schema.oauthClient.clientSecret,
124
+ disabled: Schema.oauthClient.disabled,
125
+ })
126
+ .from(Schema.oauthClient)
127
+ .where(eq(Schema.oauthClient.clientId, options.clientId))
128
+ .limit(1)
129
+ if (!row?.clientSecret || row.disabled) return false
130
+ return equal(await hashSecret(options.clientSecret), row.clientSecret)
131
+ }
132
+
133
+ export declare namespace authenticate {
134
+ type Options = {
135
+ /** The client ID that the request names. */
136
+ clientId: string
137
+ /** The client secret that the request sends. */
138
+ clientSecret: string
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Registers an app, and returns it with its client secret, which appears only here. Throws
144
+ * `InvalidError` for an invalid value, and `ExistsError` for a client ID in use.
145
+ */
146
+ export async function create(db: Realm.Database, options: create.Options) {
147
+ const type = options.type ?? 'web'
148
+ const name = parseName(options.name)
149
+ const postLogoutRedirectUris = parsePostLogoutRedirectUris(
150
+ options.postLogoutRedirectUris ?? [],
151
+ { type },
152
+ )
153
+ const device = options.device ?? false
154
+ // A CLI cannot keep a secret, and the device grant's poll sends none, so a device app is public.
155
+ if (device && (options.secret || options.clientSecret !== undefined))
156
+ throw new InvalidError(
157
+ 'Invalid app: a device app has no client secret, since a CLI cannot keep one. Leave out the secret.',
158
+ )
159
+ // A device app redirects nowhere, so it needs no redirect URI.
160
+ const redirectUris =
161
+ device && (options.redirectUris ?? []).length === 0
162
+ ? []
163
+ : parseRedirectUris(options.redirectUris ?? [], { type })
164
+ const clientId =
165
+ options.clientId === undefined
166
+ ? // Better Auth's format: 32 random letters.
167
+ generateRandomString(32, 'a-z', 'A-Z')
168
+ : parseClientId(options.clientId)
169
+ const clientSecret = (() => {
170
+ if (options.clientSecret !== undefined)
171
+ return parseClientSecret(options.clientSecret)
172
+ return options.secret ? secret() : undefined
173
+ })()
174
+
175
+ const now = new Date()
176
+ const [row] = await db
177
+ .insert(Schema.oauthClient)
178
+ .values({
179
+ applicationType: type,
180
+ clientId,
181
+ clientSecret: clientSecret ? await hashSecret(clientSecret) : null,
182
+ createdAt: now,
183
+ // Lets the app end the session at `GET /oauth2/end-session`, and puts `sid` in its ID tokens.
184
+ enableEndSession: true,
185
+ // A device app has no authorization code grant, so `/oauth2/authorize` refuses it.
186
+ grantTypes: device
187
+ ? [deviceGrant, 'refresh_token']
188
+ : ['authorization_code', 'refresh_token'],
189
+ id: crypto.randomUUID(),
190
+ name,
191
+ postLogoutRedirectUris: [...postLogoutRedirectUris],
192
+ redirectUris: [...redirectUris],
193
+ responseTypes: ['code'],
194
+ scopes: scopesOf({ sign: options.sign ?? false }),
195
+ // Every registered app is first-party.
196
+ skipConsent: true,
197
+ // The client package sends the secret in the form body.
198
+ tokenEndpointAuthMethod: clientSecret ? 'client_secret_post' : 'none',
199
+ updatedAt: now,
200
+ })
201
+ .onConflictDoNothing({ target: Schema.oauthClient.clientId })
202
+ .returning()
203
+ if (!row) throw new ExistsError({ clientId })
204
+
205
+ return { app: toApp(row), ...(clientSecret ? { clientSecret } : {}) }
206
+ }
207
+
208
+ export declare namespace create {
209
+ type Options = {
210
+ /** Another deployment's client ID to keep. Defaults to 32 random letters. */
211
+ clientId?: string | undefined
212
+ /** Another deployment's client secret to keep. Implies `secret`. */
213
+ clientSecret?: string | undefined
214
+ /** Whether the app signs in through the device grant. Defaults to `false`. */
215
+ device?: boolean | undefined
216
+ /** The display name on the approval page. */
217
+ name: string
218
+ /** The URIs that `GET /oauth2/end-session` may return to. Defaults to none. */
219
+ postLogoutRedirectUris?: readonly string[] | undefined
220
+ /** The URIs that the app returns to, in every environment. A device app may have none. */
221
+ redirectUris?: readonly string[] | undefined
222
+ /** Whether the app receives a new client secret. Defaults to `false`. */
223
+ secret?: boolean | undefined
224
+ /** Whether the app holds the `tempo-id:sign` scope. Defaults to `false`. */
225
+ sign?: boolean | undefined
226
+ /** The application type. Defaults to `web`. */
227
+ type?: App['type'] | undefined
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Returns the fetch of third-party apps' metadata documents, through `fetcher`. It refuses
233
+ * redirects, since a document must sit at its client ID's URL.
234
+ */
235
+ export function fetchMetadata(
236
+ fetcher: fetchMetadata.Fetcher = globalThis,
237
+ ): ClientMetadataResourceFetch {
238
+ return async (input, init) => {
239
+ // Workers support only `follow` and `manual`, so a redirect returns, and the transport refuses it.
240
+ const response = await fetcher.fetch(
241
+ new Request(input, { ...init, redirect: 'manual' }),
242
+ )
243
+ // A 304 answers the discovery's own conditional request, and moves nothing.
244
+ if (
245
+ response.status < 300 ||
246
+ response.status >= 400 ||
247
+ response.status === 304
248
+ )
249
+ return response
250
+ await response.body?.cancel()
251
+ throw new TypeError('The metadata document redirects.')
252
+ }
253
+ }
254
+
255
+ export declare namespace fetchMetadata {
256
+ /** The global scope or a service binding. */
257
+ type Fetcher = {
258
+ /** Fetches the request. */
259
+ fetch: (request: Request) => Promise<Response>
260
+ }
261
+ }
262
+
263
+ /** Returns the enabled first-party apps with a redirect URI at `origin`. */
264
+ export async function firstPartyOrigin(
265
+ db: Realm.Database,
266
+ options: firstPartyOrigin.Options,
267
+ ): Promise<readonly App[]> {
268
+ const rows = await db
269
+ .select()
270
+ .from(Schema.oauthClient)
271
+ .where(
272
+ and(
273
+ isNull(Schema.oauthClient.clientDiscoveryId),
274
+ eq(Schema.oauthClient.skipConsent, true),
275
+ or(
276
+ isNull(Schema.oauthClient.disabled),
277
+ eq(Schema.oauthClient.disabled, false),
278
+ ),
279
+ ),
280
+ )
281
+ return rows
282
+ .filter((row) =>
283
+ row.redirectUris.some((uri) => {
284
+ const url = URL.parse(uri)
285
+ return (
286
+ (url?.protocol === 'https:' || url?.protocol === 'http:') &&
287
+ url.origin === options.origin
288
+ )
289
+ }),
290
+ )
291
+ .map(toApp)
292
+ }
293
+
294
+ export declare namespace firstPartyOrigin {
295
+ type Options = {
296
+ /** The request's `Origin`. */
297
+ origin: string
298
+ }
299
+ }
300
+
301
+ /**
302
+ * Returns the app with `clientId`. Throws `NotFoundError` if it is unknown, or disabled with
303
+ * `enabled`.
304
+ */
305
+ export async function get(db: Realm.Database, options: get.Options) {
306
+ const row = await find(db, options)
307
+ if (options.enabled && row.disabled)
308
+ throw new NotFoundError({ clientId: options.clientId })
309
+ return toApp(row)
310
+ }
311
+
312
+ export declare namespace get {
313
+ type Options = {
314
+ /** The app's client ID. */
315
+ clientId: string
316
+ /** Whether a disabled app counts as no app. Defaults to `false`. */
317
+ enabled?: boolean | undefined
318
+ }
319
+ }
320
+
321
+ /** Returns the SHA-256 hash of a client secret as unpadded base64url, as the row holds it. */
322
+ export async function hashSecret(secret: string) {
323
+ const digest = await crypto.subtle.digest(
324
+ 'SHA-256',
325
+ new TextEncoder().encode(secret),
326
+ )
327
+ return Base64.fromBytes(new Uint8Array(digest), { pad: false, url: true })
328
+ }
329
+
330
+ /**
331
+ * Compares two `hashSecret` hashes in constant time. The CLI runs this module in Node, whose
332
+ * `crypto.subtle` has no `timingSafeEqual`.
333
+ */
334
+ function equal(a: string, b: string) {
335
+ const left = Base64.toBytes(a)
336
+ const right = Base64.toBytes(b)
337
+ if (left.length !== right.length) return false
338
+ let difference = 0
339
+ for (let index = 0; index < left.length; index++)
340
+ difference |= left[index]! ^ right[index]!
341
+ return difference === 0
342
+ }
343
+
344
+ /** Returns every registered app, oldest first, without third-party apps. */
345
+ export async function list(db: Realm.Database): Promise<readonly App[]> {
346
+ const rows = await db
347
+ .select()
348
+ .from(Schema.oauthClient)
349
+ .where(isNull(Schema.oauthClient.clientDiscoveryId))
350
+ .orderBy(
351
+ asc(Schema.oauthClient.createdAt),
352
+ asc(Schema.oauthClient.clientId),
353
+ )
354
+ return rows.map(toApp)
355
+ }
356
+
357
+ /** The origins whose resource row this isolate read, so later instances skip the seed's read. */
358
+ const seeded = new Set<string>()
359
+
360
+ /** Returns the Better Auth plugins that serve OAuth apps: the JWT plugin and the OAuth provider. */
361
+ export function plugins(options: plugins.Options) {
362
+ const { accountStep, baseURL, cache, pendingKey } = options
363
+ const fetch = options.metadataFetch ?? fetchMetadata()
364
+ return [
365
+ // `iss` is the configured origin, never the request's host. No client reads the session's JWT
366
+ // header, and each session read would otherwise read the signing keys and sign one.
367
+ jwt({
368
+ adapter: SigningKey.adapter({ cache }),
369
+ disableSettingJwtHeader: true,
370
+ jwks: SigningKey.jwks,
371
+ jwt: { issuer: baseURL },
372
+ }),
373
+ oauthProvider({
374
+ allowDynamicClientRegistration: false,
375
+ // The resource's row holds only the values below, so the isolate reads it once.
376
+ cachedResources: new Set([baseURL]),
377
+ // The provider keeps each client row that it reads for the life of its options, which each
378
+ // request creates again, so a request reads each app once, and the next one reads it again.
379
+ // A cached client cannot change through the provider's client endpoints, which no route serves.
380
+ cachedTrustedClients: Object.assign(new Set<string>(), {
381
+ has: () => true,
382
+ }),
383
+ // A third-party app holds only the scopes that every app may request, never `tempo-id:sign`.
384
+ clientRegistrationDefaultScopes: [...scopes],
385
+ consentPage: '/authorize',
386
+ // Apps read the user's address from the ID token, so a grant of `email` puts it there as well
387
+ // as in userinfo, as OIDC Core §5.4 allows.
388
+ customIdTokenClaims: (info) =>
389
+ info.scopes.includes('email')
390
+ ? {
391
+ email: info.user.email,
392
+ email_verified: info.user.emailVerified,
393
+ }
394
+ : {},
395
+ // Every app may request the one resource.
396
+ enforcePerClientResources: false,
397
+ // A third-party app names its metadata document's URL or its origin as its client ID, and
398
+ // registers no row.
399
+ extensions: [
400
+ {
401
+ clientDiscovery: [discovery({ fetch }), originDiscovery({ fetch })],
402
+ },
403
+ ],
404
+ loginPage: '/login',
405
+ // The account step runs after sign-in and before consent, and `oauth2Continue` resumes the
406
+ // authorization with `postLogin`, which checks again.
407
+ ...(accountStep
408
+ ? {
409
+ postLogin: {
410
+ consentReferenceId: () => undefined,
411
+ page: '/choose-account',
412
+ shouldRedirect: async (context: {
413
+ headers: Headers
414
+ session: { id: string }
415
+ user: { id: string }
416
+ }) => {
417
+ // The authorization stores its query before it checks, so the hook reads the app.
418
+ const stored = (await getOAuthProviderState())?.query
419
+ const query = new URLSearchParams(stored ?? '')
420
+ const clientId = query.get('client_id')
421
+ if (!clientId) return false
422
+ return await accountStep({
423
+ clientId,
424
+ headers: context.headers,
425
+ query,
426
+ sessionId: context.session.id,
427
+ userId: context.user.id,
428
+ })
429
+ },
430
+ },
431
+ }
432
+ : {}),
433
+ // A code's redemption returns the key that its approval signed, once. Better Auth calls this
434
+ // after it checks the verifier against the code's challenge.
435
+ ...(pendingKey
436
+ ? {
437
+ customTokenResponseFields: async (info: {
438
+ grantType: string
439
+ user?: { id: string } | null | undefined
440
+ verificationValue?: {
441
+ query: {
442
+ client_id: string
443
+ code_challenge?: string | undefined
444
+ key_authorization?: unknown
445
+ }
446
+ }
447
+ }) => {
448
+ const query = info.verificationValue?.query
449
+ if (
450
+ info.grantType !== 'authorization_code' ||
451
+ !query?.code_challenge ||
452
+ // Only a code whose request carried the key takes it, so a keyless code for a reused
453
+ // challenge leaves it for the keyed one.
454
+ query.key_authorization === undefined ||
455
+ !info.user
456
+ )
457
+ return {}
458
+ const key = await pendingKey({
459
+ clientId: query.client_id,
460
+ codeChallenge: query.code_challenge,
461
+ userId: info.user.id,
462
+ })
463
+ if (!key) return {}
464
+ return {
465
+ account: key.account,
466
+ key_authorization: key.keyAuthorization,
467
+ }
468
+ },
469
+ }
470
+ : {}),
471
+ // Every access token names one audience, so each API verifies tokens for every app the same way.
472
+ resources: seeded.has(baseURL)
473
+ ? []
474
+ : [{ accessTokenTtl: 300, identifier: baseURL, name: 'Tempo ID' }],
475
+ // Better Auth checks a registered app's scopes against its own row, so `tempo-id:sign` stays out
476
+ // of this list. A row without scopes falls back to this list, and never receives the scope.
477
+ scopes: [...scopes],
478
+ // `create` and `rotateSecret` store each secret with the same hash.
479
+ storeClientSecret: { hash: hashSecret },
480
+ }),
481
+ // A session read inside the authorization extends no session, since the provider's after hook
482
+ // reads the session cookie of the extension as a sign-in, and authorizes again, with a second
483
+ // code. This hook runs after the provider's, so it extends a session that is due once the
484
+ // authorization returns. Better Auth's read extends it and sets the cookie.
485
+ {
486
+ hooks: {
487
+ after: [
488
+ {
489
+ handler: createAuthMiddleware(async (ctx) => {
490
+ await setShouldSkipSessionRefresh(false)
491
+ const session = ctx.context.session
492
+ if (!session) return
493
+ // Better Auth extends a session once `updateAge` of its lifetime passed.
494
+ const { expiresIn, updateAge } = ctx.context.sessionConfig
495
+ const due =
496
+ new Date(session.session.expiresAt).getTime() -
497
+ (expiresIn - updateAge) * 1000 <=
498
+ Date.now()
499
+ if (!due) return
500
+ ctx.context.session = null
501
+ await getSessionFromCtx(ctx)
502
+ }),
503
+ matcher: (ctx) => ctx.path === '/oauth2/authorize',
504
+ },
505
+ ],
506
+ before: [
507
+ {
508
+ handler: createAuthMiddleware(async () => {
509
+ await setShouldSkipSessionRefresh(true)
510
+ }),
511
+ matcher: (ctx) => ctx.path === '/oauth2/authorize',
512
+ },
513
+ ],
514
+ },
515
+ id: 'tempo-id-authorize-session',
516
+ } satisfies BetterAuthPlugin,
517
+ // Tempo ID's own checks read the `oauth_client` row, which only a resolution writes for a
518
+ // third-party app. Better Auth resolves a client only inside its endpoints, so a route resolves
519
+ // it here before the checks.
520
+ {
521
+ endpoints: {
522
+ resolveOAuthClient: createAuthEndpoint.serverOnly(
523
+ { body: z.object({ client_id: z.string() }), method: 'POST' },
524
+ async (ctx) => {
525
+ const plugin = ctx.context.getPlugin('oauth-provider')
526
+ if (!plugin)
527
+ throw new Error('The OAuth provider plugin is missing.')
528
+ const client = await getOAuthProviderApi(
529
+ ctx,
530
+ plugin.options,
531
+ ).getClient(ctx.body.client_id)
532
+ return ctx.json({ resolved: Boolean(client && !client.disabled) })
533
+ },
534
+ ),
535
+ },
536
+ id: 'tempo-id-client-discovery',
537
+ } satisfies BetterAuthPlugin,
538
+ // Plugins run `init` in order, so this one runs after the provider's seed. A seed that failed
539
+ // logs and leaves no row, so the next instance seeds again.
540
+ {
541
+ id: 'tempo-id-resource-seed',
542
+ init: async (ctx) => {
543
+ if (seeded.has(baseURL)) return
544
+ const row = await ctx.adapter.findOne({
545
+ model: 'oauthResource',
546
+ where: [{ field: 'identifier', value: baseURL }],
547
+ })
548
+ if (row) seeded.add(baseURL)
549
+ },
550
+ } satisfies BetterAuthPlugin,
551
+ ]
552
+ }
553
+
554
+ export declare namespace plugins {
555
+ type Options = {
556
+ /** Returns whether the app's authorization needs `/choose-account`. Absent, none does. */
557
+ accountStep?:
558
+ | ((options: {
559
+ clientId: string
560
+ headers: Headers
561
+ query: URLSearchParams
562
+ sessionId: string
563
+ userId: string
564
+ }) => Promise<boolean>)
565
+ | undefined
566
+ /** Tempo ID's origin, which is `iss` and the one resource. */
567
+ baseURL: string
568
+ /** The isolate's cache for the signing keys. Absent, nothing is cached. */
569
+ cache?: Cache.Cache | undefined
570
+ /** Fetches third-party apps' metadata documents. Defaults to `fetchMetadata()`. */
571
+ metadataFetch?: ClientMetadataResourceFetch | undefined
572
+ /** Takes a code's held key authorization, as `PendingKey.take` does. Absent, codes carry none. */
573
+ pendingKey?:
574
+ | ((options: {
575
+ clientId: string
576
+ codeChallenge: string
577
+ userId: string
578
+ }) => Promise<PendingKey.PendingKey | undefined>)
579
+ | undefined
580
+ }
581
+ }
582
+
583
+ /**
584
+ * Removes the registered app with `clientId`, with its consents, tokens, and realms. Throws
585
+ * `NotFoundError` when no registered app has it.
586
+ */
587
+ export async function remove(db: Realm.Database, options: remove.Options) {
588
+ const removed = await db
589
+ .delete(Schema.oauthClient)
590
+ .where(
591
+ and(
592
+ eq(Schema.oauthClient.clientId, options.clientId),
593
+ isNull(Schema.oauthClient.clientDiscoveryId),
594
+ ),
595
+ )
596
+ .returning()
597
+ const [row] = removed
598
+ if (!row) throw new NotFoundError({ clientId: options.clientId })
599
+ return toApp(row)
600
+ }
601
+
602
+ export declare namespace remove {
603
+ type Options = {
604
+ /** The app's client ID. */
605
+ clientId: string
606
+ }
607
+ }
608
+
609
+ /**
610
+ * Replaces the client secret of the app with `clientId`, and returns the app with the new secret.
611
+ * The earlier secret stops working at once. Throws `NotFoundError` for an unknown app,
612
+ * `PublicError` for an app without a secret, and `InvalidError` for an invalid or unchanged secret.
613
+ */
614
+ export async function rotateSecret(
615
+ db: Realm.Database,
616
+ options: rotateSecret.Options,
617
+ ) {
618
+ const clientSecret =
619
+ options.clientSecret === undefined
620
+ ? secret()
621
+ : parseClientSecret(options.clientSecret)
622
+ const current = await find(db, options)
623
+ if (!current.clientSecret) throw new PublicError(options)
624
+ // A rotation to the same secret would leave a leaked secret working while it reports success.
625
+ if (equal(current.clientSecret, await hashSecret(clientSecret)))
626
+ throw new InvalidError(
627
+ 'Invalid client secret: it matches the current secret. Use a new secret.',
628
+ )
629
+
630
+ const [row] = await db
631
+ .update(Schema.oauthClient)
632
+ .set({
633
+ clientSecret: await hashSecret(clientSecret),
634
+ updatedAt: new Date(),
635
+ })
636
+ .where(eq(Schema.oauthClient.clientId, options.clientId))
637
+ .returning()
638
+ // A concurrent `remove` deleted the app after the read.
639
+ if (!row) throw new NotFoundError(options)
640
+ // The row, not the earlier read, since a concurrent `update` can change the app between them.
641
+ return { app: toApp(row), clientSecret }
642
+ }
643
+
644
+ export declare namespace rotateSecret {
645
+ type Options = {
646
+ /** The app's client ID. */
647
+ clientId: string
648
+ /** Another deployment's client secret to keep. Defaults to a new secret. */
649
+ clientSecret?: string | undefined
650
+ }
651
+ }
652
+
653
+ /** Returns whether `clientId` is a canonical `https` origin, such as `https://app.example`. */
654
+ export function originId(clientId: string) {
655
+ const url = URL.parse(clientId)
656
+ return url?.protocol === 'https:' && url.origin === clientId
657
+ }
658
+
659
+ /** Returns whether `clientId` names a third-party app: an `https` URL or origin. */
660
+ export function thirdParty(clientId: string) {
661
+ return isCimdClientIdUrlCandidate(clientId)
662
+ }
663
+
664
+ /** Returns the third-party client IDs in `clientIds` without a row within `discoveryFreshness`. */
665
+ export async function stale(
666
+ db: Realm.Database,
667
+ options: stale.Options,
668
+ ): Promise<readonly string[]> {
669
+ const candidates = [...new Set(options.clientIds.filter(thirdParty))]
670
+ if (candidates.length === 0) return []
671
+ const rows = await db
672
+ .select({
673
+ clientDiscoveryId: Schema.oauthClient.clientDiscoveryId,
674
+ clientId: Schema.oauthClient.clientId,
675
+ updatedAt: Schema.oauthClient.updatedAt,
676
+ })
677
+ .from(Schema.oauthClient)
678
+ .where(inArray(Schema.oauthClient.clientId, candidates))
679
+ const current = new Set(
680
+ rows.filter((row) => fresh(row)).map((row) => row.clientId),
681
+ )
682
+ return candidates.filter((clientId) => !current.has(clientId))
683
+ }
684
+
685
+ export declare namespace stale {
686
+ type Options = {
687
+ /** The client IDs in the request's parameters or Basic credentials. */
688
+ clientIds: readonly string[]
689
+ }
690
+ }
691
+
692
+ /**
693
+ * Updates the registered app with `clientId`, and returns it. A value left out stays. Throws
694
+ * `NotFoundError` when no registered app has it, and `InvalidError` for an invalid value.
695
+ */
696
+ export async function update(db: Realm.Database, options: update.Options) {
697
+ const current = await find(db, options)
698
+ // The discovery rewrites a third-party app's row from its document, so no update would hold.
699
+ if (current.clientDiscoveryId)
700
+ throw new NotFoundError({ clientId: options.clientId })
701
+ const app = toApp(current)
702
+ const name = options.name === undefined ? undefined : parseName(options.name)
703
+ const postLogoutRedirectUris =
704
+ options.postLogoutRedirectUris === undefined
705
+ ? undefined
706
+ : parsePostLogoutRedirectUris(options.postLogoutRedirectUris, {
707
+ type: app.type,
708
+ })
709
+ const redirectUris =
710
+ options.redirectUris === undefined
711
+ ? undefined
712
+ : parseRedirectUris(options.redirectUris, { type: app.type })
713
+
714
+ const [row] = await db
715
+ .update(Schema.oauthClient)
716
+ .set({
717
+ ...(name === undefined ? {} : { name }),
718
+ ...(postLogoutRedirectUris === undefined
719
+ ? {}
720
+ : { postLogoutRedirectUris: [...postLogoutRedirectUris] }),
721
+ // An app registered before logout existed gains it with its post-logout redirect URIs.
722
+ ...(postLogoutRedirectUris?.length ? { enableEndSession: true } : {}),
723
+ ...(redirectUris === undefined
724
+ ? {}
725
+ : { redirectUris: [...redirectUris] }),
726
+ ...(options.sign === undefined
727
+ ? {}
728
+ : {
729
+ scopes: scopesOf({
730
+ scopes: current.scopes ?? undefined,
731
+ sign: options.sign,
732
+ }),
733
+ }),
734
+ updatedAt: new Date(),
735
+ })
736
+ .where(eq(Schema.oauthClient.clientId, options.clientId))
737
+ .returning()
738
+ // A concurrent `remove` deleted the app after the read.
739
+ if (!row) throw new NotFoundError(options)
740
+ return toApp(row)
741
+ }
742
+
743
+ export declare namespace update {
744
+ type Options = {
745
+ /** The app's client ID. */
746
+ clientId: string
747
+ /** The display name. */
748
+ name?: string | undefined
749
+ /** Replaces the URIs that `GET /oauth2/end-session` may return to. An empty list clears them. */
750
+ postLogoutRedirectUris?: readonly string[] | undefined
751
+ /** Replaces the URIs that the app returns to. */
752
+ redirectUris?: readonly string[] | undefined
753
+ /** Whether the app holds the `tempo-id:sign` scope. */
754
+ sign?: boolean | undefined
755
+ }
756
+ }
757
+
758
+ /** Milliseconds that a third-party app's row serves before the next fetch of its document. */
759
+ const discoveryFreshness = 5 * 60 * 1000
760
+
761
+ /** Returns whether `row` is a third-party app's row written within `discoveryFreshness`. */
762
+ function fresh(
763
+ row:
764
+ | { clientDiscoveryId?: string | null; updatedAt?: Date | null }
765
+ | null
766
+ | undefined,
767
+ ): row is { clientDiscoveryId: string; updatedAt: Date } {
768
+ if (!row?.clientDiscoveryId || !row.updatedAt) return false
769
+ return Date.now() - row.updatedAt.getTime() < discoveryFreshness
770
+ }
771
+
772
+ /**
773
+ * Returns the client discovery of apps whose client ID is a metadata document's URL. It binds every
774
+ * URL in the document to that origin. It refuses `http` or loopback URIs, grants other than
775
+ * `authorization_code` and `refresh_token`, and client authentication.
776
+ */
777
+ function discovery(options: { fetch: ClientMetadataResourceFetch }) {
778
+ const cimd = createCimdClientDiscovery({
779
+ fetchClientMetadataResource: options.fetch,
780
+ originBoundFields: [
781
+ 'client_uri',
782
+ 'logo_uri',
783
+ 'policy_uri',
784
+ 'post_logout_redirect_uris',
785
+ 'redirect_uris',
786
+ 'tos_uri',
787
+ ],
788
+ })
789
+ // An authorization with a key resolves the app before the issuer does. A failed fetch blocks the
790
+ // next fetch for the per-client interval, so the second resolve repeats the first one's result.
791
+ const resolutions = new Map<string, ReturnType<typeof cimd.resolve>>()
792
+ return {
793
+ ...cimd,
794
+ // An origin client ID has no metadata document, and `originDiscovery` resolves it.
795
+ matches: (clientId) => cimd.matches(clientId) && !originId(clientId),
796
+ resolve: async (ctx, clientId, existing) => {
797
+ // The discovery's own cache lives in one Better Auth instance, which serves one request, so a
798
+ // fresh row serves as the cache. A row that the checks below refused stays refused.
799
+ const client = await (() => {
800
+ if (fresh(existing)) return existing
801
+ const resolution =
802
+ resolutions.get(clientId) ?? cimd.resolve(ctx, clientId, existing)
803
+ resolutions.set(clientId, resolution)
804
+ return resolution
805
+ })()
806
+ if (!client) return client
807
+ // The discovery admits loopback redirects, such as `http://localhost` and `https://x.localhost`,
808
+ // outside the origin binding. Tempo ID bans them, as `create` does.
809
+ // A custom scheme is refused too: any app on the device can claim it, so the key would reach an
810
+ // app other than the host that the approval page names. A mobile app uses a claimed https link.
811
+ const refused = [
812
+ ...(client.redirectUris ?? []),
813
+ ...(client.postLogoutRedirectUris ?? []),
814
+ ].find((uri) => {
815
+ const url = URL.parse(uri)
816
+ if (!url || url.protocol !== 'https:') return true
817
+ return (
818
+ isLoopbackHost(url.hostname) || url.hostname.endsWith('.localhost')
819
+ )
820
+ })
821
+ if (refused)
822
+ throw new APIError('BAD_REQUEST', {
823
+ error: 'invalid_client',
824
+ error_description: `Invalid redirect URI in the metadata document: ${refused}. Use an https URI on the client ID's origin.`,
825
+ })
826
+ // A third-party app signs in through a redirect alone. The device grant would show its name on
827
+ // the device page, beside no host that proves it.
828
+ const grant = (client.grantTypes ?? []).find(
829
+ (type) => type !== 'authorization_code' && type !== 'refresh_token',
830
+ )
831
+ if (grant)
832
+ throw new APIError('BAD_REQUEST', {
833
+ error: 'invalid_client',
834
+ error_description: `Unsupported grant type in the metadata document: ${grant}. Use authorization_code and refresh_token.`,
835
+ })
836
+ // A third-party app is a public client that redeems codes with PKCE alone, so it holds no key
837
+ // that Tempo ID would fetch from a `jwks_uri`.
838
+ const method = client.tokenEndpointAuthMethod ?? 'none'
839
+ if (method !== 'none')
840
+ throw new APIError('BAD_REQUEST', {
841
+ error: 'invalid_client',
842
+ error_description: `Unsupported token_endpoint_auth_method in the metadata document: ${method}. Use none.`,
843
+ })
844
+ return client
845
+ },
846
+ } satisfies ClientDiscovery
847
+ }
848
+
849
+ /**
850
+ * Returns the client discovery of apps whose client ID is their `https` origin. A failed `describe`
851
+ * falls back to the origin's root and host, so it never blocks a sign-in.
852
+ */
853
+ function originDiscovery(options: { fetch: ClientMetadataResourceFetch }) {
854
+ // An authorization with a key resolves the app before the issuer does, so both read it once.
855
+ const resolutions = new Map<
856
+ string,
857
+ ReturnType<typeof registerClientMetadataDocument>
858
+ >()
859
+ return {
860
+ id: 'origin',
861
+ matches: originId,
862
+ resolve: async (ctx, clientId, existing) => {
863
+ // Tempo ID fetches the origin, so a private or reserved address is refused, as a metadata
864
+ // document's URL is.
865
+ const { host, hostname } = new URL(clientId)
866
+ if (!isPublicRoutableHost(hostname))
867
+ throw new APIError('BAD_REQUEST', {
868
+ error: 'invalid_client',
869
+ error_description: `Invalid client ID: ${clientId} is not a public host. Use the app's public https origin.`,
870
+ })
871
+
872
+ return await (async () => {
873
+ if (fresh(existing)) return existing
874
+ const plugin = ctx.context.getPlugin('oauth-provider')
875
+ if (!plugin) throw new Error('The OAuth provider plugin is missing.')
876
+ const resolution =
877
+ resolutions.get(clientId) ??
878
+ describe({ fetch: options.fetch, origin: clientId }).then((app) =>
879
+ registerClientMetadataDocument(ctx, plugin.options, {
880
+ clientDiscoveryId: 'origin',
881
+ clientId,
882
+ ...(existing ? { existingClient: existing } : {}),
883
+ metadata: {
884
+ client_id: clientId,
885
+ client_name: app.name ?? host,
886
+ grant_types: ['authorization_code', 'refresh_token'],
887
+ ...(app.logo ? { logo_uri: app.logo } : {}),
888
+ // Better Auth matches each redirect URI exactly, so no other path on the origin, such as
889
+ // an open redirect, receives a code.
890
+ redirect_uris: app.redirectUris?.length
891
+ ? [...app.redirectUris]
892
+ : [`${clientId}/`],
893
+ response_types: ['code'],
894
+ token_endpoint_auth_method: 'none',
895
+ },
896
+ }),
897
+ )
898
+ resolutions.set(clientId, resolution)
899
+ return (await resolution).client
900
+ })()
901
+ },
902
+ } satisfies ClientDiscovery
903
+ }
904
+
905
+ /** The most that `describe` reads of the origin's page, and of its manifest, in bytes. */
906
+ const pageLimit = 64 * 1024
907
+
908
+ /** The largest logo that `describe` inlines, in bytes. */
909
+ const logoLimit = 32 * 1024
910
+
911
+ /** The image types that `describe` inlines as a logo. */
912
+ const logoTypes = new Set([
913
+ 'image/gif',
914
+ 'image/jpeg',
915
+ 'image/png',
916
+ 'image/svg+xml',
917
+ 'image/webp',
918
+ ])
919
+
920
+ /**
921
+ * Returns the name, logo, and redirect URIs of the app at `origin`, from its manifest, else from its
922
+ * page. The logo is a `data:` URL, so the approval page loads nothing from the app. The reads share
923
+ * a 5-second limit, and a failed read returns what it found.
924
+ */
925
+ async function describe(options: {
926
+ fetch: ClientMetadataResourceFetch
927
+ origin: string
928
+ }): Promise<{
929
+ logo?: string | undefined
930
+ name?: string | undefined
931
+ redirectUris?: readonly string[] | undefined
932
+ }> {
933
+ const { origin } = options
934
+ const signal = AbortSignal.timeout(5000)
935
+
936
+ const read = async (url: string, accept: string) => {
937
+ const response = await options.fetch(url, {
938
+ headers: { accept },
939
+ redirect: 'error',
940
+ signal,
941
+ })
942
+ if (response.status !== 200 || !response.body) {
943
+ await response.body?.cancel()
944
+ throw new Error(`The read of ${url} responded with ${response.status}.`)
945
+ }
946
+ // The page's head comes first, so the read keeps only the start of a longer body. A chunk can
947
+ // be of any size, so each one is cut to the bytes left.
948
+ const reader = response.body.getReader()
949
+ const decoder = new TextDecoder()
950
+ // Each read has its own budget, so a long page leaves the manifest whole.
951
+ let remaining = pageLimit
952
+ let text = ''
953
+ while (remaining > 0) {
954
+ const { done, value } = await reader.read()
955
+ if (done) break
956
+ const chunk = value.subarray(0, remaining)
957
+ remaining -= chunk.byteLength
958
+ text += decoder.decode(chunk, { stream: true })
959
+ }
960
+ await reader.cancel()
961
+ return text
962
+ }
963
+
964
+ // A URL on another origin, such as a CDN or a `data:` URL, is not the app's.
965
+ const own = (href: unknown, base: string) => {
966
+ if (typeof href !== 'string') return undefined
967
+ const url = URL.parse(href, base)
968
+ return url?.origin === origin ? url.href : undefined
969
+ }
970
+
971
+ const page = await read(`${origin}/`, 'text/html')
972
+ .then(parsePage)
973
+ .catch(() => undefined)
974
+ if (!page) return {}
975
+
976
+ // The page's links resolve against its `<base>`, as a browser resolves them.
977
+ const base = URL.parse(page.base ?? '', `${origin}/`)?.href ?? `${origin}/`
978
+ const manifestUrl = own(page.manifest, base)
979
+ const manifest = manifestUrl
980
+ ? await read(manifestUrl, 'application/manifest+json, application/json')
981
+ .then((text): unknown => JSON.parse(text))
982
+ .catch(() => undefined)
983
+ : undefined
984
+ const fields =
985
+ typeof manifest === 'object' && manifest !== null
986
+ ? (manifest as Record<string, unknown>)
987
+ : {}
988
+ const icons = Array.isArray(fields.icons)
989
+ ? fields.icons.flatMap((icon: unknown) => {
990
+ if (typeof icon !== 'object' || icon === null) return []
991
+ const { purpose, sizes, src } = icon as Record<string, unknown>
992
+ // A monochrome icon is a mask, not a logo.
993
+ if (typeof purpose === 'string' && !/\b(any|maskable)\b/.test(purpose))
994
+ return []
995
+ const href = manifestUrl ? own(src, manifestUrl) : undefined
996
+ return href ? [{ href, size: iconSize(sizes, 0) }] : []
997
+ })
998
+ : []
999
+ // The page's icons apply only when the manifest names none. The page shows the logo at 48 pixels,
1000
+ // so the smallest icon of at least 96 pixels fills it on any screen, else the largest icon.
1001
+ const candidates =
1002
+ icons.length > 0
1003
+ ? icons
1004
+ : page.icons.flatMap((icon) => {
1005
+ const href = own(icon.href, base)
1006
+ return href ? [{ href, size: icon.size }] : []
1007
+ })
1008
+ const icon = candidates.reduce<{ href: string; size: number } | undefined>(
1009
+ (best, icon) => {
1010
+ if (!best) return icon
1011
+ if (best.size >= 96 && icon.size >= 96)
1012
+ return icon.size < best.size ? icon : best
1013
+ return icon.size > best.size ? icon : best
1014
+ },
1015
+ undefined,
1016
+ )
1017
+ const logo = icon
1018
+ ? await (async () => {
1019
+ const response = await options.fetch(icon.href, {
1020
+ headers: { accept: [...logoTypes].join(', ') },
1021
+ redirect: 'error',
1022
+ signal,
1023
+ })
1024
+ const type = response.headers
1025
+ .get('content-type')
1026
+ ?.split(';')[0]
1027
+ ?.trim()
1028
+ .toLowerCase()
1029
+ if (response.status !== 200 || !type || !logoTypes.has(type)) {
1030
+ await response.body?.cancel()
1031
+ return undefined
1032
+ }
1033
+ const reader = response.body?.getReader()
1034
+ if (!reader) return undefined
1035
+ const chunks: Uint8Array[] = []
1036
+ let size = 0
1037
+ while (true) {
1038
+ const { done, value } = await reader.read()
1039
+ if (done) break
1040
+ size += value.byteLength
1041
+ // A larger logo is refused whole, since a cut image does not render.
1042
+ if (size > logoLimit) {
1043
+ await reader.cancel()
1044
+ return undefined
1045
+ }
1046
+ chunks.push(value)
1047
+ }
1048
+ return `data:${type};base64,${Base64.fromBytes(Bytes.concat(...chunks))}`
1049
+ })().catch(() => undefined)
1050
+ : undefined
1051
+
1052
+ // Each redirect URI is an exact `https` URI on the origin, as a metadata document names one.
1053
+ const redirectUris = Array.isArray(fields.redirect_uris)
1054
+ ? fields.redirect_uris
1055
+ .flatMap((uri: unknown) => {
1056
+ if (typeof uri !== 'string' || uri.includes('#')) return []
1057
+ const url = URL.parse(uri)
1058
+ if (url?.origin !== origin || url.username || url.password) return []
1059
+ return [url.href]
1060
+ })
1061
+ .slice(0, 10)
1062
+ : undefined
1063
+
1064
+ const name = [fields.name, fields.short_name, page.title]
1065
+ .map((value) =>
1066
+ typeof value === 'string'
1067
+ ? // Control characters and runs of spaces would break the line that the page shows, and
1068
+ // format characters, such as bidi overrides, would reorder the host beside the name.
1069
+ value
1070
+ .replace(/[\p{Cc}\p{Cf}\s]+/gu, ' ')
1071
+ .trim()
1072
+ .slice(0, 64)
1073
+ : '',
1074
+ )
1075
+ .find(Boolean)
1076
+ return { logo, name, redirectUris }
1077
+ }
1078
+
1079
+ /**
1080
+ * Returns the largest dimension in an icon's `sizes`, such as 512 for `192x192 512x512`, and
1081
+ * infinity for `any`. Without sizes, returns `fallback`.
1082
+ */
1083
+ function iconSize(sizes: unknown, fallback: number) {
1084
+ if (typeof sizes !== 'string' || !sizes.trim()) return fallback
1085
+ return Math.max(
1086
+ ...sizes
1087
+ .toLowerCase()
1088
+ .split(/\s+/)
1089
+ .map((size) => {
1090
+ if (size === 'any') return Number.POSITIVE_INFINITY
1091
+ const [width, height] = size.split('x').map(Number)
1092
+ return Math.max(width || 0, height || 0)
1093
+ }),
1094
+ )
1095
+ }
1096
+
1097
+ /**
1098
+ * Returns the `<base>` URL, `<title>`, manifest link, and icon links of an untrusted HTML page, with
1099
+ * patterns that each scan in linear time.
1100
+ */
1101
+ function parsePage(html: string) {
1102
+ const source = html.replace(
1103
+ /<!--[\s\S]*?(?:-->|$)|<(script|style)\b[\s\S]*?(?:<\/\1\s*>|$)/gi,
1104
+ '',
1105
+ )
1106
+ const attributesOf = (tag: string) =>
1107
+ new Map(
1108
+ [
1109
+ ...tag.matchAll(
1110
+ /([^\s"'=<>/]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]*)))?/g,
1111
+ ),
1112
+ ].map((entry) => [
1113
+ entry[1]!.toLowerCase(),
1114
+ decode(entry[2] ?? entry[3] ?? entry[4] ?? ''),
1115
+ ]),
1116
+ )
1117
+ const links = [...source.matchAll(/<link\b([^>]*)(?:>|$)/gi)].map((match) => {
1118
+ const attributes = attributesOf(match[1] ?? '')
1119
+ const rel = (attributes.get('rel') ?? '').toLowerCase().split(/\s+/)
1120
+ return { attributes, rel }
1121
+ })
1122
+ const title = /<title\b[^>]*(?:>([^<]*)|$)/i.exec(source)?.[1]
1123
+ // A browser reads the first `<base>` with an `href`.
1124
+ const base = [...source.matchAll(/<base\b([^>]*)(?:>|$)/gi)]
1125
+ .map((match) => attributesOf(match[1] ?? '').get('href'))
1126
+ .find(Boolean)
1127
+ return {
1128
+ base,
1129
+ icons: links.flatMap((link) => {
1130
+ const href = link.attributes.get('href')
1131
+ if (!href) return []
1132
+ // An Apple touch icon without sizes is 180 pixels, larger than a favicon.
1133
+ if (link.rel.includes('apple-touch-icon'))
1134
+ return [{ href, size: iconSize(link.attributes.get('sizes'), 180) }]
1135
+ if (link.rel.includes('icon'))
1136
+ return [{ href, size: iconSize(link.attributes.get('sizes'), 0) }]
1137
+ return []
1138
+ }),
1139
+ manifest: links
1140
+ .find((link) => link.rel.includes('manifest'))
1141
+ ?.attributes.get('href'),
1142
+ title: title === undefined ? undefined : decode(title),
1143
+ }
1144
+ }
1145
+
1146
+ /** Returns `text` with its HTML character references for markup and numbers replaced. */
1147
+ function decode(text: string) {
1148
+ const named: Record<string, string> = {
1149
+ amp: '&',
1150
+ apos: "'",
1151
+ gt: '>',
1152
+ lt: '<',
1153
+ nbsp: ' ',
1154
+ quot: '"',
1155
+ }
1156
+ return text.replace(
1157
+ /&(#x[0-9a-f]+|#[0-9]+|[a-z]+);/gi,
1158
+ (match, name: string) => {
1159
+ if (!name.startsWith('#')) return named[name.toLowerCase()] ?? match
1160
+ const code =
1161
+ name[1]?.toLowerCase() === 'x'
1162
+ ? Number.parseInt(name.slice(2), 16)
1163
+ : Number.parseInt(name.slice(1), 10)
1164
+ return code > 0 && code <= 0x10ffff ? String.fromCodePoint(code) : match
1165
+ },
1166
+ )
1167
+ }
1168
+
1169
+ /** Returns the `oauth_client` row with `clientId`. Throws `NotFoundError` when no app has it. */
1170
+ async function find(db: Realm.Database, options: { clientId: string }) {
1171
+ const [row] = await db
1172
+ .select()
1173
+ .from(Schema.oauthClient)
1174
+ .where(eq(Schema.oauthClient.clientId, options.clientId))
1175
+ if (!row) throw new NotFoundError({ clientId: options.clientId })
1176
+ return row
1177
+ }
1178
+
1179
+ /** Returns `clientId`. Throws `InvalidError` unless it is 8 to 64 letters, digits, `-`, or `_`. */
1180
+ function parseClientId(clientId: string) {
1181
+ if (!/^[A-Za-z0-9_-]{8,64}$/.test(clientId))
1182
+ throw new InvalidError(
1183
+ `Invalid client ID: ${clientId}. Use 8 to 64 letters, digits, -, or _.`,
1184
+ )
1185
+ return clientId
1186
+ }
1187
+
1188
+ /** Returns `clientSecret`. Throws `InvalidError` when it holds fewer than 32 characters. */
1189
+ function parseClientSecret(clientSecret: string) {
1190
+ // The message leaves the secret out, since errors never hold one.
1191
+ if (clientSecret.length < 32)
1192
+ throw new InvalidError(
1193
+ 'Invalid client secret: fewer than 32 characters. Use a longer secret.',
1194
+ )
1195
+ return clientSecret
1196
+ }
1197
+
1198
+ /** Returns `name` trimmed. Throws `InvalidError` when it is empty. */
1199
+ function parseName(name: string) {
1200
+ const trimmed = name.trim()
1201
+ if (!trimmed)
1202
+ throw new InvalidError('Invalid app: the name is empty. Set a name.')
1203
+ return trimmed
1204
+ }
1205
+
1206
+ /** Returns `uris` as `parseRedirectUris` does, but accepts an empty list. */
1207
+ function parsePostLogoutRedirectUris(
1208
+ uris: readonly string[],
1209
+ options: { type: App['type'] },
1210
+ ): readonly string[] {
1211
+ if (uris.length === 0) return []
1212
+ return parseRedirectUris(uris, options)
1213
+ }
1214
+
1215
+ /**
1216
+ * Returns `uris`, each named once. A web app takes `https` URIs, and a native app also a custom
1217
+ * scheme. Loopback and `http` URIs are refused. Throws `InvalidError` for an invalid URI or none.
1218
+ */
1219
+ function parseRedirectUris(
1220
+ uris: readonly string[],
1221
+ options: { type: App['type'] },
1222
+ ): readonly string[] {
1223
+ if (uris.length === 0)
1224
+ throw new InvalidError(
1225
+ 'Invalid app: no redirect URI. Set at least one redirect URI.',
1226
+ )
1227
+
1228
+ for (const uri of uris) {
1229
+ const url = URL.parse(uri)
1230
+ const reason = (() => {
1231
+ if (!url) return 'is not an absolute URI'
1232
+ // RFC 6749 §3.1.2 bars a fragment from a redirect URI.
1233
+ if (url.hash || uri.includes('#')) return 'has a fragment'
1234
+ if (url.username || url.password) return 'holds credentials'
1235
+ if (url.protocol === 'https:')
1236
+ return isLoopbackHost(url.hostname) ? 'has a loopback host' : undefined
1237
+ if (url.protocol === 'http:') return 'uses http'
1238
+ if (options.type === 'web') return 'is not https'
1239
+ // Refuses reserved schemes, such as `javascript:` and `file:`, as Better Auth's registration does.
1240
+ if (!isNativePrivateUseRedirectUri(url))
1241
+ return 'is not a valid custom scheme'
1242
+ return undefined
1243
+ })()
1244
+ if (reason)
1245
+ throw new InvalidError(
1246
+ `Invalid redirect URI: ${uri} ${reason}. Use an https URI${options.type === 'native' ? ', or a custom scheme such as com.example.app:/callback' : ''}.`,
1247
+ )
1248
+ }
1249
+ return [...new Set(uris)]
1250
+ }
1251
+
1252
+ /** Returns `scopes`, or the default scopes, with `tempo-id:sign` only when `sign` is set. */
1253
+ function scopesOf(options: {
1254
+ scopes?: readonly string[] | undefined
1255
+ sign: boolean
1256
+ }): string[] {
1257
+ const kept = (options.scopes ?? scopes).filter((scope) => scope !== signScope)
1258
+ return [...kept, ...(options.sign ? [signScope] : [])]
1259
+ }
1260
+
1261
+ /** Returns a new client secret: 32 random letters, as Better Auth creates. */
1262
+ function secret() {
1263
+ return generateRandomString(32, 'a-z', 'A-Z')
1264
+ }
1265
+
1266
+ /** Returns the app of an `oauth_client` row. */
1267
+ function toApp(row: typeof Schema.oauthClient.$inferSelect): App {
1268
+ return {
1269
+ clientId: row.clientId,
1270
+ createdAt: row.createdAt,
1271
+ device: (row.grantTypes ?? []).includes(deviceGrant),
1272
+ // A metadata document cannot skip consent, so a discovered client is never first-party.
1273
+ firstParty: !row.clientDiscoveryId && row.skipConsent === true,
1274
+ // Only an inlined logo shows, so the approval page loads nothing from a third-party origin.
1275
+ logo: row.icon?.startsWith('data:image/') ? row.icon : null,
1276
+ name: row.name,
1277
+ postLogoutRedirectUris: row.postLogoutRedirectUris ?? [],
1278
+ redirectUris: row.redirectUris,
1279
+ secret: Boolean(row.clientSecret),
1280
+ sign: (row.scopes ?? []).includes(signScope),
1281
+ type: row.applicationType === 'native' ? 'native' : 'web',
1282
+ }
1283
+ }