@tempoxyz/id 0.0.0-stage → 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -2
- 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-11GtFGrq.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 +79 -3
- 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,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request IDs for the Worker. Each request takes the Ray ID Cloudflare assigned it, or a random UUID
|
|
3
|
+
* without one, and never an ID the client sent. The ID goes out in `X-Request-Id` on every response
|
|
4
|
+
* and as `request_id` in every OAuth error body, so apps can quote it. `Log` records it with each
|
|
5
|
+
* entry, and `Timing` with each request's line.
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import type { Context } from 'hono'
|
|
9
|
+
import { createMiddleware } from 'hono/factory'
|
|
10
|
+
import { requestId } from 'hono/request-id'
|
|
11
|
+
import type { Env } from './Env.js'
|
|
12
|
+
import * as Timing from './Timing.js'
|
|
13
|
+
|
|
14
|
+
/** The codes of a refusal's OAuth error body, which `Timing` logs with the request. */
|
|
15
|
+
export type Refusal = {
|
|
16
|
+
/** The OAuth `error` code. */
|
|
17
|
+
error?: string | undefined
|
|
18
|
+
/** The refusal's `reason`. */
|
|
19
|
+
reason?: string | undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The response header that carries the request ID. */
|
|
23
|
+
export const header = 'X-Request-Id'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Assigns the request ID, and returns it in {@link header} and error bodies. An error body's codes
|
|
27
|
+
* go in `c.var.refusal`. Register it right after `Timing.middleware`, before any other middleware.
|
|
28
|
+
*/
|
|
29
|
+
export function middleware() {
|
|
30
|
+
// `headerName: ''` ignores any `X-Request-Id` the client sends, so logs only hold IDs the Worker
|
|
31
|
+
// chose. It also stops `requestId` from setting the header, which happens below instead.
|
|
32
|
+
const assign = requestId({ generator, headerName: '' })
|
|
33
|
+
|
|
34
|
+
return createMiddleware<Env>(async (c, next) => {
|
|
35
|
+
await assign(c, next)
|
|
36
|
+
|
|
37
|
+
const id = c.var.requestId
|
|
38
|
+
const response = c.res
|
|
39
|
+
const body = failed(response)
|
|
40
|
+
? await Timing.measure(c, read(response), 'response.json')
|
|
41
|
+
: undefined
|
|
42
|
+
if (body) c.set('refusal', annotate(c, { body, id }))
|
|
43
|
+
c.header(header, id)
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Replaces the response with its OAuth error `body` plus `request_id`, and returns the body's
|
|
49
|
+
* `error` and `reason` codes.
|
|
50
|
+
*/
|
|
51
|
+
function annotate(c: Context<Env>, options: annotate.Options): Refusal {
|
|
52
|
+
const response = c.res
|
|
53
|
+
c.res = new Response(
|
|
54
|
+
JSON.stringify({ ...options.body, request_id: options.id }),
|
|
55
|
+
{
|
|
56
|
+
headers: response.headers,
|
|
57
|
+
status: response.status,
|
|
58
|
+
statusText: response.statusText,
|
|
59
|
+
},
|
|
60
|
+
)
|
|
61
|
+
// Hono copies the old response's headers onto the new one, including a stale length.
|
|
62
|
+
c.header('content-length', undefined)
|
|
63
|
+
|
|
64
|
+
// Proxied bodies can hold anything, so only code-shaped values reach the log.
|
|
65
|
+
return {
|
|
66
|
+
error: code(options.body.error),
|
|
67
|
+
reason: code(options.body.reason),
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
declare namespace annotate {
|
|
72
|
+
type Options = {
|
|
73
|
+
/** The OAuth error body. */
|
|
74
|
+
body: Record<string, unknown>
|
|
75
|
+
/** The request ID. */
|
|
76
|
+
id: string
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Returns `value` when it is a short snake-case code, such as an OAuth `error` or a `reason`. */
|
|
81
|
+
function code(value: unknown) {
|
|
82
|
+
return typeof value === 'string' && /^[a-z_]{1,64}$/.test(value)
|
|
83
|
+
? value
|
|
84
|
+
: undefined
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Whether `response` is a JSON error response, which may hold an OAuth error body. */
|
|
88
|
+
function failed(response: Response) {
|
|
89
|
+
return (
|
|
90
|
+
response.status >= 400 &&
|
|
91
|
+
!!response.headers.get('content-type')?.startsWith('application/json')
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The Ray ID when the request carries a well-formed one, or a random UUID. Cloudflare sets `cf-ray`
|
|
97
|
+
* on every request it delivers, replacing any value the client sent.
|
|
98
|
+
*/
|
|
99
|
+
function generator(c: Context) {
|
|
100
|
+
const ray = c.req.header('cf-ray')
|
|
101
|
+
return ray && /^[\da-f]{16}(?:-[A-Z]{3})?$/.test(ray)
|
|
102
|
+
? ray
|
|
103
|
+
: crypto.randomUUID()
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Whether `value` is a plain JSON object. */
|
|
107
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
108
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Reads a copy of `response`'s body as an OAuth error, with a string `error`. */
|
|
112
|
+
async function read(response: Response) {
|
|
113
|
+
const body: unknown = await response
|
|
114
|
+
.clone()
|
|
115
|
+
.json()
|
|
116
|
+
.catch(() => undefined)
|
|
117
|
+
return isRecord(body) && typeof body.error === 'string' ? body : undefined
|
|
118
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Records the grants of keys that the sign-in page showed. A sign-in that continues an app's
|
|
3
|
+
* authorization request with a key grants the key, and spends the request, so a replayed request
|
|
4
|
+
* grants nothing. A sign-in that reaches the account step holds its grant for the session until the
|
|
5
|
+
* user chooses an account. Each record lives in Better Auth's `verification` table.
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { and, eq, gt, sql } from 'drizzle-orm'
|
|
9
|
+
import { Bytes, Hash, Hex } from 'ox'
|
|
10
|
+
import * as z from 'zod'
|
|
11
|
+
import * as Schema from '../app/db/schema.js'
|
|
12
|
+
import type * as Realm from './Realm.js'
|
|
13
|
+
|
|
14
|
+
/** How long a held grant waits for the account step, in seconds. */
|
|
15
|
+
const heldLifetime = 10 * 60
|
|
16
|
+
|
|
17
|
+
/** The prefix of a held grant's `verification` identifier. */
|
|
18
|
+
const heldPrefix = 'sign-in-grant-held:'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* How long a spent request stays recorded when its query names no expiry, in seconds. Better Auth's
|
|
22
|
+
* signed queries expire sooner.
|
|
23
|
+
*/
|
|
24
|
+
const spentLifetime = 60 * 60
|
|
25
|
+
|
|
26
|
+
/** The prefix of a spent request's `verification` identifier. */
|
|
27
|
+
const spentPrefix = 'sign-in-grant-spent:'
|
|
28
|
+
|
|
29
|
+
namespace schema {
|
|
30
|
+
// The one-tap assertion stays opaque here. The route that takes it validates it again.
|
|
31
|
+
export const held = z.object({
|
|
32
|
+
assertion: z.unknown().optional(),
|
|
33
|
+
witness: z.templateLiteral(['0x', z.string()]).optional(),
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Holds the grant of the request `query` for the session with `sessionId`, until the user chooses an
|
|
39
|
+
* account on the account step. A one-tap sign-in holds its assertion and witness too.
|
|
40
|
+
*/
|
|
41
|
+
export async function hold(db: Realm.Database, options: hold.Options) {
|
|
42
|
+
await db.insert(Schema.verification).values({
|
|
43
|
+
expiresAt: new Date(Date.now() + heldLifetime * 1000),
|
|
44
|
+
id: crypto.randomUUID(),
|
|
45
|
+
identifier: heldIdentifier(options),
|
|
46
|
+
value: JSON.stringify(
|
|
47
|
+
schema.held.parse({
|
|
48
|
+
assertion: options.oneTap?.assertion,
|
|
49
|
+
witness: options.oneTap?.witness,
|
|
50
|
+
}),
|
|
51
|
+
),
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export declare namespace hold {
|
|
56
|
+
type Options = {
|
|
57
|
+
/** The one-tap sign-in's assertion and witness, if the sign-in was one. */
|
|
58
|
+
oneTap?:
|
|
59
|
+
| {
|
|
60
|
+
/** The passkey's assertion, as the sign-in received it. */
|
|
61
|
+
assertion: unknown
|
|
62
|
+
/** The witness that the key's digest binds. */
|
|
63
|
+
witness: Hex.Hex
|
|
64
|
+
}
|
|
65
|
+
| undefined
|
|
66
|
+
/** The authorization request, as Better Auth signed it for the account step. */
|
|
67
|
+
query: URLSearchParams
|
|
68
|
+
/** The ID of the session that the sign-in created. */
|
|
69
|
+
sessionId: string
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Returns the identity of an app's authorization request in `query`: the SHA-256 digest of its
|
|
75
|
+
* client ID, redirect URI, `state`, `code_challenge`, `key_authorization`, `challenge`, and `scope`,
|
|
76
|
+
* as hex. Better Auth signs the query again for each page that it sends the browser to, and keeps
|
|
77
|
+
* these parameters. A request that changes any of them, such as one that adds a challenge, has
|
|
78
|
+
* another identity, so it takes no grant of the first.
|
|
79
|
+
*/
|
|
80
|
+
export function identity(query: URLSearchParams) {
|
|
81
|
+
const parts = [
|
|
82
|
+
'client_id',
|
|
83
|
+
'redirect_uri',
|
|
84
|
+
'state',
|
|
85
|
+
'code_challenge',
|
|
86
|
+
'key_authorization',
|
|
87
|
+
'challenge',
|
|
88
|
+
'scope',
|
|
89
|
+
].map((name) => query.get(name) ?? '')
|
|
90
|
+
return Hex.fromBytes(Hash.sha256(Bytes.fromString(JSON.stringify(parts))))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Records the request `query` as spent by a sign-in, until its query expires, and returns whether
|
|
95
|
+
* this call spent it. A request that a sign-in spent before returns `false`, and grants nothing.
|
|
96
|
+
*/
|
|
97
|
+
export async function spend(db: Realm.Database, options: spend.Options) {
|
|
98
|
+
const identifier = spentPrefix + identity(options.query)
|
|
99
|
+
const expires = Number(options.query.get('exp'))
|
|
100
|
+
const expiresAt = new Date(
|
|
101
|
+
Number.isSafeInteger(expires) && expires > 0
|
|
102
|
+
? expires * 1000
|
|
103
|
+
: Date.now() + spentLifetime * 1000,
|
|
104
|
+
)
|
|
105
|
+
return await db.transaction(async (tx) => {
|
|
106
|
+
// The lock serializes the sign-ins of one request, so only the first records it.
|
|
107
|
+
await tx.execute(
|
|
108
|
+
sql`select pg_advisory_xact_lock(hashtextextended(${identifier}, 0))`,
|
|
109
|
+
)
|
|
110
|
+
const [spent] = await tx
|
|
111
|
+
.select({ id: Schema.verification.id })
|
|
112
|
+
.from(Schema.verification)
|
|
113
|
+
.where(
|
|
114
|
+
and(
|
|
115
|
+
eq(Schema.verification.identifier, identifier),
|
|
116
|
+
gt(Schema.verification.expiresAt, new Date()),
|
|
117
|
+
),
|
|
118
|
+
)
|
|
119
|
+
if (spent) return false
|
|
120
|
+
await tx.insert(Schema.verification).values({
|
|
121
|
+
expiresAt,
|
|
122
|
+
id: crypto.randomUUID(),
|
|
123
|
+
identifier,
|
|
124
|
+
value: '{}',
|
|
125
|
+
})
|
|
126
|
+
return true
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export declare namespace spend {
|
|
131
|
+
type Options = {
|
|
132
|
+
/** The authorization request, whose `exp` bounds the record. */
|
|
133
|
+
query: URLSearchParams
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Deletes and returns the grant that a sign-in held for the request `query` and the session with
|
|
139
|
+
* `sessionId`, or `undefined` when none waits. One statement deletes and returns the row, so two
|
|
140
|
+
* concurrent account steps cannot both take it.
|
|
141
|
+
*/
|
|
142
|
+
export async function take(db: Realm.Database, options: take.Options) {
|
|
143
|
+
const [row] = await db
|
|
144
|
+
.delete(Schema.verification)
|
|
145
|
+
.where(
|
|
146
|
+
and(
|
|
147
|
+
eq(Schema.verification.identifier, heldIdentifier(options)),
|
|
148
|
+
gt(Schema.verification.expiresAt, new Date()),
|
|
149
|
+
),
|
|
150
|
+
)
|
|
151
|
+
.returning({ value: Schema.verification.value })
|
|
152
|
+
if (!row) return undefined
|
|
153
|
+
return schema.held.parse(JSON.parse(row.value))
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export declare namespace take {
|
|
157
|
+
type Options = {
|
|
158
|
+
/** The authorization request, as Better Auth signed it after the account step. */
|
|
159
|
+
query: URLSearchParams
|
|
160
|
+
/** The ID of the signed-in session. */
|
|
161
|
+
sessionId: string
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Returns the `verification` identifier of the grant held for a request and a session. */
|
|
166
|
+
function heldIdentifier(options: take.Options) {
|
|
167
|
+
return `${heldPrefix}${identity(options.query)}:${options.sessionId}`
|
|
168
|
+
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The keys that sign Tempo ID's tokens: the JWT plugin's key options, and the rotation that
|
|
3
|
+
* `tempo-id admin rotate-key` runs on the `jwks` table. A rotation writes the row that the plugin
|
|
4
|
+
* writes when it creates a key, with Better Auth's key generation and encryption.
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import type { GenericEndpointContext } from '@better-auth/core'
|
|
8
|
+
import { getCurrentAdapter } from '@better-auth/core/context'
|
|
9
|
+
import { symmetricDecrypt, symmetricEncrypt } from 'better-auth/crypto'
|
|
10
|
+
import { generateExportedKeyPair, type Jwk } from 'better-auth/plugins/jwt'
|
|
11
|
+
import { count, desc, eq, gt, isNull, or, sql } from 'drizzle-orm'
|
|
12
|
+
import { decodeProtectedHeader } from 'jose'
|
|
13
|
+
import * as Schema from '../app/db/schema.js'
|
|
14
|
+
import type * as Realm from './Realm.js'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* As many keys as the JWT plugin reads are live or in their grace period, so the plugin would not
|
|
18
|
+
* read a new key.
|
|
19
|
+
*/
|
|
20
|
+
export class FullError extends Error {
|
|
21
|
+
override readonly name = 'SigningKey.FullError'
|
|
22
|
+
|
|
23
|
+
constructor() {
|
|
24
|
+
super(
|
|
25
|
+
`Too many signing keys: ${capacity} keys are live or in their 30-day grace period. Rotate again once the oldest grace period ends.`,
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** The table holds no signing key yet, so a rotation has no key to retire. */
|
|
31
|
+
export class MissingError extends Error {
|
|
32
|
+
override readonly name = 'SigningKey.MissingError'
|
|
33
|
+
|
|
34
|
+
constructor() {
|
|
35
|
+
super(
|
|
36
|
+
'No signing key exists. Tempo ID creates the first key when it signs its first token.',
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** The secret does not decrypt the current signing key, so the Worker could not use a new one. */
|
|
42
|
+
export class SecretError extends Error {
|
|
43
|
+
override readonly name = 'SigningKey.SecretError'
|
|
44
|
+
|
|
45
|
+
constructor() {
|
|
46
|
+
super(
|
|
47
|
+
"Invalid SECRET: it does not decrypt the current signing key. Set SECRET to the deployment's SECRET variable.",
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Seconds that `GET /oauth2/jwks` serves a key after it stops signing, so verifiers accept the tokens
|
|
54
|
+
* that it signed before. This is Better Auth's default, 30 days.
|
|
55
|
+
*/
|
|
56
|
+
export const gracePeriod = 60 * 60 * 24 * 30
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Seconds between a rotation and the first token that the new key signs. `GET /oauth2/jwks` serves
|
|
60
|
+
* the new key at once, so a verifier that caches the key set, with a refetch cooldown such as jose's
|
|
61
|
+
* 30 seconds, holds the key before any token names it.
|
|
62
|
+
*/
|
|
63
|
+
export const publication = 5 * 60
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The most keys that the JWT plugin reads: Better Auth's default limit on a read. A rotation keeps
|
|
67
|
+
* the live keys and the keys in their grace period within it.
|
|
68
|
+
*/
|
|
69
|
+
export const capacity = 100
|
|
70
|
+
|
|
71
|
+
/** The JWT plugin's `jwks` options. RS256, since Privy and the existing verifiers accept it. */
|
|
72
|
+
export const jwks = {
|
|
73
|
+
gracePeriod,
|
|
74
|
+
jwksPath: '/oauth2/jwks',
|
|
75
|
+
keyPairConfig: { alg: 'RS256' as const, modulusLength: 2048 },
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The JWT plugin's read of the `jwks` table: every live key, and every key in its grace period.
|
|
80
|
+
* Better Auth's own read returns any 100 rows, and a rotation backdates each new key's `createdAt`,
|
|
81
|
+
* so neither row order nor creation time can pick the keys once retired rows build up.
|
|
82
|
+
*/
|
|
83
|
+
export const adapter = {
|
|
84
|
+
getJwks: async (ctx: GenericEndpointContext) =>
|
|
85
|
+
await (
|
|
86
|
+
await getCurrentAdapter(ctx.context.adapter)
|
|
87
|
+
).findMany<Jwk>({
|
|
88
|
+
limit: capacity,
|
|
89
|
+
model: 'jwks',
|
|
90
|
+
sortBy: { direction: 'desc', field: 'createdAt' },
|
|
91
|
+
where: [
|
|
92
|
+
{ connector: 'OR', field: 'expiresAt', value: null },
|
|
93
|
+
{
|
|
94
|
+
connector: 'OR',
|
|
95
|
+
field: 'expiresAt',
|
|
96
|
+
operator: 'gt',
|
|
97
|
+
value: new Date(Date.now() - gracePeriod * 1000),
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
}),
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Returns the public key that an ID token hint names in its `kid` header, as a key set, retired keys
|
|
105
|
+
* included, past the grace period too. Logout verifies the hint against it, since a session can
|
|
106
|
+
* outlast the grace period of the key that signed its ID token. A hint without a `kid`, or with an
|
|
107
|
+
* unknown one, returns an empty set. Tokens that grant access verify only against the keys that
|
|
108
|
+
* `GET /oauth2/jwks` serves.
|
|
109
|
+
*/
|
|
110
|
+
export async function hintKeys(
|
|
111
|
+
db: Realm.Database,
|
|
112
|
+
options: hintKeys.Options,
|
|
113
|
+
): Promise<hintKeys.ReturnType> {
|
|
114
|
+
// The header is read before the signature is checked, so a forged hint costs one indexed read.
|
|
115
|
+
const kid = (() => {
|
|
116
|
+
try {
|
|
117
|
+
return decodeProtectedHeader(options.hint).kid
|
|
118
|
+
} catch {
|
|
119
|
+
return undefined
|
|
120
|
+
}
|
|
121
|
+
})()
|
|
122
|
+
if (!kid) return { keys: [] }
|
|
123
|
+
|
|
124
|
+
const rows = await db
|
|
125
|
+
.select()
|
|
126
|
+
.from(Schema.jwks)
|
|
127
|
+
.where(eq(Schema.jwks.id, kid))
|
|
128
|
+
.limit(1)
|
|
129
|
+
return {
|
|
130
|
+
keys: rows.map((row) => ({
|
|
131
|
+
...(JSON.parse(row.publicKey) as JsonWebKey),
|
|
132
|
+
alg: row.alg ?? jwks.keyPairConfig.alg,
|
|
133
|
+
kid: row.id,
|
|
134
|
+
})),
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export declare namespace hintKeys {
|
|
139
|
+
type Options = {
|
|
140
|
+
/** The ID token hint, whose `kid` header names its signing key. */
|
|
141
|
+
hint: string
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
type ReturnType = {
|
|
145
|
+
/** Each public key, with its ID as `kid`. */
|
|
146
|
+
keys: (JsonWebKey & {
|
|
147
|
+
/** The key's ID, which each token that it signed names as `kid`. */
|
|
148
|
+
kid: string
|
|
149
|
+
})[]
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Adds a new signing key, which signs every token after the {@link publication} delay, and retires
|
|
155
|
+
* every earlier key that is still live at the end of that delay. `GET /oauth2/jwks` serves the new key
|
|
156
|
+
* at once, and serves each retired key until its grace period ends.
|
|
157
|
+
*
|
|
158
|
+
* Throws `MissingError` when no key exists, `SecretError` when `secret` does not decrypt the current
|
|
159
|
+
* key, and `FullError` when `capacity` keys are live or in their grace period.
|
|
160
|
+
*/
|
|
161
|
+
export async function rotate(
|
|
162
|
+
db: Realm.Database,
|
|
163
|
+
options: rotate.Options,
|
|
164
|
+
): Promise<rotate.ReturnType> {
|
|
165
|
+
const { secret } = options
|
|
166
|
+
|
|
167
|
+
return await db.transaction(async (tx) => {
|
|
168
|
+
// Serializes rotations, and keeps the Worker from creating a key between the read and the writes.
|
|
169
|
+
// Reads proceed, so the Worker signs with the current key until the commit.
|
|
170
|
+
await tx.execute(sql`lock table ${Schema.jwks} in share row exclusive mode`)
|
|
171
|
+
|
|
172
|
+
// The database's clock, which every deployment shares, so a skewed clock on the machine that
|
|
173
|
+
// runs the command cannot end the publication delay early. `clock_timestamp()` reads it after the
|
|
174
|
+
// lock, where `now()` would return the transaction's start and count the wait for the lock.
|
|
175
|
+
const [clock] = await tx
|
|
176
|
+
.select({
|
|
177
|
+
now: sql<number>`(extract(epoch from clock_timestamp()) * 1000)::float8`,
|
|
178
|
+
})
|
|
179
|
+
.from(Schema.jwks)
|
|
180
|
+
.limit(1)
|
|
181
|
+
if (!clock) throw new MissingError()
|
|
182
|
+
const now = new Date(Number(clock.now))
|
|
183
|
+
const signsFrom = new Date(now.getTime() + publication * 1000)
|
|
184
|
+
const live = await tx
|
|
185
|
+
.select()
|
|
186
|
+
.from(Schema.jwks)
|
|
187
|
+
.where(or(isNull(Schema.jwks.expiresAt), gt(Schema.jwks.expiresAt, now)))
|
|
188
|
+
.orderBy(desc(Schema.jwks.createdAt))
|
|
189
|
+
const [current] = live
|
|
190
|
+
const oldest = live.at(-1)
|
|
191
|
+
if (!current || !oldest) throw new MissingError()
|
|
192
|
+
|
|
193
|
+
// A key encrypted with another secret would fail every signature, so the rotation checks first.
|
|
194
|
+
const decrypted = await symmetricDecrypt({
|
|
195
|
+
data: JSON.parse(current.privateKey) as string,
|
|
196
|
+
key: secret,
|
|
197
|
+
}).catch(() => undefined)
|
|
198
|
+
if (decrypted === undefined) throw new SecretError()
|
|
199
|
+
|
|
200
|
+
// The read returns at most `capacity` rows, and a rotated key sorts last, so one more would hide it.
|
|
201
|
+
// The Worker applies the grace cutoff by its own clock, so the count also includes the keys whose
|
|
202
|
+
// grace period ended up to `publication` seconds ago, in case that clock is behind the database's.
|
|
203
|
+
const [served] = await tx
|
|
204
|
+
.select({ count: count() })
|
|
205
|
+
.from(Schema.jwks)
|
|
206
|
+
.where(
|
|
207
|
+
or(
|
|
208
|
+
isNull(Schema.jwks.expiresAt),
|
|
209
|
+
gt(
|
|
210
|
+
Schema.jwks.expiresAt,
|
|
211
|
+
new Date(now.getTime() - (gracePeriod + publication) * 1000),
|
|
212
|
+
),
|
|
213
|
+
),
|
|
214
|
+
)
|
|
215
|
+
if (served!.count >= capacity) throw new FullError()
|
|
216
|
+
|
|
217
|
+
const pair = await generateExportedKeyPair({ jwks })
|
|
218
|
+
const [key] = await tx
|
|
219
|
+
.insert(Schema.jwks)
|
|
220
|
+
.values({
|
|
221
|
+
alg: pair.alg,
|
|
222
|
+
// Better Auth signs with the live key of the latest `createdAt`. A `createdAt` before every
|
|
223
|
+
// live key's keeps the new key from signing until the earlier keys expire at `signsFrom`.
|
|
224
|
+
createdAt: new Date(oldest.createdAt.getTime() - 1),
|
|
225
|
+
id: crypto.randomUUID(),
|
|
226
|
+
// The JWT plugin stores the encrypted key as a JSON string.
|
|
227
|
+
privateKey: JSON.stringify(
|
|
228
|
+
await symmetricEncrypt({
|
|
229
|
+
data: JSON.stringify(pair.privateWebKey),
|
|
230
|
+
key: secret,
|
|
231
|
+
}),
|
|
232
|
+
),
|
|
233
|
+
publicKey: JSON.stringify(pair.publicWebKey),
|
|
234
|
+
})
|
|
235
|
+
.returning({ id: Schema.jwks.id })
|
|
236
|
+
|
|
237
|
+
// A key that an earlier rotation already retires keeps its earlier expiry.
|
|
238
|
+
const retired = live.map((entry) => ({
|
|
239
|
+
expiresAt:
|
|
240
|
+
entry.expiresAt && entry.expiresAt < signsFrom
|
|
241
|
+
? entry.expiresAt
|
|
242
|
+
: signsFrom,
|
|
243
|
+
id: entry.id,
|
|
244
|
+
}))
|
|
245
|
+
for (const entry of retired)
|
|
246
|
+
await tx
|
|
247
|
+
.update(Schema.jwks)
|
|
248
|
+
.set({ expiresAt: entry.expiresAt })
|
|
249
|
+
.where(eq(Schema.jwks.id, entry.id))
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
key: { id: key!.id, signsFrom },
|
|
253
|
+
retired: retired.map((entry) => ({
|
|
254
|
+
id: entry.id,
|
|
255
|
+
servedUntil: new Date(entry.expiresAt.getTime() + gracePeriod * 1000),
|
|
256
|
+
signsUntil: entry.expiresAt,
|
|
257
|
+
})),
|
|
258
|
+
}
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export declare namespace rotate {
|
|
263
|
+
type Options = {
|
|
264
|
+
/** The deployment's `SECRET` variable, which encrypts each private key. */
|
|
265
|
+
secret: string
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
type ReturnType = {
|
|
269
|
+
/** The new signing key. */
|
|
270
|
+
key: {
|
|
271
|
+
/** The key's ID, which each token names as `kid`. */
|
|
272
|
+
id: string
|
|
273
|
+
/** When the key signs its first token, after the publication delay. */
|
|
274
|
+
signsFrom: Date
|
|
275
|
+
}
|
|
276
|
+
/** The keys that the rotation retires, newest first. */
|
|
277
|
+
retired: readonly {
|
|
278
|
+
/** The key's ID. */
|
|
279
|
+
id: string
|
|
280
|
+
/** When `GET /oauth2/jwks` stops serving the key. */
|
|
281
|
+
servedUntil: Date
|
|
282
|
+
/** When the key signs its last token. */
|
|
283
|
+
signsUntil: Date
|
|
284
|
+
}[]
|
|
285
|
+
}
|
|
286
|
+
}
|