@hammadj/better-auth 1.5.0-beta.10
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 +33 -0
- package/dist/_virtual/rolldown_runtime.mjs +36 -0
- package/dist/adapters/drizzle-adapter/index.d.mts +1 -0
- package/dist/adapters/drizzle-adapter/index.mjs +3 -0
- package/dist/adapters/index.d.mts +23 -0
- package/dist/adapters/index.mjs +13 -0
- package/dist/adapters/index.mjs.map +1 -0
- package/dist/adapters/kysely-adapter/index.d.mts +1 -0
- package/dist/adapters/kysely-adapter/index.mjs +3 -0
- package/dist/adapters/memory-adapter/index.d.mts +1 -0
- package/dist/adapters/memory-adapter/index.mjs +3 -0
- package/dist/adapters/mongodb-adapter/index.d.mts +1 -0
- package/dist/adapters/mongodb-adapter/index.mjs +3 -0
- package/dist/adapters/prisma-adapter/index.d.mts +1 -0
- package/dist/adapters/prisma-adapter/index.mjs +3 -0
- package/dist/api/index.d.mts +40 -0
- package/dist/api/index.mjs +205 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/api/middlewares/index.d.mts +1 -0
- package/dist/api/middlewares/index.mjs +3 -0
- package/dist/api/middlewares/origin-check.d.mts +17 -0
- package/dist/api/middlewares/origin-check.mjs +140 -0
- package/dist/api/middlewares/origin-check.mjs.map +1 -0
- package/dist/api/rate-limiter/index.mjs +177 -0
- package/dist/api/rate-limiter/index.mjs.map +1 -0
- package/dist/api/routes/account.d.mts +10 -0
- package/dist/api/routes/account.mjs +493 -0
- package/dist/api/routes/account.mjs.map +1 -0
- package/dist/api/routes/callback.d.mts +5 -0
- package/dist/api/routes/callback.mjs +178 -0
- package/dist/api/routes/callback.mjs.map +1 -0
- package/dist/api/routes/email-verification.d.mts +29 -0
- package/dist/api/routes/email-verification.mjs +301 -0
- package/dist/api/routes/email-verification.mjs.map +1 -0
- package/dist/api/routes/error.d.mts +5 -0
- package/dist/api/routes/error.mjs +386 -0
- package/dist/api/routes/error.mjs.map +1 -0
- package/dist/api/routes/index.d.mts +11 -0
- package/dist/api/routes/index.mjs +13 -0
- package/dist/api/routes/ok.d.mts +5 -0
- package/dist/api/routes/ok.mjs +30 -0
- package/dist/api/routes/ok.mjs.map +1 -0
- package/dist/api/routes/password.d.mts +8 -0
- package/dist/api/routes/password.mjs +198 -0
- package/dist/api/routes/password.mjs.map +1 -0
- package/dist/api/routes/session.d.mts +52 -0
- package/dist/api/routes/session.mjs +478 -0
- package/dist/api/routes/session.mjs.map +1 -0
- package/dist/api/routes/sign-in.d.mts +8 -0
- package/dist/api/routes/sign-in.mjs +262 -0
- package/dist/api/routes/sign-in.mjs.map +1 -0
- package/dist/api/routes/sign-out.d.mts +5 -0
- package/dist/api/routes/sign-out.mjs +33 -0
- package/dist/api/routes/sign-out.mjs.map +1 -0
- package/dist/api/routes/sign-up.d.mts +7 -0
- package/dist/api/routes/sign-up.mjs +227 -0
- package/dist/api/routes/sign-up.mjs.map +1 -0
- package/dist/api/routes/update-user.d.mts +12 -0
- package/dist/api/routes/update-user.mjs +493 -0
- package/dist/api/routes/update-user.mjs.map +1 -0
- package/dist/api/state/oauth.d.mts +5 -0
- package/dist/api/state/oauth.mjs +8 -0
- package/dist/api/state/oauth.mjs.map +1 -0
- package/dist/api/state/should-session-refresh.d.mts +13 -0
- package/dist/api/state/should-session-refresh.mjs +16 -0
- package/dist/api/state/should-session-refresh.mjs.map +1 -0
- package/dist/api/to-auth-endpoints.mjs +197 -0
- package/dist/api/to-auth-endpoints.mjs.map +1 -0
- package/dist/auth/base.mjs +44 -0
- package/dist/auth/base.mjs.map +1 -0
- package/dist/auth/full.d.mts +30 -0
- package/dist/auth/full.mjs +32 -0
- package/dist/auth/full.mjs.map +1 -0
- package/dist/auth/minimal.d.mts +12 -0
- package/dist/auth/minimal.mjs +14 -0
- package/dist/auth/minimal.mjs.map +1 -0
- package/dist/auth/trusted-origins.mjs +31 -0
- package/dist/auth/trusted-origins.mjs.map +1 -0
- package/dist/client/broadcast-channel.d.mts +20 -0
- package/dist/client/broadcast-channel.mjs +46 -0
- package/dist/client/broadcast-channel.mjs.map +1 -0
- package/dist/client/config.mjs +90 -0
- package/dist/client/config.mjs.map +1 -0
- package/dist/client/fetch-plugins.mjs +18 -0
- package/dist/client/fetch-plugins.mjs.map +1 -0
- package/dist/client/focus-manager.d.mts +11 -0
- package/dist/client/focus-manager.mjs +32 -0
- package/dist/client/focus-manager.mjs.map +1 -0
- package/dist/client/index.d.mts +30 -0
- package/dist/client/index.mjs +21 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/client/lynx/index.d.mts +62 -0
- package/dist/client/lynx/index.mjs +24 -0
- package/dist/client/lynx/index.mjs.map +1 -0
- package/dist/client/lynx/lynx-store.d.mts +47 -0
- package/dist/client/lynx/lynx-store.mjs +47 -0
- package/dist/client/lynx/lynx-store.mjs.map +1 -0
- package/dist/client/online-manager.d.mts +12 -0
- package/dist/client/online-manager.mjs +35 -0
- package/dist/client/online-manager.mjs.map +1 -0
- package/dist/client/parser.mjs +73 -0
- package/dist/client/parser.mjs.map +1 -0
- package/dist/client/path-to-object.d.mts +57 -0
- package/dist/client/plugins/index.d.mts +58 -0
- package/dist/client/plugins/index.mjs +33 -0
- package/dist/client/plugins/infer-plugin.d.mts +9 -0
- package/dist/client/plugins/infer-plugin.mjs +11 -0
- package/dist/client/plugins/infer-plugin.mjs.map +1 -0
- package/dist/client/proxy.mjs +79 -0
- package/dist/client/proxy.mjs.map +1 -0
- package/dist/client/query.d.mts +23 -0
- package/dist/client/query.mjs +98 -0
- package/dist/client/query.mjs.map +1 -0
- package/dist/client/react/index.d.mts +63 -0
- package/dist/client/react/index.mjs +24 -0
- package/dist/client/react/index.mjs.map +1 -0
- package/dist/client/react/react-store.d.mts +47 -0
- package/dist/client/react/react-store.mjs +47 -0
- package/dist/client/react/react-store.mjs.map +1 -0
- package/dist/client/session-atom.mjs +29 -0
- package/dist/client/session-atom.mjs.map +1 -0
- package/dist/client/session-refresh.d.mts +28 -0
- package/dist/client/session-refresh.mjs +140 -0
- package/dist/client/session-refresh.mjs.map +1 -0
- package/dist/client/solid/index.d.mts +57 -0
- package/dist/client/solid/index.mjs +22 -0
- package/dist/client/solid/index.mjs.map +1 -0
- package/dist/client/solid/solid-store.mjs +24 -0
- package/dist/client/solid/solid-store.mjs.map +1 -0
- package/dist/client/svelte/index.d.mts +63 -0
- package/dist/client/svelte/index.mjs +20 -0
- package/dist/client/svelte/index.mjs.map +1 -0
- package/dist/client/types.d.mts +58 -0
- package/dist/client/vanilla.d.mts +62 -0
- package/dist/client/vanilla.mjs +20 -0
- package/dist/client/vanilla.mjs.map +1 -0
- package/dist/client/vue/index.d.mts +86 -0
- package/dist/client/vue/index.mjs +38 -0
- package/dist/client/vue/index.mjs.map +1 -0
- package/dist/client/vue/vue-store.mjs +26 -0
- package/dist/client/vue/vue-store.mjs.map +1 -0
- package/dist/context/create-context.mjs +211 -0
- package/dist/context/create-context.mjs.map +1 -0
- package/dist/context/helpers.mjs +62 -0
- package/dist/context/helpers.mjs.map +1 -0
- package/dist/context/init-minimal.mjs +20 -0
- package/dist/context/init-minimal.mjs.map +1 -0
- package/dist/context/init.mjs +22 -0
- package/dist/context/init.mjs.map +1 -0
- package/dist/cookies/cookie-utils.d.mts +29 -0
- package/dist/cookies/cookie-utils.mjs +105 -0
- package/dist/cookies/cookie-utils.mjs.map +1 -0
- package/dist/cookies/index.d.mts +67 -0
- package/dist/cookies/index.mjs +264 -0
- package/dist/cookies/index.mjs.map +1 -0
- package/dist/cookies/session-store.d.mts +36 -0
- package/dist/cookies/session-store.mjs +200 -0
- package/dist/cookies/session-store.mjs.map +1 -0
- package/dist/crypto/buffer.d.mts +8 -0
- package/dist/crypto/buffer.mjs +18 -0
- package/dist/crypto/buffer.mjs.map +1 -0
- package/dist/crypto/index.d.mts +27 -0
- package/dist/crypto/index.mjs +38 -0
- package/dist/crypto/index.mjs.map +1 -0
- package/dist/crypto/jwt.d.mts +8 -0
- package/dist/crypto/jwt.mjs +95 -0
- package/dist/crypto/jwt.mjs.map +1 -0
- package/dist/crypto/password.d.mts +12 -0
- package/dist/crypto/password.mjs +36 -0
- package/dist/crypto/password.mjs.map +1 -0
- package/dist/crypto/random.d.mts +5 -0
- package/dist/crypto/random.mjs +8 -0
- package/dist/crypto/random.mjs.map +1 -0
- package/dist/db/adapter-base.d.mts +8 -0
- package/dist/db/adapter-base.mjs +28 -0
- package/dist/db/adapter-base.mjs.map +1 -0
- package/dist/db/adapter-kysely.d.mts +8 -0
- package/dist/db/adapter-kysely.mjs +21 -0
- package/dist/db/adapter-kysely.mjs.map +1 -0
- package/dist/db/field-converter.d.mts +8 -0
- package/dist/db/field-converter.mjs +21 -0
- package/dist/db/field-converter.mjs.map +1 -0
- package/dist/db/field.d.mts +55 -0
- package/dist/db/field.mjs +11 -0
- package/dist/db/field.mjs.map +1 -0
- package/dist/db/get-migration.d.mts +23 -0
- package/dist/db/get-migration.mjs +339 -0
- package/dist/db/get-migration.mjs.map +1 -0
- package/dist/db/get-schema.d.mts +11 -0
- package/dist/db/get-schema.mjs +39 -0
- package/dist/db/get-schema.mjs.map +1 -0
- package/dist/db/index.d.mts +9 -0
- package/dist/db/index.mjs +36 -0
- package/dist/db/index.mjs.map +1 -0
- package/dist/db/internal-adapter.d.mts +14 -0
- package/dist/db/internal-adapter.mjs +616 -0
- package/dist/db/internal-adapter.mjs.map +1 -0
- package/dist/db/schema.d.mts +26 -0
- package/dist/db/schema.mjs +118 -0
- package/dist/db/schema.mjs.map +1 -0
- package/dist/db/to-zod.d.mts +36 -0
- package/dist/db/to-zod.mjs +26 -0
- package/dist/db/to-zod.mjs.map +1 -0
- package/dist/db/verification-token-storage.mjs +28 -0
- package/dist/db/verification-token-storage.mjs.map +1 -0
- package/dist/db/with-hooks.d.mts +33 -0
- package/dist/db/with-hooks.mjs +159 -0
- package/dist/db/with-hooks.mjs.map +1 -0
- package/dist/index.d.mts +52 -0
- package/dist/index.mjs +26 -0
- package/dist/integrations/next-js.d.mts +14 -0
- package/dist/integrations/next-js.mjs +78 -0
- package/dist/integrations/next-js.mjs.map +1 -0
- package/dist/integrations/node.d.mts +13 -0
- package/dist/integrations/node.mjs +16 -0
- package/dist/integrations/node.mjs.map +1 -0
- package/dist/integrations/solid-start.d.mts +23 -0
- package/dist/integrations/solid-start.mjs +17 -0
- package/dist/integrations/solid-start.mjs.map +1 -0
- package/dist/integrations/svelte-kit.d.mts +29 -0
- package/dist/integrations/svelte-kit.mjs +57 -0
- package/dist/integrations/svelte-kit.mjs.map +1 -0
- package/dist/integrations/tanstack-start-solid.d.mts +22 -0
- package/dist/integrations/tanstack-start-solid.mjs +61 -0
- package/dist/integrations/tanstack-start-solid.mjs.map +1 -0
- package/dist/integrations/tanstack-start.d.mts +22 -0
- package/dist/integrations/tanstack-start.mjs +61 -0
- package/dist/integrations/tanstack-start.mjs.map +1 -0
- package/dist/oauth2/index.d.mts +5 -0
- package/dist/oauth2/index.mjs +7 -0
- package/dist/oauth2/link-account.d.mts +31 -0
- package/dist/oauth2/link-account.mjs +144 -0
- package/dist/oauth2/link-account.mjs.map +1 -0
- package/dist/oauth2/state.d.mts +26 -0
- package/dist/oauth2/state.mjs +51 -0
- package/dist/oauth2/state.mjs.map +1 -0
- package/dist/oauth2/utils.d.mts +8 -0
- package/dist/oauth2/utils.mjs +31 -0
- package/dist/oauth2/utils.mjs.map +1 -0
- package/dist/plugins/access/access.d.mts +30 -0
- package/dist/plugins/access/access.mjs +46 -0
- package/dist/plugins/access/access.mjs.map +1 -0
- package/dist/plugins/access/index.d.mts +3 -0
- package/dist/plugins/access/index.mjs +3 -0
- package/dist/plugins/access/types.d.mts +17 -0
- package/dist/plugins/additional-fields/client.d.mts +14 -0
- package/dist/plugins/additional-fields/client.mjs +11 -0
- package/dist/plugins/additional-fields/client.mjs.map +1 -0
- package/dist/plugins/admin/access/index.d.mts +2 -0
- package/dist/plugins/admin/access/index.mjs +3 -0
- package/dist/plugins/admin/access/statement.d.mts +118 -0
- package/dist/plugins/admin/access/statement.mjs +53 -0
- package/dist/plugins/admin/access/statement.mjs.map +1 -0
- package/dist/plugins/admin/admin.d.mts +14 -0
- package/dist/plugins/admin/admin.mjs +95 -0
- package/dist/plugins/admin/admin.mjs.map +1 -0
- package/dist/plugins/admin/client.d.mts +14 -0
- package/dist/plugins/admin/client.mjs +36 -0
- package/dist/plugins/admin/client.mjs.map +1 -0
- package/dist/plugins/admin/error-codes.d.mts +5 -0
- package/dist/plugins/admin/error-codes.mjs +30 -0
- package/dist/plugins/admin/error-codes.mjs.map +1 -0
- package/dist/plugins/admin/has-permission.mjs +16 -0
- package/dist/plugins/admin/has-permission.mjs.map +1 -0
- package/dist/plugins/admin/index.d.mts +3 -0
- package/dist/plugins/admin/index.mjs +3 -0
- package/dist/plugins/admin/routes.mjs +855 -0
- package/dist/plugins/admin/routes.mjs.map +1 -0
- package/dist/plugins/admin/schema.d.mts +6 -0
- package/dist/plugins/admin/schema.mjs +34 -0
- package/dist/plugins/admin/schema.mjs.map +1 -0
- package/dist/plugins/admin/types.d.mts +89 -0
- package/dist/plugins/anonymous/client.d.mts +9 -0
- package/dist/plugins/anonymous/client.mjs +22 -0
- package/dist/plugins/anonymous/client.mjs.map +1 -0
- package/dist/plugins/anonymous/error-codes.d.mts +5 -0
- package/dist/plugins/anonymous/error-codes.mjs +16 -0
- package/dist/plugins/anonymous/error-codes.mjs.map +1 -0
- package/dist/plugins/anonymous/index.d.mts +14 -0
- package/dist/plugins/anonymous/index.mjs +163 -0
- package/dist/plugins/anonymous/index.mjs.map +1 -0
- package/dist/plugins/anonymous/schema.d.mts +5 -0
- package/dist/plugins/anonymous/schema.mjs +11 -0
- package/dist/plugins/anonymous/schema.mjs.map +1 -0
- package/dist/plugins/anonymous/types.d.mts +68 -0
- package/dist/plugins/api-key/adapter.mjs +468 -0
- package/dist/plugins/api-key/adapter.mjs.map +1 -0
- package/dist/plugins/api-key/client.d.mts +9 -0
- package/dist/plugins/api-key/client.mjs +19 -0
- package/dist/plugins/api-key/client.mjs.map +1 -0
- package/dist/plugins/api-key/error-codes.d.mts +5 -0
- package/dist/plugins/api-key/error-codes.mjs +34 -0
- package/dist/plugins/api-key/error-codes.mjs.map +1 -0
- package/dist/plugins/api-key/index.d.mts +17 -0
- package/dist/plugins/api-key/index.mjs +134 -0
- package/dist/plugins/api-key/index.mjs.map +1 -0
- package/dist/plugins/api-key/rate-limit.mjs +74 -0
- package/dist/plugins/api-key/rate-limit.mjs.map +1 -0
- package/dist/plugins/api-key/routes/create-api-key.mjs +252 -0
- package/dist/plugins/api-key/routes/create-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/routes/delete-all-expired-api-keys.mjs +24 -0
- package/dist/plugins/api-key/routes/delete-all-expired-api-keys.mjs.map +1 -0
- package/dist/plugins/api-key/routes/delete-api-key.mjs +74 -0
- package/dist/plugins/api-key/routes/delete-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/routes/get-api-key.mjs +158 -0
- package/dist/plugins/api-key/routes/get-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/routes/index.mjs +71 -0
- package/dist/plugins/api-key/routes/index.mjs.map +1 -0
- package/dist/plugins/api-key/routes/list-api-keys.mjs +194 -0
- package/dist/plugins/api-key/routes/list-api-keys.mjs.map +1 -0
- package/dist/plugins/api-key/routes/update-api-key.mjs +248 -0
- package/dist/plugins/api-key/routes/update-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/routes/verify-api-key.mjs +223 -0
- package/dist/plugins/api-key/routes/verify-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/schema.d.mts +11 -0
- package/dist/plugins/api-key/schema.mjs +130 -0
- package/dist/plugins/api-key/schema.mjs.map +1 -0
- package/dist/plugins/api-key/types.d.mts +346 -0
- package/dist/plugins/bearer/index.d.mts +25 -0
- package/dist/plugins/bearer/index.mjs +66 -0
- package/dist/plugins/bearer/index.mjs.map +1 -0
- package/dist/plugins/captcha/constants.d.mts +10 -0
- package/dist/plugins/captcha/constants.mjs +22 -0
- package/dist/plugins/captcha/constants.mjs.map +1 -0
- package/dist/plugins/captcha/error-codes.mjs +16 -0
- package/dist/plugins/captcha/error-codes.mjs.map +1 -0
- package/dist/plugins/captcha/index.d.mts +14 -0
- package/dist/plugins/captcha/index.mjs +60 -0
- package/dist/plugins/captcha/index.mjs.map +1 -0
- package/dist/plugins/captcha/types.d.mts +28 -0
- package/dist/plugins/captcha/utils.mjs +11 -0
- package/dist/plugins/captcha/utils.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/captchafox.mjs +27 -0
- package/dist/plugins/captcha/verify-handlers/captchafox.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +25 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +29 -0
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +27 -0
- package/dist/plugins/captcha/verify-handlers/h-captcha.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/index.mjs +6 -0
- package/dist/plugins/custom-session/client.d.mts +10 -0
- package/dist/plugins/custom-session/client.mjs +11 -0
- package/dist/plugins/custom-session/client.mjs.map +1 -0
- package/dist/plugins/custom-session/index.d.mts +26 -0
- package/dist/plugins/custom-session/index.mjs +70 -0
- package/dist/plugins/custom-session/index.mjs.map +1 -0
- package/dist/plugins/device-authorization/client.d.mts +5 -0
- package/dist/plugins/device-authorization/client.mjs +18 -0
- package/dist/plugins/device-authorization/client.mjs.map +1 -0
- package/dist/plugins/device-authorization/error-codes.mjs +21 -0
- package/dist/plugins/device-authorization/error-codes.mjs.map +1 -0
- package/dist/plugins/device-authorization/index.d.mts +28 -0
- package/dist/plugins/device-authorization/index.mjs +50 -0
- package/dist/plugins/device-authorization/index.mjs.map +1 -0
- package/dist/plugins/device-authorization/routes.mjs +510 -0
- package/dist/plugins/device-authorization/routes.mjs.map +1 -0
- package/dist/plugins/device-authorization/schema.mjs +57 -0
- package/dist/plugins/device-authorization/schema.mjs.map +1 -0
- package/dist/plugins/email-otp/client.d.mts +7 -0
- package/dist/plugins/email-otp/client.mjs +18 -0
- package/dist/plugins/email-otp/client.mjs.map +1 -0
- package/dist/plugins/email-otp/error-codes.d.mts +5 -0
- package/dist/plugins/email-otp/error-codes.mjs +12 -0
- package/dist/plugins/email-otp/error-codes.mjs.map +1 -0
- package/dist/plugins/email-otp/index.d.mts +14 -0
- package/dist/plugins/email-otp/index.mjs +108 -0
- package/dist/plugins/email-otp/index.mjs.map +1 -0
- package/dist/plugins/email-otp/otp-token.mjs +29 -0
- package/dist/plugins/email-otp/otp-token.mjs.map +1 -0
- package/dist/plugins/email-otp/routes.mjs +564 -0
- package/dist/plugins/email-otp/routes.mjs.map +1 -0
- package/dist/plugins/email-otp/types.d.mts +74 -0
- package/dist/plugins/email-otp/utils.mjs +17 -0
- package/dist/plugins/email-otp/utils.mjs.map +1 -0
- package/dist/plugins/generic-oauth/client.d.mts +19 -0
- package/dist/plugins/generic-oauth/client.mjs +14 -0
- package/dist/plugins/generic-oauth/client.mjs.map +1 -0
- package/dist/plugins/generic-oauth/error-codes.d.mts +5 -0
- package/dist/plugins/generic-oauth/error-codes.mjs +15 -0
- package/dist/plugins/generic-oauth/error-codes.mjs.map +1 -0
- package/dist/plugins/generic-oauth/index.d.mts +34 -0
- package/dist/plugins/generic-oauth/index.mjs +137 -0
- package/dist/plugins/generic-oauth/index.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/auth0.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/auth0.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/auth0.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/gumroad.d.mts +32 -0
- package/dist/plugins/generic-oauth/providers/gumroad.mjs +60 -0
- package/dist/plugins/generic-oauth/providers/gumroad.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/hubspot.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/hubspot.mjs +60 -0
- package/dist/plugins/generic-oauth/providers/hubspot.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/index.d.mts +9 -0
- package/dist/plugins/generic-oauth/providers/index.mjs +11 -0
- package/dist/plugins/generic-oauth/providers/keycloak.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/keycloak.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/keycloak.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/line.d.mts +55 -0
- package/dist/plugins/generic-oauth/providers/line.mjs +91 -0
- package/dist/plugins/generic-oauth/providers/line.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +66 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/okta.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/okta.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/okta.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/patreon.d.mts +30 -0
- package/dist/plugins/generic-oauth/providers/patreon.mjs +59 -0
- package/dist/plugins/generic-oauth/providers/patreon.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/slack.d.mts +30 -0
- package/dist/plugins/generic-oauth/providers/slack.mjs +61 -0
- package/dist/plugins/generic-oauth/providers/slack.mjs.map +1 -0
- package/dist/plugins/generic-oauth/routes.mjs +394 -0
- package/dist/plugins/generic-oauth/routes.mjs.map +1 -0
- package/dist/plugins/generic-oauth/types.d.mts +145 -0
- package/dist/plugins/haveibeenpwned/index.d.mts +21 -0
- package/dist/plugins/haveibeenpwned/index.mjs +56 -0
- package/dist/plugins/haveibeenpwned/index.mjs.map +1 -0
- package/dist/plugins/index.d.mts +68 -0
- package/dist/plugins/index.mjs +51 -0
- package/dist/plugins/jwt/adapter.mjs +27 -0
- package/dist/plugins/jwt/adapter.mjs.map +1 -0
- package/dist/plugins/jwt/client.d.mts +18 -0
- package/dist/plugins/jwt/client.mjs +19 -0
- package/dist/plugins/jwt/client.mjs.map +1 -0
- package/dist/plugins/jwt/index.d.mts +17 -0
- package/dist/plugins/jwt/index.mjs +202 -0
- package/dist/plugins/jwt/index.mjs.map +1 -0
- package/dist/plugins/jwt/schema.d.mts +5 -0
- package/dist/plugins/jwt/schema.mjs +23 -0
- package/dist/plugins/jwt/schema.mjs.map +1 -0
- package/dist/plugins/jwt/sign.d.mts +57 -0
- package/dist/plugins/jwt/sign.mjs +66 -0
- package/dist/plugins/jwt/sign.mjs.map +1 -0
- package/dist/plugins/jwt/types.d.mts +194 -0
- package/dist/plugins/jwt/utils.d.mts +42 -0
- package/dist/plugins/jwt/utils.mjs +64 -0
- package/dist/plugins/jwt/utils.mjs.map +1 -0
- package/dist/plugins/jwt/verify.d.mts +12 -0
- package/dist/plugins/jwt/verify.mjs +46 -0
- package/dist/plugins/jwt/verify.mjs.map +1 -0
- package/dist/plugins/last-login-method/client.d.mts +18 -0
- package/dist/plugins/last-login-method/client.mjs +32 -0
- package/dist/plugins/last-login-method/client.mjs.map +1 -0
- package/dist/plugins/last-login-method/index.d.mts +52 -0
- package/dist/plugins/last-login-method/index.mjs +77 -0
- package/dist/plugins/last-login-method/index.mjs.map +1 -0
- package/dist/plugins/magic-link/client.d.mts +5 -0
- package/dist/plugins/magic-link/client.mjs +11 -0
- package/dist/plugins/magic-link/client.mjs.map +1 -0
- package/dist/plugins/magic-link/index.d.mts +61 -0
- package/dist/plugins/magic-link/index.mjs +167 -0
- package/dist/plugins/magic-link/index.mjs.map +1 -0
- package/dist/plugins/magic-link/utils.mjs +12 -0
- package/dist/plugins/magic-link/utils.mjs.map +1 -0
- package/dist/plugins/mcp/authorize.mjs +133 -0
- package/dist/plugins/mcp/authorize.mjs.map +1 -0
- package/dist/plugins/mcp/index.d.mts +46 -0
- package/dist/plugins/mcp/index.mjs +717 -0
- package/dist/plugins/mcp/index.mjs.map +1 -0
- package/dist/plugins/multi-session/client.d.mts +8 -0
- package/dist/plugins/multi-session/client.mjs +20 -0
- package/dist/plugins/multi-session/client.mjs.map +1 -0
- package/dist/plugins/multi-session/error-codes.d.mts +5 -0
- package/dist/plugins/multi-session/error-codes.mjs +8 -0
- package/dist/plugins/multi-session/error-codes.mjs.map +1 -0
- package/dist/plugins/multi-session/index.d.mts +22 -0
- package/dist/plugins/multi-session/index.mjs +172 -0
- package/dist/plugins/multi-session/index.mjs.map +1 -0
- package/dist/plugins/oauth-proxy/index.d.mts +39 -0
- package/dist/plugins/oauth-proxy/index.mjs +305 -0
- package/dist/plugins/oauth-proxy/index.mjs.map +1 -0
- package/dist/plugins/oauth-proxy/utils.mjs +44 -0
- package/dist/plugins/oauth-proxy/utils.mjs.map +1 -0
- package/dist/plugins/oidc-provider/authorize.mjs +194 -0
- package/dist/plugins/oidc-provider/authorize.mjs.map +1 -0
- package/dist/plugins/oidc-provider/client.d.mts +8 -0
- package/dist/plugins/oidc-provider/client.mjs +11 -0
- package/dist/plugins/oidc-provider/client.mjs.map +1 -0
- package/dist/plugins/oidc-provider/error.mjs +17 -0
- package/dist/plugins/oidc-provider/error.mjs.map +1 -0
- package/dist/plugins/oidc-provider/index.d.mts +32 -0
- package/dist/plugins/oidc-provider/index.mjs +1093 -0
- package/dist/plugins/oidc-provider/index.mjs.map +1 -0
- package/dist/plugins/oidc-provider/schema.d.mts +26 -0
- package/dist/plugins/oidc-provider/schema.mjs +132 -0
- package/dist/plugins/oidc-provider/schema.mjs.map +1 -0
- package/dist/plugins/oidc-provider/types.d.mts +517 -0
- package/dist/plugins/oidc-provider/utils/prompt.mjs +19 -0
- package/dist/plugins/oidc-provider/utils/prompt.mjs.map +1 -0
- package/dist/plugins/oidc-provider/utils.mjs +15 -0
- package/dist/plugins/oidc-provider/utils.mjs.map +1 -0
- package/dist/plugins/one-tap/client.d.mts +159 -0
- package/dist/plugins/one-tap/client.mjs +214 -0
- package/dist/plugins/one-tap/client.mjs.map +1 -0
- package/dist/plugins/one-tap/index.d.mts +27 -0
- package/dist/plugins/one-tap/index.mjs +96 -0
- package/dist/plugins/one-tap/index.mjs.map +1 -0
- package/dist/plugins/one-time-token/client.d.mts +7 -0
- package/dist/plugins/one-time-token/client.mjs +11 -0
- package/dist/plugins/one-time-token/client.mjs.map +1 -0
- package/dist/plugins/one-time-token/index.d.mts +53 -0
- package/dist/plugins/one-time-token/index.mjs +82 -0
- package/dist/plugins/one-time-token/index.mjs.map +1 -0
- package/dist/plugins/one-time-token/utils.mjs +12 -0
- package/dist/plugins/one-time-token/utils.mjs.map +1 -0
- package/dist/plugins/open-api/generator.d.mts +115 -0
- package/dist/plugins/open-api/generator.mjs +315 -0
- package/dist/plugins/open-api/generator.mjs.map +1 -0
- package/dist/plugins/open-api/index.d.mts +45 -0
- package/dist/plugins/open-api/index.mjs +67 -0
- package/dist/plugins/open-api/index.mjs.map +1 -0
- package/dist/plugins/open-api/logo.mjs +15 -0
- package/dist/plugins/open-api/logo.mjs.map +1 -0
- package/dist/plugins/organization/access/index.d.mts +2 -0
- package/dist/plugins/organization/access/index.mjs +3 -0
- package/dist/plugins/organization/access/statement.d.mts +249 -0
- package/dist/plugins/organization/access/statement.mjs +81 -0
- package/dist/plugins/organization/access/statement.mjs.map +1 -0
- package/dist/plugins/organization/adapter.d.mts +205 -0
- package/dist/plugins/organization/adapter.mjs +624 -0
- package/dist/plugins/organization/adapter.mjs.map +1 -0
- package/dist/plugins/organization/call.mjs +19 -0
- package/dist/plugins/organization/call.mjs.map +1 -0
- package/dist/plugins/organization/client.d.mts +151 -0
- package/dist/plugins/organization/client.mjs +107 -0
- package/dist/plugins/organization/client.mjs.map +1 -0
- package/dist/plugins/organization/error-codes.d.mts +5 -0
- package/dist/plugins/organization/error-codes.mjs +65 -0
- package/dist/plugins/organization/error-codes.mjs.map +1 -0
- package/dist/plugins/organization/has-permission.mjs +35 -0
- package/dist/plugins/organization/has-permission.mjs.map +1 -0
- package/dist/plugins/organization/index.d.mts +5 -0
- package/dist/plugins/organization/index.mjs +4 -0
- package/dist/plugins/organization/organization.d.mts +252 -0
- package/dist/plugins/organization/organization.mjs +428 -0
- package/dist/plugins/organization/organization.mjs.map +1 -0
- package/dist/plugins/organization/permission.d.mts +26 -0
- package/dist/plugins/organization/permission.mjs +16 -0
- package/dist/plugins/organization/permission.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-access-control.d.mts +11 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs +656 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-invites.d.mts +16 -0
- package/dist/plugins/organization/routes/crud-invites.mjs +555 -0
- package/dist/plugins/organization/routes/crud-invites.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-members.d.mts +13 -0
- package/dist/plugins/organization/routes/crud-members.mjs +473 -0
- package/dist/plugins/organization/routes/crud-members.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-org.d.mts +13 -0
- package/dist/plugins/organization/routes/crud-org.mjs +447 -0
- package/dist/plugins/organization/routes/crud-org.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-team.d.mts +15 -0
- package/dist/plugins/organization/routes/crud-team.mjs +676 -0
- package/dist/plugins/organization/routes/crud-team.mjs.map +1 -0
- package/dist/plugins/organization/schema.d.mts +376 -0
- package/dist/plugins/organization/schema.mjs +68 -0
- package/dist/plugins/organization/schema.mjs.map +1 -0
- package/dist/plugins/organization/types.d.mts +733 -0
- package/dist/plugins/phone-number/client.d.mts +8 -0
- package/dist/plugins/phone-number/client.mjs +20 -0
- package/dist/plugins/phone-number/client.mjs.map +1 -0
- package/dist/plugins/phone-number/error-codes.d.mts +5 -0
- package/dist/plugins/phone-number/error-codes.mjs +21 -0
- package/dist/plugins/phone-number/error-codes.mjs.map +1 -0
- package/dist/plugins/phone-number/index.d.mts +14 -0
- package/dist/plugins/phone-number/index.mjs +49 -0
- package/dist/plugins/phone-number/index.mjs.map +1 -0
- package/dist/plugins/phone-number/routes.mjs +459 -0
- package/dist/plugins/phone-number/routes.mjs.map +1 -0
- package/dist/plugins/phone-number/schema.d.mts +5 -0
- package/dist/plugins/phone-number/schema.mjs +20 -0
- package/dist/plugins/phone-number/schema.mjs.map +1 -0
- package/dist/plugins/phone-number/types.d.mts +118 -0
- package/dist/plugins/siwe/client.d.mts +5 -0
- package/dist/plugins/siwe/client.mjs +11 -0
- package/dist/plugins/siwe/client.mjs.map +1 -0
- package/dist/plugins/siwe/error-codes.mjs +13 -0
- package/dist/plugins/siwe/error-codes.mjs.map +1 -0
- package/dist/plugins/siwe/index.d.mts +26 -0
- package/dist/plugins/siwe/index.mjs +261 -0
- package/dist/plugins/siwe/index.mjs.map +1 -0
- package/dist/plugins/siwe/schema.d.mts +5 -0
- package/dist/plugins/siwe/schema.mjs +32 -0
- package/dist/plugins/siwe/schema.mjs.map +1 -0
- package/dist/plugins/siwe/types.d.mts +44 -0
- package/dist/plugins/two-factor/backup-codes/index.d.mts +91 -0
- package/dist/plugins/two-factor/backup-codes/index.mjs +277 -0
- package/dist/plugins/two-factor/backup-codes/index.mjs.map +1 -0
- package/dist/plugins/two-factor/client.d.mts +17 -0
- package/dist/plugins/two-factor/client.mjs +37 -0
- package/dist/plugins/two-factor/client.mjs.map +1 -0
- package/dist/plugins/two-factor/constant.mjs +8 -0
- package/dist/plugins/two-factor/constant.mjs.map +1 -0
- package/dist/plugins/two-factor/error-code.d.mts +5 -0
- package/dist/plugins/two-factor/error-code.mjs +18 -0
- package/dist/plugins/two-factor/error-code.mjs.map +1 -0
- package/dist/plugins/two-factor/index.d.mts +19 -0
- package/dist/plugins/two-factor/index.mjs +207 -0
- package/dist/plugins/two-factor/index.mjs.map +1 -0
- package/dist/plugins/two-factor/otp/index.d.mts +96 -0
- package/dist/plugins/two-factor/otp/index.mjs +199 -0
- package/dist/plugins/two-factor/otp/index.mjs.map +1 -0
- package/dist/plugins/two-factor/schema.d.mts +5 -0
- package/dist/plugins/two-factor/schema.mjs +36 -0
- package/dist/plugins/two-factor/schema.mjs.map +1 -0
- package/dist/plugins/two-factor/totp/index.d.mts +81 -0
- package/dist/plugins/two-factor/totp/index.mjs +157 -0
- package/dist/plugins/two-factor/totp/index.mjs.map +1 -0
- package/dist/plugins/two-factor/types.d.mts +65 -0
- package/dist/plugins/two-factor/utils.mjs +12 -0
- package/dist/plugins/two-factor/utils.mjs.map +1 -0
- package/dist/plugins/two-factor/verify-two-factor.mjs +76 -0
- package/dist/plugins/two-factor/verify-two-factor.mjs.map +1 -0
- package/dist/plugins/username/client.d.mts +7 -0
- package/dist/plugins/username/client.mjs +18 -0
- package/dist/plugins/username/client.mjs.map +1 -0
- package/dist/plugins/username/error-codes.d.mts +5 -0
- package/dist/plugins/username/error-codes.mjs +17 -0
- package/dist/plugins/username/error-codes.mjs.map +1 -0
- package/dist/plugins/username/index.d.mts +74 -0
- package/dist/plugins/username/index.mjs +237 -0
- package/dist/plugins/username/index.mjs.map +1 -0
- package/dist/plugins/username/schema.d.mts +9 -0
- package/dist/plugins/username/schema.mjs +26 -0
- package/dist/plugins/username/schema.mjs.map +1 -0
- package/dist/social-providers/index.d.mts +1 -0
- package/dist/social-providers/index.mjs +3 -0
- package/dist/state.d.mts +42 -0
- package/dist/state.mjs +107 -0
- package/dist/state.mjs.map +1 -0
- package/dist/test-utils/headers.d.mts +9 -0
- package/dist/test-utils/headers.mjs +24 -0
- package/dist/test-utils/headers.mjs.map +1 -0
- package/dist/test-utils/index.d.mts +3 -0
- package/dist/test-utils/index.mjs +4 -0
- package/dist/test-utils/test-instance.d.mts +181 -0
- package/dist/test-utils/test-instance.mjs +210 -0
- package/dist/test-utils/test-instance.mjs.map +1 -0
- package/dist/types/adapter.d.mts +24 -0
- package/dist/types/api.d.mts +62 -0
- package/dist/types/auth.d.mts +30 -0
- package/dist/types/helper.d.mts +21 -0
- package/dist/types/index.d.mts +11 -0
- package/dist/types/index.mjs +1 -0
- package/dist/types/models.d.mts +17 -0
- package/dist/types/plugins.d.mts +16 -0
- package/dist/utils/boolean.mjs +8 -0
- package/dist/utils/boolean.mjs.map +1 -0
- package/dist/utils/constants.mjs +6 -0
- package/dist/utils/constants.mjs.map +1 -0
- package/dist/utils/date.mjs +8 -0
- package/dist/utils/date.mjs.map +1 -0
- package/dist/utils/get-request-ip.d.mts +7 -0
- package/dist/utils/get-request-ip.mjs +23 -0
- package/dist/utils/get-request-ip.mjs.map +1 -0
- package/dist/utils/hashing.mjs +21 -0
- package/dist/utils/hashing.mjs.map +1 -0
- package/dist/utils/hide-metadata.d.mts +7 -0
- package/dist/utils/hide-metadata.mjs +6 -0
- package/dist/utils/hide-metadata.mjs.map +1 -0
- package/dist/utils/index.d.mts +3 -0
- package/dist/utils/index.mjs +5 -0
- package/dist/utils/is-api-error.d.mts +7 -0
- package/dist/utils/is-api-error.mjs +11 -0
- package/dist/utils/is-api-error.mjs.map +1 -0
- package/dist/utils/is-atom.mjs +8 -0
- package/dist/utils/is-atom.mjs.map +1 -0
- package/dist/utils/is-promise.mjs +8 -0
- package/dist/utils/is-promise.mjs.map +1 -0
- package/dist/utils/middleware-response.mjs +6 -0
- package/dist/utils/middleware-response.mjs.map +1 -0
- package/dist/utils/password.mjs +26 -0
- package/dist/utils/password.mjs.map +1 -0
- package/dist/utils/plugin-helper.mjs +17 -0
- package/dist/utils/plugin-helper.mjs.map +1 -0
- package/dist/utils/shim.mjs +24 -0
- package/dist/utils/shim.mjs.map +1 -0
- package/dist/utils/time.d.mts +49 -0
- package/dist/utils/time.mjs +100 -0
- package/dist/utils/time.mjs.map +1 -0
- package/dist/utils/url.mjs +92 -0
- package/dist/utils/url.mjs.map +1 -0
- package/dist/utils/wildcard.mjs +108 -0
- package/dist/utils/wildcard.mjs.map +1 -0
- package/package.json +601 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { mergeSchema } from "../../db/schema.mjs";
|
|
2
|
+
import { sessionMiddleware } from "../../api/routes/session.mjs";
|
|
3
|
+
import { APIError as APIError$1 } from "../../api/index.mjs";
|
|
4
|
+
import { getJwksAdapter } from "./adapter.mjs";
|
|
5
|
+
import { schema } from "./schema.mjs";
|
|
6
|
+
import { createJwk, generateExportedKeyPair, toExpJWT } from "./utils.mjs";
|
|
7
|
+
import { getJwtToken, signJWT } from "./sign.mjs";
|
|
8
|
+
import { verifyJWT } from "./verify.mjs";
|
|
9
|
+
import { BetterAuthError } from "@better-auth/core/error";
|
|
10
|
+
import { createAuthEndpoint, createAuthMiddleware } from "@better-auth/core/api";
|
|
11
|
+
import * as z from "zod";
|
|
12
|
+
|
|
13
|
+
//#region src/plugins/jwt/index.ts
|
|
14
|
+
const signJWTBodySchema = z.object({
|
|
15
|
+
payload: z.record(z.string(), z.any()),
|
|
16
|
+
overrideOptions: z.record(z.string(), z.any()).optional()
|
|
17
|
+
});
|
|
18
|
+
const verifyJWTBodySchema = z.object({
|
|
19
|
+
token: z.string(),
|
|
20
|
+
issuer: z.string().optional()
|
|
21
|
+
});
|
|
22
|
+
const jwt = (options) => {
|
|
23
|
+
if (options?.jwt?.sign && !options.jwks?.remoteUrl) throw new BetterAuthError("options.jwks.remoteUrl must be set when using options.jwt.sign");
|
|
24
|
+
if (options?.jwks?.remoteUrl && !options.jwks?.keyPairConfig?.alg) throw new BetterAuthError("options.jwks.keyPairConfig.alg must be specified when using the oidc plugin with options.jwks.remoteUrl");
|
|
25
|
+
const jwksPath = options?.jwks?.jwksPath ?? "/jwks";
|
|
26
|
+
if (typeof jwksPath !== "string" || jwksPath.length === 0 || !jwksPath.startsWith("/") || jwksPath.includes("..")) throw new BetterAuthError("options.jwks.jwksPath must be a non-empty string starting with '/' and not contain '..'");
|
|
27
|
+
return {
|
|
28
|
+
id: "jwt",
|
|
29
|
+
options,
|
|
30
|
+
endpoints: {
|
|
31
|
+
getJwks: createAuthEndpoint(jwksPath, {
|
|
32
|
+
method: "GET",
|
|
33
|
+
metadata: { openapi: {
|
|
34
|
+
operationId: "getJSONWebKeySet",
|
|
35
|
+
description: "Get the JSON Web Key Set",
|
|
36
|
+
responses: { "200": {
|
|
37
|
+
description: "JSON Web Key Set retrieved successfully",
|
|
38
|
+
content: { "application/json": { schema: {
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: { keys: {
|
|
41
|
+
type: "array",
|
|
42
|
+
description: "Array of public JSON Web Keys",
|
|
43
|
+
items: {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
kid: {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "Key ID uniquely identifying the key, corresponds to the 'id' from the stored Jwk"
|
|
49
|
+
},
|
|
50
|
+
kty: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "Key type (e.g., 'RSA', 'EC', 'OKP')"
|
|
53
|
+
},
|
|
54
|
+
alg: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "Algorithm intended for use with the key (e.g., 'EdDSA', 'RS256')"
|
|
57
|
+
},
|
|
58
|
+
use: {
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "Intended use of the public key (e.g., 'sig' for signature)",
|
|
61
|
+
enum: ["sig"],
|
|
62
|
+
nullable: true
|
|
63
|
+
},
|
|
64
|
+
n: {
|
|
65
|
+
type: "string",
|
|
66
|
+
description: "Modulus for RSA keys (base64url-encoded)",
|
|
67
|
+
nullable: true
|
|
68
|
+
},
|
|
69
|
+
e: {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "Exponent for RSA keys (base64url-encoded)",
|
|
72
|
+
nullable: true
|
|
73
|
+
},
|
|
74
|
+
crv: {
|
|
75
|
+
type: "string",
|
|
76
|
+
description: "Curve name for elliptic curve keys (e.g., 'Ed25519', 'P-256')",
|
|
77
|
+
nullable: true
|
|
78
|
+
},
|
|
79
|
+
x: {
|
|
80
|
+
type: "string",
|
|
81
|
+
description: "X coordinate for elliptic curve keys (base64url-encoded)",
|
|
82
|
+
nullable: true
|
|
83
|
+
},
|
|
84
|
+
y: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "Y coordinate for elliptic curve keys (base64url-encoded)",
|
|
87
|
+
nullable: true
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
required: [
|
|
91
|
+
"kid",
|
|
92
|
+
"kty",
|
|
93
|
+
"alg"
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
} },
|
|
97
|
+
required: ["keys"]
|
|
98
|
+
} } }
|
|
99
|
+
} }
|
|
100
|
+
} }
|
|
101
|
+
}, async (ctx) => {
|
|
102
|
+
if (options?.jwks?.remoteUrl) throw new APIError$1("NOT_FOUND");
|
|
103
|
+
const adapter = getJwksAdapter(ctx.context.adapter, options);
|
|
104
|
+
let keySets = await adapter.getAllKeys(ctx);
|
|
105
|
+
if (!keySets || keySets?.length === 0) {
|
|
106
|
+
await createJwk(ctx, options);
|
|
107
|
+
keySets = await adapter.getAllKeys(ctx);
|
|
108
|
+
}
|
|
109
|
+
if (!keySets?.length) throw new BetterAuthError("No key sets found. Make sure you have a key in your database.");
|
|
110
|
+
const now = Date.now();
|
|
111
|
+
const gracePeriod = (options?.jwks?.gracePeriod ?? 3600 * 24 * 30) * 1e3;
|
|
112
|
+
const keys = keySets.filter((key) => {
|
|
113
|
+
if (!key.expiresAt) return true;
|
|
114
|
+
return key.expiresAt.getTime() + gracePeriod > now;
|
|
115
|
+
});
|
|
116
|
+
const keyPairConfig = options?.jwks?.keyPairConfig;
|
|
117
|
+
const defaultCrv = keyPairConfig ? "crv" in keyPairConfig ? keyPairConfig.crv : void 0 : void 0;
|
|
118
|
+
return ctx.json({ keys: keys.map((keySet) => {
|
|
119
|
+
return {
|
|
120
|
+
alg: keySet.alg ?? options?.jwks?.keyPairConfig?.alg ?? "EdDSA",
|
|
121
|
+
crv: keySet.crv ?? defaultCrv,
|
|
122
|
+
...JSON.parse(keySet.publicKey),
|
|
123
|
+
kid: keySet.id
|
|
124
|
+
};
|
|
125
|
+
}) });
|
|
126
|
+
}),
|
|
127
|
+
getToken: createAuthEndpoint("/token", {
|
|
128
|
+
method: "GET",
|
|
129
|
+
requireHeaders: true,
|
|
130
|
+
use: [sessionMiddleware],
|
|
131
|
+
metadata: { openapi: {
|
|
132
|
+
operationId: "getJSONWebToken",
|
|
133
|
+
description: "Get a JWT token",
|
|
134
|
+
responses: { 200: {
|
|
135
|
+
description: "Success",
|
|
136
|
+
content: { "application/json": { schema: {
|
|
137
|
+
type: "object",
|
|
138
|
+
properties: { token: { type: "string" } }
|
|
139
|
+
} } }
|
|
140
|
+
} }
|
|
141
|
+
} }
|
|
142
|
+
}, async (ctx) => {
|
|
143
|
+
const jwt = await getJwtToken(ctx, options);
|
|
144
|
+
return ctx.json({ token: jwt });
|
|
145
|
+
}),
|
|
146
|
+
signJWT: createAuthEndpoint({
|
|
147
|
+
method: "POST",
|
|
148
|
+
metadata: { $Infer: { body: {} } },
|
|
149
|
+
body: signJWTBodySchema
|
|
150
|
+
}, async (c) => {
|
|
151
|
+
const jwt = await signJWT(c, {
|
|
152
|
+
options: {
|
|
153
|
+
...options,
|
|
154
|
+
...c.body.overrideOptions
|
|
155
|
+
},
|
|
156
|
+
payload: c.body.payload
|
|
157
|
+
});
|
|
158
|
+
return c.json({ token: jwt });
|
|
159
|
+
}),
|
|
160
|
+
verifyJWT: createAuthEndpoint({
|
|
161
|
+
method: "POST",
|
|
162
|
+
metadata: { $Infer: {
|
|
163
|
+
body: {},
|
|
164
|
+
response: {}
|
|
165
|
+
} },
|
|
166
|
+
body: verifyJWTBodySchema
|
|
167
|
+
}, async (ctx) => {
|
|
168
|
+
const overrideOptions = ctx.body.issuer ? {
|
|
169
|
+
...options,
|
|
170
|
+
jwt: {
|
|
171
|
+
...options?.jwt,
|
|
172
|
+
issuer: ctx.body.issuer
|
|
173
|
+
}
|
|
174
|
+
} : options;
|
|
175
|
+
const payload = await verifyJWT(ctx.body.token, overrideOptions);
|
|
176
|
+
return ctx.json({ payload });
|
|
177
|
+
})
|
|
178
|
+
},
|
|
179
|
+
hooks: { after: [{
|
|
180
|
+
matcher(context) {
|
|
181
|
+
return context.path === "/get-session";
|
|
182
|
+
},
|
|
183
|
+
handler: createAuthMiddleware(async (ctx) => {
|
|
184
|
+
if (options?.disableSettingJwtHeader) return;
|
|
185
|
+
const session = ctx.context.session || ctx.context.newSession;
|
|
186
|
+
if (session && session.session) {
|
|
187
|
+
const jwt = await getJwtToken(ctx, options);
|
|
188
|
+
const exposedHeaders = ctx.context.responseHeaders?.get("access-control-expose-headers") || "";
|
|
189
|
+
const headersSet = new Set(exposedHeaders.split(",").map((header) => header.trim()).filter(Boolean));
|
|
190
|
+
headersSet.add("set-auth-jwt");
|
|
191
|
+
ctx.setHeader("set-auth-jwt", jwt);
|
|
192
|
+
ctx.setHeader("Access-Control-Expose-Headers", Array.from(headersSet).join(", "));
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
}] },
|
|
196
|
+
schema: mergeSchema(schema, options?.schema)
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
export { createJwk, generateExportedKeyPair, getJwtToken, jwt, signJWT, toExpJWT, verifyJWT };
|
|
202
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["APIError","verifyJWTHelper"],"sources":["../../../src/plugins/jwt/index.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport { BetterAuthError } from \"@better-auth/core/error\";\nimport type { JSONWebKeySet, JWTPayload } from \"jose\";\nimport * as z from \"zod\";\nimport { APIError, sessionMiddleware } from \"../../api\";\nimport { mergeSchema } from \"../../db/schema\";\nimport { getJwksAdapter } from \"./adapter\";\nimport { schema } from \"./schema\";\nimport { getJwtToken, signJWT } from \"./sign\";\nimport type { JwtOptions } from \"./types\";\nimport { createJwk } from \"./utils\";\nimport { verifyJWT as verifyJWTHelper } from \"./verify\";\n\nexport { signJWT } from \"./sign\";\nexport type * from \"./types\";\nexport { createJwk, generateExportedKeyPair, toExpJWT } from \"./utils\";\nexport { verifyJWT } from \"./verify\";\n\ndeclare module \"@better-auth/core\" {\n\tinterface BetterAuthPluginRegistry<AuthOptions, Options> {\n\t\tjwt: {\n\t\t\tcreator: typeof jwt;\n\t\t};\n\t}\n}\n\nconst signJWTBodySchema = z.object({\n\tpayload: z.record(z.string(), z.any()),\n\toverrideOptions: z.record(z.string(), z.any()).optional(),\n});\n\nconst verifyJWTBodySchema = z.object({\n\ttoken: z.string(),\n\tissuer: z.string().optional(),\n});\n\nexport const jwt = <O extends JwtOptions>(options?: O) => {\n\t// Remote url must be set when using signing function\n\tif (options?.jwt?.sign && !options.jwks?.remoteUrl) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"options.jwks.remoteUrl must be set when using options.jwt.sign\",\n\t\t);\n\t}\n\n\t// Alg is required to be specified when using remote url (needed in openid metadata)\n\tif (options?.jwks?.remoteUrl && !options.jwks?.keyPairConfig?.alg) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"options.jwks.keyPairConfig.alg must be specified when using the oidc plugin with options.jwks.remoteUrl\",\n\t\t);\n\t}\n\n\tconst jwksPath = options?.jwks?.jwksPath ?? \"/jwks\";\n\tif (\n\t\ttypeof jwksPath !== \"string\" ||\n\t\tjwksPath.length === 0 ||\n\t\t!jwksPath.startsWith(\"/\") ||\n\t\tjwksPath.includes(\"..\")\n\t) {\n\t\tthrow new BetterAuthError(\n\t\t\t\"options.jwks.jwksPath must be a non-empty string starting with '/' and not contain '..'\",\n\t\t);\n\t}\n\n\treturn {\n\t\tid: \"jwt\",\n\t\toptions: options as NoInfer<O>,\n\t\tendpoints: {\n\t\t\tgetJwks: createAuthEndpoint(\n\t\t\t\tjwksPath,\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\toperationId: \"getJSONWebKeySet\",\n\t\t\t\t\t\t\tdescription: \"Get the JSON Web Key Set\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\t\t\tdescription: \"JSON Web Key Set retrieved successfully\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tkeys: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Array of public JSON Web Keys\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\titems: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tkid: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Key ID uniquely identifying the key, corresponds to the 'id' from the stored Jwk\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tkty: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Key type (e.g., 'RSA', 'EC', 'OKP')\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\talg: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Algorithm intended for use with the key (e.g., 'EdDSA', 'RS256')\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tuse: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Intended use of the public key (e.g., 'sig' for signature)\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [\"sig\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tn: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Modulus for RSA keys (base64url-encoded)\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Exponent for RSA keys (base64url-encoded)\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcrv: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Curve name for elliptic curve keys (e.g., 'Ed25519', 'P-256')\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tx: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"X coordinate for elliptic curve keys (base64url-encoded)\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ty: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Y coordinate for elliptic curve keys (base64url-encoded)\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trequired: [\"kid\", \"kty\", \"alg\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\trequired: [\"keys\"],\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\t// Disables endpoint if using remote url strategy\n\t\t\t\t\tif (options?.jwks?.remoteUrl) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst adapter = getJwksAdapter(ctx.context.adapter, options);\n\n\t\t\t\t\tlet keySets = await adapter.getAllKeys(ctx);\n\n\t\t\t\t\tif (!keySets || keySets?.length === 0) {\n\t\t\t\t\t\tawait createJwk(ctx, options);\n\t\t\t\t\t\tkeySets = await adapter.getAllKeys(ctx);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!keySets?.length) {\n\t\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t\t\"No key sets found. Make sure you have a key in your database.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\tconst DEFAULT_GRACE_PERIOD = 60 * 60 * 24 * 30;\n\t\t\t\t\tconst gracePeriod =\n\t\t\t\t\t\t(options?.jwks?.gracePeriod ?? DEFAULT_GRACE_PERIOD) * 1000;\n\n\t\t\t\t\tconst keys = keySets.filter((key) => {\n\t\t\t\t\t\tif (!key.expiresAt) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn key.expiresAt.getTime() + gracePeriod > now;\n\t\t\t\t\t});\n\n\t\t\t\t\tconst keyPairConfig = options?.jwks?.keyPairConfig;\n\t\t\t\t\tconst defaultCrv = keyPairConfig\n\t\t\t\t\t\t? \"crv\" in keyPairConfig\n\t\t\t\t\t\t\t? (keyPairConfig as { crv: string }).crv\n\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t: undefined;\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tkeys: keys.map((keySet) => {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\talg: keySet.alg ?? options?.jwks?.keyPairConfig?.alg ?? \"EdDSA\",\n\t\t\t\t\t\t\t\tcrv: keySet.crv ?? defaultCrv,\n\t\t\t\t\t\t\t\t...JSON.parse(keySet.publicKey),\n\t\t\t\t\t\t\t\tkid: keySet.id,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}),\n\t\t\t\t\t} satisfies JSONWebKeySet as JSONWebKeySet);\n\t\t\t\t},\n\t\t\t),\n\n\t\t\tgetToken: createAuthEndpoint(\n\t\t\t\t\"/token\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\toperationId: \"getJSONWebToken\",\n\t\t\t\t\t\t\tdescription: \"Get a JWT token\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\ttoken: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst jwt = await getJwtToken(ctx, options);\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\ttoken: jwt,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tsignJWT: createAuthEndpoint(\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t$Infer: {\n\t\t\t\t\t\t\tbody: {} as {\n\t\t\t\t\t\t\t\tpayload: JWTPayload;\n\t\t\t\t\t\t\t\toverrideOptions?: JwtOptions | undefined;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tbody: signJWTBodySchema,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\tconst jwt = await signJWT(c, {\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\t...options,\n\t\t\t\t\t\t\t...c.body.overrideOptions,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpayload: c.body.payload,\n\t\t\t\t\t});\n\t\t\t\t\treturn c.json({ token: jwt });\n\t\t\t\t},\n\t\t\t),\n\t\t\tverifyJWT: createAuthEndpoint(\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t$Infer: {\n\t\t\t\t\t\t\tbody: {} as {\n\t\t\t\t\t\t\t\ttoken: string;\n\t\t\t\t\t\t\t\tissuer?: string;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tresponse: {} as {\n\t\t\t\t\t\t\t\tpayload: {\n\t\t\t\t\t\t\t\t\tsub: string;\n\t\t\t\t\t\t\t\t\taud: string;\n\t\t\t\t\t\t\t\t\t[key: string]: any;\n\t\t\t\t\t\t\t\t} | null;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tbody: verifyJWTBodySchema,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst overrideOptions = ctx.body.issuer\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...options,\n\t\t\t\t\t\t\t\tjwt: {\n\t\t\t\t\t\t\t\t\t...options?.jwt,\n\t\t\t\t\t\t\t\t\tissuer: ctx.body.issuer,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: options;\n\n\t\t\t\t\tconst payload = await verifyJWTHelper(\n\t\t\t\t\t\tctx.body.token,\n\t\t\t\t\t\toverrideOptions,\n\t\t\t\t\t);\n\n\t\t\t\t\treturn ctx.json({ payload });\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher(context) {\n\t\t\t\t\t\treturn context.path === \"/get-session\";\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tif (options?.disableSettingJwtHeader) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst session = ctx.context.session || ctx.context.newSession;\n\t\t\t\t\t\tif (session && session.session) {\n\t\t\t\t\t\t\tconst jwt = await getJwtToken(ctx, options);\n\t\t\t\t\t\t\tconst exposedHeaders =\n\t\t\t\t\t\t\t\tctx.context.responseHeaders?.get(\n\t\t\t\t\t\t\t\t\t\"access-control-expose-headers\",\n\t\t\t\t\t\t\t\t) || \"\";\n\t\t\t\t\t\t\tconst headersSet = new Set(\n\t\t\t\t\t\t\t\texposedHeaders\n\t\t\t\t\t\t\t\t\t.split(\",\")\n\t\t\t\t\t\t\t\t\t.map((header) => header.trim())\n\t\t\t\t\t\t\t\t\t.filter(Boolean),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\theadersSet.add(\"set-auth-jwt\");\n\t\t\t\t\t\t\tctx.setHeader(\"set-auth-jwt\", jwt);\n\t\t\t\t\t\t\tctx.setHeader(\n\t\t\t\t\t\t\t\t\"Access-Control-Expose-Headers\",\n\t\t\t\t\t\t\t\tArray.from(headersSet).join(\", \"),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tschema: mergeSchema(schema, options?.schema),\n\t} satisfies BetterAuthPlugin;\n};\n\nexport { getJwtToken };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/plugins/jwt/schema.ts
|
|
2
|
+
const schema = { jwks: { fields: {
|
|
3
|
+
publicKey: {
|
|
4
|
+
type: "string",
|
|
5
|
+
required: true
|
|
6
|
+
},
|
|
7
|
+
privateKey: {
|
|
8
|
+
type: "string",
|
|
9
|
+
required: true
|
|
10
|
+
},
|
|
11
|
+
createdAt: {
|
|
12
|
+
type: "date",
|
|
13
|
+
required: true
|
|
14
|
+
},
|
|
15
|
+
expiresAt: {
|
|
16
|
+
type: "date",
|
|
17
|
+
required: false
|
|
18
|
+
}
|
|
19
|
+
} } };
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { schema };
|
|
23
|
+
//# sourceMappingURL=schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.mjs","names":[],"sources":["../../../src/plugins/jwt/schema.ts"],"sourcesContent":["import type { BetterAuthPluginDBSchema } from \"@better-auth/core/db\";\n\nexport const schema = {\n\tjwks: {\n\t\tfields: {\n\t\t\tpublicKey: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tprivateKey: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tcreatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\texpiresAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t\trequired: false,\n\t\t\t},\n\t\t},\n\t},\n} satisfies BetterAuthPluginDBSchema;\n"],"mappings":";AAEA,MAAa,SAAS,EACrB,MAAM,EACL,QAAQ;CACP,WAAW;EACV,MAAM;EACN,UAAU;EACV;CACD,YAAY;EACX,MAAM;EACN,UAAU;EACV;CACD,WAAW;EACV,MAAM;EACN,UAAU;EACV;CACD,WAAW;EACV,MAAM;EACN,UAAU;EACV;CACD,EACD,EACD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { JwtOptions } from "./types.mjs";
|
|
2
|
+
import { GenericEndpointContext } from "@better-auth/core";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/jwt/sign.d.ts
|
|
5
|
+
type JWTPayloadWithOptional = {
|
|
6
|
+
/**
|
|
7
|
+
* JWT Issuer
|
|
8
|
+
*
|
|
9
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1 RFC7519#section-4.1.1}
|
|
10
|
+
*/
|
|
11
|
+
iss?: string | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* JWT Subject
|
|
14
|
+
*
|
|
15
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2 RFC7519#section-4.1.2}
|
|
16
|
+
*/
|
|
17
|
+
sub?: string | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* JWT Audience
|
|
20
|
+
*
|
|
21
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3 RFC7519#section-4.1.3}
|
|
22
|
+
*/
|
|
23
|
+
aud?: string | string[] | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* JWT ID
|
|
26
|
+
*
|
|
27
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7 RFC7519#section-4.1.7}
|
|
28
|
+
*/
|
|
29
|
+
jti?: string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* JWT Not Before
|
|
32
|
+
*
|
|
33
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5 RFC7519#section-4.1.5}
|
|
34
|
+
*/
|
|
35
|
+
nbf?: number | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* JWT Expiration Time
|
|
38
|
+
*
|
|
39
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4 RFC7519#section-4.1.4}
|
|
40
|
+
*/
|
|
41
|
+
exp?: number | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* JWT Issued At
|
|
44
|
+
*
|
|
45
|
+
* @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 RFC7519#section-4.1.6}
|
|
46
|
+
*/
|
|
47
|
+
iat?: number | undefined; /** Any other JWT Claim Set member. */
|
|
48
|
+
[propName: string]: unknown | undefined;
|
|
49
|
+
};
|
|
50
|
+
declare function signJWT(ctx: GenericEndpointContext, config: {
|
|
51
|
+
options?: JwtOptions | undefined;
|
|
52
|
+
payload: JWTPayloadWithOptional;
|
|
53
|
+
}): Promise<any>;
|
|
54
|
+
declare function getJwtToken(ctx: GenericEndpointContext, options?: JwtOptions | undefined): Promise<any>;
|
|
55
|
+
//#endregion
|
|
56
|
+
export { getJwtToken, signJWT };
|
|
57
|
+
//# sourceMappingURL=sign.d.mts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { symmetricDecrypt } from "../../crypto/index.mjs";
|
|
2
|
+
import { getJwksAdapter } from "./adapter.mjs";
|
|
3
|
+
import { createJwk, toExpJWT } from "./utils.mjs";
|
|
4
|
+
import { BetterAuthError } from "@better-auth/core/error";
|
|
5
|
+
import { SignJWT, importJWK } from "jose";
|
|
6
|
+
|
|
7
|
+
//#region src/plugins/jwt/sign.ts
|
|
8
|
+
async function signJWT(ctx, config) {
|
|
9
|
+
const { options } = config;
|
|
10
|
+
const payload = config.payload;
|
|
11
|
+
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
12
|
+
const iat = payload.iat;
|
|
13
|
+
let exp = payload.exp;
|
|
14
|
+
const defaultExp = toExpJWT(options?.jwt?.expirationTime ?? "15m", iat ?? nowSeconds);
|
|
15
|
+
exp = exp ?? defaultExp;
|
|
16
|
+
const nbf = payload.nbf;
|
|
17
|
+
const iss = payload.iss;
|
|
18
|
+
const defaultIss = options?.jwt?.issuer ?? ctx.context.options.baseURL;
|
|
19
|
+
const aud = payload.aud;
|
|
20
|
+
const defaultAud = options?.jwt?.audience ?? ctx.context.options.baseURL;
|
|
21
|
+
if (options?.jwt?.sign) {
|
|
22
|
+
const jwtPayload = {
|
|
23
|
+
...payload,
|
|
24
|
+
iat,
|
|
25
|
+
exp,
|
|
26
|
+
nbf,
|
|
27
|
+
iss: iss ?? defaultIss,
|
|
28
|
+
aud: aud ?? defaultAud
|
|
29
|
+
};
|
|
30
|
+
return options.jwt.sign(jwtPayload);
|
|
31
|
+
}
|
|
32
|
+
let key = await getJwksAdapter(ctx.context.adapter, options).getLatestKey(ctx);
|
|
33
|
+
if (!key || key.expiresAt && key.expiresAt < /* @__PURE__ */ new Date()) key = await createJwk(ctx, options);
|
|
34
|
+
const privateWebKey = !options?.jwks?.disablePrivateKeyEncryption ? await symmetricDecrypt({
|
|
35
|
+
key: ctx.context.secret,
|
|
36
|
+
data: JSON.parse(key.privateKey)
|
|
37
|
+
}).catch(() => {
|
|
38
|
+
throw new BetterAuthError("Failed to decrypt private key. Make sure the secret currently in use is the same as the one used to encrypt the private key. If you are using a different secret, either clean up your JWKS or disable private key encryption.");
|
|
39
|
+
}) : key.privateKey;
|
|
40
|
+
const alg = key.alg ?? options?.jwks?.keyPairConfig?.alg ?? "EdDSA";
|
|
41
|
+
const privateKey = await importJWK(JSON.parse(privateWebKey), alg);
|
|
42
|
+
const jwt = new SignJWT(payload).setProtectedHeader({
|
|
43
|
+
alg,
|
|
44
|
+
kid: key.id
|
|
45
|
+
}).setExpirationTime(exp).setIssuer(iss ?? defaultIss).setAudience(aud ?? defaultAud);
|
|
46
|
+
if (iat) jwt.setIssuedAt(iat);
|
|
47
|
+
if (payload.sub) jwt.setSubject(payload.sub);
|
|
48
|
+
if (payload.nbf) jwt.setNotBefore(payload.nbf);
|
|
49
|
+
if (payload.jti) jwt.setJti(payload.jti);
|
|
50
|
+
return await jwt.sign(privateKey);
|
|
51
|
+
}
|
|
52
|
+
async function getJwtToken(ctx, options) {
|
|
53
|
+
const payload = !options?.jwt?.definePayload ? ctx.context.session.user : await options.jwt.definePayload(ctx.context.session);
|
|
54
|
+
return await signJWT(ctx, {
|
|
55
|
+
options,
|
|
56
|
+
payload: {
|
|
57
|
+
iat: Math.floor(Date.now() / 1e3),
|
|
58
|
+
...payload,
|
|
59
|
+
sub: await options?.jwt?.getSubject?.(ctx.context.session) ?? ctx.context.session.user.id
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//#endregion
|
|
65
|
+
export { getJwtToken, signJWT };
|
|
66
|
+
//# sourceMappingURL=sign.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign.mjs","names":[],"sources":["../../../src/plugins/jwt/sign.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { BetterAuthError } from \"@better-auth/core/error\";\nimport type { JWTPayload } from \"jose\";\nimport { importJWK, SignJWT } from \"jose\";\nimport { symmetricDecrypt } from \"../../crypto\";\nimport { getJwksAdapter } from \"./adapter\";\nimport type { JwtOptions } from \"./types\";\nimport { createJwk, toExpJWT } from \"./utils\";\n\ntype JWTPayloadWithOptional = {\n\t/**\n\t * JWT Issuer\n\t *\n\t * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.1 RFC7519#section-4.1.1}\n\t */\n\tiss?: string | undefined;\n\n\t/**\n\t * JWT Subject\n\t *\n\t * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.2 RFC7519#section-4.1.2}\n\t */\n\tsub?: string | undefined;\n\n\t/**\n\t * JWT Audience\n\t *\n\t * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.3 RFC7519#section-4.1.3}\n\t */\n\taud?: string | string[] | undefined;\n\n\t/**\n\t * JWT ID\n\t *\n\t * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.7 RFC7519#section-4.1.7}\n\t */\n\tjti?: string | undefined;\n\n\t/**\n\t * JWT Not Before\n\t *\n\t * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.5 RFC7519#section-4.1.5}\n\t */\n\tnbf?: number | undefined;\n\n\t/**\n\t * JWT Expiration Time\n\t *\n\t * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.4 RFC7519#section-4.1.4}\n\t */\n\texp?: number | undefined;\n\n\t/**\n\t * JWT Issued At\n\t *\n\t * @see {@link https://www.rfc-editor.org/rfc/rfc7519#section-4.1.6 RFC7519#section-4.1.6}\n\t */\n\tiat?: number | undefined;\n\n\t/** Any other JWT Claim Set member. */\n\t[propName: string]: unknown | undefined;\n};\n\nexport async function signJWT(\n\tctx: GenericEndpointContext,\n\tconfig: {\n\t\toptions?: JwtOptions | undefined;\n\t\tpayload: JWTPayloadWithOptional;\n\t},\n) {\n\tconst { options } = config;\n\tconst payload = config.payload as JWTPayload;\n\n\t// Iat\n\tconst nowSeconds = Math.floor(Date.now() / 1000);\n\tconst iat = payload.iat!;\n\n\t// Exp\n\tlet exp = payload.exp;\n\tconst defaultExp = toExpJWT(\n\t\toptions?.jwt?.expirationTime ?? \"15m\",\n\t\tiat ?? nowSeconds,\n\t);\n\texp = exp ?? defaultExp;\n\n\t// Nbf\n\tconst nbf = payload.nbf!;\n\n\t// Iss\n\tconst iss = payload.iss;\n\tconst defaultIss = options?.jwt?.issuer ?? ctx.context.options.baseURL!;\n\n\t// Aud\n\tconst aud = payload.aud;\n\tconst defaultAud = options?.jwt?.audience ?? ctx.context.options.baseURL!;\n\n\t// Custom/remote signing function\n\tif (options?.jwt?.sign) {\n\t\tconst jwtPayload = {\n\t\t\t...payload,\n\t\t\tiat,\n\t\t\texp,\n\t\t\tnbf,\n\t\t\tiss: iss ?? defaultIss,\n\t\t\taud: aud ?? defaultAud,\n\t\t};\n\t\treturn options.jwt.sign(jwtPayload);\n\t}\n\n\tconst adapter = getJwksAdapter(ctx.context.adapter, options);\n\tlet key = await adapter.getLatestKey(ctx);\n\tif (!key || (key.expiresAt && key.expiresAt < new Date())) {\n\t\tkey = await createJwk(ctx, options);\n\t}\n\tconst privateKeyEncryptionEnabled =\n\t\t!options?.jwks?.disablePrivateKeyEncryption;\n\n\tconst privateWebKey = privateKeyEncryptionEnabled\n\t\t? await symmetricDecrypt({\n\t\t\t\tkey: ctx.context.secret,\n\t\t\t\tdata: JSON.parse(key.privateKey),\n\t\t\t}).catch(() => {\n\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\"Failed to decrypt private key. Make sure the secret currently in use is the same as the one used to encrypt the private key. If you are using a different secret, either clean up your JWKS or disable private key encryption.\",\n\t\t\t\t);\n\t\t\t})\n\t\t: key.privateKey;\n\tconst alg = key.alg ?? options?.jwks?.keyPairConfig?.alg ?? \"EdDSA\";\n\tconst privateKey = await importJWK(JSON.parse(privateWebKey), alg);\n\n\tconst jwt = new SignJWT(payload)\n\t\t.setProtectedHeader({\n\t\t\talg,\n\t\t\tkid: key.id,\n\t\t})\n\t\t.setExpirationTime(exp)\n\t\t.setIssuer(iss ?? defaultIss)\n\t\t.setAudience(aud ?? defaultAud);\n\tif (iat) jwt.setIssuedAt(iat);\n\tif (payload.sub) jwt.setSubject(payload.sub);\n\tif (payload.nbf) jwt.setNotBefore(payload.nbf);\n\tif (payload.jti) jwt.setJti(payload.jti);\n\treturn await jwt.sign(privateKey);\n}\n\nexport async function getJwtToken(\n\tctx: GenericEndpointContext,\n\toptions?: JwtOptions | undefined,\n) {\n\tconst payload = !options?.jwt?.definePayload\n\t\t? ctx.context.session!.user\n\t\t: await options.jwt.definePayload(ctx.context.session!);\n\n\treturn await signJWT(ctx, {\n\t\toptions,\n\t\tpayload: {\n\t\t\tiat: Math.floor(Date.now() / 1000),\n\t\t\t...payload,\n\t\t\tsub:\n\t\t\t\t(await options?.jwt?.getSubject?.(ctx.context.session!)) ??\n\t\t\t\tctx.context.session!.user.id,\n\t\t},\n\t});\n}\n"],"mappings":";;;;;;;AA+DA,eAAsB,QACrB,KACA,QAIC;CACD,MAAM,EAAE,YAAY;CACpB,MAAM,UAAU,OAAO;CAGvB,MAAM,aAAa,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;CAChD,MAAM,MAAM,QAAQ;CAGpB,IAAI,MAAM,QAAQ;CAClB,MAAM,aAAa,SAClB,SAAS,KAAK,kBAAkB,OAChC,OAAO,WACP;AACD,OAAM,OAAO;CAGb,MAAM,MAAM,QAAQ;CAGpB,MAAM,MAAM,QAAQ;CACpB,MAAM,aAAa,SAAS,KAAK,UAAU,IAAI,QAAQ,QAAQ;CAG/D,MAAM,MAAM,QAAQ;CACpB,MAAM,aAAa,SAAS,KAAK,YAAY,IAAI,QAAQ,QAAQ;AAGjE,KAAI,SAAS,KAAK,MAAM;EACvB,MAAM,aAAa;GAClB,GAAG;GACH;GACA;GACA;GACA,KAAK,OAAO;GACZ,KAAK,OAAO;GACZ;AACD,SAAO,QAAQ,IAAI,KAAK,WAAW;;CAIpC,IAAI,MAAM,MADM,eAAe,IAAI,QAAQ,SAAS,QAAQ,CACpC,aAAa,IAAI;AACzC,KAAI,CAAC,OAAQ,IAAI,aAAa,IAAI,4BAAY,IAAI,MAAM,CACvD,OAAM,MAAM,UAAU,KAAK,QAAQ;CAKpC,MAAM,gBAFL,CAAC,SAAS,MAAM,8BAGd,MAAM,iBAAiB;EACvB,KAAK,IAAI,QAAQ;EACjB,MAAM,KAAK,MAAM,IAAI,WAAW;EAChC,CAAC,CAAC,YAAY;AACd,QAAM,IAAI,gBACT,iOACA;GACA,GACD,IAAI;CACP,MAAM,MAAM,IAAI,OAAO,SAAS,MAAM,eAAe,OAAO;CAC5D,MAAM,aAAa,MAAM,UAAU,KAAK,MAAM,cAAc,EAAE,IAAI;CAElE,MAAM,MAAM,IAAI,QAAQ,QAAQ,CAC9B,mBAAmB;EACnB;EACA,KAAK,IAAI;EACT,CAAC,CACD,kBAAkB,IAAI,CACtB,UAAU,OAAO,WAAW,CAC5B,YAAY,OAAO,WAAW;AAChC,KAAI,IAAK,KAAI,YAAY,IAAI;AAC7B,KAAI,QAAQ,IAAK,KAAI,WAAW,QAAQ,IAAI;AAC5C,KAAI,QAAQ,IAAK,KAAI,aAAa,QAAQ,IAAI;AAC9C,KAAI,QAAQ,IAAK,KAAI,OAAO,QAAQ,IAAI;AACxC,QAAO,MAAM,IAAI,KAAK,WAAW;;AAGlC,eAAsB,YACrB,KACA,SACC;CACD,MAAM,UAAU,CAAC,SAAS,KAAK,gBAC5B,IAAI,QAAQ,QAAS,OACrB,MAAM,QAAQ,IAAI,cAAc,IAAI,QAAQ,QAAS;AAExD,QAAO,MAAM,QAAQ,KAAK;EACzB;EACA,SAAS;GACR,KAAK,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;GAClC,GAAG;GACH,KACE,MAAM,SAAS,KAAK,aAAa,IAAI,QAAQ,QAAS,IACvD,IAAI,QAAQ,QAAS,KAAK;GAC3B;EACD,CAAC"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { Session, User } from "../../types/models.mjs";
|
|
2
|
+
import { InferOptionSchema } from "../../types/plugins.mjs";
|
|
3
|
+
import "../../types/index.mjs";
|
|
4
|
+
import { index_d_exports } from "../../index.mjs";
|
|
5
|
+
import { schema } from "./schema.mjs";
|
|
6
|
+
import { Awaitable } from "@better-auth/core";
|
|
7
|
+
import { JWTPayload } from "jose";
|
|
8
|
+
|
|
9
|
+
//#region src/plugins/jwt/types.d.ts
|
|
10
|
+
interface JwtOptions {
|
|
11
|
+
jwks?: {
|
|
12
|
+
/**
|
|
13
|
+
* Disables the /jwks endpoint and uses this endpoint in discovery.
|
|
14
|
+
*
|
|
15
|
+
* Useful if jwks are not managed at /jwks or
|
|
16
|
+
* if your jwks are signed with a certificate and placed on your CDN.
|
|
17
|
+
*/
|
|
18
|
+
remoteUrl?: string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Key pair configuration
|
|
21
|
+
* @description A subset of the options available for the generateKeyPair function
|
|
22
|
+
*
|
|
23
|
+
* @see https://github.com/panva/jose/blob/main/src/runtime/node/generate.ts
|
|
24
|
+
*
|
|
25
|
+
* @default { alg: 'EdDSA', crv: 'Ed25519' }
|
|
26
|
+
*/
|
|
27
|
+
keyPairConfig?: JWKOptions | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Disable private key encryption
|
|
30
|
+
* @description Disable the encryption of the private key in the database
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
disablePrivateKeyEncryption?: boolean | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* The key rotation interval in seconds.
|
|
37
|
+
*
|
|
38
|
+
* @default undefined (disabled)
|
|
39
|
+
*/
|
|
40
|
+
rotationInterval?: number | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* The grace period in seconds.
|
|
43
|
+
*
|
|
44
|
+
* @default 2592000 (30 days)
|
|
45
|
+
*/
|
|
46
|
+
gracePeriod?: number | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* The path of the endpoint exposing the JWKS.
|
|
49
|
+
* When set, this replaces the default /jwks endpoint.
|
|
50
|
+
* The old endpoint will return 404.
|
|
51
|
+
*
|
|
52
|
+
* @default /jwks
|
|
53
|
+
* @example "/.well-known/jwks.json"
|
|
54
|
+
*/
|
|
55
|
+
jwksPath?: string | undefined;
|
|
56
|
+
} | undefined;
|
|
57
|
+
jwt?: {
|
|
58
|
+
/**
|
|
59
|
+
* The issuer of the JWT
|
|
60
|
+
*/
|
|
61
|
+
issuer?: string | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* The audience of the JWT
|
|
64
|
+
*/
|
|
65
|
+
audience?: string | string[] | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Set the "exp" (Expiration Time) Claim.
|
|
68
|
+
*
|
|
69
|
+
* - If a `number` is passed as an argument it is used as the claim directly.
|
|
70
|
+
* - If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the
|
|
71
|
+
* claim.
|
|
72
|
+
* - If a `string` is passed as an argument it is resolved to a time span, and then added to the
|
|
73
|
+
* current unix timestamp and used as the claim.
|
|
74
|
+
*
|
|
75
|
+
* Format used for time span should be a number followed by a unit, such as "5 minutes" or "1
|
|
76
|
+
* day".
|
|
77
|
+
*
|
|
78
|
+
* Valid units are: "sec", "secs", "second", "seconds", "s", "minute", "minutes", "min", "mins",
|
|
79
|
+
* "m", "hour", "hours", "hr", "hrs", "h", "day", "days", "d", "week", "weeks", "w", "year",
|
|
80
|
+
* "years", "yr", "yrs", and "y". It is not possible to specify months. 365.25 days is used as an
|
|
81
|
+
* alias for a year.
|
|
82
|
+
*
|
|
83
|
+
* If the string is suffixed with "ago", or prefixed with a "-", the resulting time span gets
|
|
84
|
+
* subtracted from the current unix timestamp. A "from now" suffix can also be used for
|
|
85
|
+
* readability when adding to the current unix timestamp.
|
|
86
|
+
*
|
|
87
|
+
* @default 15m
|
|
88
|
+
*/
|
|
89
|
+
expirationTime?: number | string | Date | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* A function that is called to define the payload of the JWT
|
|
92
|
+
*/
|
|
93
|
+
definePayload?: (session: {
|
|
94
|
+
user: User & Record<string, any>;
|
|
95
|
+
session: Session & Record<string, any>;
|
|
96
|
+
}) => Awaitable<Record<string, any>> | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* A function that is called to get the subject of the JWT
|
|
99
|
+
*
|
|
100
|
+
* @default session.user.id
|
|
101
|
+
*/
|
|
102
|
+
getSubject?: (session: {
|
|
103
|
+
user: User & Record<string, any>;
|
|
104
|
+
session: Session & Record<string, any>;
|
|
105
|
+
}) => Awaitable<string> | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* A custom function to remote sign the jwt payload.
|
|
108
|
+
*
|
|
109
|
+
* All headers, such as `alg` and `kid`,
|
|
110
|
+
* MUST be defined within this function.
|
|
111
|
+
* You can safely define the header `typ: 'JWT'`.
|
|
112
|
+
*
|
|
113
|
+
* @requires jwks.remoteUrl
|
|
114
|
+
* @invalidates other jwt.* options
|
|
115
|
+
*/
|
|
116
|
+
sign?: ((payload: JWTPayload) => Awaitable<string>) | undefined;
|
|
117
|
+
} | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Disables setting JWTs through middleware.
|
|
120
|
+
*
|
|
121
|
+
* Recommended to set `true` when using an oAuth provider plugin
|
|
122
|
+
* like OIDC or MCP where session payloads should not be signed.
|
|
123
|
+
*
|
|
124
|
+
* @default false
|
|
125
|
+
*/
|
|
126
|
+
disableSettingJwtHeader?: boolean | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* Custom schema for the admin plugin
|
|
129
|
+
*/
|
|
130
|
+
schema?: InferOptionSchema<typeof schema> | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Custom adapter for the jwt plugin
|
|
133
|
+
*
|
|
134
|
+
* This will override the default adapter
|
|
135
|
+
*
|
|
136
|
+
* @default adapter from the database
|
|
137
|
+
*/
|
|
138
|
+
adapter?: {
|
|
139
|
+
/**
|
|
140
|
+
* A custom function to get the JWKS from the database or
|
|
141
|
+
* other source
|
|
142
|
+
*
|
|
143
|
+
* This will override the default getJwks from the database
|
|
144
|
+
*
|
|
145
|
+
* @param ctx - The context of the request
|
|
146
|
+
* @returns The JWKS
|
|
147
|
+
*/
|
|
148
|
+
getJwks?: (ctx: index_d_exports.GenericEndpointContext) => Promise<Jwk[] | null | undefined>;
|
|
149
|
+
/**
|
|
150
|
+
* A custom function to create a new key in the database or
|
|
151
|
+
* other source
|
|
152
|
+
*
|
|
153
|
+
* This will override the default createJwk from the database
|
|
154
|
+
*
|
|
155
|
+
* @param data - The key to create
|
|
156
|
+
* @returns The created key
|
|
157
|
+
*/
|
|
158
|
+
createJwk?: (data: Omit<Jwk, "id">, ctx: index_d_exports.GenericEndpointContext) => Promise<Jwk>;
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Asymmetric (JWS) Supported.
|
|
163
|
+
*
|
|
164
|
+
* @see https://github.com/panva/jose/issues/210
|
|
165
|
+
*/
|
|
166
|
+
type JWKOptions = {
|
|
167
|
+
alg: "EdDSA";
|
|
168
|
+
crv?: "Ed25519" | undefined;
|
|
169
|
+
} | {
|
|
170
|
+
alg: "ES256";
|
|
171
|
+
crv?: never | undefined;
|
|
172
|
+
} | {
|
|
173
|
+
alg: "ES512";
|
|
174
|
+
crv?: never | undefined;
|
|
175
|
+
} | {
|
|
176
|
+
alg: "PS256";
|
|
177
|
+
modulusLength?: number | undefined;
|
|
178
|
+
} | {
|
|
179
|
+
alg: "RS256";
|
|
180
|
+
modulusLength?: number | undefined;
|
|
181
|
+
};
|
|
182
|
+
type JWSAlgorithms = JWKOptions["alg"];
|
|
183
|
+
interface Jwk {
|
|
184
|
+
id: string;
|
|
185
|
+
publicKey: string;
|
|
186
|
+
privateKey: string;
|
|
187
|
+
createdAt: Date;
|
|
188
|
+
expiresAt?: Date;
|
|
189
|
+
alg?: JWSAlgorithms | undefined;
|
|
190
|
+
crv?: ("Ed25519" | "P-256" | "P-521") | undefined;
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
193
|
+
export { JWKOptions, JWSAlgorithms, Jwk, JwtOptions };
|
|
194
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { JwtOptions } from "./types.mjs";
|
|
2
|
+
import { GenericEndpointContext } from "@better-auth/core";
|
|
3
|
+
import * as jose0 from "jose";
|
|
4
|
+
|
|
5
|
+
//#region src/plugins/jwt/utils.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Converts an expirationTime to ISO seconds expiration time (the format of JWT exp)
|
|
8
|
+
*
|
|
9
|
+
* See https://github.com/panva/jose/blob/main/src/lib/jwt_claims_set.ts#L245
|
|
10
|
+
*
|
|
11
|
+
* @param expirationTime - see options.jwt.expirationTime
|
|
12
|
+
* @param iat - the iat time to consolidate on
|
|
13
|
+
* @returns
|
|
14
|
+
*/
|
|
15
|
+
declare function toExpJWT(expirationTime: number | Date | string, iat: number): number;
|
|
16
|
+
declare function generateExportedKeyPair(options?: JwtOptions | undefined): Promise<{
|
|
17
|
+
publicWebKey: jose0.JWK;
|
|
18
|
+
privateWebKey: jose0.JWK;
|
|
19
|
+
alg: "EdDSA" | "ES256" | "ES512" | "PS256" | "RS256";
|
|
20
|
+
cfg: {
|
|
21
|
+
crv?: "Ed25519" | undefined;
|
|
22
|
+
} | {
|
|
23
|
+
crv?: never | undefined;
|
|
24
|
+
} | {
|
|
25
|
+
crv?: never | undefined;
|
|
26
|
+
} | {
|
|
27
|
+
modulusLength?: number | undefined;
|
|
28
|
+
} | {
|
|
29
|
+
modulusLength?: number | undefined;
|
|
30
|
+
};
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Creates a Jwk on the database
|
|
34
|
+
*
|
|
35
|
+
* @param ctx
|
|
36
|
+
* @param options
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
declare function createJwk(ctx: GenericEndpointContext, options?: JwtOptions | undefined): Promise<any>;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { createJwk, generateExportedKeyPair, toExpJWT };
|
|
42
|
+
//# sourceMappingURL=utils.d.mts.map
|