@hammadj/better-auth 1.5.0-beta.9
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/LICENSE.md +20 -0
- 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 +29 -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 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/mcp/index.ts"],"sourcesContent":["import type {\n\tBetterAuthOptions,\n\tBetterAuthPlugin,\n\tGenericEndpointContext,\n} from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport { isProduction, logger } from \"@better-auth/core/env\";\nimport { safeJSONParse } from \"@better-auth/core/utils/json\";\nimport { getWebcryptoSubtle } from \"@better-auth/utils\";\nimport { base64 } from \"@better-auth/utils/base64\";\nimport { createHash } from \"@better-auth/utils/hash\";\nimport { SignJWT } from \"jose\";\nimport * as z from \"zod\";\nimport { APIError, getSessionFromCtx } from \"../../api\";\nimport { expireCookie, parseSetCookieHeader } from \"../../cookies\";\nimport { generateRandomString } from \"../../crypto\";\nimport { HIDE_METADATA } from \"../../utils\";\nimport { getBaseURL } from \"../../utils/url\";\nimport type {\n\tClient,\n\tCodeVerificationValue,\n\tOAuthAccessToken,\n\tOIDCMetadata,\n\tOIDCOptions,\n} from \"../oidc-provider\";\nimport { oidcProvider } from \"../oidc-provider\";\nimport { schema } from \"../oidc-provider/schema\";\nimport { parsePrompt } from \"../oidc-provider/utils/prompt\";\nimport { authorizeMCPOAuth } from \"./authorize\";\n\ndeclare module \"@better-auth/core\" {\n\tinterface BetterAuthPluginRegistry<AuthOptions, Options> {\n\t\tmcp: {\n\t\t\tcreator: typeof mcp;\n\t\t};\n\t}\n}\n\ninterface MCPOptions {\n\tloginPage: string;\n\tresource?: string | undefined;\n\toidcConfig?: OIDCOptions | undefined;\n}\n\nexport const getMCPProviderMetadata = (\n\tctx: GenericEndpointContext,\n\toptions?: OIDCOptions | undefined,\n): OIDCMetadata => {\n\tconst issuer = ctx.context.options.baseURL as string;\n\tconst baseURL = ctx.context.baseURL;\n\tif (!issuer || !baseURL) {\n\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\terror: \"invalid_issuer\",\n\t\t\terror_description:\n\t\t\t\t\"issuer or baseURL is not set. If you're the app developer, please make sure to set the `baseURL` in your auth config.\",\n\t\t});\n\t}\n\treturn {\n\t\tissuer,\n\t\tauthorization_endpoint: `${baseURL}/mcp/authorize`,\n\t\ttoken_endpoint: `${baseURL}/mcp/token`,\n\t\tuserinfo_endpoint: `${baseURL}/mcp/userinfo`,\n\t\tjwks_uri: `${baseURL}/mcp/jwks`,\n\t\tregistration_endpoint: `${baseURL}/mcp/register`,\n\t\tscopes_supported: [\"openid\", \"profile\", \"email\", \"offline_access\"],\n\t\tresponse_types_supported: [\"code\"],\n\t\tresponse_modes_supported: [\"query\"],\n\t\tgrant_types_supported: [\"authorization_code\", \"refresh_token\"],\n\t\tacr_values_supported: [\n\t\t\t\"urn:mace:incommon:iap:silver\",\n\t\t\t\"urn:mace:incommon:iap:bronze\",\n\t\t],\n\t\tsubject_types_supported: [\"public\"],\n\t\tid_token_signing_alg_values_supported: [\"RS256\", \"none\"],\n\t\ttoken_endpoint_auth_methods_supported: [\n\t\t\t\"client_secret_basic\",\n\t\t\t\"client_secret_post\",\n\t\t\t\"none\",\n\t\t],\n\t\tcode_challenge_methods_supported: [\"S256\"],\n\t\tclaims_supported: [\n\t\t\t\"sub\",\n\t\t\t\"iss\",\n\t\t\t\"aud\",\n\t\t\t\"exp\",\n\t\t\t\"nbf\",\n\t\t\t\"iat\",\n\t\t\t\"jti\",\n\t\t\t\"email\",\n\t\t\t\"email_verified\",\n\t\t\t\"name\",\n\t\t],\n\t\t...options?.metadata,\n\t};\n};\n\nexport const getMCPProtectedResourceMetadata = (\n\tctx: GenericEndpointContext,\n\toptions?: MCPOptions | undefined,\n) => {\n\tconst baseURL = ctx.context.baseURL;\n\tconst origin = new URL(baseURL).origin;\n\n\treturn {\n\t\tresource: options?.resource ?? origin,\n\t\tauthorization_servers: [origin],\n\t\tjwks_uri: options?.oidcConfig?.metadata?.jwks_uri ?? `${baseURL}/mcp/jwks`,\n\t\tscopes_supported: options?.oidcConfig?.metadata?.scopes_supported ?? [\n\t\t\t\"openid\",\n\t\t\t\"profile\",\n\t\t\t\"email\",\n\t\t\t\"offline_access\",\n\t\t],\n\t\tbearer_methods_supported: [\"header\"],\n\t\tresource_signing_alg_values_supported: [\"RS256\", \"none\"],\n\t};\n};\n\nconst registerMcpClientBodySchema = z.object({\n\tredirect_uris: z.array(z.string()),\n\ttoken_endpoint_auth_method: z\n\t\t.enum([\"none\", \"client_secret_basic\", \"client_secret_post\"])\n\t\t.default(\"client_secret_basic\")\n\t\t.optional(),\n\tgrant_types: z\n\t\t.array(\n\t\t\tz.enum([\n\t\t\t\t\"authorization_code\",\n\t\t\t\t\"implicit\",\n\t\t\t\t\"password\",\n\t\t\t\t\"client_credentials\",\n\t\t\t\t\"refresh_token\",\n\t\t\t\t\"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n\t\t\t\t\"urn:ietf:params:oauth:grant-type:saml2-bearer\",\n\t\t\t]),\n\t\t)\n\t\t.default([\"authorization_code\"])\n\t\t.optional(),\n\tresponse_types: z\n\t\t.array(z.enum([\"code\", \"token\"]))\n\t\t.default([\"code\"])\n\t\t.optional(),\n\tclient_name: z.string().optional(),\n\tclient_uri: z.string().optional(),\n\tlogo_uri: z.string().optional(),\n\tscope: z.string().optional(),\n\tcontacts: z.array(z.string()).optional(),\n\ttos_uri: z.string().optional(),\n\tpolicy_uri: z.string().optional(),\n\tjwks_uri: z.string().optional(),\n\tjwks: z.record(z.string(), z.any()).optional(),\n\tmetadata: z.record(z.any(), z.any()).optional(),\n\tsoftware_id: z.string().optional(),\n\tsoftware_version: z.string().optional(),\n\tsoftware_statement: z.string().optional(),\n});\n\nconst mcpOAuthTokenBodySchema = z.record(z.any(), z.any());\n\nexport const mcp = (options: MCPOptions) => {\n\tconst opts = {\n\t\tcodeExpiresIn: 600,\n\t\tdefaultScope: \"openid\",\n\t\taccessTokenExpiresIn: 3600,\n\t\trefreshTokenExpiresIn: 604800,\n\t\tallowPlainCodeChallengeMethod: true,\n\t\t...options.oidcConfig,\n\t\tloginPage: options.loginPage,\n\t\tscopes: [\n\t\t\t\"openid\",\n\t\t\t\"profile\",\n\t\t\t\"email\",\n\t\t\t\"offline_access\",\n\t\t\t...(options.oidcConfig?.scopes || []),\n\t\t],\n\t};\n\tconst modelName = {\n\t\toauthClient: \"oauthApplication\",\n\t\toauthAccessToken: \"oauthAccessToken\",\n\t\toauthConsent: \"oauthConsent\",\n\t};\n\tconst provider = oidcProvider(opts);\n\treturn {\n\t\tid: \"mcp\",\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher() {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookie = await ctx.getSignedCookie(\n\t\t\t\t\t\t\t\"oidc_login_prompt\",\n\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst cookieName = ctx.context.authCookies.sessionToken.name;\n\t\t\t\t\t\tconst parsedSetCookieHeader = parseSetCookieHeader(\n\t\t\t\t\t\t\tctx.context.responseHeaders?.get(\"set-cookie\") || \"\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst hasSessionToken = parsedSetCookieHeader.has(cookieName);\n\t\t\t\t\t\tif (!cookie || !hasSessionToken) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\texpireCookie(ctx, {\n\t\t\t\t\t\t\tname: \"oidc_login_prompt\",\n\t\t\t\t\t\t\tattributes: { path: \"/\" },\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst sessionCookie = parsedSetCookieHeader.get(cookieName)?.value;\n\t\t\t\t\t\tconst sessionToken = sessionCookie?.split(\".\")[0]!;\n\t\t\t\t\t\tif (!sessionToken) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst session =\n\t\t\t\t\t\t\t(await ctx.context.internalAdapter.findSession(sessionToken)) ||\n\t\t\t\t\t\t\tctx.context.newSession;\n\t\t\t\t\t\tif (!session) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst parsedCookie = safeJSONParse<Record<string, string>>(cookie);\n\t\t\t\t\t\tif (!parsedCookie) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.query = parsedCookie;\n\n\t\t\t\t\t\t// Remove \"login\" from prompt since user just logged in\n\t\t\t\t\t\tconst promptSet = parsePrompt(String(ctx.query?.prompt));\n\t\t\t\t\t\tif (promptSet.has(\"login\")) {\n\t\t\t\t\t\t\tconst newPromptSet = new Set(promptSet);\n\t\t\t\t\t\t\tnewPromptSet.delete(\"login\");\n\t\t\t\t\t\t\tctx.query = {\n\t\t\t\t\t\t\t\t...ctx.query,\n\t\t\t\t\t\t\t\tprompt: Array.from(newPromptSet).join(\" \"),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tctx.context.session = session;\n\t\t\t\t\t\tconst response = await authorizeMCPOAuth(ctx, opts);\n\t\t\t\t\t\treturn response;\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tendpoints: {\n\t\t\toAuthConsent: provider.endpoints.oAuthConsent,\n\t\t\tgetMcpOAuthConfig: createAuthEndpoint(\n\t\t\t\t\"/.well-known/oauth-authorization-server\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tmetadata: HIDE_METADATA,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst metadata = getMCPProviderMetadata(c, options);\n\t\t\t\t\t\treturn c.json(metadata);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.log(e);\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetMCPProtectedResource: createAuthEndpoint(\n\t\t\t\t\"/.well-known/oauth-protected-resource\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tmetadata: HIDE_METADATA,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\tconst metadata = getMCPProtectedResourceMetadata(c, options);\n\t\t\t\t\treturn c.json(metadata);\n\t\t\t\t},\n\t\t\t),\n\t\t\tmcpOAuthAuthorize: createAuthEndpoint(\n\t\t\t\t\"/mcp/authorize\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tquery: z.record(z.string(), z.any()),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Authorize an OAuth2 request using MCP\",\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: \"Authorization response generated 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\tadditionalProperties: true,\n\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\"Authorization response, contents depend on the authorize function implementation\",\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\treturn authorizeMCPOAuth(ctx, opts);\n\t\t\t\t},\n\t\t\t),\n\t\t\tmcpOAuthToken: createAuthEndpoint(\n\t\t\t\t\"/mcp/token\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: mcpOAuthTokenBodySchema,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t...HIDE_METADATA,\n\t\t\t\t\t\tallowedMediaTypes: [\n\t\t\t\t\t\t\t\"application/x-www-form-urlencoded\",\n\t\t\t\t\t\t\t\"application/json\",\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//cors\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Methods\", \"POST, OPTIONS\");\n\t\t\t\t\tctx.setHeader(\n\t\t\t\t\t\t\"Access-Control-Allow-Headers\",\n\t\t\t\t\t\t\"Content-Type, Authorization\",\n\t\t\t\t\t);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\n\t\t\t\t\tlet { body } = ctx;\n\t\t\t\t\tif (!body) {\n\t\t\t\t\t\tthrow ctx.error(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"request body not found\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (body instanceof FormData) {\n\t\t\t\t\t\tbody = Object.fromEntries(body.entries());\n\t\t\t\t\t}\n\t\t\t\t\tif (!(body instanceof Object)) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"request body is not an object\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tlet { client_id, client_secret } = body;\n\t\t\t\t\tconst authorization =\n\t\t\t\t\t\tctx.request?.headers.get(\"authorization\") || null;\n\t\t\t\t\tif (\n\t\t\t\t\t\tauthorization &&\n\t\t\t\t\t\t!client_id &&\n\t\t\t\t\t\t!client_secret &&\n\t\t\t\t\t\tauthorization.startsWith(\"Basic \")\n\t\t\t\t\t) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst encoded = authorization.replace(\"Basic \", \"\");\n\t\t\t\t\t\t\tconst decoded = new TextDecoder().decode(base64.decode(encoded));\n\t\t\t\t\t\t\tif (!decoded.includes(\":\")) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst [id, secret] = decoded.split(\":\");\n\t\t\t\t\t\t\tif (!id || !secret) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tclient_id = id;\n\t\t\t\t\t\t\tclient_secret = secret;\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\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\tconst {\n\t\t\t\t\t\tgrant_type,\n\t\t\t\t\t\tcode,\n\t\t\t\t\t\tredirect_uri,\n\t\t\t\t\t\trefresh_token,\n\t\t\t\t\t\tcode_verifier,\n\t\t\t\t\t} = body;\n\t\t\t\t\tif (grant_type === \"refresh_token\") {\n\t\t\t\t\t\tif (!refresh_token) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror_description: \"refresh_token is required\",\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst token = await ctx.context.adapter.findOne<OAuthAccessToken>({\n\t\t\t\t\t\t\tmodel: \"oauthAccessToken\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfield: \"refreshToken\",\n\t\t\t\t\t\t\t\t\tvalue: refresh_token.toString(),\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\tif (!token) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid refresh token\",\n\t\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (token.clientId !== client_id?.toString()) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (token.refreshTokenExpiresAt < new Date()) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"refresh token expired\",\n\t\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst accessToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\t\tconst newRefreshToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\t\tconst accessTokenExpiresAt = new Date(\n\t\t\t\t\t\t\tDate.now() + opts.accessTokenExpiresIn * 1000,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst refreshTokenExpiresAt = new Date(\n\t\t\t\t\t\t\tDate.now() + opts.refreshTokenExpiresIn * 1000,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\taccessToken,\n\t\t\t\t\t\t\t\trefreshToken: newRefreshToken,\n\t\t\t\t\t\t\t\taccessTokenExpiresAt,\n\t\t\t\t\t\t\t\trefreshTokenExpiresAt,\n\t\t\t\t\t\t\t\tclientId: client_id.toString(),\n\t\t\t\t\t\t\t\tuserId: token.userId,\n\t\t\t\t\t\t\t\tscopes: token.scopes,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\t\taccess_token: accessToken,\n\t\t\t\t\t\t\ttoken_type: \"bearer\",\n\t\t\t\t\t\t\texpires_in: opts.accessTokenExpiresIn,\n\t\t\t\t\t\t\trefresh_token: newRefreshToken,\n\t\t\t\t\t\t\tscope: token.scopes,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (opts.requirePKCE && !code_verifier) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code verifier is missing\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * We need to check if the code is valid before we can proceed\n\t\t\t\t\t * with the rest of the request.\n\t\t\t\t\t */\n\t\t\t\t\tconst verificationValue =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findVerificationValue(\n\t\t\t\t\t\t\tcode.toString(),\n\t\t\t\t\t\t);\n\t\t\t\t\tif (!verificationValue) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid code\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (verificationValue.expiresAt < new Date()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"code expired\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteVerificationValue(\n\t\t\t\t\t\tverificationValue.id,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!client_id) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"client_id is required\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (!grant_type) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"grant_type is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (grant_type !== \"authorization_code\") {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"grant_type must be 'authorization_code'\",\n\t\t\t\t\t\t\terror: \"unsupported_grant_type\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!redirect_uri) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"redirect_uri is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst client = await ctx.context.adapter\n\t\t\t\t\t\t.findOne<Record<string, any>>({\n\t\t\t\t\t\t\tmodel: modelName.oauthClient,\n\t\t\t\t\t\t\twhere: [{ field: \"clientId\", value: client_id.toString() }],\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\tif (!res) {\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...res,\n\t\t\t\t\t\t\t\tredirectUrls: res.redirectUrls.split(\",\"),\n\t\t\t\t\t\t\t\tmetadata: res.metadata ? JSON.parse(res.metadata) : {},\n\t\t\t\t\t\t\t} as Client;\n\t\t\t\t\t\t});\n\t\t\t\t\tif (!client) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (client.disabled) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"client is disabled\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// For public clients (type: 'public'), validate PKCE instead of client_secret\n\t\t\t\t\tif (client.type === \"public\") {\n\t\t\t\t\t\t// Public clients must use PKCE\n\t\t\t\t\t\tif (!code_verifier) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"code verifier is required for public clients\",\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// PKCE validation happens later in the flow, so we skip client_secret validation\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// For confidential clients, validate client_secret\n\t\t\t\t\t\tif (!client_secret) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"client_secret is required for confidential clients\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst isValidSecret =\n\t\t\t\t\t\t\tclient.clientSecret === client_secret.toString();\n\t\t\t\t\t\tif (!isValidSecret) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid client_secret\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\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\tconst value = JSON.parse(\n\t\t\t\t\t\tverificationValue.value,\n\t\t\t\t\t) as CodeVerificationValue;\n\t\t\t\t\tif (value.clientId !== client_id.toString()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (value.redirectURI !== redirect_uri.toString()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid redirect_uri\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (value.codeChallenge && !code_verifier) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code verifier is missing\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst challenge =\n\t\t\t\t\t\tvalue.codeChallengeMethod === \"plain\"\n\t\t\t\t\t\t\t? code_verifier\n\t\t\t\t\t\t\t: await createHash(\"SHA-256\", \"base64urlnopad\").digest(\n\t\t\t\t\t\t\t\t\tcode_verifier,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\tif (challenge !== value.codeChallenge) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"code verification failed\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst requestedScopes = value.scope;\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteVerificationValue(\n\t\t\t\t\t\tverificationValue.id,\n\t\t\t\t\t);\n\t\t\t\t\tconst accessToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\tconst refreshToken = generateRandomString(32, \"A-Z\", \"a-z\");\n\t\t\t\t\tconst accessTokenExpiresAt = new Date(\n\t\t\t\t\t\tDate.now() + opts.accessTokenExpiresIn * 1000,\n\t\t\t\t\t);\n\t\t\t\t\tconst refreshTokenExpiresAt = new Date(\n\t\t\t\t\t\tDate.now() + opts.refreshTokenExpiresIn * 1000,\n\t\t\t\t\t);\n\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\taccessToken,\n\t\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\t\taccessTokenExpiresAt,\n\t\t\t\t\t\t\trefreshTokenExpiresAt,\n\t\t\t\t\t\t\tclientId: client_id.toString(),\n\t\t\t\t\t\t\tuserId: value.userId,\n\t\t\t\t\t\t\tscopes: requestedScopes.join(\" \"),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tconst user = await ctx.context.internalAdapter.findUserById(\n\t\t\t\t\t\tvalue.userId,\n\t\t\t\t\t);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"user not found\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst secretKey = {\n\t\t\t\t\t\talg: \"HS256\",\n\t\t\t\t\t\tkey: await getWebcryptoSubtle().generateKey(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: \"HMAC\",\n\t\t\t\t\t\t\t\thash: \"SHA-256\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t[\"sign\", \"verify\"],\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t\tconst profile = {\n\t\t\t\t\t\tgiven_name: user.name.split(\" \")[0]!,\n\t\t\t\t\t\tfamily_name: user.name.split(\" \")[1]!,\n\t\t\t\t\t\tname: user.name,\n\t\t\t\t\t\tprofile: user.image,\n\t\t\t\t\t\tupdated_at: Math.floor(new Date(user.updatedAt).getTime() / 1000),\n\t\t\t\t\t};\n\t\t\t\t\tconst email = {\n\t\t\t\t\t\temail: user.email,\n\t\t\t\t\t\temail_verified: user.emailVerified,\n\t\t\t\t\t};\n\t\t\t\t\tconst userClaims = {\n\t\t\t\t\t\t...(requestedScopes.includes(\"profile\") ? profile : {}),\n\t\t\t\t\t\t...(requestedScopes.includes(\"email\") ? email : {}),\n\t\t\t\t\t};\n\n\t\t\t\t\tconst additionalUserClaims = opts.getAdditionalUserInfoClaim\n\t\t\t\t\t\t? await opts.getAdditionalUserInfoClaim(\n\t\t\t\t\t\t\t\tuser,\n\t\t\t\t\t\t\t\trequestedScopes,\n\t\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: {};\n\n\t\t\t\t\tconst idToken = await new SignJWT({\n\t\t\t\t\t\tsub: user.id,\n\t\t\t\t\t\taud: client_id.toString(),\n\t\t\t\t\t\tiat: Date.now(),\n\t\t\t\t\t\tauth_time: ctx.context.session\n\t\t\t\t\t\t\t? new Date(ctx.context.session.session.createdAt).getTime()\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tnonce: value.nonce,\n\t\t\t\t\t\tacr: \"urn:mace:incommon:iap:silver\", // default to silver - ⚠︎ this should be configurable and should be validated against the client's metadata\n\t\t\t\t\t\t...userClaims,\n\t\t\t\t\t\t...additionalUserClaims,\n\t\t\t\t\t})\n\t\t\t\t\t\t.setProtectedHeader({ alg: secretKey.alg })\n\t\t\t\t\t\t.setIssuedAt()\n\t\t\t\t\t\t.setExpirationTime(\n\t\t\t\t\t\t\tMath.floor(Date.now() / 1000) + opts.accessTokenExpiresIn,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.sign(secretKey.key);\n\t\t\t\t\treturn ctx.json(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taccess_token: accessToken,\n\t\t\t\t\t\t\ttoken_type: \"Bearer\",\n\t\t\t\t\t\t\texpires_in: opts.accessTokenExpiresIn,\n\t\t\t\t\t\t\trefresh_token: requestedScopes.includes(\"offline_access\")\n\t\t\t\t\t\t\t\t? refreshToken\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tscope: requestedScopes.join(\" \"),\n\t\t\t\t\t\t\tid_token: requestedScopes.includes(\"openid\")\n\t\t\t\t\t\t\t\t? idToken\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t\t\t\t\t\tPragma: \"no-cache\",\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\tregisterMcpClient: createAuthEndpoint(\n\t\t\t\t\"/mcp/register\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: registerMcpClientBodySchema,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Register an OAuth2 application\",\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: \"OAuth2 application registered 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\tname: {\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\tdescription: \"Name of the OAuth2 application\",\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\ticon: {\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\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Icon URL for the application\",\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\tmetadata: {\n\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\tadditionalProperties: true,\n\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\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Additional metadata for the application\",\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\tclientId: {\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\tdescription: \"Unique identifier for the client\",\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\tclientSecret: {\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\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Secret key for the client. Not included for public clients.\",\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\tredirectUrls: {\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\titems: { type: \"string\", format: \"uri\" },\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"List of allowed redirect URLs\",\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\ttype: {\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\tdescription: \"Type of the client\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [\"web\", \"public\"],\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\tauthenticationScheme: {\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\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Authentication scheme used by the client\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [\"client_secret\", \"none\"],\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\tdisabled: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Whether the client is disabled\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [false],\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\tuserId: {\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\tnullable: true,\n\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\"ID of the user who registered the client, null if registered anonymously\",\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\tcreatedAt: {\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\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Creation timestamp\",\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\tupdatedAt: {\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\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Last update timestamp\",\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: [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"clientId\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"redirectUrls\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"authenticationScheme\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"disabled\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"createdAt\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"updatedAt\",\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 body = ctx.body;\n\t\t\t\t\tconst session = await getSessionFromCtx(ctx);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Methods\", \"POST, OPTIONS\");\n\t\t\t\t\tctx.setHeader(\n\t\t\t\t\t\t\"Access-Control-Allow-Headers\",\n\t\t\t\t\t\t\"Content-Type, Authorization\",\n\t\t\t\t\t);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\t\t\t\t\tctx.headers?.set(\"Access-Control-Max-Age\", \"86400\");\n\t\t\t\t\tif (\n\t\t\t\t\t\t(!body.grant_types ||\n\t\t\t\t\t\t\tbody.grant_types.includes(\"authorization_code\") ||\n\t\t\t\t\t\t\tbody.grant_types.includes(\"implicit\")) &&\n\t\t\t\t\t\t(!body.redirect_uris || body.redirect_uris.length === 0)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror: \"invalid_redirect_uri\",\n\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\"Redirect URIs are required for authorization_code and implicit grant types\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (body.grant_types && body.response_types) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tbody.grant_types.includes(\"authorization_code\") &&\n\t\t\t\t\t\t\t!body.response_types.includes(\"code\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror: \"invalid_client_metadata\",\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"When 'authorization_code' grant type is used, 'code' response type must be included\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tbody.grant_types.includes(\"implicit\") &&\n\t\t\t\t\t\t\t!body.response_types.includes(\"token\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror: \"invalid_client_metadata\",\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"When 'implicit' grant type is used, 'token' response type must be included\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst clientId =\n\t\t\t\t\t\topts.generateClientId?.() || generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\tconst clientSecret =\n\t\t\t\t\t\topts.generateClientSecret?.() ||\n\t\t\t\t\t\tgenerateRandomString(32, \"a-z\", \"A-Z\");\n\n\t\t\t\t\t// Determine client type based on auth method\n\t\t\t\t\tconst clientType =\n\t\t\t\t\t\tbody.token_endpoint_auth_method === \"none\" ? \"public\" : \"web\";\n\t\t\t\t\tconst finalClientSecret = clientType === \"public\" ? \"\" : clientSecret;\n\n\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: modelName.oauthClient,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tname: body.client_name,\n\t\t\t\t\t\t\ticon: body.logo_uri,\n\t\t\t\t\t\t\tmetadata: body.metadata ? JSON.stringify(body.metadata) : null,\n\t\t\t\t\t\t\tclientId: clientId,\n\t\t\t\t\t\t\tclientSecret: finalClientSecret,\n\t\t\t\t\t\t\tredirectUrls: body.redirect_uris.join(\",\"),\n\t\t\t\t\t\t\ttype: clientType,\n\t\t\t\t\t\t\tauthenticationScheme:\n\t\t\t\t\t\t\t\tbody.token_endpoint_auth_method || \"client_secret_basic\",\n\t\t\t\t\t\t\tdisabled: false,\n\t\t\t\t\t\t\tuserId: session?.session.userId,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tconst responseData = {\n\t\t\t\t\t\tclient_id: clientId,\n\t\t\t\t\t\tclient_id_issued_at: Math.floor(Date.now() / 1000),\n\t\t\t\t\t\tredirect_uris: body.redirect_uris,\n\t\t\t\t\t\ttoken_endpoint_auth_method:\n\t\t\t\t\t\t\tbody.token_endpoint_auth_method || \"client_secret_basic\",\n\t\t\t\t\t\tgrant_types: body.grant_types || [\"authorization_code\"],\n\t\t\t\t\t\tresponse_types: body.response_types || [\"code\"],\n\t\t\t\t\t\tclient_name: body.client_name,\n\t\t\t\t\t\tclient_uri: body.client_uri,\n\t\t\t\t\t\tlogo_uri: body.logo_uri,\n\t\t\t\t\t\tscope: body.scope,\n\t\t\t\t\t\tcontacts: body.contacts,\n\t\t\t\t\t\ttos_uri: body.tos_uri,\n\t\t\t\t\t\tpolicy_uri: body.policy_uri,\n\t\t\t\t\t\tjwks_uri: body.jwks_uri,\n\t\t\t\t\t\tjwks: body.jwks,\n\t\t\t\t\t\tsoftware_id: body.software_id,\n\t\t\t\t\t\tsoftware_version: body.software_version,\n\t\t\t\t\t\tsoftware_statement: body.software_statement,\n\t\t\t\t\t\tmetadata: body.metadata,\n\t\t\t\t\t\t...(clientType !== \"public\"\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tclient_secret: finalClientSecret,\n\t\t\t\t\t\t\t\t\tclient_secret_expires_at: 0, // 0 means it doesn't expire\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t};\n\n\t\t\t\t\treturn new Response(JSON.stringify(responseData), {\n\t\t\t\t\t\tstatus: 201,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t\t\t\t\tPragma: \"no-cache\",\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\tgetMcpSession: createAuthEndpoint(\n\t\t\t\t\"/mcp/get-session\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\tconst accessToken = c.headers\n\t\t\t\t\t\t?.get(\"Authorization\")\n\t\t\t\t\t\t?.replace(\"Bearer \", \"\");\n\t\t\t\t\tif (!accessToken) {\n\t\t\t\t\t\tc.headers?.set(\"WWW-Authenticate\", \"Bearer\");\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t\tconst accessTokenData =\n\t\t\t\t\t\tawait c.context.adapter.findOne<OAuthAccessToken>({\n\t\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfield: \"accessToken\",\n\t\t\t\t\t\t\t\t\tvalue: accessToken,\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\tif (!accessTokenData) {\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t\treturn c.json(accessTokenData);\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\tschema,\n\t\toptions,\n\t} satisfies BetterAuthPlugin;\n};\n\nexport const withMcpAuth = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMcpSession: (...args: any) => Promise<OAuthAccessToken | null>;\n\t\t};\n\t\toptions: BetterAuthOptions;\n\t},\n>(\n\tauth: Auth,\n\thandler: (\n\t\treq: Request,\n\t\tsession: OAuthAccessToken,\n\t) => Response | Promise<Response>,\n) => {\n\treturn async (req: Request) => {\n\t\tconst baseURL = getBaseURL(auth.options.baseURL, auth.options.basePath);\n\t\tif (!baseURL && !isProduction) {\n\t\t\tlogger.warn(\"Unable to get the baseURL, please check your config!\");\n\t\t}\n\t\tconst session = await auth.api.getMcpSession({\n\t\t\theaders: req.headers,\n\t\t});\n\t\tconst wwwAuthenticateValue = `Bearer resource_metadata=\"${baseURL}/.well-known/oauth-protected-resource\"`;\n\t\tif (!session) {\n\t\t\treturn Response.json(\n\t\t\t\t{\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: -32000,\n\t\t\t\t\t\tmessage: \"Unauthorized: Authentication required\",\n\t\t\t\t\t\t\"www-authenticate\": wwwAuthenticateValue,\n\t\t\t\t\t},\n\t\t\t\t\tid: null,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tstatus: 401,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"WWW-Authenticate\": wwwAuthenticateValue,\n\t\t\t\t\t\t// we also add this headers otherwise browser based clients will not be able to read the `www-authenticate` header\n\t\t\t\t\t\t\"Access-Control-Expose-Headers\": \"WWW-Authenticate\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\treturn handler(req, session);\n\t};\n};\n\nexport const oAuthDiscoveryMetadata = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMcpOAuthConfig: (...args: any) => any;\n\t\t};\n\t},\n>(\n\tauth: Auth,\n) => {\n\treturn async (request: Request) => {\n\t\tconst res = await auth.api.getMcpOAuthConfig();\n\t\treturn new Response(JSON.stringify(res), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Access-Control-Allow-Origin\": \"*\",\n\t\t\t\t\"Access-Control-Allow-Methods\": \"POST, OPTIONS\",\n\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\"Access-Control-Max-Age\": \"86400\",\n\t\t\t},\n\t\t});\n\t};\n};\n\nexport const oAuthProtectedResourceMetadata = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMCPProtectedResource: (...args: any) => any;\n\t\t};\n\t},\n>(\n\tauth: Auth,\n) => {\n\treturn async (request: Request) => {\n\t\tconst res = await auth.api.getMCPProtectedResource();\n\t\treturn new Response(JSON.stringify(res), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Access-Control-Allow-Origin\": \"*\",\n\t\t\t\t\"Access-Control-Allow-Methods\": \"POST, OPTIONS\",\n\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\"Access-Control-Max-Age\": \"86400\",\n\t\t\t},\n\t\t});\n\t};\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MULTI_SESSION_ERROR_CODES } from "./error-codes.mjs";
|
|
2
|
+
import { MultiSessionConfig } from "./index.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/multi-session/client.d.ts
|
|
5
|
+
declare const multiSessionClient: () => BetterAuthClientPlugin;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { multiSessionClient };
|
|
8
|
+
//# sourceMappingURL=client.d.mts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { MULTI_SESSION_ERROR_CODES } from "./error-codes.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/multi-session/client.ts
|
|
4
|
+
const multiSessionClient = () => {
|
|
5
|
+
return {
|
|
6
|
+
id: "multi-session",
|
|
7
|
+
$InferServerPlugin: {},
|
|
8
|
+
atomListeners: [{
|
|
9
|
+
matcher(path) {
|
|
10
|
+
return path === "/multi-session/set-active";
|
|
11
|
+
},
|
|
12
|
+
signal: "$sessionSignal"
|
|
13
|
+
}],
|
|
14
|
+
$ERROR_CODES: MULTI_SESSION_ERROR_CODES
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { multiSessionClient };
|
|
20
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../../../src/plugins/multi-session/client.ts"],"sourcesContent":["import type { BetterAuthClientPlugin } from \"@better-auth/core\";\nimport type { multiSession } from \".\";\nimport { MULTI_SESSION_ERROR_CODES } from \"./error-codes\";\n\nexport * from \"./error-codes\";\n\nexport const multiSessionClient = () => {\n\treturn {\n\t\tid: \"multi-session\",\n\t\t$InferServerPlugin: {} as ReturnType<typeof multiSession>,\n\t\tatomListeners: [\n\t\t\t{\n\t\t\t\tmatcher(path) {\n\t\t\t\t\treturn path === \"/multi-session/set-active\";\n\t\t\t\t},\n\t\t\t\tsignal: \"$sessionSignal\",\n\t\t\t},\n\t\t],\n\t\t$ERROR_CODES: MULTI_SESSION_ERROR_CODES,\n\t} satisfies BetterAuthClientPlugin;\n};\n\nexport type { MultiSessionConfig } from \"./index\";\n"],"mappings":";;;AAMA,MAAa,2BAA2B;AACvC,QAAO;EACN,IAAI;EACJ,oBAAoB,EAAE;EACtB,eAAe,CACd;GACC,QAAQ,MAAM;AACb,WAAO,SAAS;;GAEjB,QAAQ;GACR,CACD;EACD,cAAc;EACd"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { defineErrorCodes } from "@better-auth/core/utils/error-codes";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/multi-session/error-codes.ts
|
|
4
|
+
const MULTI_SESSION_ERROR_CODES = defineErrorCodes({ INVALID_SESSION_TOKEN: "Invalid session token" });
|
|
5
|
+
|
|
6
|
+
//#endregion
|
|
7
|
+
export { MULTI_SESSION_ERROR_CODES };
|
|
8
|
+
//# sourceMappingURL=error-codes.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-codes.mjs","names":[],"sources":["../../../src/plugins/multi-session/error-codes.ts"],"sourcesContent":["import { defineErrorCodes } from \"@better-auth/core/utils/error-codes\";\n\nexport const MULTI_SESSION_ERROR_CODES = defineErrorCodes({\n\tINVALID_SESSION_TOKEN: \"Invalid session token\",\n});\n"],"mappings":";;;AAEA,MAAa,4BAA4B,iBAAiB,EACzD,uBAAuB,yBACvB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MULTI_SESSION_ERROR_CODES } from "./error-codes.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/multi-session/index.d.ts
|
|
4
|
+
declare module "@better-auth/core" {
|
|
5
|
+
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
6
|
+
"multi-session": {
|
|
7
|
+
creator: typeof multiSession;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
interface MultiSessionConfig {
|
|
12
|
+
/**
|
|
13
|
+
* The maximum number of sessions a user can have
|
|
14
|
+
* at a time
|
|
15
|
+
* @default 5
|
|
16
|
+
*/
|
|
17
|
+
maximumSessions?: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
declare const multiSession: (options?: MultiSessionConfig | undefined) => BetterAuthPlugin;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { MULTI_SESSION_ERROR_CODES as ERROR_CODES, MultiSessionConfig, multiSession };
|
|
22
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { parseSessionOutput, parseUserOutput } from "../../db/schema.mjs";
|
|
2
|
+
import { SECURE_COOKIE_PREFIX, parseSetCookieHeader } from "../../cookies/cookie-utils.mjs";
|
|
3
|
+
import { deleteSessionCookie, expireCookie, parseCookies, setSessionCookie } from "../../cookies/index.mjs";
|
|
4
|
+
import { sessionMiddleware } from "../../api/routes/session.mjs";
|
|
5
|
+
import { APIError } from "../../api/index.mjs";
|
|
6
|
+
import { MULTI_SESSION_ERROR_CODES } from "./error-codes.mjs";
|
|
7
|
+
import { createAuthEndpoint, createAuthMiddleware } from "@better-auth/core/api";
|
|
8
|
+
import * as z from "zod";
|
|
9
|
+
|
|
10
|
+
//#region src/plugins/multi-session/index.ts
|
|
11
|
+
const setActiveSessionBodySchema = z.object({ sessionToken: z.string().meta({ description: "The session token to set as active" }) });
|
|
12
|
+
const revokeDeviceSessionBodySchema = z.object({ sessionToken: z.string().meta({ description: "The session token to revoke" }) });
|
|
13
|
+
const multiSession = (options) => {
|
|
14
|
+
const opts = {
|
|
15
|
+
maximumSessions: 5,
|
|
16
|
+
...options
|
|
17
|
+
};
|
|
18
|
+
const isMultiSessionCookie = (key) => key.includes("_multi-");
|
|
19
|
+
return {
|
|
20
|
+
id: "multi-session",
|
|
21
|
+
endpoints: {
|
|
22
|
+
listDeviceSessions: createAuthEndpoint("/multi-session/list-device-sessions", {
|
|
23
|
+
method: "GET",
|
|
24
|
+
requireHeaders: true
|
|
25
|
+
}, async (ctx) => {
|
|
26
|
+
const cookieHeader = ctx.headers?.get("cookie");
|
|
27
|
+
if (!cookieHeader) return ctx.json([]);
|
|
28
|
+
const cookies = Object.fromEntries(parseCookies(cookieHeader));
|
|
29
|
+
const sessionTokens = (await Promise.all(Object.entries(cookies).filter(([key]) => isMultiSessionCookie(key)).map(async ([key]) => await ctx.getSignedCookie(key, ctx.context.secret)))).filter((v) => typeof v === "string");
|
|
30
|
+
if (!sessionTokens.length) return ctx.json([]);
|
|
31
|
+
const uniqueUserSessions = (await ctx.context.internalAdapter.findSessions(sessionTokens)).filter((session) => session && session.session.expiresAt > /* @__PURE__ */ new Date()).reduce((acc, session) => {
|
|
32
|
+
if (!acc.find((s) => s.user.id === session.user.id)) acc.push(session);
|
|
33
|
+
return acc;
|
|
34
|
+
}, []);
|
|
35
|
+
return ctx.json(uniqueUserSessions.map((item) => ({
|
|
36
|
+
session: parseSessionOutput(ctx.context.options, item.session),
|
|
37
|
+
user: parseUserOutput(ctx.context.options, item.user)
|
|
38
|
+
})));
|
|
39
|
+
}),
|
|
40
|
+
setActiveSession: createAuthEndpoint("/multi-session/set-active", {
|
|
41
|
+
method: "POST",
|
|
42
|
+
body: setActiveSessionBodySchema,
|
|
43
|
+
requireHeaders: true,
|
|
44
|
+
use: [sessionMiddleware],
|
|
45
|
+
metadata: { openapi: {
|
|
46
|
+
description: "Set the active session",
|
|
47
|
+
responses: { 200: {
|
|
48
|
+
description: "Success",
|
|
49
|
+
content: { "application/json": { schema: {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: { session: { $ref: "#/components/schemas/Session" } }
|
|
52
|
+
} } }
|
|
53
|
+
} }
|
|
54
|
+
} }
|
|
55
|
+
}, async (ctx) => {
|
|
56
|
+
const sessionToken = ctx.body.sessionToken;
|
|
57
|
+
const multiSessionCookieName = `${ctx.context.authCookies.sessionToken.name}_multi-${sessionToken.toLowerCase()}`;
|
|
58
|
+
if (!await ctx.getSignedCookie(multiSessionCookieName, ctx.context.secret)) throw APIError.from("UNAUTHORIZED", MULTI_SESSION_ERROR_CODES.INVALID_SESSION_TOKEN);
|
|
59
|
+
const session = await ctx.context.internalAdapter.findSession(sessionToken);
|
|
60
|
+
if (!session || session.session.expiresAt < /* @__PURE__ */ new Date()) {
|
|
61
|
+
expireCookie(ctx, {
|
|
62
|
+
name: multiSessionCookieName,
|
|
63
|
+
attributes: ctx.context.authCookies.sessionToken.attributes
|
|
64
|
+
});
|
|
65
|
+
throw APIError.from("UNAUTHORIZED", MULTI_SESSION_ERROR_CODES.INVALID_SESSION_TOKEN);
|
|
66
|
+
}
|
|
67
|
+
await setSessionCookie(ctx, session);
|
|
68
|
+
return ctx.json({
|
|
69
|
+
session: parseSessionOutput(ctx.context.options, session.session),
|
|
70
|
+
user: parseUserOutput(ctx.context.options, session.user)
|
|
71
|
+
});
|
|
72
|
+
}),
|
|
73
|
+
revokeDeviceSession: createAuthEndpoint("/multi-session/revoke", {
|
|
74
|
+
method: "POST",
|
|
75
|
+
body: revokeDeviceSessionBodySchema,
|
|
76
|
+
requireHeaders: true,
|
|
77
|
+
use: [sessionMiddleware],
|
|
78
|
+
metadata: { openapi: {
|
|
79
|
+
description: "Revoke a device session",
|
|
80
|
+
responses: { 200: {
|
|
81
|
+
description: "Success",
|
|
82
|
+
content: { "application/json": { schema: {
|
|
83
|
+
type: "object",
|
|
84
|
+
properties: { status: { type: "boolean" } }
|
|
85
|
+
} } }
|
|
86
|
+
} }
|
|
87
|
+
} }
|
|
88
|
+
}, async (ctx) => {
|
|
89
|
+
const sessionToken = ctx.body.sessionToken;
|
|
90
|
+
const multiSessionCookieName = `${ctx.context.authCookies.sessionToken.name}_multi-${sessionToken.toLowerCase()}`;
|
|
91
|
+
if (!await ctx.getSignedCookie(multiSessionCookieName, ctx.context.secret)) throw APIError.from("UNAUTHORIZED", MULTI_SESSION_ERROR_CODES.INVALID_SESSION_TOKEN);
|
|
92
|
+
await ctx.context.internalAdapter.deleteSession(sessionToken);
|
|
93
|
+
expireCookie(ctx, {
|
|
94
|
+
name: multiSessionCookieName,
|
|
95
|
+
attributes: ctx.context.authCookies.sessionToken.attributes
|
|
96
|
+
});
|
|
97
|
+
if (!(ctx.context.session?.session.token === sessionToken)) return ctx.json({ status: true });
|
|
98
|
+
const cookieHeader = ctx.headers?.get("cookie");
|
|
99
|
+
if (cookieHeader) {
|
|
100
|
+
const cookies = Object.fromEntries(parseCookies(cookieHeader));
|
|
101
|
+
const sessionTokens = (await Promise.all(Object.entries(cookies).filter(([key]) => isMultiSessionCookie(key)).map(async ([key]) => await ctx.getSignedCookie(key, ctx.context.secret)))).filter((v) => typeof v === "string");
|
|
102
|
+
const internalAdapter = ctx.context.internalAdapter;
|
|
103
|
+
if (sessionTokens.length > 0) {
|
|
104
|
+
const validSessions = (await internalAdapter.findSessions(sessionTokens)).filter((session) => session && session.session.expiresAt > /* @__PURE__ */ new Date());
|
|
105
|
+
if (validSessions.length > 0) {
|
|
106
|
+
const nextSession = validSessions[0];
|
|
107
|
+
await setSessionCookie(ctx, nextSession);
|
|
108
|
+
} else deleteSessionCookie(ctx);
|
|
109
|
+
} else deleteSessionCookie(ctx);
|
|
110
|
+
} else deleteSessionCookie(ctx);
|
|
111
|
+
return ctx.json({ status: true });
|
|
112
|
+
})
|
|
113
|
+
},
|
|
114
|
+
hooks: { after: [{
|
|
115
|
+
matcher: () => true,
|
|
116
|
+
handler: createAuthMiddleware(async (ctx) => {
|
|
117
|
+
const cookieString = ctx.context.responseHeaders?.get("set-cookie");
|
|
118
|
+
if (!cookieString) return;
|
|
119
|
+
const newSession = ctx.context.newSession;
|
|
120
|
+
if (!newSession) return;
|
|
121
|
+
const sessionCookieConfig = ctx.context.authCookies.sessionToken;
|
|
122
|
+
const sessionToken = newSession.session.token;
|
|
123
|
+
const cookieName = `${sessionCookieConfig.name}_multi-${sessionToken.toLowerCase()}`;
|
|
124
|
+
const setCookies = parseSetCookieHeader(cookieString);
|
|
125
|
+
const cookies = parseCookies(ctx.headers?.get("cookie") || "");
|
|
126
|
+
if (setCookies.get(cookieName) || cookies.get(cookieName)) return;
|
|
127
|
+
const multiSessionKeys = Object.keys(Object.fromEntries(cookies)).filter(isMultiSessionCookie);
|
|
128
|
+
const tokensToDelete = [];
|
|
129
|
+
for (const key of multiSessionKeys) {
|
|
130
|
+
const token = await ctx.getSignedCookie(key, ctx.context.secret);
|
|
131
|
+
if (!token) continue;
|
|
132
|
+
if ((await ctx.context.internalAdapter.findSession(token))?.user.id === newSession.user.id) {
|
|
133
|
+
tokensToDelete.push(token);
|
|
134
|
+
ctx.setCookie(key, "", {
|
|
135
|
+
...sessionCookieConfig.attributes,
|
|
136
|
+
maxAge: 0
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (tokensToDelete.length > 0) await ctx.context.internalAdapter.deleteSessions(tokensToDelete);
|
|
141
|
+
if (multiSessionKeys.length - tokensToDelete.length + (cookieString.includes(sessionCookieConfig.name) ? 1 : 0) > opts.maximumSessions) return;
|
|
142
|
+
await ctx.setSignedCookie(cookieName, sessionToken, ctx.context.secret, sessionCookieConfig.attributes);
|
|
143
|
+
})
|
|
144
|
+
}, {
|
|
145
|
+
matcher: (context) => context.path === "/sign-out",
|
|
146
|
+
handler: createAuthMiddleware(async (ctx) => {
|
|
147
|
+
const cookieHeader = ctx.headers?.get("cookie");
|
|
148
|
+
if (!cookieHeader) return;
|
|
149
|
+
const cookies = Object.fromEntries(parseCookies(cookieHeader));
|
|
150
|
+
const multiSessionKeys = Object.keys(cookies).filter((key) => isMultiSessionCookie(key));
|
|
151
|
+
const verifiedTokens = (await Promise.all(multiSessionKeys.map(async (key) => {
|
|
152
|
+
const verifiedToken = await ctx.getSignedCookie(key, ctx.context.secret);
|
|
153
|
+
if (verifiedToken) {
|
|
154
|
+
expireCookie(ctx, {
|
|
155
|
+
name: key.toLowerCase().replace(SECURE_COOKIE_PREFIX.toLowerCase(), SECURE_COOKIE_PREFIX),
|
|
156
|
+
attributes: ctx.context.authCookies.sessionToken.attributes
|
|
157
|
+
});
|
|
158
|
+
return verifiedToken;
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}))).filter((v) => typeof v === "string");
|
|
162
|
+
if (verifiedTokens.length > 0) await ctx.context.internalAdapter.deleteSessions(verifiedTokens);
|
|
163
|
+
})
|
|
164
|
+
}] },
|
|
165
|
+
options,
|
|
166
|
+
$ERROR_CODES: MULTI_SESSION_ERROR_CODES
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
export { MULTI_SESSION_ERROR_CODES as ERROR_CODES, multiSession };
|
|
172
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["ERROR_CODES"],"sources":["../../../src/plugins/multi-session/index.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport * as z from \"zod\";\nimport { APIError, sessionMiddleware } from \"../../api\";\nimport {\n\tdeleteSessionCookie,\n\texpireCookie,\n\tparseCookies,\n\tparseSetCookieHeader,\n\tSECURE_COOKIE_PREFIX,\n\tsetSessionCookie,\n} from \"../../cookies\";\nimport { parseSessionOutput, parseUserOutput } from \"../../db/schema\";\n\ndeclare module \"@better-auth/core\" {\n\tinterface BetterAuthPluginRegistry<AuthOptions, Options> {\n\t\t\"multi-session\": {\n\t\t\tcreator: typeof multiSession;\n\t\t};\n\t}\n}\n\nexport interface MultiSessionConfig {\n\t/**\n\t * The maximum number of sessions a user can have\n\t * at a time\n\t * @default 5\n\t */\n\tmaximumSessions?: number | undefined;\n}\n\nimport { MULTI_SESSION_ERROR_CODES as ERROR_CODES } from \"./error-codes\";\n\nexport { MULTI_SESSION_ERROR_CODES as ERROR_CODES } from \"./error-codes\";\n\nconst setActiveSessionBodySchema = z.object({\n\tsessionToken: z.string().meta({\n\t\tdescription: \"The session token to set as active\",\n\t}),\n});\n\nconst revokeDeviceSessionBodySchema = z.object({\n\tsessionToken: z.string().meta({\n\t\tdescription: \"The session token to revoke\",\n\t}),\n});\n\nexport const multiSession = (options?: MultiSessionConfig | undefined) => {\n\tconst opts = {\n\t\tmaximumSessions: 5,\n\t\t...options,\n\t};\n\n\tconst isMultiSessionCookie = (key: string) => key.includes(\"_multi-\");\n\n\treturn {\n\t\tid: \"multi-session\",\n\t\tendpoints: {\n\t\t\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * GET `/multi-session/list-device-sessions`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.listDeviceSessions`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.listDeviceSessions`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-list-device-sessions)\n\t\t\t */\n\t\t\tlistDeviceSessions: createAuthEndpoint(\n\t\t\t\t\"/multi-session/list-device-sessions\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\tif (!cookieHeader) return ctx.json([]);\n\n\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\t\t\t\t\tconst sessionTokens = (\n\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\tObject.entries(cookies)\n\t\t\t\t\t\t\t\t.filter(([key]) => isMultiSessionCookie(key))\n\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\tasync ([key]) =>\n\t\t\t\t\t\t\t\t\t\tawait ctx.getSignedCookie(key, ctx.context.secret),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\n\t\t\t\t\tif (!sessionTokens.length) return ctx.json([]);\n\t\t\t\t\tconst sessions =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findSessions(sessionTokens);\n\t\t\t\t\tconst validSessions = sessions.filter(\n\t\t\t\t\t\t(session) => session && session.session.expiresAt > new Date(),\n\t\t\t\t\t);\n\t\t\t\t\tconst uniqueUserSessions = validSessions.reduce(\n\t\t\t\t\t\t(acc, session) => {\n\t\t\t\t\t\t\tif (!acc.find((s) => s.user.id === session.user.id)) {\n\t\t\t\t\t\t\t\tacc.push(session);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn acc;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t[] as typeof validSessions,\n\t\t\t\t\t);\n\t\t\t\t\treturn ctx.json(\n\t\t\t\t\t\tuniqueUserSessions.map((item) => ({\n\t\t\t\t\t\t\tsession: parseSessionOutput(ctx.context.options, item.session),\n\t\t\t\t\t\t\tuser: parseUserOutput(ctx.context.options, item.user),\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\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * POST `/multi-session/set-active`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.setActiveSession`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.setActive`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-set-active)\n\t\t\t */\n\t\t\tsetActiveSession: createAuthEndpoint(\n\t\t\t\t\"/multi-session/set-active\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: setActiveSessionBodySchema,\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\tdescription: \"Set the active session\",\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\tsession: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$ref: \"#/components/schemas/Session\",\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 sessionToken = ctx.body.sessionToken;\n\t\t\t\t\tconst multiSessionCookieName = `${\n\t\t\t\t\t\tctx.context.authCookies.sessionToken.name\n\t\t\t\t\t}_multi-${sessionToken.toLowerCase()}`;\n\t\t\t\t\tconst sessionCookie = await ctx.getSignedCookie(\n\t\t\t\t\t\tmultiSessionCookieName,\n\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t);\n\t\t\t\t\tif (!sessionCookie) {\n\t\t\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\t\t\"UNAUTHORIZED\",\n\t\t\t\t\t\t\tERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst session =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findSession(sessionToken);\n\t\t\t\t\tif (!session || session.session.expiresAt < new Date()) {\n\t\t\t\t\t\texpireCookie(ctx, {\n\t\t\t\t\t\t\tname: multiSessionCookieName,\n\t\t\t\t\t\t\tattributes: ctx.context.authCookies.sessionToken.attributes,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\t\t\"UNAUTHORIZED\",\n\t\t\t\t\t\t\tERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tawait setSessionCookie(ctx, session);\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tsession: parseSessionOutput(ctx.context.options, session.session),\n\t\t\t\t\t\tuser: parseUserOutput(ctx.context.options, session.user),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * POST `/multi-session/revoke`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.revokeDeviceSession`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.revoke`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-revoke)\n\t\t\t */\n\t\t\trevokeDeviceSession: createAuthEndpoint(\n\t\t\t\t\"/multi-session/revoke\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: revokeDeviceSessionBodySchema,\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\tdescription: \"Revoke a device session\",\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\tstatus: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\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 sessionToken = ctx.body.sessionToken;\n\t\t\t\t\tconst multiSessionCookieName = `${\n\t\t\t\t\t\tctx.context.authCookies.sessionToken.name\n\t\t\t\t\t}_multi-${sessionToken.toLowerCase()}`;\n\t\t\t\t\tconst sessionCookie = await ctx.getSignedCookie(\n\t\t\t\t\t\tmultiSessionCookieName,\n\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t);\n\t\t\t\t\tif (!sessionCookie) {\n\t\t\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\t\t\"UNAUTHORIZED\",\n\t\t\t\t\t\t\tERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteSession(sessionToken);\n\t\t\t\t\texpireCookie(ctx, {\n\t\t\t\t\t\tname: multiSessionCookieName,\n\t\t\t\t\t\tattributes: ctx.context.authCookies.sessionToken.attributes,\n\t\t\t\t\t});\n\t\t\t\t\tconst isActive = ctx.context.session?.session.token === sessionToken;\n\t\t\t\t\tif (!isActive) return ctx.json({ status: true });\n\n\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\tif (cookieHeader) {\n\t\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\n\t\t\t\t\t\tconst sessionTokens = (\n\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\tObject.entries(cookies)\n\t\t\t\t\t\t\t\t\t.filter(([key]) => isMultiSessionCookie(key))\n\t\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\t\tasync ([key]) =>\n\t\t\t\t\t\t\t\t\t\t\tawait ctx.getSignedCookie(key, ctx.context.secret),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\t\t\t\t\t\tconst internalAdapter = ctx.context.internalAdapter;\n\n\t\t\t\t\t\tif (sessionTokens.length > 0) {\n\t\t\t\t\t\t\tconst sessions =\n\t\t\t\t\t\t\t\tawait internalAdapter.findSessions(sessionTokens);\n\t\t\t\t\t\t\tconst validSessions = sessions.filter(\n\t\t\t\t\t\t\t\t(session) => session && session.session.expiresAt > new Date(),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (validSessions.length > 0) {\n\t\t\t\t\t\t\t\tconst nextSession = validSessions[0]!;\n\t\t\t\t\t\t\t\tawait setSessionCookie(ctx, nextSession);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t}\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tstatus: true,\n\t\t\t\t\t});\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: () => true,\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookieString = ctx.context.responseHeaders?.get(\"set-cookie\");\n\t\t\t\t\t\tif (!cookieString) return;\n\t\t\t\t\t\tconst newSession = ctx.context.newSession;\n\t\t\t\t\t\tif (!newSession) return;\n\n\t\t\t\t\t\tconst sessionCookieConfig = ctx.context.authCookies.sessionToken;\n\t\t\t\t\t\tconst sessionToken = newSession.session.token;\n\t\t\t\t\t\tconst cookieName = `${sessionCookieConfig.name}_multi-${sessionToken.toLowerCase()}`;\n\n\t\t\t\t\t\tconst setCookies = parseSetCookieHeader(cookieString);\n\t\t\t\t\t\tconst cookies = parseCookies(ctx.headers?.get(\"cookie\") || \"\");\n\t\t\t\t\t\tif (setCookies.get(cookieName) || cookies.get(cookieName)) return;\n\n\t\t\t\t\t\tconst multiSessionKeys = Object.keys(\n\t\t\t\t\t\t\tObject.fromEntries(cookies),\n\t\t\t\t\t\t).filter(isMultiSessionCookie);\n\n\t\t\t\t\t\tconst tokensToDelete: string[] = [];\n\t\t\t\t\t\tfor (const key of multiSessionKeys) {\n\t\t\t\t\t\t\tconst token = await ctx.getSignedCookie(key, ctx.context.secret);\n\t\t\t\t\t\t\tif (!token) continue;\n\t\t\t\t\t\t\tconst session =\n\t\t\t\t\t\t\t\tawait ctx.context.internalAdapter.findSession(token);\n\t\t\t\t\t\t\tif (session?.user.id === newSession.user.id) {\n\t\t\t\t\t\t\t\ttokensToDelete.push(token);\n\t\t\t\t\t\t\t\tctx.setCookie(key, \"\", {\n\t\t\t\t\t\t\t\t\t...sessionCookieConfig.attributes,\n\t\t\t\t\t\t\t\t\tmaxAge: 0,\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\tif (tokensToDelete.length > 0) {\n\t\t\t\t\t\t\tawait ctx.context.internalAdapter.deleteSessions(tokensToDelete);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst currentCount =\n\t\t\t\t\t\t\tmultiSessionKeys.length -\n\t\t\t\t\t\t\ttokensToDelete.length +\n\t\t\t\t\t\t\t(cookieString.includes(sessionCookieConfig.name) ? 1 : 0);\n\n\t\t\t\t\t\tif (currentCount > opts.maximumSessions) return;\n\n\t\t\t\t\t\tawait ctx.setSignedCookie(\n\t\t\t\t\t\t\tcookieName,\n\t\t\t\t\t\t\tsessionToken,\n\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t\tsessionCookieConfig.attributes,\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmatcher: (context) => context.path === \"/sign-out\",\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\t\tif (!cookieHeader) return;\n\t\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\t\t\t\t\t\tconst multiSessionKeys = Object.keys(cookies).filter((key) =>\n\t\t\t\t\t\t\tisMultiSessionCookie(key),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst verifiedTokens = (\n\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\tmultiSessionKeys.map(async (key) => {\n\t\t\t\t\t\t\t\t\tconst verifiedToken = await ctx.getSignedCookie(\n\t\t\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tif (verifiedToken) {\n\t\t\t\t\t\t\t\t\t\texpireCookie(ctx, {\n\t\t\t\t\t\t\t\t\t\t\tname: key\n\t\t\t\t\t\t\t\t\t\t\t\t.toLowerCase()\n\t\t\t\t\t\t\t\t\t\t\t\t.replace(\n\t\t\t\t\t\t\t\t\t\t\t\t\tSECURE_COOKIE_PREFIX.toLowerCase(),\n\t\t\t\t\t\t\t\t\t\t\t\t\tSECURE_COOKIE_PREFIX,\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\tattributes:\n\t\t\t\t\t\t\t\t\t\t\t\tctx.context.authCookies.sessionToken.attributes,\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\treturn verifiedToken;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\t\t\t\t\t\tif (verifiedTokens.length > 0) {\n\t\t\t\t\t\t\tawait ctx.context.internalAdapter.deleteSessions(verifiedTokens);\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\toptions,\n\t\t$ERROR_CODES: ERROR_CODES,\n\t} satisfies BetterAuthPlugin;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/plugins/oauth-proxy/index.d.ts
|
|
2
|
+
declare module "@better-auth/core" {
|
|
3
|
+
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
4
|
+
"oauth-proxy": {
|
|
5
|
+
creator: typeof oAuthProxy;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
interface OAuthProxyOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The current URL of the application.
|
|
12
|
+
* The plugin will attempt to infer the current URL from your environment
|
|
13
|
+
* by checking the base URL from popular hosting providers,
|
|
14
|
+
* from the request URL if invoked by a client,
|
|
15
|
+
* or as a fallback, from the `baseURL` in your auth config.
|
|
16
|
+
* If the URL is not inferred correctly, you can provide a value here."
|
|
17
|
+
*/
|
|
18
|
+
currentURL?: string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* If a request in a production url it won't be proxied.
|
|
21
|
+
*
|
|
22
|
+
* default to `BETTER_AUTH_URL`
|
|
23
|
+
*/
|
|
24
|
+
productionURL?: string | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Maximum age in seconds for the encrypted cookies payload.
|
|
27
|
+
* Payloads older than this will be rejected to prevent replay attacks.
|
|
28
|
+
*
|
|
29
|
+
* Keep this value short (e.g., 30-60 seconds) to minimize the window
|
|
30
|
+
* for potential replay attacks while still allowing normal OAuth flows.
|
|
31
|
+
*
|
|
32
|
+
* @default 60 (1 minute)
|
|
33
|
+
*/
|
|
34
|
+
maxAge?: number | undefined;
|
|
35
|
+
}
|
|
36
|
+
declare const oAuthProxy: <O extends OAuthProxyOptions>(opts?: O) => BetterAuthPlugin;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { OAuthProxyOptions, oAuthProxy };
|
|
39
|
+
//# sourceMappingURL=index.d.mts.map
|