@tempoxyz/id 0.0.0-pr-187.sha-eed04d3
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.
- package/README.md +81 -0
- package/dist/App.d.ts +20 -0
- package/dist/App.d.ts.map +1 -0
- package/dist/App.js +26 -0
- package/dist/App.js.map +1 -0
- package/dist/app/client/.assetsignore +2 -0
- package/dist/app/client/assets/BRLA-CZvVDNYr.png +0 -0
- package/dist/app/client/assets/CHFAU-DCedc4aH.png +0 -0
- package/dist/app/client/assets/DLUSD-BnRXm3EI.png +0 -0
- package/dist/app/client/assets/PRIME-CiFp2-3e.svg +14 -0
- package/dist/app/client/assets/Pilat-Bold-C1t1eIrF.woff2 +0 -0
- package/dist/app/client/assets/Pilat-Book-CbS8ofT8.woff2 +0 -0
- package/dist/app/client/assets/Pilat-Demi-CADSbPAt.woff2 +0 -0
- package/dist/app/client/assets/Pilat-Regular-Bx8vzE7q.woff2 +0 -0
- package/dist/app/client/assets/USD1-COVcO_PB.svg +30 -0
- package/dist/app/client/assets/YLDS-CRh8Zw0g.svg +3 -0
- package/dist/app/client/assets/ccip-Cq1mMiVl.js +1 -0
- package/dist/app/client/assets/frxUSD-n9pTpinR.svg +1 -0
- package/dist/app/client/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/app/client/assets/index-B7YJVP00.css +1 -0
- package/dist/app/client/assets/index-UXTxXCLk.js +55 -0
- package/dist/app/client/assets/pathUSD-BvaO6ooS.svg +25 -0
- package/dist/app/client/assets/reset-co-CHrff.css +1 -0
- package/dist/app/client/assets/wYLDS-CaCKDrO-.svg +10 -0
- package/dist/app/db/auth.d.ts +3207 -0
- package/dist/app/db/auth.d.ts.map +1 -0
- package/dist/app/db/auth.js +330 -0
- package/dist/app/db/auth.js.map +1 -0
- package/dist/app/db/schema.d.ts +932 -0
- package/dist/app/db/schema.d.ts.map +1 -0
- package/dist/app/db/schema.js +171 -0
- package/dist/app/db/schema.js.map +1 -0
- package/dist/app/server/.vite/manifest.json +489 -0
- package/dist/app/server/assets/BRLA-CZvVDNYr.png +0 -0
- package/dist/app/server/assets/CHFAU-DCedc4aH.png +0 -0
- package/dist/app/server/assets/DLUSD-BnRXm3EI.png +0 -0
- package/dist/app/server/assets/PRIME-CiFp2-3e.svg +14 -0
- package/dist/app/server/assets/Pilat-Bold-C1t1eIrF.woff2 +0 -0
- package/dist/app/server/assets/Pilat-Book-CbS8ofT8.woff2 +0 -0
- package/dist/app/server/assets/Pilat-Demi-CADSbPAt.woff2 +0 -0
- package/dist/app/server/assets/Pilat-Regular-Bx8vzE7q.woff2 +0 -0
- package/dist/app/server/assets/USD1-COVcO_PB.svg +30 -0
- package/dist/app/server/assets/YLDS-CRh8Zw0g.svg +3 -0
- package/dist/app/server/assets/_tanstack-start-manifest_v-DjQNeRZp.js +1 -0
- package/dist/app/server/assets/arktype-aI7TBD0R-D1R3Byo5.js +2 -0
- package/dist/app/server/assets/arktype-aI7TBD0R-D1R3Byo5.js.map +1 -0
- package/dist/app/server/assets/authorize-C95F-9E1-CbESJKGU.js +31 -0
- package/dist/app/server/assets/authorize-C95F-9E1-CbESJKGU.js.map +1 -0
- package/dist/app/server/assets/bun-sqlite-dialect-DoOVo4ja-CtyBkVMb.js +2 -0
- package/dist/app/server/assets/bun-sqlite-dialect-DoOVo4ja-CtyBkVMb.js.map +1 -0
- package/dist/app/server/assets/call-UQamaCKN.js +32 -0
- package/dist/app/server/assets/call-UQamaCKN.js.map +1 -0
- package/dist/app/server/assets/ccip-CbNKFO4n.js +2 -0
- package/dist/app/server/assets/ccip-CbNKFO4n.js.map +1 -0
- package/dist/app/server/assets/compiled-query-Ds2NVcFT.js +2 -0
- package/dist/app/server/assets/compiled-query-Ds2NVcFT.js.map +1 -0
- package/dist/app/server/assets/convert-BIC8n32x.js +2 -0
- package/dist/app/server/assets/convert-BIC8n32x.js.map +1 -0
- package/dist/app/server/assets/cookie-CS900nSP.css +1 -0
- package/dist/app/server/assets/cookie-Cce9CrIP.js +10 -0
- package/dist/app/server/assets/cookie-Cce9CrIP.js.map +1 -0
- package/dist/app/server/assets/core-B1HCXUmx.js +56 -0
- package/dist/app/server/assets/core-B1HCXUmx.js.map +1 -0
- package/dist/app/server/assets/d1-sqlite-dialect-m0f01-4z-Cv-csE1u.js +2 -0
- package/dist/app/server/assets/d1-sqlite-dialect-m0f01-4z-Cv-csE1u.js.map +1 -0
- package/dist/app/server/assets/default-u_dwuiYb-BJJ9PwCi.js +2 -0
- package/dist/app/server/assets/default-u_dwuiYb-BJJ9PwCi.js.map +1 -0
- package/dist/app/server/assets/dist-BxSwugSY.js +1 -0
- package/dist/app/server/assets/dist-CZGFhmQd.js +2 -0
- package/dist/app/server/assets/dist-CZGFhmQd.js.map +1 -0
- package/dist/app/server/assets/dist-Dg3PQqiW.js +15 -0
- package/dist/app/server/assets/dist-Dg3PQqiW.js.map +1 -0
- package/dist/app/server/assets/effect-QlVUlMFu-2tSPDT2b.js +2 -0
- package/dist/app/server/assets/effect-QlVUlMFu-2tSPDT2b.js.map +1 -0
- package/dist/app/server/assets/empty-plugin-adapters-BaGcmrjC.js +2 -0
- package/dist/app/server/assets/empty-plugin-adapters-BaGcmrjC.js.map +1 -0
- package/dist/app/server/assets/factory-ipHlJXZY.js +5 -0
- package/dist/app/server/assets/factory-ipHlJXZY.js.map +1 -0
- package/dist/app/server/assets/frxUSD-n9pTpinR.svg +1 -0
- package/dist/app/server/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/app/server/assets/get-id-field-B0x109VU.js +6 -0
- package/dist/app/server/assets/get-id-field-B0x109VU.js.map +1 -0
- package/dist/app/server/assets/index-CLddUTqr-xpSuLpBt.js +2 -0
- package/dist/app/server/assets/index-CLddUTqr-xpSuLpBt.js.map +1 -0
- package/dist/app/server/assets/index-DZEfthgZ-8Uq5s5Pt.js +2 -0
- package/dist/app/server/assets/index-DZEfthgZ-8Uq5s5Pt.js.map +1 -0
- package/dist/app/server/assets/kysely-adapter-MkHAI9Jk.js +1 -0
- package/dist/app/server/assets/node-sqlite-dialect-BowWLXvK.js +2 -0
- package/dist/app/server/assets/node-sqlite-dialect-BowWLXvK.js.map +1 -0
- package/dist/app/server/assets/pathUSD-BvaO6ooS.svg +25 -0
- package/dist/app/server/assets/reset-co-CHrff.css +1 -0
- package/dist/app/server/assets/rolldown-runtime-B0Z9INg1.js +1 -0
- package/dist/app/server/assets/router-CcbyBCI4.css +1 -0
- package/dist/app/server/assets/router-xjZtEeaI.js +7 -0
- package/dist/app/server/assets/router-xjZtEeaI.js.map +1 -0
- package/dist/app/server/assets/schema-check-Cf7QOZZD.js +9 -0
- package/dist/app/server/assets/schema-check-Cf7QOZZD.js.map +1 -0
- package/dist/app/server/assets/schemas-C2lCYmR5.js +2 -0
- package/dist/app/server/assets/schemas-C2lCYmR5.js.map +1 -0
- package/dist/app/server/assets/secp256k1-buM5g4AL.js +2 -0
- package/dist/app/server/assets/secp256k1-buM5g4AL.js.map +1 -0
- package/dist/app/server/assets/sqlite-adapter-C_LAV4e3.js +2 -0
- package/dist/app/server/assets/sqlite-adapter-C_LAV4e3.js.map +1 -0
- package/dist/app/server/assets/sqlite-introspector-DSCAP82F-Crx7Ny14.js +6 -0
- package/dist/app/server/assets/sqlite-introspector-DSCAP82F-Crx7Ny14.js.map +1 -0
- package/dist/app/server/assets/standard-json-Cg1N07hM.js +2 -0
- package/dist/app/server/assets/standard-json-Cg1N07hM.js.map +1 -0
- package/dist/app/server/assets/standard-json-DY77efq0.js +2 -0
- package/dist/app/server/assets/standard-json-DY77efq0.js.map +1 -0
- package/dist/app/server/assets/standard-json-ig2t0wRt.js +2 -0
- package/dist/app/server/assets/standard-json-ig2t0wRt.js.map +1 -0
- package/dist/app/server/assets/standard-json-t-LNckA6.js +2 -0
- package/dist/app/server/assets/standard-json-t-LNckA6.js.map +1 -0
- package/dist/app/server/assets/standard-openapi-CONmVRl8.js +2 -0
- package/dist/app/server/assets/standard-openapi-CONmVRl8.js.map +1 -0
- package/dist/app/server/assets/start-C63VetBp.js +2 -0
- package/dist/app/server/assets/start-C63VetBp.js.map +1 -0
- package/dist/app/server/assets/sury-CWZTCd75-xt1mWc9f.js +2 -0
- package/dist/app/server/assets/sury-CWZTCd75-xt1mWc9f.js.map +1 -0
- package/dist/app/server/assets/typebox-Dei93FPO-D_lCVdAz.js +2 -0
- package/dist/app/server/assets/typebox-Dei93FPO-D_lCVdAz.js.map +1 -0
- package/dist/app/server/assets/utils-C4ZXZIZW.js +2 -0
- package/dist/app/server/assets/utils-C4ZXZIZW.js.map +1 -0
- package/dist/app/server/assets/valibot--1zFm7rT-NSoY2xTp.js +2 -0
- package/dist/app/server/assets/valibot--1zFm7rT-NSoY2xTp.js.map +1 -0
- package/dist/app/server/assets/valibot-D_HTw1Gn-CJwWeOUE.js +2 -0
- package/dist/app/server/assets/valibot-D_HTw1Gn-CJwWeOUE.js.map +1 -0
- package/dist/app/server/assets/wYLDS-CaCKDrO-.svg +10 -0
- package/dist/app/server/assets/zod-Bwrt9trS-CV38yPnQ.js +2 -0
- package/dist/app/server/assets/zod-Bwrt9trS-CV38yPnQ.js.map +1 -0
- package/dist/app/server/assets/zod-DSgpEGAE-BvlnBE2L.js +2 -0
- package/dist/app/server/assets/zod-DSgpEGAE-BvlnBE2L.js.map +1 -0
- package/dist/app/server/index.js +574 -0
- package/dist/app/server/index.js.map +1 -0
- package/dist/app/server/wrangler.json +1 -0
- package/dist/cli/Admin.d.ts +38 -0
- package/dist/cli/Admin.d.ts.map +1 -0
- package/dist/cli/Admin.js +62 -0
- package/dist/cli/Admin.js.map +1 -0
- package/dist/cli/Apps.d.ts +9 -0
- package/dist/cli/Apps.d.ts.map +1 -0
- package/dist/cli/Apps.js +36 -0
- package/dist/cli/Apps.js.map +1 -0
- package/dist/cli/Cli.d.ts +14 -0
- package/dist/cli/Cli.d.ts.map +1 -0
- package/dist/cli/Cli.js +27 -0
- package/dist/cli/Cli.js.map +1 -0
- package/dist/cli/Project.d.ts +20 -0
- package/dist/cli/Project.d.ts.map +1 -0
- package/dist/cli/Project.js +88 -0
- package/dist/cli/Project.js.map +1 -0
- package/dist/cli/Realms.d.ts +24 -0
- package/dist/cli/Realms.d.ts.map +1 -0
- package/dist/cli/Realms.js +49 -0
- package/dist/cli/Realms.js.map +1 -0
- package/dist/cli/Session.d.ts +85 -0
- package/dist/cli/Session.d.ts.map +1 -0
- package/dist/cli/Session.js +178 -0
- package/dist/cli/Session.js.map +1 -0
- package/dist/cli/User.d.ts +29 -0
- package/dist/cli/User.d.ts.map +1 -0
- package/dist/cli/User.js +39 -0
- package/dist/cli/User.js.map +1 -0
- package/dist/cli/V1.d.ts +35 -0
- package/dist/cli/V1.d.ts.map +1 -0
- package/dist/cli/V1.js +41 -0
- package/dist/cli/V1.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +46 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/admin/apps/create.d.ts +23 -0
- package/dist/cli/commands/admin/apps/create.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/create.js +89 -0
- package/dist/cli/commands/admin/apps/create.js.map +1 -0
- package/dist/cli/commands/admin/apps/delete.d.ts +14 -0
- package/dist/cli/commands/admin/apps/delete.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/delete.js +41 -0
- package/dist/cli/commands/admin/apps/delete.js.map +1 -0
- package/dist/cli/commands/admin/apps/index.d.ts +5 -0
- package/dist/cli/commands/admin/apps/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/index.js +14 -0
- package/dist/cli/commands/admin/apps/index.js.map +1 -0
- package/dist/cli/commands/admin/apps/list.d.ts +9 -0
- package/dist/cli/commands/admin/apps/list.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/list.js +26 -0
- package/dist/cli/commands/admin/apps/list.js.map +1 -0
- package/dist/cli/commands/admin/apps/rotate-secret.d.ts +16 -0
- package/dist/cli/commands/admin/apps/rotate-secret.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/rotate-secret.js +47 -0
- package/dist/cli/commands/admin/apps/rotate-secret.js.map +1 -0
- package/dist/cli/commands/admin/apps/update.d.ts +20 -0
- package/dist/cli/commands/admin/apps/update.d.ts.map +1 -0
- package/dist/cli/commands/admin/apps/update.js +76 -0
- package/dist/cli/commands/admin/apps/update.js.map +1 -0
- package/dist/cli/commands/admin/index.d.ts +5 -0
- package/dist/cli/commands/admin/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/index.js +13 -0
- package/dist/cli/commands/admin/index.js.map +1 -0
- package/dist/cli/commands/admin/migrate.d.ts +9 -0
- package/dist/cli/commands/admin/migrate.d.ts.map +1 -0
- package/dist/cli/commands/admin/migrate.js +17 -0
- package/dist/cli/commands/admin/migrate.js.map +1 -0
- package/dist/cli/commands/admin/realms/add.d.ts +12 -0
- package/dist/cli/commands/admin/realms/add.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/add.js +42 -0
- package/dist/cli/commands/admin/realms/add.js.map +1 -0
- package/dist/cli/commands/admin/realms/index.d.ts +5 -0
- package/dist/cli/commands/admin/realms/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/index.js +13 -0
- package/dist/cli/commands/admin/realms/index.js.map +1 -0
- package/dist/cli/commands/admin/realms/list.d.ts +13 -0
- package/dist/cli/commands/admin/realms/list.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/list.js +36 -0
- package/dist/cli/commands/admin/realms/list.js.map +1 -0
- package/dist/cli/commands/admin/realms/passkeys/index.d.ts +5 -0
- package/dist/cli/commands/admin/realms/passkeys/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/passkeys/index.js +13 -0
- package/dist/cli/commands/admin/realms/passkeys/index.js.map +1 -0
- package/dist/cli/commands/admin/realms/passkeys/set.d.ts +16 -0
- package/dist/cli/commands/admin/realms/passkeys/set.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/passkeys/set.js +46 -0
- package/dist/cli/commands/admin/realms/passkeys/set.js.map +1 -0
- package/dist/cli/commands/admin/realms/privy/index.d.ts +5 -0
- package/dist/cli/commands/admin/realms/privy/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/privy/index.js +13 -0
- package/dist/cli/commands/admin/realms/privy/index.js.map +1 -0
- package/dist/cli/commands/admin/realms/privy/set.d.ts +18 -0
- package/dist/cli/commands/admin/realms/privy/set.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/privy/set.js +66 -0
- package/dist/cli/commands/admin/realms/privy/set.js.map +1 -0
- package/dist/cli/commands/admin/realms/remove.d.ts +11 -0
- package/dist/cli/commands/admin/realms/remove.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/remove.js +35 -0
- package/dist/cli/commands/admin/realms/remove.js.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/disable.d.ts +15 -0
- package/dist/cli/commands/admin/realms/secp256k1/disable.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/disable.js +42 -0
- package/dist/cli/commands/admin/realms/secp256k1/disable.js.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/enable.d.ts +15 -0
- package/dist/cli/commands/admin/realms/secp256k1/enable.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/enable.js +42 -0
- package/dist/cli/commands/admin/realms/secp256k1/enable.js.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/index.d.ts +9 -0
- package/dist/cli/commands/admin/realms/secp256k1/index.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/secp256k1/index.js +17 -0
- package/dist/cli/commands/admin/realms/secp256k1/index.js.map +1 -0
- package/dist/cli/commands/admin/realms/set.d.ts +16 -0
- package/dist/cli/commands/admin/realms/set.d.ts.map +1 -0
- package/dist/cli/commands/admin/realms/set.js +46 -0
- package/dist/cli/commands/admin/realms/set.js.map +1 -0
- package/dist/cli/commands/admin/rotate-key.d.ts +15 -0
- package/dist/cli/commands/admin/rotate-key.d.ts.map +1 -0
- package/dist/cli/commands/admin/rotate-key.js +46 -0
- package/dist/cli/commands/admin/rotate-key.js.map +1 -0
- package/dist/cli/commands/init.d.ts +11 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +34 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/login.d.ts +12 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +29 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +8 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +19 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/whoami.d.ts +12 -0
- package/dist/cli/commands/whoami.d.ts.map +1 -0
- package/dist/cli/commands/whoami.js +24 -0
- package/dist/cli/commands/whoami.js.map +1 -0
- package/dist/client/Actions.d.ts +101 -0
- package/dist/client/Actions.d.ts.map +1 -0
- package/dist/client/Actions.js +90 -0
- package/dist/client/Actions.js.map +1 -0
- package/dist/client/Auth.d.ts +161 -0
- package/dist/client/Auth.d.ts.map +1 -0
- package/dist/client/Auth.js +113 -0
- package/dist/client/Auth.js.map +1 -0
- package/dist/client/Authorization.d.ts +29 -0
- package/dist/client/Authorization.d.ts.map +1 -0
- package/dist/client/Authorization.js +12 -0
- package/dist/client/Authorization.js.map +1 -0
- package/dist/client/Decorator.d.ts +170 -0
- package/dist/client/Decorator.d.ts.map +1 -0
- package/dist/client/Decorator.js +227 -0
- package/dist/client/Decorator.js.map +1 -0
- package/dist/client/Key.d.ts +85 -0
- package/dist/client/Key.d.ts.map +1 -0
- package/dist/client/Key.js +83 -0
- package/dist/client/Key.js.map +1 -0
- package/dist/client/Pending.d.ts +39 -0
- package/dist/client/Pending.d.ts.map +1 -0
- package/dist/client/Pending.js +12 -0
- package/dist/client/Pending.js.map +1 -0
- package/dist/client/Permissions.d.ts +34 -0
- package/dist/client/Permissions.d.ts.map +1 -0
- package/dist/client/Permissions.js +16 -0
- package/dist/client/Permissions.js.map +1 -0
- package/dist/client/Provider.d.ts +16 -0
- package/dist/client/Provider.d.ts.map +1 -0
- package/dist/client/Provider.js +12 -0
- package/dist/client/Provider.js.map +1 -0
- package/dist/client/Step.d.ts +21 -0
- package/dist/client/Step.d.ts.map +1 -0
- package/dist/client/Step.js +16 -0
- package/dist/client/Step.js.map +1 -0
- package/dist/client/Storage.d.ts +27 -0
- package/dist/client/Storage.d.ts.map +1 -0
- package/dist/client/Storage.js +16 -0
- package/dist/client/Storage.js.map +1 -0
- package/dist/client/TempoAccount.d.ts +40 -0
- package/dist/client/TempoAccount.d.ts.map +1 -0
- package/dist/client/TempoAccount.js +16 -0
- package/dist/client/TempoAccount.js.map +1 -0
- package/dist/client/Tokens.d.ts +25 -0
- package/dist/client/Tokens.d.ts.map +1 -0
- package/dist/client/Tokens.js +12 -0
- package/dist/client/Tokens.js.map +1 -0
- package/dist/client/User.d.ts +21 -0
- package/dist/client/User.d.ts.map +1 -0
- package/dist/client/User.js +12 -0
- package/dist/client/User.js.map +1 -0
- package/dist/client/actions/account.d.ts +25 -0
- package/dist/client/actions/account.d.ts.map +1 -0
- package/dist/client/actions/account.js +34 -0
- package/dist/client/actions/account.js.map +1 -0
- package/dist/client/actions/device.d.ts +53 -0
- package/dist/client/actions/device.d.ts.map +1 -0
- package/dist/client/actions/device.js +79 -0
- package/dist/client/actions/device.js.map +1 -0
- package/dist/client/actions/email.d.ts +84 -0
- package/dist/client/actions/email.d.ts.map +1 -0
- package/dist/client/actions/email.js +63 -0
- package/dist/client/actions/email.js.map +1 -0
- package/dist/client/actions/oauth.d.ts +115 -0
- package/dist/client/actions/oauth.d.ts.map +1 -0
- package/dist/client/actions/oauth.js +105 -0
- package/dist/client/actions/oauth.js.map +1 -0
- package/dist/client/actions/passkey.d.ts +88 -0
- package/dist/client/actions/passkey.d.ts.map +1 -0
- package/dist/client/actions/passkey.js +60 -0
- package/dist/client/actions/passkey.js.map +1 -0
- package/dist/client/actions/provider.d.ts +49 -0
- package/dist/client/actions/provider.d.ts.map +1 -0
- package/dist/client/actions/provider.js +34 -0
- package/dist/client/actions/provider.js.map +1 -0
- package/dist/client/actions/realm.d.ts +24 -0
- package/dist/client/actions/realm.d.ts.map +1 -0
- package/dist/client/actions/realm.js +15 -0
- package/dist/client/actions/realm.js.map +1 -0
- package/dist/client/actions/redirect.d.ts +153 -0
- package/dist/client/actions/redirect.d.ts.map +1 -0
- package/dist/client/actions/redirect.js +236 -0
- package/dist/client/actions/redirect.js.map +1 -0
- package/dist/client/internal/accessKey.d.ts +21 -0
- package/dist/client/internal/accessKey.d.ts.map +1 -0
- package/dist/client/internal/accessKey.js +38 -0
- package/dist/client/internal/accessKey.js.map +1 -0
- package/dist/client/internal/account.d.ts +14 -0
- package/dist/client/internal/account.d.ts.map +1 -0
- package/dist/client/internal/account.js +3 -0
- package/dist/client/internal/account.js.map +1 -0
- package/dist/client/internal/api.d.ts +106 -0
- package/dist/client/internal/api.d.ts.map +1 -0
- package/dist/client/internal/api.js +129 -0
- package/dist/client/internal/api.js.map +1 -0
- package/dist/client/internal/headless.d.ts +33 -0
- package/dist/client/internal/headless.d.ts.map +1 -0
- package/dist/client/internal/headless.js +46 -0
- package/dist/client/internal/headless.js.map +1 -0
- package/dist/client/internal/indexedDb.d.ts +9 -0
- package/dist/client/internal/indexedDb.d.ts.map +1 -0
- package/dist/client/internal/indexedDb.js +32 -0
- package/dist/client/internal/indexedDb.js.map +1 -0
- package/dist/client/internal/request.d.ts +58 -0
- package/dist/client/internal/request.d.ts.map +1 -0
- package/dist/client/internal/request.js +45 -0
- package/dist/client/internal/request.js.map +1 -0
- package/dist/client/internal/store.d.ts +12 -0
- package/dist/client/internal/store.d.ts.map +1 -0
- package/dist/client/internal/store.js +15 -0
- package/dist/client/internal/store.js.map +1 -0
- package/dist/client.d.ts +20 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +20 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/Apps.d.ts +3051 -0
- package/dist/internal/Apps.d.ts.map +1 -0
- package/dist/internal/Apps.js +472 -0
- package/dist/internal/Apps.js.map +1 -0
- package/dist/internal/Auth.d.ts +4058 -0
- package/dist/internal/Auth.d.ts.map +1 -0
- package/dist/internal/Auth.js +137 -0
- package/dist/internal/Auth.js.map +1 -0
- package/dist/internal/Authorize.d.ts +532 -0
- package/dist/internal/Authorize.d.ts.map +1 -0
- package/dist/internal/Authorize.js +326 -0
- package/dist/internal/Authorize.js.map +1 -0
- package/dist/internal/Device.d.ts +371 -0
- package/dist/internal/Device.d.ts.map +1 -0
- package/dist/internal/Device.js +271 -0
- package/dist/internal/Device.js.map +1 -0
- package/dist/internal/Env.d.ts +57 -0
- package/dist/internal/Env.d.ts.map +1 -0
- package/dist/internal/Env.js +2 -0
- package/dist/internal/Env.js.map +1 -0
- package/dist/internal/ErrorResponse.d.ts +609 -0
- package/dist/internal/ErrorResponse.d.ts.map +1 -0
- package/dist/internal/ErrorResponse.js +679 -0
- package/dist/internal/ErrorResponse.js.map +1 -0
- package/dist/internal/Id.d.ts +10 -0
- package/dist/internal/Id.d.ts.map +1 -0
- package/dist/internal/Id.js +34 -0
- package/dist/internal/Id.js.map +1 -0
- package/dist/internal/KeyAuthorization.d.ts +1456 -0
- package/dist/internal/KeyAuthorization.d.ts.map +1 -0
- package/dist/internal/KeyAuthorization.js +1030 -0
- package/dist/internal/KeyAuthorization.js.map +1 -0
- package/dist/internal/Limits.d.ts +65 -0
- package/dist/internal/Limits.d.ts.map +1 -0
- package/dist/internal/Limits.js +35 -0
- package/dist/internal/Limits.js.map +1 -0
- package/dist/internal/Log.d.ts +49 -0
- package/dist/internal/Log.d.ts.map +1 -0
- package/dist/internal/Log.js +101 -0
- package/dist/internal/Log.js.map +1 -0
- package/dist/internal/LogLine.d.ts +33 -0
- package/dist/internal/LogLine.d.ts.map +1 -0
- package/dist/internal/LogLine.js +56 -0
- package/dist/internal/LogLine.js.map +1 -0
- package/dist/internal/Migrations.d.ts +19 -0
- package/dist/internal/Migrations.d.ts.map +1 -0
- package/dist/internal/Migrations.js +57 -0
- package/dist/internal/Migrations.js.map +1 -0
- package/dist/internal/Owner.d.ts +146 -0
- package/dist/internal/Owner.d.ts.map +1 -0
- package/dist/internal/Owner.js +65 -0
- package/dist/internal/Owner.js.map +1 -0
- package/dist/internal/Passkey.d.ts +528 -0
- package/dist/internal/Passkey.d.ts.map +1 -0
- package/dist/internal/Passkey.js +658 -0
- package/dist/internal/Passkey.js.map +1 -0
- package/dist/internal/PendingKey.d.ts +49 -0
- package/dist/internal/PendingKey.d.ts.map +1 -0
- package/dist/internal/PendingKey.js +58 -0
- package/dist/internal/PendingKey.js.map +1 -0
- package/dist/internal/Privy.d.ts +105 -0
- package/dist/internal/Privy.d.ts.map +1 -0
- package/dist/internal/Privy.js +224 -0
- package/dist/internal/Privy.js.map +1 -0
- package/dist/internal/RateLimit.d.ts +190 -0
- package/dist/internal/RateLimit.d.ts.map +1 -0
- package/dist/internal/RateLimit.js +148 -0
- package/dist/internal/RateLimit.js.map +1 -0
- package/dist/internal/Realm.d.ts +281 -0
- package/dist/internal/Realm.d.ts.map +1 -0
- package/dist/internal/Realm.js +477 -0
- package/dist/internal/Realm.js.map +1 -0
- package/dist/internal/RequestId.d.ts +16 -0
- package/dist/internal/RequestId.d.ts.map +1 -0
- package/dist/internal/RequestId.js +78 -0
- package/dist/internal/RequestId.js.map +1 -0
- package/dist/internal/SigningKey.d.ts +115 -0
- package/dist/internal/SigningKey.d.ts.map +1 -0
- package/dist/internal/SigningKey.js +197 -0
- package/dist/internal/SigningKey.js.map +1 -0
- package/dist/internal/TestInbox.d.ts +42 -0
- package/dist/internal/TestInbox.d.ts.map +1 -0
- package/dist/internal/TestInbox.js +20 -0
- package/dist/internal/TestInbox.js.map +1 -0
- package/dist/internal/Timing.d.ts +51 -0
- package/dist/internal/Timing.d.ts.map +1 -0
- package/dist/internal/Timing.js +103 -0
- package/dist/internal/Timing.js.map +1 -0
- package/dist/internal/Validation.d.ts +52 -0
- package/dist/internal/Validation.d.ts.map +1 -0
- package/dist/internal/Validation.js +22 -0
- package/dist/internal/Validation.js.map +1 -0
- package/dist/internal/Wallet.d.ts +37 -0
- package/dist/internal/Wallet.d.ts.map +1 -0
- package/dist/internal/Wallet.js +43 -0
- package/dist/internal/Wallet.js.map +1 -0
- package/dist/worker.d.ts +12 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +12 -0
- package/dist/worker.js.map +1 -0
- package/package.json +82 -0
- package/src/Api.ts +151 -0
- package/src/App.ts +56 -0
- package/src/api/account.ts +311 -0
- package/src/api/authenticate.ts +1290 -0
- package/src/api/authorize.ts +1030 -0
- package/src/api/device.ts +874 -0
- package/src/api/health.ts +72 -0
- package/src/api/lib/AccountStep.ts +335 -0
- package/src/api/lib/Auth.ts +134 -0
- package/src/api/lib/Consent.ts +339 -0
- package/src/api/lib/Cors.ts +107 -0
- package/src/api/lib/Database.ts +10 -0
- package/src/api/lib/DeviceRequest.ts +265 -0
- package/src/api/lib/FirstAccount.ts +90 -0
- package/src/api/lib/KeySigner.ts +393 -0
- package/src/api/lib/PasskeyLink.ts +162 -0
- package/src/api/lib/Session.ts +34 -0
- package/src/api/lib/SignInConsent.ts +316 -0
- package/src/api/oauth.ts +1282 -0
- package/src/api/provider.ts +441 -0
- package/src/app/components/Button.tsx +128 -0
- package/src/app/components/CodeInput.tsx +186 -0
- package/src/app/components/ErrorMessage.tsx +66 -0
- package/src/app/components/Grant.tsx +323 -0
- package/src/app/components/Input.tsx +48 -0
- package/src/app/components/Tooltip.tsx +45 -0
- package/src/app/components/icons/BRLA.png +0 -0
- package/src/app/components/icons/BRZ.svg +1 -0
- package/src/app/components/icons/CHFAU.png +0 -0
- package/src/app/components/icons/DLUSD.png +0 -0
- package/src/app/components/icons/EURAU.svg +1 -0
- package/src/app/components/icons/EURC.e.svg +1 -0
- package/src/app/components/icons/GBPA.svg +4 -0
- package/src/app/components/icons/GUSD.svg +1 -0
- package/src/app/components/icons/MACH.svg +4 -0
- package/src/app/components/icons/OUSD.svg +5 -0
- package/src/app/components/icons/PRIME.svg +14 -0
- package/src/app/components/icons/SBC.svg +1 -0
- package/src/app/components/icons/SEKAU.svg +5 -0
- package/src/app/components/icons/USD1.svg +30 -0
- package/src/app/components/icons/USDB.svg +11 -0
- package/src/app/components/icons/USDC.e.svg +1 -0
- package/src/app/components/icons/USDT0.svg +1 -0
- package/src/app/components/icons/USDY.svg +16 -0
- package/src/app/components/icons/USDe.svg +1 -0
- package/src/app/components/icons/YLDS.svg +3 -0
- package/src/app/components/icons/alphaUSD.svg +1 -0
- package/src/app/components/icons/betaUSD.svg +1 -0
- package/src/app/components/icons/cUSD.svg +1 -0
- package/src/app/components/icons/cbBTC.svg +1 -0
- package/src/app/components/icons/frxUSD.svg +1 -0
- package/src/app/components/icons/goUSD.svg +5 -0
- package/src/app/components/icons/iUSD.svg +1 -0
- package/src/app/components/icons/pathUSD.svg +25 -0
- package/src/app/components/icons/rUSD.svg +1 -0
- package/src/app/components/icons/reUSD.svg +1 -0
- package/src/app/components/icons/sUSDe.svg +1 -0
- package/src/app/components/icons/siUSD.svg +1 -0
- package/src/app/components/icons/stcUSD.svg +1 -0
- package/src/app/components/icons/syrupUSDC.svg +5 -0
- package/src/app/components/icons/thetaUSD.svg +1 -0
- package/src/app/components/icons/wYLDS.svg +10 -0
- package/src/app/components/icons/wsrUSD.svg +1 -0
- package/src/app/components/logos/OUSD.dark.svg +17 -0
- package/src/app/components/logos/OUSD.light.svg +17 -0
- package/src/app/crons/cleanup.ts +42 -0
- package/src/app/db/auth.ts +416 -0
- package/src/app/db/migrations/0000_better_auth.sql +53 -0
- package/src/app/db/migrations/0001_oauth_provider.sql +162 -0
- package/src/app/db/migrations/0002_device_code.sql +17 -0
- package/src/app/db/migrations/0003_realms.sql +27 -0
- package/src/app/db/migrations/0004_default_realm.sql +2 -0
- package/src/app/db/migrations/0005_passkeys.sql +30 -0
- package/src/app/db/migrations/0006_first_accounts.sql +9 -0
- package/src/app/db/migrations/0007_pending_keys.sql +13 -0
- package/src/app/db/migrations/0008_secp256k1_owners.sql +18 -0
- package/src/app/db/migrations/0009_device_requests.sql +8 -0
- package/src/app/db/migrations/0010_device_keys.sql +4 -0
- package/src/app/db/migrations/meta/0000_snapshot.json +362 -0
- package/src/app/db/migrations/meta/0001_snapshot.json +1487 -0
- package/src/app/db/migrations/meta/0002_snapshot.json +1603 -0
- package/src/app/db/migrations/meta/0003_snapshot.json +1760 -0
- package/src/app/db/migrations/meta/0004_snapshot.json +1760 -0
- package/src/app/db/migrations/meta/0005_snapshot.json +1911 -0
- package/src/app/db/migrations/meta/0006_snapshot.json +1967 -0
- package/src/app/db/migrations/meta/0007_snapshot.json +2047 -0
- package/src/app/db/migrations/meta/0008_snapshot.json +2157 -0
- package/src/app/db/migrations/meta/0009_snapshot.json +2207 -0
- package/src/app/db/migrations/meta/0010_snapshot.json +2231 -0
- package/src/app/db/migrations/meta/_journal.json +83 -0
- package/src/app/db/schema.ts +218 -0
- package/src/app/env.ts +49 -0
- package/src/app/lib/Client.ts +82 -0
- package/src/app/lib/Loader.ts +24 -0
- package/src/app/package.json +8 -0
- package/src/app/routeTree.gen.ts +198 -0
- package/src/app/router.tsx +48 -0
- package/src/app/routes/[_].flows.tsx +3001 -0
- package/src/app/routes/__root.tsx +91 -0
- package/src/app/routes/authorize.tsx +197 -0
- package/src/app/routes/choose-account.tsx +111 -0
- package/src/app/routes/deposit.tsx +105 -0
- package/src/app/routes/device.tsx +227 -0
- package/src/app/routes/index.tsx +115 -0
- package/src/app/routes/login.tsx +506 -0
- package/src/app/screens/Account.tsx +347 -0
- package/src/app/screens/Approval.tsx +276 -0
- package/src/app/screens/ChooseAccount.tsx +240 -0
- package/src/app/screens/Deposit.tsx +762 -0
- package/src/app/screens/DeviceApproval.tsx +480 -0
- package/src/app/screens/SignIn.tsx +362 -0
- package/src/app/screens/chains/base.svg +3 -0
- package/src/app/screens/chains/ethereum.svg +11 -0
- package/src/app/screens/chains/solana.svg +4 -0
- package/src/app/screens/chains/tempo.svg +4 -0
- package/src/app/server.ts +204 -0
- package/src/app/vite.config.ts +95 -0
- package/src/app/void.config.ts +29 -0
- package/src/app/zyzz.config.ts +274 -0
- package/src/cli/Admin.ts +73 -0
- package/src/cli/Apps.ts +29 -0
- package/src/cli/Cli.ts +42 -0
- package/src/cli/Project.ts +117 -0
- package/src/cli/Realms.ts +50 -0
- package/src/cli/Session.ts +239 -0
- package/src/cli/User.ts +45 -0
- package/src/cli/V1.ts +57 -0
- package/src/cli/bin.ts +44 -0
- package/src/cli/commands/admin/apps/create.ts +101 -0
- package/src/cli/commands/admin/apps/delete.ts +38 -0
- package/src/cli/commands/admin/apps/index.ts +15 -0
- package/src/cli/commands/admin/apps/list.ts +25 -0
- package/src/cli/commands/admin/apps/rotate-secret.ts +47 -0
- package/src/cli/commands/admin/apps/update.ts +86 -0
- package/src/cli/commands/admin/index.ts +14 -0
- package/src/cli/commands/admin/migrate.ts +16 -0
- package/src/cli/commands/admin/realms/add.ts +40 -0
- package/src/cli/commands/admin/realms/index.ts +14 -0
- package/src/cli/commands/admin/realms/list.ts +38 -0
- package/src/cli/commands/admin/realms/passkeys/index.ts +15 -0
- package/src/cli/commands/admin/realms/passkeys/set.ts +44 -0
- package/src/cli/commands/admin/realms/privy/index.ts +14 -0
- package/src/cli/commands/admin/realms/privy/set.ts +69 -0
- package/src/cli/commands/admin/realms/remove.ts +33 -0
- package/src/cli/commands/admin/realms/secp256k1/disable.ts +40 -0
- package/src/cli/commands/admin/realms/secp256k1/enable.ts +40 -0
- package/src/cli/commands/admin/realms/secp256k1/index.ts +19 -0
- package/src/cli/commands/admin/realms/set.ts +46 -0
- package/src/cli/commands/admin/rotate-key.ts +47 -0
- package/src/cli/commands/init.ts +42 -0
- package/src/cli/commands/login.ts +32 -0
- package/src/cli/commands/logout.ts +19 -0
- package/src/cli/commands/whoami.ts +23 -0
- package/src/client/Actions.ts +168 -0
- package/src/client/Auth.ts +285 -0
- package/src/client/Authorization.ts +34 -0
- package/src/client/Decorator.ts +410 -0
- package/src/client/Key.ts +140 -0
- package/src/client/Pending.ts +46 -0
- package/src/client/Permissions.ts +39 -0
- package/src/client/Provider.ts +18 -0
- package/src/client/Step.ts +24 -0
- package/src/client/Storage.ts +29 -0
- package/src/client/TempoAccount.ts +42 -0
- package/src/client/Tokens.ts +27 -0
- package/src/client/User.ts +23 -0
- package/src/client/actions/account.ts +57 -0
- package/src/client/actions/device.ts +151 -0
- package/src/client/actions/email.ts +141 -0
- package/src/client/actions/oauth.ts +182 -0
- package/src/client/actions/passkey.ts +141 -0
- package/src/client/actions/provider.ts +70 -0
- package/src/client/actions/realm.ts +36 -0
- package/src/client/actions/redirect.ts +408 -0
- package/src/client/internal/accessKey.ts +54 -0
- package/src/client/internal/account.ts +15 -0
- package/src/client/internal/api.ts +224 -0
- package/src/client/internal/headless.ts +77 -0
- package/src/client/internal/indexedDb.ts +44 -0
- package/src/client/internal/request.ts +71 -0
- package/src/client/internal/store.ts +20 -0
- package/src/client.ts +19 -0
- package/src/index.ts +6 -0
- package/src/internal/Apps.ts +718 -0
- package/src/internal/Auth.ts +203 -0
- package/src/internal/Authorize.ts +424 -0
- package/src/internal/Balance.ts +168 -0
- package/src/internal/BodyLimit.ts +36 -0
- package/src/internal/Chain.ts +16 -0
- package/src/internal/Device.ts +469 -0
- package/src/internal/Env.ts +58 -0
- package/src/internal/ErrorResponse.ts +854 -0
- package/src/internal/Id.ts +41 -0
- package/src/internal/KeyAuthorization.ts +1339 -0
- package/src/internal/Limits.ts +39 -0
- package/src/internal/Log.ts +178 -0
- package/src/internal/LogLine.ts +87 -0
- package/src/internal/Logout.ts +336 -0
- package/src/internal/Migrations.ts +86 -0
- package/src/internal/OpenApi.ts +300 -0
- package/src/internal/Owner.ts +211 -0
- package/src/internal/Passkey.ts +1052 -0
- package/src/internal/PendingKey.ts +104 -0
- package/src/internal/Privy.ts +402 -0
- package/src/internal/Provider.ts +125 -0
- package/src/internal/RateLimit.ts +259 -0
- package/src/internal/Realm.ts +768 -0
- package/src/internal/RequestId.ts +118 -0
- package/src/internal/SignInGrant.ts +168 -0
- package/src/internal/SigningKey.ts +286 -0
- package/src/internal/TempoAccount.ts +342 -0
- package/src/internal/TestInbox.ts +51 -0
- package/src/internal/Timing.ts +158 -0
- package/src/internal/Validation.ts +52 -0
- package/src/internal/Wallet.ts +62 -0
- package/src/internal/owners/Passkey.ts +72 -0
- package/src/internal/owners/Privy.ts +81 -0
- package/src/internal/owners/Secp256k1.ts +143 -0
- package/src/types/app.d.ts +19 -0
- package/src/worker.ts +11 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Key authorizations that the approval page signed, held until the app redeems the code that the
|
|
3
|
+
* same approval returned. A signed authorization lets whoever holds its key spend, so no redirect
|
|
4
|
+
* carries it. Each row is keyed by the app's client ID and the request's PKCE challenge, and only
|
|
5
|
+
* the redemption that proves the challenge's verifier takes it.
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { and, eq, gt } from 'drizzle-orm'
|
|
9
|
+
import * as Schema from '../app/db/schema.js'
|
|
10
|
+
import type * as KeyAuthorization from './KeyAuthorization.js'
|
|
11
|
+
import type * as Realm from './Realm.js'
|
|
12
|
+
|
|
13
|
+
/** Seconds that a signed key authorization waits for its code's redemption, as long as the code lasts. */
|
|
14
|
+
export const lifetime = 10 * 60
|
|
15
|
+
|
|
16
|
+
/** A signed key authorization, and the Tempo Account that it acts for. */
|
|
17
|
+
export type PendingKey = {
|
|
18
|
+
/** The Tempo Account that the key acts for. */
|
|
19
|
+
account: `0x${string}`
|
|
20
|
+
/** The signed key authorization, in the node's RPC format. */
|
|
21
|
+
keyAuthorization: Awaited<ReturnType<typeof KeyAuthorization.sign>>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Holds `key` for the app with `clientId` and the PKCE challenge `codeChallenge`, for
|
|
26
|
+
* {@link lifetime} seconds, or until the key expires if sooner. A later approval of the same request
|
|
27
|
+
* by the same user replaces the key that an earlier approval left, so the key matches the approval
|
|
28
|
+
* that the user made last. Another user's approval replaces nothing.
|
|
29
|
+
*/
|
|
30
|
+
export async function put(db: Realm.Database, options: put.Options) {
|
|
31
|
+
const { clientId, codeChallenge, expiry, key, userId } = options
|
|
32
|
+
const values = {
|
|
33
|
+
account: key.account,
|
|
34
|
+
expiresAt: new Date(Math.min(Date.now() + lifetime * 1000, expiry * 1000)),
|
|
35
|
+
keyAuthorization: key.keyAuthorization,
|
|
36
|
+
userId,
|
|
37
|
+
}
|
|
38
|
+
await db
|
|
39
|
+
.insert(Schema.pendingKeys)
|
|
40
|
+
.values({ ...values, clientId, codeChallenge })
|
|
41
|
+
.onConflictDoUpdate({
|
|
42
|
+
set: { ...values, createdAt: new Date() },
|
|
43
|
+
setWhere: eq(Schema.pendingKeys.userId, userId),
|
|
44
|
+
target: [Schema.pendingKeys.clientId, Schema.pendingKeys.codeChallenge],
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export declare namespace put {
|
|
49
|
+
type Options = {
|
|
50
|
+
/** The client ID of the app that requested the key. */
|
|
51
|
+
clientId: string
|
|
52
|
+
/** The S256 PKCE challenge of the authorization request. */
|
|
53
|
+
codeChallenge: string
|
|
54
|
+
/** When the signed key expires, in Unix seconds, which bounds how long the row waits. */
|
|
55
|
+
expiry: number
|
|
56
|
+
/** The signed key authorization, and the account that it acts for. */
|
|
57
|
+
key: PendingKey
|
|
58
|
+
/** The ID of the user who approved the key. */
|
|
59
|
+
userId: string
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Deletes the key held for the app with `clientId`, the PKCE challenge `codeChallenge`, and the
|
|
65
|
+
* user `userId`, and returns it. Returns `undefined` when none is held, when it expired, or when an
|
|
66
|
+
* earlier redemption took it, so a second code for the same challenge carries no key.
|
|
67
|
+
*/
|
|
68
|
+
export async function take(
|
|
69
|
+
db: Realm.Database,
|
|
70
|
+
options: take.Options,
|
|
71
|
+
): Promise<PendingKey | undefined> {
|
|
72
|
+
const { clientId, codeChallenge, userId } = options
|
|
73
|
+
const [row] = await db
|
|
74
|
+
.delete(Schema.pendingKeys)
|
|
75
|
+
.where(
|
|
76
|
+
and(
|
|
77
|
+
eq(Schema.pendingKeys.clientId, clientId),
|
|
78
|
+
eq(Schema.pendingKeys.codeChallenge, codeChallenge),
|
|
79
|
+
gt(Schema.pendingKeys.expiresAt, new Date()),
|
|
80
|
+
// A challenge that an app reuses for another user's request never carries this user's key.
|
|
81
|
+
eq(Schema.pendingKeys.userId, userId),
|
|
82
|
+
),
|
|
83
|
+
)
|
|
84
|
+
.returning({
|
|
85
|
+
account: Schema.pendingKeys.account,
|
|
86
|
+
keyAuthorization: Schema.pendingKeys.keyAuthorization,
|
|
87
|
+
})
|
|
88
|
+
if (!row) return undefined
|
|
89
|
+
return {
|
|
90
|
+
account: row.account as `0x${string}`,
|
|
91
|
+
keyAuthorization: row.keyAuthorization as PendingKey['keyAuthorization'],
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export declare namespace take {
|
|
96
|
+
type Options = {
|
|
97
|
+
/** The client ID of the app that redeems the code. */
|
|
98
|
+
clientId: string
|
|
99
|
+
/** The PKCE challenge that the redemption's verifier proved. */
|
|
100
|
+
codeChallenge: string
|
|
101
|
+
/** The ID of the user whom the code names. */
|
|
102
|
+
userId: string
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Each user's Privy embedded wallets, which hold the owner keys of their Privy-owned Tempo Accounts.
|
|
3
|
+
* Each realm's Privy app keys the user by their user ID, the `sub` of every token Tempo ID issues,
|
|
4
|
+
* as a custom auth ID. Tempo ID reads and creates wallets with the app secret, and signs as a wallet
|
|
5
|
+
* with a token that only Privy trusts.
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { PrivyClient } from '@privy-io/node'
|
|
9
|
+
import { createViemAccount } from '@privy-io/node/viem'
|
|
10
|
+
import { Base64 } from 'ox'
|
|
11
|
+
import { Account } from 'viem/tempo'
|
|
12
|
+
import * as ErrorResponse from './ErrorResponse.js'
|
|
13
|
+
import * as Timing from './Timing.js'
|
|
14
|
+
|
|
15
|
+
/** No `PRIVY_JWT_PRIVATE_KEY` is set, so Tempo ID cannot sign as a Privy wallet. */
|
|
16
|
+
export class SigningKeyMissingError extends Error {
|
|
17
|
+
override readonly name = 'Privy.SigningKeyMissingError'
|
|
18
|
+
|
|
19
|
+
constructor() {
|
|
20
|
+
super(
|
|
21
|
+
'Missing PRIVY_JWT_PRIVATE_KEY. Set the RS256 private key whose public half each Privy app trusts.',
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** How long a token for Privy lasts, in seconds: long enough for one signing request. */
|
|
27
|
+
const tokenLifetime = 60
|
|
28
|
+
|
|
29
|
+
/** A realm's Privy app, which holds the owner wallets of the realm's Privy-owned accounts. */
|
|
30
|
+
export type App = {
|
|
31
|
+
/** The Privy app ID. */
|
|
32
|
+
appId: string
|
|
33
|
+
/** The Privy app secret. */
|
|
34
|
+
appSecret: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** A user's Privy wallet. */
|
|
38
|
+
export type Wallet = {
|
|
39
|
+
/** The wallet's address. */
|
|
40
|
+
address: `0x${string}`
|
|
41
|
+
/** When Privy created the wallet, or a lower bound when Privy omits it. */
|
|
42
|
+
createdAt: Date
|
|
43
|
+
/** The Privy wallet ID, which signing requests name. */
|
|
44
|
+
id: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Returns the user's first Privy wallet in `app`, and creates their Privy user and the wallet when
|
|
49
|
+
* they have none. Concurrent first calls return the same wallet, and hold no database connection
|
|
50
|
+
* while Privy responds.
|
|
51
|
+
*/
|
|
52
|
+
export async function firstWallet(
|
|
53
|
+
c: Timing.measure.Context,
|
|
54
|
+
options: firstWallet.Options,
|
|
55
|
+
): Promise<Wallet> {
|
|
56
|
+
const { app, userId } = options
|
|
57
|
+
|
|
58
|
+
const privyUser =
|
|
59
|
+
(await Timing.measure(c, findUser(c, { app, userId }), 'Privy.findUser')) ??
|
|
60
|
+
(await Timing.measure(
|
|
61
|
+
c,
|
|
62
|
+
createUser(c, { app, userId }),
|
|
63
|
+
'Privy.createUser',
|
|
64
|
+
))
|
|
65
|
+
// The user is created without a wallet, so every call that finds no wallet sends the same
|
|
66
|
+
// idempotent create, and concurrent calls receive one wallet.
|
|
67
|
+
return (
|
|
68
|
+
wallets(privyUser)[0] ??
|
|
69
|
+
(await Timing.measure(
|
|
70
|
+
c,
|
|
71
|
+
addWallet(c, { app, privyUserId: privyUser.id }),
|
|
72
|
+
'Privy.addWallet',
|
|
73
|
+
))
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export namespace firstWallet {
|
|
78
|
+
export type Options = {
|
|
79
|
+
/** The Privy app that holds the user's wallets. */
|
|
80
|
+
app: App
|
|
81
|
+
/** The user's ID. */
|
|
82
|
+
userId: string
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** The refusals `firstWallet` throws, which `ErrorResponse.handle` responds with: Privy's failures. */
|
|
86
|
+
export const errors = ErrorResponse.fromUpstream.errors
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Returns the user's Privy wallets in `app`, oldest first, or none when they have no Privy user yet.
|
|
91
|
+
* Creates nothing.
|
|
92
|
+
*/
|
|
93
|
+
export async function listWallets(
|
|
94
|
+
c: Timing.measure.Context,
|
|
95
|
+
options: listWallets.Options,
|
|
96
|
+
): Promise<readonly Wallet[]> {
|
|
97
|
+
const privyUser = await Timing.measure(
|
|
98
|
+
c,
|
|
99
|
+
findUser(c, options),
|
|
100
|
+
'Privy.findUser',
|
|
101
|
+
)
|
|
102
|
+
return privyUser ? wallets(privyUser) : []
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export namespace listWallets {
|
|
106
|
+
export type Options = {
|
|
107
|
+
/** The Privy app that holds the user's wallets. */
|
|
108
|
+
app: App
|
|
109
|
+
/** The user's ID. */
|
|
110
|
+
userId: string
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The refusals `listWallets` throws, which `ErrorResponse.handle` responds with: Privy's failures. */
|
|
114
|
+
export const errors = ErrorResponse.fromUpstream.errors
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Returns a token that names the user for `app`, which Privy exchanges for the right to sign as the
|
|
119
|
+
* user's wallet. `privateKey` signs it, and Privy trusts only that key's public half, so no token
|
|
120
|
+
* that Tempo ID issues to apps signs as a wallet. It lasts {@link tokenLifetime} seconds, and its
|
|
121
|
+
* `aud` is the Privy app ID. Throws {@link SigningKeyMissingError} without `privateKey`.
|
|
122
|
+
*/
|
|
123
|
+
export async function token(
|
|
124
|
+
auth: token.Auth,
|
|
125
|
+
options: token.Options,
|
|
126
|
+
): Promise<string> {
|
|
127
|
+
const { app, privateKey, userId } = options
|
|
128
|
+
if (!privateKey) throw new SigningKeyMissingError()
|
|
129
|
+
|
|
130
|
+
const key = await crypto.subtle.importKey(
|
|
131
|
+
'pkcs8',
|
|
132
|
+
new Uint8Array(
|
|
133
|
+
Base64.toBytes(privateKey.replace(/-----[^-]+-----|\s/g, '')),
|
|
134
|
+
),
|
|
135
|
+
{ hash: 'SHA-256', name: 'RSASSA-PKCS1-v1_5' },
|
|
136
|
+
true,
|
|
137
|
+
['sign'],
|
|
138
|
+
)
|
|
139
|
+
const jwk = (await crypto.subtle.exportKey('jwk', key)) as JsonWebKey
|
|
140
|
+
const now = Math.floor(Date.now() / 1000)
|
|
141
|
+
|
|
142
|
+
// Better Auth signs with this key alone, never with the keys that sign apps' tokens.
|
|
143
|
+
const signed = await auth.api.signJWT({
|
|
144
|
+
body: {
|
|
145
|
+
overrideOptions: {
|
|
146
|
+
adapter: {
|
|
147
|
+
getJwks: () => [
|
|
148
|
+
{
|
|
149
|
+
alg: 'RS256',
|
|
150
|
+
createdAt: new Date(0),
|
|
151
|
+
id: 'privy',
|
|
152
|
+
privateKey: JSON.stringify(jwk),
|
|
153
|
+
publicKey: JSON.stringify({ e: jwk.e, kty: jwk.kty, n: jwk.n }),
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
},
|
|
157
|
+
jwks: {
|
|
158
|
+
disablePrivateKeyEncryption: true,
|
|
159
|
+
keyPairConfig: { alg: 'RS256' },
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
payload: {
|
|
163
|
+
aud: app.appId,
|
|
164
|
+
exp: now + tokenLifetime,
|
|
165
|
+
iat: now,
|
|
166
|
+
sub: userId,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
})
|
|
170
|
+
return signed.token
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export declare namespace token {
|
|
174
|
+
/** The capability that signs the token: Better Auth's in-process `signJWT`. */
|
|
175
|
+
type Auth = {
|
|
176
|
+
/** Better Auth's server API. */
|
|
177
|
+
api: {
|
|
178
|
+
/** Signs `payload` with the key set that `overrideOptions` names. */
|
|
179
|
+
signJWT: (input: {
|
|
180
|
+
body: {
|
|
181
|
+
overrideOptions?: Record<string, unknown> | undefined
|
|
182
|
+
payload: Record<string, unknown>
|
|
183
|
+
}
|
|
184
|
+
}) => Promise<{ token: string }>
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
type Options = {
|
|
189
|
+
/** The Privy app that exchanges the token. */
|
|
190
|
+
app: App
|
|
191
|
+
/** The `PRIVY_JWT_PRIVATE_KEY` variable, as PKCS #8 PEM. */
|
|
192
|
+
privateKey: string | undefined
|
|
193
|
+
/** The user's ID, the token's `sub`. */
|
|
194
|
+
userId: string
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Returns the Tempo Account that `wallet` owns, which signs only with `token`. */
|
|
199
|
+
export function toAccount(options: toAccount.Options) {
|
|
200
|
+
const { app, token, wallet } = options
|
|
201
|
+
return Account.fromConfig({
|
|
202
|
+
owners: [
|
|
203
|
+
createViemAccount(client(app), {
|
|
204
|
+
address: wallet.address,
|
|
205
|
+
// Privy signs as the wallet only with its owner's token.
|
|
206
|
+
...(token ? { authorizationContext: { user_jwts: [token] } } : {}),
|
|
207
|
+
walletId: wallet.id,
|
|
208
|
+
}),
|
|
209
|
+
],
|
|
210
|
+
})
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export declare namespace toAccount {
|
|
214
|
+
type Options = {
|
|
215
|
+
/** The Privy app that holds `wallet`. */
|
|
216
|
+
app: App
|
|
217
|
+
/** The token from {@link token}, which signing requires. Absent, the account cannot sign. */
|
|
218
|
+
token?: string | undefined
|
|
219
|
+
/** The owner wallet. */
|
|
220
|
+
wallet: Wallet
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Adds an embedded wallet to a Privy user. While a concurrent create with the same idempotency key
|
|
226
|
+
* is still in progress, Privy refuses with a 400, so the create waits and resends a bounded number
|
|
227
|
+
* of times until Privy returns the first create's wallet.
|
|
228
|
+
*/
|
|
229
|
+
async function addWallet(
|
|
230
|
+
c: Timing.measure.Context,
|
|
231
|
+
options: addWallet.Options,
|
|
232
|
+
): Promise<Wallet> {
|
|
233
|
+
for (let attempt = 1; ; attempt++) {
|
|
234
|
+
const created = await Timing.measure(
|
|
235
|
+
c,
|
|
236
|
+
client(options.app)
|
|
237
|
+
.wallets()
|
|
238
|
+
.create({
|
|
239
|
+
chain_type: 'ethereum',
|
|
240
|
+
// A retry after a timeout or a 5xx, by the SDK or a later request, returns the wallet that
|
|
241
|
+
// the first attempt created instead of a second one.
|
|
242
|
+
idempotency_key: `tempo-id:first-wallet:${options.privyUserId}`,
|
|
243
|
+
owner: { user_id: options.privyUserId },
|
|
244
|
+
}),
|
|
245
|
+
'privy.wallets.create',
|
|
246
|
+
).catch((error: unknown) => {
|
|
247
|
+
if (attempt < addWallet.attempts && inProgress(error)) return undefined
|
|
248
|
+
throw error
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
if (created)
|
|
252
|
+
return {
|
|
253
|
+
address: created.address as Wallet['address'],
|
|
254
|
+
createdAt: new Date(created.created_at),
|
|
255
|
+
id: created.id,
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
await Timing.measure(
|
|
259
|
+
c,
|
|
260
|
+
new Promise((resolve) => setTimeout(resolve, addWallet.interval)),
|
|
261
|
+
'Privy.addWallet.wait',
|
|
262
|
+
)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
namespace addWallet {
|
|
267
|
+
/** The most creates that one call sends. */
|
|
268
|
+
export const attempts = 10
|
|
269
|
+
|
|
270
|
+
/** The wait between creates, in milliseconds. */
|
|
271
|
+
export const interval = 250
|
|
272
|
+
|
|
273
|
+
export type Options = {
|
|
274
|
+
/** The Privy app that holds the user. */
|
|
275
|
+
app: App
|
|
276
|
+
/** The Privy user's ID, which owns the new wallet. */
|
|
277
|
+
privyUserId: string
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Returns a client for the Privy app `app`. A request waits at most 8 seconds for each of two
|
|
283
|
+
* attempts, so a slow Privy fails the request with `upstream_unavailable` well before the SDK's
|
|
284
|
+
* one-minute default.
|
|
285
|
+
*/
|
|
286
|
+
function client(app: App) {
|
|
287
|
+
return new PrivyClient({
|
|
288
|
+
appId: app.appId,
|
|
289
|
+
appSecret: app.appSecret,
|
|
290
|
+
maxRetries: 1,
|
|
291
|
+
timeout: 8_000,
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** Creates the Privy user for a user ID, without a wallet. */
|
|
296
|
+
async function createUser(
|
|
297
|
+
c: Timing.measure.Context,
|
|
298
|
+
options: createUser.Options,
|
|
299
|
+
) {
|
|
300
|
+
return await Timing.measure(
|
|
301
|
+
c,
|
|
302
|
+
client(options.app)
|
|
303
|
+
.users()
|
|
304
|
+
.create({
|
|
305
|
+
linked_accounts: [
|
|
306
|
+
{ custom_user_id: options.userId, type: 'custom_auth' },
|
|
307
|
+
],
|
|
308
|
+
}),
|
|
309
|
+
'privy.users.create',
|
|
310
|
+
).catch(async (error: unknown) => {
|
|
311
|
+
// A concurrent request may create the user first, so a conflict reads it instead.
|
|
312
|
+
const existing = await Timing.measure(
|
|
313
|
+
c,
|
|
314
|
+
findUser(c, options),
|
|
315
|
+
'Privy.findUser',
|
|
316
|
+
)
|
|
317
|
+
if (!existing) throw error
|
|
318
|
+
return existing
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
declare namespace createUser {
|
|
323
|
+
type Options = {
|
|
324
|
+
/** The Privy app that holds the user. */
|
|
325
|
+
app: App
|
|
326
|
+
/** The user's ID, which Privy stores as the custom auth ID. */
|
|
327
|
+
userId: string
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/** Returns the Privy user for a user ID, or `undefined` when there is none yet. */
|
|
332
|
+
async function findUser(c: Timing.measure.Context, options: findUser.Options) {
|
|
333
|
+
return await Timing.measure(
|
|
334
|
+
c,
|
|
335
|
+
client(options.app)
|
|
336
|
+
.users()
|
|
337
|
+
.getByCustomAuthID({ custom_user_id: options.userId }),
|
|
338
|
+
'privy.users.get',
|
|
339
|
+
).catch((error: unknown) => {
|
|
340
|
+
if (error instanceof Error && 'status' in error && error.status === 404)
|
|
341
|
+
return undefined
|
|
342
|
+
throw error
|
|
343
|
+
})
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
declare namespace findUser {
|
|
347
|
+
type Options = {
|
|
348
|
+
/** The Privy app that holds the user. */
|
|
349
|
+
app: App
|
|
350
|
+
/** The user's ID, which Privy stores as the custom auth ID. */
|
|
351
|
+
userId: string
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Returns whether `error` is Privy's refusal of a create whose idempotency key names a create still
|
|
357
|
+
* in progress. Privy marks it only with a 400 and its message.
|
|
358
|
+
*/
|
|
359
|
+
function inProgress(error: unknown) {
|
|
360
|
+
return (
|
|
361
|
+
error instanceof Error &&
|
|
362
|
+
'status' in error &&
|
|
363
|
+
error.status === 400 &&
|
|
364
|
+
error.message.includes('idempotency key is still in progress')
|
|
365
|
+
)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/** Returns a Privy user's embedded Ethereum wallets, in the order Privy created them. */
|
|
369
|
+
function wallets(
|
|
370
|
+
privyUser: Awaited<ReturnType<typeof createUser>>,
|
|
371
|
+
): readonly Wallet[] {
|
|
372
|
+
return privyUser.linked_accounts
|
|
373
|
+
.flatMap((entry) =>
|
|
374
|
+
entry.type === 'wallet' &&
|
|
375
|
+
'chain_type' in entry &&
|
|
376
|
+
entry.chain_type === 'ethereum' &&
|
|
377
|
+
'connector_type' in entry &&
|
|
378
|
+
entry.connector_type === 'embedded' &&
|
|
379
|
+
'id' in entry &&
|
|
380
|
+
entry.id
|
|
381
|
+
? [{ ...entry, id: entry.id }]
|
|
382
|
+
: [],
|
|
383
|
+
)
|
|
384
|
+
.sort((a, b) => (a.wallet_index ?? 0) - (b.wallet_index ?? 0))
|
|
385
|
+
.reduce<readonly Wallet[]>((list, entry) => {
|
|
386
|
+
// Privy records a wallet's creation as its first verification, in seconds. Without it, the
|
|
387
|
+
// first wallet was created with the user, and a later one after the wallet before it. That
|
|
388
|
+
// time is a lower bound that keeps the wallets in order.
|
|
389
|
+
const createdAt =
|
|
390
|
+
typeof entry.first_verified_at === 'number'
|
|
391
|
+
? new Date(entry.first_verified_at * 1000)
|
|
392
|
+
: (list.at(-1)?.createdAt ?? new Date(privyUser.created_at * 1000))
|
|
393
|
+
return [
|
|
394
|
+
...list,
|
|
395
|
+
{
|
|
396
|
+
address: entry.address as Wallet['address'],
|
|
397
|
+
createdAt,
|
|
398
|
+
id: entry.id,
|
|
399
|
+
},
|
|
400
|
+
]
|
|
401
|
+
}, [])
|
|
402
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The OAuth providers that Tempo ID offers for sign-in, such as Google, and the checks on the page
|
|
3
|
+
* that a provider sign-in returns to. Better Auth's social sign-in runs each provider's flow.
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { eq } from 'drizzle-orm'
|
|
7
|
+
import * as Schema from '../app/db/schema.js'
|
|
8
|
+
import * as ErrorResponse from './ErrorResponse.js'
|
|
9
|
+
import type * as Realm from './Realm.js'
|
|
10
|
+
|
|
11
|
+
/** The page that a provider sign-in returns to is on neither Tempo ID's origin nor the app's. */
|
|
12
|
+
export class ReturnToNotPermittedError extends ErrorResponse.define(
|
|
13
|
+
'return_to_not_permitted',
|
|
14
|
+
) {
|
|
15
|
+
override readonly name = 'Provider.ReturnToNotPermittedError'
|
|
16
|
+
|
|
17
|
+
constructor(options: ReturnToNotPermittedError.Options) {
|
|
18
|
+
super({
|
|
19
|
+
error_description: `Invalid return_to: ${options.origin} is not an origin of the app's redirect URIs. Return to a page on one of them, and pass the app's client_id.`,
|
|
20
|
+
field: 'return_to',
|
|
21
|
+
meta: { origin: options.origin },
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export declare namespace ReturnToNotPermittedError {
|
|
27
|
+
type Options = {
|
|
28
|
+
/** The origin of the refused page. */
|
|
29
|
+
origin: string
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The sign-in names a provider that Tempo ID does not offer. */
|
|
34
|
+
export class UnknownError extends ErrorResponse.define('unknown_provider') {
|
|
35
|
+
override readonly name = 'Provider.UnknownError'
|
|
36
|
+
|
|
37
|
+
constructor(options: UnknownError.Options) {
|
|
38
|
+
super({
|
|
39
|
+
error_description: `Unknown provider: ${options.provider} is not offered. Request GET /v1/auth/providers for the providers offered.`,
|
|
40
|
+
field: 'provider',
|
|
41
|
+
meta: { provider: options.provider },
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export declare namespace UnknownError {
|
|
47
|
+
type Options = {
|
|
48
|
+
/** The provider that the sign-in names. */
|
|
49
|
+
provider: string
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** The ID of an OAuth provider that Tempo ID can offer. */
|
|
54
|
+
export type Provider = keyof typeof names
|
|
55
|
+
|
|
56
|
+
/** The name to show for each provider that Tempo ID can offer, by its ID. */
|
|
57
|
+
export const names = { google: 'Google' } as const
|
|
58
|
+
|
|
59
|
+
/** Returns the providers that `options` configures, in the order a page shows them. */
|
|
60
|
+
export function list(options: list.Options): list.ReturnType {
|
|
61
|
+
return options.google ? [{ id: 'google', name: names.google }] : []
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export declare namespace list {
|
|
65
|
+
type Options = {
|
|
66
|
+
/** Google's OAuth client. Absent, Tempo ID offers no Google sign-in. */
|
|
67
|
+
google?: { clientId: string; clientSecret: string } | undefined
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
type ReturnType = readonly {
|
|
71
|
+
/** The provider's ID. */
|
|
72
|
+
id: Provider
|
|
73
|
+
/** The name to show, such as `Google`. */
|
|
74
|
+
name: string
|
|
75
|
+
}[]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Returns `returnTo` when a provider sign-in may return there: a page on Tempo ID's own origin, or on
|
|
80
|
+
* an origin of a redirect URI of the app with `clientId`. Otherwise returns the refusal.
|
|
81
|
+
*/
|
|
82
|
+
export async function returnTo(
|
|
83
|
+
db: Realm.Database,
|
|
84
|
+
options: returnTo.Options,
|
|
85
|
+
): Promise<string | ErrorResponse.Instance<typeof returnTo.errors>> {
|
|
86
|
+
const { clientId, own } = options
|
|
87
|
+
const url = new URL(options.returnTo, own)
|
|
88
|
+
// A `blob:` URL carries the origin of the page that made it, so only a page's own scheme passes.
|
|
89
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:')
|
|
90
|
+
return new ReturnToNotPermittedError({ origin: url.origin })
|
|
91
|
+
if (url.origin === own) return url.href
|
|
92
|
+
|
|
93
|
+
const [app] = clientId
|
|
94
|
+
? await db
|
|
95
|
+
.select({ redirectUris: Schema.oauthClient.redirectUris })
|
|
96
|
+
.from(Schema.oauthClient)
|
|
97
|
+
.where(eq(Schema.oauthClient.clientId, clientId))
|
|
98
|
+
: []
|
|
99
|
+
const origins = (app?.redirectUris ?? []).flatMap((uri) => {
|
|
100
|
+
const parsed = URL.parse(uri)
|
|
101
|
+
return parsed &&
|
|
102
|
+
(parsed.protocol === 'https:' || parsed.protocol === 'http:')
|
|
103
|
+
? [parsed.origin]
|
|
104
|
+
: []
|
|
105
|
+
})
|
|
106
|
+
if (!origins.includes(url.origin))
|
|
107
|
+
return new ReturnToNotPermittedError({ origin: url.origin })
|
|
108
|
+
return url.href
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export namespace returnTo {
|
|
112
|
+
/** The refusal `returnTo` returns. */
|
|
113
|
+
export const errors = [ReturnToNotPermittedError] as const
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export declare namespace returnTo {
|
|
117
|
+
type Options = {
|
|
118
|
+
/** The client ID of the app that the sign-in names, if any. */
|
|
119
|
+
clientId?: string | undefined
|
|
120
|
+
/** Tempo ID's own origin. */
|
|
121
|
+
own: string
|
|
122
|
+
/** The page to return to, absolute or relative to `own`. */
|
|
123
|
+
returnTo: string
|
|
124
|
+
}
|
|
125
|
+
}
|