@sirketio/auth 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.mjs +36 -0
- package/dist/adapter/index.d.mts +4 -0
- package/dist/adapter/index.mjs +7 -0
- package/dist/api/index.d.mts +3872 -0
- package/dist/api/index.mjs +206 -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 +18 -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 +204 -0
- package/dist/api/rate-limiter/index.mjs.map +1 -0
- package/dist/api/routes/account.d.mts +410 -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 +31 -0
- package/dist/api/routes/callback.mjs +179 -0
- package/dist/api/routes/callback.mjs.map +1 -0
- package/dist/api/routes/email-verification.d.mts +161 -0
- package/dist/api/routes/email-verification.mjs +299 -0
- package/dist/api/routes/email-verification.mjs.map +1 -0
- package/dist/api/routes/error.d.mts +28 -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 +36 -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 +182 -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 +415 -0
- package/dist/api/routes/session.mjs +483 -0
- package/dist/api/routes/session.mjs.map +1 -0
- package/dist/api/routes/sign-in.d.mts +171 -0
- package/dist/api/routes/sign-in.mjs +263 -0
- package/dist/api/routes/sign-in.mjs.map +1 -0
- package/dist/api/routes/sign-out.d.mts +36 -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 +160 -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 +445 -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 +18 -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 +45 -0
- package/dist/auth/base.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 +33 -0
- package/dist/client/index.mjs +21 -0
- package/dist/client/index.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 +65 -0
- package/dist/client/plugins/index.d.mts +53 -0
- package/dist/client/plugins/index.mjs +30 -0
- package/dist/client/plugins/infer-plugin.d.mts +16 -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 +128 -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/types.d.mts +41 -0
- package/dist/client/vanilla.d.mts +127 -0
- package/dist/client/vanilla.mjs +20 -0
- package/dist/client/vanilla.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 +83 -0
- package/dist/context/helpers.mjs.map +1 -0
- package/dist/context/init.mjs +20 -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 +121 -0
- package/dist/cookies/index.mjs +261 -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 +19 -0
- package/dist/db/adapter-base.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 +42 -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 +18 -0
- package/dist/db/index.mjs +34 -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 +49 -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 +53 -0
- package/dist/index.mjs +27 -0
- package/dist/integrations/next-js.d.mts +29 -0
- package/dist/integrations/next-js.mjs +85 -0
- package/dist/integrations/next-js.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 +48 -0
- package/dist/oauth2/link-account.mjs +143 -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 +96 -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 +911 -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 +76 -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 +29 -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 +841 -0
- package/dist/plugins/admin/routes.mjs.map +1 -0
- package/dist/plugins/admin/schema.d.mts +40 -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/api-key/adapter.mjs +468 -0
- package/dist/plugins/api-key/adapter.mjs.map +1 -0
- package/dist/plugins/api-key/client.d.mts +46 -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 +33 -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 +1251 -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 +224 -0
- package/dist/plugins/api-key/routes/verify-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/schema.d.mts +199 -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 +45 -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 +21 -0
- package/dist/plugins/captcha/index.mjs +62 -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 +28 -0
- package/dist/plugins/captcha/verify-handlers/captchafox.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +26 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +30 -0
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +28 -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 +17 -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 +72 -0
- package/dist/plugins/custom-session/index.mjs +78 -0
- package/dist/plugins/custom-session/index.mjs.map +1 -0
- package/dist/plugins/device-authorization/client.d.mts +17 -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 +424 -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 +21 -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 +11 -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 +428 -0
- package/dist/plugins/email-otp/index.mjs +130 -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 +631 -0
- package/dist/plugins/email-otp/routes.mjs.map +1 -0
- package/dist/plugins/email-otp/types.d.mts +86 -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 +33 -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 +16 -0
- package/dist/plugins/generic-oauth/error-codes.mjs +17 -0
- package/dist/plugins/generic-oauth/error-codes.mjs.map +1 -0
- package/dist/plugins/generic-oauth/index.d.mts +201 -0
- package/dist/plugins/generic-oauth/index.mjs +145 -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 +411 -0
- package/dist/plugins/generic-oauth/routes.mjs.map +1 -0
- package/dist/plugins/generic-oauth/types.d.mts +159 -0
- package/dist/plugins/haveibeenpwned/index.d.mts +46 -0
- package/dist/plugins/haveibeenpwned/index.mjs +57 -0
- package/dist/plugins/haveibeenpwned/index.mjs.map +1 -0
- package/dist/plugins/index.d.mts +65 -0
- package/dist/plugins/index.mjs +48 -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 +40 -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 +224 -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 +26 -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 +38 -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 +118 -0
- package/dist/plugins/last-login-method/index.mjs +76 -0
- package/dist/plugins/last-login-method/index.mjs.map +1 -0
- package/dist/plugins/magic-link/client.d.mts +10 -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 +193 -0
- package/dist/plugins/magic-link/index.mjs +177 -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 +458 -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 +19 -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 +9 -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 +235 -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 +97 -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 +51 -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 +12 -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 +702 -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 +160 -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 +174 -0
- package/dist/plugins/one-tap/client.mjs +188 -0
- package/dist/plugins/one-tap/client.mjs.map +1 -0
- package/dist/plugins/one-tap/index.d.mts +83 -0
- package/dist/plugins/one-tap/index.mjs +95 -0
- package/dist/plugins/one-tap/index.mjs.map +1 -0
- package/dist/plugins/one-time-token/client.d.mts +10 -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 +133 -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 +97 -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 +792 -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 +372 -0
- package/dist/plugins/organization/client.mjs +95 -0
- package/dist/plugins/organization/client.mjs.map +1 -0
- package/dist/plugins/organization/error-codes.d.mts +65 -0
- package/dist/plugins/organization/error-codes.mjs +66 -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 +394 -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 +17 -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 +394 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs +678 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-invites.d.mts +1031 -0
- package/dist/plugins/organization/routes/crud-invites.mjs +551 -0
- package/dist/plugins/organization/routes/crud-invites.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-members.d.mts +940 -0
- package/dist/plugins/organization/routes/crud-members.mjs +466 -0
- package/dist/plugins/organization/routes/crud-members.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-org.d.mts +708 -0
- package/dist/plugins/organization/routes/crud-org.mjs +423 -0
- package/dist/plugins/organization/routes/crud-org.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-team.d.mts +1071 -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 +677 -0
- package/dist/plugins/phone-number/client.d.mts +31 -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 +20 -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 +318 -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 +472 -0
- package/dist/plugins/phone-number/routes.mjs.map +1 -0
- package/dist/plugins/phone-number/schema.d.mts +23 -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/two-factor/backup-codes/index.d.mts +279 -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 +55 -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 +17 -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 +670 -0
- package/dist/plugins/two-factor/index.mjs +228 -0
- package/dist/plugins/two-factor/index.mjs.map +1 -0
- package/dist/plugins/two-factor/otp/index.d.mts +216 -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 +41 -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 +210 -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 +73 -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 +85 -0
- package/dist/plugins/two-factor/verify-two-factor.mjs.map +1 -0
- package/dist/plugins/username/client.d.mts +26 -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 +16 -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 +251 -0
- package/dist/plugins/username/index.mjs +234 -0
- package/dist/plugins/username/index.mjs.map +1 -0
- package/dist/plugins/username/schema.d.mts +33 -0
- package/dist/plugins/username/schema.mjs +26 -0
- package/dist/plugins/username/schema.mjs.map +1 -0
- package/dist/providers/index.d.mts +1 -0
- package/dist/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/types/adapter.d.mts +2 -0
- package/dist/types/api.d.mts +29 -0
- package/dist/types/auth.d.mts +29 -0
- package/dist/types/helper.d.mts +10 -0
- package/dist/types/index.d.mts +11 -0
- package/dist/types/index.mjs +1 -0
- package/dist/types/models.d.mts +11 -0
- package/dist/types/plugins.d.mts +20 -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/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 +4 -0
- package/dist/utils/index.mjs +6 -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 +9 -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.d.mts +8 -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 +428 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { isAPIError } from "../utils/is-api-error.mjs";
|
|
2
|
+
import { formCsrfMiddleware, originCheck, originCheckMiddleware } from "./middlewares/origin-check.mjs";
|
|
3
|
+
import "./middlewares/index.mjs";
|
|
4
|
+
import { getIp } from "../utils/get-request-ip.mjs";
|
|
5
|
+
import { onRequestRateLimit, onResponseRateLimit } from "./rate-limiter/index.mjs";
|
|
6
|
+
import { getOAuthState } from "./state/oauth.mjs";
|
|
7
|
+
import { getShouldSkipSessionRefresh, setShouldSkipSessionRefresh } from "./state/should-session-refresh.mjs";
|
|
8
|
+
import { freshSessionMiddleware, getSession, getSessionFromCtx, listSessions, requestOnlySessionMiddleware, revokeOtherSessions, revokeSession, revokeSessions, sensitiveSessionMiddleware, sessionMiddleware } from "./routes/session.mjs";
|
|
9
|
+
import { accountInfo, getAccessToken, linkSocialAccount, listUserAccounts, refreshToken, unlinkAccount } from "./routes/account.mjs";
|
|
10
|
+
import { callbackOAuth } from "./routes/callback.mjs";
|
|
11
|
+
import { createEmailVerificationToken, sendVerificationEmail, sendVerificationEmailFn, verifyEmail } from "./routes/email-verification.mjs";
|
|
12
|
+
import { error } from "./routes/error.mjs";
|
|
13
|
+
import { ok } from "./routes/ok.mjs";
|
|
14
|
+
import { requestPasswordReset, requestPasswordResetCallback, resetPassword, verifyPassword } from "./routes/password.mjs";
|
|
15
|
+
import { signInEmail, signInSocial } from "./routes/sign-in.mjs";
|
|
16
|
+
import { signOut } from "./routes/sign-out.mjs";
|
|
17
|
+
import { signUpEmail } from "./routes/sign-up.mjs";
|
|
18
|
+
import { changeEmail, changePassword, deleteUser, deleteUserCallback, setPassword, updateUser } from "./routes/update-user.mjs";
|
|
19
|
+
import "./routes/index.mjs";
|
|
20
|
+
import { toAuthEndpoints } from "./to-auth-endpoints.mjs";
|
|
21
|
+
import { logger } from "@better-auth/core/env";
|
|
22
|
+
import { APIError } from "@better-auth/core/error";
|
|
23
|
+
import { normalizePathname } from "@better-auth/core/utils/url";
|
|
24
|
+
import { createRouter } from "better-call";
|
|
25
|
+
import { createAuthEndpoint, createAuthMiddleware, optionsMiddleware } from "@better-auth/core/api";
|
|
26
|
+
|
|
27
|
+
//#region src/api/index.ts
|
|
28
|
+
function checkEndpointConflicts(options, logger) {
|
|
29
|
+
const endpointRegistry = /* @__PURE__ */ new Map();
|
|
30
|
+
options.plugins?.forEach((plugin) => {
|
|
31
|
+
if (plugin.endpoints) {
|
|
32
|
+
for (const [key, endpoint] of Object.entries(plugin.endpoints)) if (endpoint && "path" in endpoint && typeof endpoint.path === "string") {
|
|
33
|
+
const path = endpoint.path;
|
|
34
|
+
let methods = [];
|
|
35
|
+
if (endpoint.options && "method" in endpoint.options) {
|
|
36
|
+
if (Array.isArray(endpoint.options.method)) methods = endpoint.options.method;
|
|
37
|
+
else if (typeof endpoint.options.method === "string") methods = [endpoint.options.method];
|
|
38
|
+
}
|
|
39
|
+
if (methods.length === 0) methods = ["*"];
|
|
40
|
+
if (!endpointRegistry.has(path)) endpointRegistry.set(path, []);
|
|
41
|
+
endpointRegistry.get(path).push({
|
|
42
|
+
pluginId: plugin.id,
|
|
43
|
+
endpointKey: key,
|
|
44
|
+
methods
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const conflicts = [];
|
|
50
|
+
for (const [path, entries] of endpointRegistry.entries()) if (entries.length > 1) {
|
|
51
|
+
const methodMap = /* @__PURE__ */ new Map();
|
|
52
|
+
let hasConflict = false;
|
|
53
|
+
for (const entry of entries) for (const method of entry.methods) {
|
|
54
|
+
if (!methodMap.has(method)) methodMap.set(method, []);
|
|
55
|
+
methodMap.get(method).push(entry.pluginId);
|
|
56
|
+
if (methodMap.get(method).length > 1) hasConflict = true;
|
|
57
|
+
if (method === "*" && entries.length > 1) hasConflict = true;
|
|
58
|
+
else if (method !== "*" && methodMap.has("*")) hasConflict = true;
|
|
59
|
+
}
|
|
60
|
+
if (hasConflict) {
|
|
61
|
+
const uniquePlugins = [...new Set(entries.map((e) => e.pluginId))];
|
|
62
|
+
const conflictingMethods = [];
|
|
63
|
+
for (const [method, plugins] of methodMap.entries()) if (plugins.length > 1 || method === "*" && entries.length > 1 || method !== "*" && methodMap.has("*")) conflictingMethods.push(method);
|
|
64
|
+
conflicts.push({
|
|
65
|
+
path,
|
|
66
|
+
plugins: uniquePlugins,
|
|
67
|
+
conflictingMethods
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (conflicts.length > 0) {
|
|
72
|
+
const conflictMessages = conflicts.map((conflict) => ` - "${conflict.path}" [${conflict.conflictingMethods.join(", ")}] used by plugins: ${conflict.plugins.join(", ")}`).join("\n");
|
|
73
|
+
logger.error(`Endpoint path conflicts detected! Multiple plugins are trying to use the same endpoint paths with conflicting HTTP methods:
|
|
74
|
+
${conflictMessages}
|
|
75
|
+
|
|
76
|
+
To resolve this, you can:
|
|
77
|
+
1. Use only one of the conflicting plugins
|
|
78
|
+
2. Configure the plugins to use different paths (if supported)
|
|
79
|
+
3. Ensure plugins use different HTTP methods for the same path
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function getEndpoints(ctx, options) {
|
|
84
|
+
const pluginEndpoints = options.plugins?.reduce((acc, plugin) => {
|
|
85
|
+
return {
|
|
86
|
+
...acc,
|
|
87
|
+
...plugin.endpoints
|
|
88
|
+
};
|
|
89
|
+
}, {}) ?? {};
|
|
90
|
+
const middlewares = options.plugins?.map((plugin) => plugin.middlewares?.map((m) => {
|
|
91
|
+
const middleware = (async (context) => {
|
|
92
|
+
const authContext = await ctx;
|
|
93
|
+
return m.middleware({
|
|
94
|
+
...context,
|
|
95
|
+
context: {
|
|
96
|
+
...authContext,
|
|
97
|
+
...context.context
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
middleware.options = m.middleware.options;
|
|
102
|
+
return {
|
|
103
|
+
path: m.path,
|
|
104
|
+
middleware
|
|
105
|
+
};
|
|
106
|
+
})).filter((plugin) => plugin !== void 0).flat() || [];
|
|
107
|
+
return {
|
|
108
|
+
api: toAuthEndpoints({
|
|
109
|
+
signInSocial: signInSocial(),
|
|
110
|
+
callbackOAuth,
|
|
111
|
+
getSession: getSession(),
|
|
112
|
+
signOut,
|
|
113
|
+
signUpEmail: signUpEmail(),
|
|
114
|
+
signInEmail: signInEmail(),
|
|
115
|
+
resetPassword,
|
|
116
|
+
verifyPassword,
|
|
117
|
+
verifyEmail,
|
|
118
|
+
sendVerificationEmail,
|
|
119
|
+
changeEmail,
|
|
120
|
+
changePassword,
|
|
121
|
+
setPassword,
|
|
122
|
+
updateUser: updateUser(),
|
|
123
|
+
deleteUser,
|
|
124
|
+
requestPasswordReset,
|
|
125
|
+
requestPasswordResetCallback,
|
|
126
|
+
listSessions: listSessions(),
|
|
127
|
+
revokeSession,
|
|
128
|
+
revokeSessions,
|
|
129
|
+
revokeOtherSessions,
|
|
130
|
+
linkSocialAccount,
|
|
131
|
+
listUserAccounts,
|
|
132
|
+
deleteUserCallback,
|
|
133
|
+
unlinkAccount,
|
|
134
|
+
refreshToken,
|
|
135
|
+
getAccessToken,
|
|
136
|
+
accountInfo,
|
|
137
|
+
...pluginEndpoints,
|
|
138
|
+
ok,
|
|
139
|
+
error
|
|
140
|
+
}, ctx),
|
|
141
|
+
middlewares
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const router = (ctx, options) => {
|
|
145
|
+
const { api, middlewares } = getEndpoints(ctx, options);
|
|
146
|
+
const basePath = new URL(ctx.baseURL).pathname;
|
|
147
|
+
return createRouter(api, {
|
|
148
|
+
routerContext: ctx,
|
|
149
|
+
openapi: { disabled: true },
|
|
150
|
+
basePath,
|
|
151
|
+
routerMiddleware: [{
|
|
152
|
+
path: "/**",
|
|
153
|
+
middleware: originCheckMiddleware
|
|
154
|
+
}, ...middlewares],
|
|
155
|
+
allowedMediaTypes: ["application/json"],
|
|
156
|
+
skipTrailingSlashes: options.advanced?.skipTrailingSlashes ?? false,
|
|
157
|
+
async onRequest(req) {
|
|
158
|
+
const disabledPaths = ctx.options.disabledPaths || [];
|
|
159
|
+
const normalizedPath = normalizePathname(req.url, basePath);
|
|
160
|
+
if (disabledPaths.includes(normalizedPath)) return new Response("Not Found", { status: 404 });
|
|
161
|
+
let currentRequest = req;
|
|
162
|
+
for (const plugin of ctx.options.plugins || []) if (plugin.onRequest) {
|
|
163
|
+
const response = await plugin.onRequest(currentRequest, ctx);
|
|
164
|
+
if (response && "response" in response) return response.response;
|
|
165
|
+
if (response && "request" in response) currentRequest = response.request;
|
|
166
|
+
}
|
|
167
|
+
const rateLimitResponse = await onRequestRateLimit(currentRequest, ctx);
|
|
168
|
+
if (rateLimitResponse) return rateLimitResponse;
|
|
169
|
+
return currentRequest;
|
|
170
|
+
},
|
|
171
|
+
async onResponse(res, req) {
|
|
172
|
+
await onResponseRateLimit(req, ctx);
|
|
173
|
+
for (const plugin of ctx.options.plugins || []) if (plugin.onResponse) {
|
|
174
|
+
const response = await plugin.onResponse(res, ctx);
|
|
175
|
+
if (response) return response.response;
|
|
176
|
+
}
|
|
177
|
+
return res;
|
|
178
|
+
},
|
|
179
|
+
onError(e) {
|
|
180
|
+
if (isAPIError(e) && e.status === "FOUND") return;
|
|
181
|
+
if (options.onAPIError?.throw) throw e;
|
|
182
|
+
if (options.onAPIError?.onError) {
|
|
183
|
+
options.onAPIError.onError(e, ctx);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const optLogLevel = options.logger?.level;
|
|
187
|
+
const log = optLogLevel === "error" || optLogLevel === "warn" || optLogLevel === "debug" ? logger : void 0;
|
|
188
|
+
if (options.logger?.disabled !== true) {
|
|
189
|
+
if (e && typeof e === "object" && "message" in e && typeof e.message === "string") {
|
|
190
|
+
if (e.message.includes("no column") || e.message.includes("column") || e.message.includes("relation") || e.message.includes("table") || e.message.includes("does not exist")) {
|
|
191
|
+
ctx.logger?.error(e.message);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (isAPIError(e)) {
|
|
196
|
+
if (e.status === "INTERNAL_SERVER_ERROR") ctx.logger.error(e.status, e);
|
|
197
|
+
log?.error(e.message);
|
|
198
|
+
} else ctx.logger?.error(e && typeof e === "object" && "name" in e ? e.name : "", e);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
//#endregion
|
|
205
|
+
export { APIError, accountInfo, callbackOAuth, changeEmail, changePassword, checkEndpointConflicts, createAuthEndpoint, createAuthMiddleware, createEmailVerificationToken, deleteUser, deleteUserCallback, error, formCsrfMiddleware, freshSessionMiddleware, getAccessToken, getEndpoints, getIp, getOAuthState, getSession, getSessionFromCtx, getShouldSkipSessionRefresh, isAPIError, linkSocialAccount, listSessions, listUserAccounts, ok, optionsMiddleware, originCheck, originCheckMiddleware, refreshToken, requestOnlySessionMiddleware, requestPasswordReset, requestPasswordResetCallback, resetPassword, revokeOtherSessions, revokeSession, revokeSessions, router, sendVerificationEmail, sendVerificationEmailFn, sensitiveSessionMiddleware, sessionMiddleware, setPassword, setShouldSkipSessionRefresh, signInEmail, signInSocial, signOut, signUpEmail, unlinkAccount, updateUser, verifyEmail, verifyPassword };
|
|
206
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/api/index.ts"],"sourcesContent":["import type {\n\tAuthContext,\n\tAwaitable,\n\tBetterAuthOptions,\n\tBetterAuthPlugin,\n} from \"@better-auth/core\";\nimport type { InternalLogger } from \"@better-auth/core/env\";\nimport { logger } from \"@better-auth/core/env\";\nimport { normalizePathname } from \"@better-auth/core/utils/url\";\nimport type { Endpoint, Middleware } from \"better-call\";\nimport { createRouter } from \"better-call\";\nimport type { UnionToIntersection } from \"../types\";\nimport { isAPIError } from \"../utils/is-api-error\";\nimport { originCheckMiddleware } from \"./middlewares\";\nimport { onRequestRateLimit, onResponseRateLimit } from \"./rate-limiter\";\nimport {\n\taccountInfo,\n\tcallbackOAuth,\n\tchangeEmail,\n\tchangePassword,\n\tdeleteUser,\n\tdeleteUserCallback,\n\terror,\n\tgetAccessToken,\n\tgetSession,\n\tlinkSocialAccount,\n\tlistSessions,\n\tlistUserAccounts,\n\tok,\n\trefreshToken,\n\trequestPasswordReset,\n\trequestPasswordResetCallback,\n\tresetPassword,\n\trevokeOtherSessions,\n\trevokeSession,\n\trevokeSessions,\n\tsendVerificationEmail,\n\tsetPassword,\n\tsignInEmail,\n\tsignInSocial,\n\tsignOut,\n\tsignUpEmail,\n\tunlinkAccount,\n\tupdateUser,\n\tverifyEmail,\n\tverifyPassword,\n} from \"./routes\";\nimport { toAuthEndpoints } from \"./to-auth-endpoints\";\n\nexport function checkEndpointConflicts(\n\toptions: BetterAuthOptions,\n\tlogger: InternalLogger,\n) {\n\tconst endpointRegistry = new Map<\n\t\tstring,\n\t\t{ pluginId: string; endpointKey: string; methods: string[] }[]\n\t>();\n\n\toptions.plugins?.forEach((plugin) => {\n\t\tif (plugin.endpoints) {\n\t\t\tfor (const [key, endpoint] of Object.entries(plugin.endpoints)) {\n\t\t\t\tif (\n\t\t\t\t\tendpoint &&\n\t\t\t\t\t\"path\" in endpoint &&\n\t\t\t\t\ttypeof endpoint.path === \"string\"\n\t\t\t\t) {\n\t\t\t\t\tconst path = endpoint.path;\n\t\t\t\t\tlet methods: string[] = [];\n\t\t\t\t\tif (endpoint.options && \"method\" in endpoint.options) {\n\t\t\t\t\t\tif (Array.isArray(endpoint.options.method)) {\n\t\t\t\t\t\t\tmethods = endpoint.options.method;\n\t\t\t\t\t\t} else if (typeof endpoint.options.method === \"string\") {\n\t\t\t\t\t\t\tmethods = [endpoint.options.method];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (methods.length === 0) {\n\t\t\t\t\t\tmethods = [\"*\"];\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!endpointRegistry.has(path)) {\n\t\t\t\t\t\tendpointRegistry.set(path, []);\n\t\t\t\t\t}\n\t\t\t\t\tendpointRegistry.get(path)!.push({\n\t\t\t\t\t\tpluginId: plugin.id,\n\t\t\t\t\t\tendpointKey: key,\n\t\t\t\t\t\tmethods,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\tconst conflicts: {\n\t\tpath: string;\n\t\tplugins: string[];\n\t\tconflictingMethods: string[];\n\t}[] = [];\n\tfor (const [path, entries] of endpointRegistry.entries()) {\n\t\tif (entries.length > 1) {\n\t\t\tconst methodMap = new Map<string, string[]>();\n\t\t\tlet hasConflict = false;\n\n\t\t\tfor (const entry of entries) {\n\t\t\t\tfor (const method of entry.methods) {\n\t\t\t\t\tif (!methodMap.has(method)) {\n\t\t\t\t\t\tmethodMap.set(method, []);\n\t\t\t\t\t}\n\t\t\t\t\tmethodMap.get(method)!.push(entry.pluginId);\n\n\t\t\t\t\tif (methodMap.get(method)!.length > 1) {\n\t\t\t\t\t\thasConflict = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (method === \"*\" && entries.length > 1) {\n\t\t\t\t\t\thasConflict = true;\n\t\t\t\t\t} else if (method !== \"*\" && methodMap.has(\"*\")) {\n\t\t\t\t\t\thasConflict = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (hasConflict) {\n\t\t\t\tconst uniquePlugins = [...new Set(entries.map((e) => e.pluginId))];\n\t\t\t\tconst conflictingMethods: string[] = [];\n\n\t\t\t\tfor (const [method, plugins] of methodMap.entries()) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tplugins.length > 1 ||\n\t\t\t\t\t\t(method === \"*\" && entries.length > 1) ||\n\t\t\t\t\t\t(method !== \"*\" && methodMap.has(\"*\"))\n\t\t\t\t\t) {\n\t\t\t\t\t\tconflictingMethods.push(method);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconflicts.push({\n\t\t\t\t\tpath,\n\t\t\t\t\tplugins: uniquePlugins,\n\t\t\t\t\tconflictingMethods,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tif (conflicts.length > 0) {\n\t\tconst conflictMessages = conflicts\n\t\t\t.map(\n\t\t\t\t(conflict) =>\n\t\t\t\t\t` - \"${conflict.path}\" [${conflict.conflictingMethods.join(\", \")}] used by plugins: ${conflict.plugins.join(\", \")}`,\n\t\t\t)\n\t\t\t.join(\"\\n\");\n\t\tlogger.error(\n\t\t\t`Endpoint path conflicts detected! Multiple plugins are trying to use the same endpoint paths with conflicting HTTP methods:\n${conflictMessages}\n\nTo resolve this, you can:\n\t1. Use only one of the conflicting plugins\n\t2. Configure the plugins to use different paths (if supported)\n\t3. Ensure plugins use different HTTP methods for the same path\n`,\n\t\t);\n\t}\n}\n\nexport function getEndpoints<Option extends BetterAuthOptions>(\n\tctx: Awaitable<AuthContext>,\n\toptions: Option,\n) {\n\tconst pluginEndpoints =\n\t\toptions.plugins?.reduce<Record<string, Endpoint>>((acc, plugin) => {\n\t\t\treturn {\n\t\t\t\t...acc,\n\t\t\t\t...plugin.endpoints,\n\t\t\t};\n\t\t}, {}) ?? {};\n\n\ttype PluginEndpoint = UnionToIntersection<\n\t\tOption[\"plugins\"] extends Array<infer T>\n\t\t\t? T extends BetterAuthPlugin\n\t\t\t\t? T extends {\n\t\t\t\t\t\tendpoints: infer E;\n\t\t\t\t\t}\n\t\t\t\t\t? E\n\t\t\t\t\t: {}\n\t\t\t\t: {}\n\t\t\t: {}\n\t>;\n\n\tconst middlewares =\n\t\toptions.plugins\n\t\t\t?.map((plugin) =>\n\t\t\t\tplugin.middlewares?.map((m) => {\n\t\t\t\t\tconst middleware = (async (context: any) => {\n\t\t\t\t\t\tconst authContext = await ctx;\n\t\t\t\t\t\treturn m.middleware({\n\t\t\t\t\t\t\t...context,\n\t\t\t\t\t\t\tcontext: {\n\t\t\t\t\t\t\t\t...authContext,\n\t\t\t\t\t\t\t\t...context.context,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}) as Middleware;\n\t\t\t\t\tmiddleware.options = m.middleware.options;\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpath: m.path,\n\t\t\t\t\t\tmiddleware,\n\t\t\t\t\t};\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.filter((plugin) => plugin !== undefined)\n\t\t\t.flat() || [];\n\n\tconst baseEndpoints = {\n\t\tsignInSocial: signInSocial<Option>(),\n\t\tcallbackOAuth,\n\t\tgetSession: getSession<Option>(),\n\t\tsignOut,\n\t\tsignUpEmail: signUpEmail<Option>(),\n\t\tsignInEmail: signInEmail<Option>(),\n\t\tresetPassword,\n\t\tverifyPassword,\n\t\tverifyEmail,\n\t\tsendVerificationEmail,\n\t\tchangeEmail,\n\t\tchangePassword,\n\t\tsetPassword,\n\t\tupdateUser: updateUser<Option>(),\n\t\tdeleteUser,\n\t\trequestPasswordReset,\n\t\trequestPasswordResetCallback,\n\t\tlistSessions: listSessions<Option>(),\n\t\trevokeSession,\n\t\trevokeSessions,\n\t\trevokeOtherSessions,\n\t\tlinkSocialAccount,\n\t\tlistUserAccounts,\n\t\tdeleteUserCallback,\n\t\tunlinkAccount,\n\t\trefreshToken,\n\t\tgetAccessToken,\n\t\taccountInfo,\n\t};\n\tconst endpoints = {\n\t\t...baseEndpoints,\n\t\t...pluginEndpoints,\n\t\tok,\n\t\terror,\n\t} as const;\n\tconst api = toAuthEndpoints(endpoints, ctx);\n\treturn {\n\t\tapi: api as typeof endpoints & PluginEndpoint,\n\t\tmiddlewares,\n\t};\n}\nexport const router = <Option extends BetterAuthOptions>(\n\tctx: AuthContext,\n\toptions: Option,\n) => {\n\tconst { api, middlewares } = getEndpoints(ctx, options);\n\tconst basePath = new URL(ctx.baseURL).pathname;\n\n\treturn createRouter(api, {\n\t\trouterContext: ctx,\n\t\topenapi: {\n\t\t\tdisabled: true,\n\t\t},\n\t\tbasePath,\n\t\trouterMiddleware: [\n\t\t\t{\n\t\t\t\tpath: \"/**\",\n\t\t\t\tmiddleware: originCheckMiddleware,\n\t\t\t},\n\t\t\t...middlewares,\n\t\t],\n\t\tallowedMediaTypes: [\"application/json\"],\n\t\tskipTrailingSlashes: options.advanced?.skipTrailingSlashes ?? false,\n\t\tasync onRequest(req) {\n\t\t\t//handle disabled paths\n\t\t\tconst disabledPaths = ctx.options.disabledPaths || [];\n\t\t\tconst normalizedPath = normalizePathname(req.url, basePath);\n\t\t\tif (disabledPaths.includes(normalizedPath)) {\n\t\t\t\treturn new Response(\"Not Found\", { status: 404 });\n\t\t\t}\n\n\t\t\tlet currentRequest = req;\n\t\t\tfor (const plugin of ctx.options.plugins || []) {\n\t\t\t\tif (plugin.onRequest) {\n\t\t\t\t\tconst response = await plugin.onRequest(currentRequest, ctx);\n\t\t\t\t\tif (response && \"response\" in response) {\n\t\t\t\t\t\treturn response.response;\n\t\t\t\t\t}\n\t\t\t\t\tif (response && \"request\" in response) {\n\t\t\t\t\t\tcurrentRequest = response.request;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst rateLimitResponse = await onRequestRateLimit(currentRequest, ctx);\n\t\t\tif (rateLimitResponse) {\n\t\t\t\treturn rateLimitResponse;\n\t\t\t}\n\n\t\t\treturn currentRequest;\n\t\t},\n\t\tasync onResponse(res, req) {\n\t\t\tawait onResponseRateLimit(req, ctx);\n\t\t\tfor (const plugin of ctx.options.plugins || []) {\n\t\t\t\tif (plugin.onResponse) {\n\t\t\t\t\tconst response = await plugin.onResponse(res, ctx);\n\t\t\t\t\tif (response) {\n\t\t\t\t\t\treturn response.response;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn res;\n\t\t},\n\t\tonError(e) {\n\t\t\tif (isAPIError(e) && e.status === \"FOUND\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (options.onAPIError?.throw) {\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t\tif (options.onAPIError?.onError) {\n\t\t\t\toptions.onAPIError.onError(e, ctx);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst optLogLevel = options.logger?.level;\n\t\t\tconst log =\n\t\t\t\toptLogLevel === \"error\" ||\n\t\t\t\toptLogLevel === \"warn\" ||\n\t\t\t\toptLogLevel === \"debug\"\n\t\t\t\t\t? logger\n\t\t\t\t\t: undefined;\n\t\t\tif (options.logger?.disabled !== true) {\n\t\t\t\tif (\n\t\t\t\t\te &&\n\t\t\t\t\ttypeof e === \"object\" &&\n\t\t\t\t\t\"message\" in e &&\n\t\t\t\t\ttypeof e.message === \"string\"\n\t\t\t\t) {\n\t\t\t\t\tif (\n\t\t\t\t\t\te.message.includes(\"no column\") ||\n\t\t\t\t\t\te.message.includes(\"column\") ||\n\t\t\t\t\t\te.message.includes(\"relation\") ||\n\t\t\t\t\t\te.message.includes(\"table\") ||\n\t\t\t\t\t\te.message.includes(\"does not exist\")\n\t\t\t\t\t) {\n\t\t\t\t\t\tctx.logger?.error(e.message);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (isAPIError(e)) {\n\t\t\t\t\tif (e.status === \"INTERNAL_SERVER_ERROR\") {\n\t\t\t\t\t\tctx.logger.error(e.status, e);\n\t\t\t\t\t}\n\t\t\t\t\tlog?.error(e.message);\n\t\t\t\t} else {\n\t\t\t\t\tctx.logger?.error(\n\t\t\t\t\t\te && typeof e === \"object\" && \"name\" in e ? (e.name as string) : \"\",\n\t\t\t\t\t\te,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t});\n};\n\nexport {\n\ttype AuthEndpoint,\n\ttype AuthMiddleware,\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n\toptionsMiddleware,\n} from \"@better-auth/core/api\";\nexport { APIError } from \"@better-auth/core/error\";\nexport { getIp } from \"../utils/get-request-ip\";\nexport { isAPIError } from \"../utils/is-api-error\";\nexport * from \"./middlewares\";\nexport * from \"./routes\";\nexport { getOAuthState } from \"./state/oauth\";\nexport {\n\tgetShouldSkipSessionRefresh,\n\tsetShouldSkipSessionRefresh,\n} from \"./state/should-session-refresh\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { formCsrfMiddleware, originCheck, originCheckMiddleware } from "./origin-check.mjs";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { GenericEndpointContext } from "@better-auth/core";
|
|
2
|
+
import * as better_call0 from "better-call";
|
|
3
|
+
|
|
4
|
+
//#region src/api/middlewares/origin-check.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* A middleware to validate callbackURL and origin against trustedOrigins.
|
|
7
|
+
* Also handles CSRF protection using Fetch Metadata for first-login scenarios.
|
|
8
|
+
*/
|
|
9
|
+
declare const originCheckMiddleware: (inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>;
|
|
10
|
+
declare const originCheck: (getValue: (ctx: GenericEndpointContext) => string | string[]) => (inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Middleware for CSRF protection using Fetch Metadata headers.
|
|
13
|
+
* This prevents cross-site navigation login attacks while supporting progressive enhancement.
|
|
14
|
+
*/
|
|
15
|
+
declare const formCsrfMiddleware: (inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { formCsrfMiddleware, originCheck, originCheckMiddleware };
|
|
18
|
+
//# sourceMappingURL=origin-check.d.mts.map
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { matchesOriginPattern } from "../../auth/trusted-origins.mjs";
|
|
2
|
+
import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
|
|
3
|
+
import { normalizePathname } from "@better-auth/core/utils/url";
|
|
4
|
+
import { createAuthMiddleware } from "@better-auth/core/api";
|
|
5
|
+
import { deprecate } from "@better-auth/core/utils/deprecate";
|
|
6
|
+
|
|
7
|
+
//#region src/api/middlewares/origin-check.ts
|
|
8
|
+
/**
|
|
9
|
+
* Checks if CSRF should be skipped for backward compatibility.
|
|
10
|
+
* Previously, disableOriginCheck also disabled CSRF checks.
|
|
11
|
+
* This maintains that behavior when disableCSRFCheck isn't explicitly set.
|
|
12
|
+
* Only triggers for skipOriginCheck === true, not for path arrays.
|
|
13
|
+
*/
|
|
14
|
+
function shouldSkipCSRFForBackwardCompat(ctx) {
|
|
15
|
+
return ctx.context.skipOriginCheck === true && ctx.context.options.advanced?.disableCSRFCheck === void 0;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Logs deprecation warning for users relying on coupled behavior.
|
|
19
|
+
* Only logs if user explicitly set disableOriginCheck (not test environment default).
|
|
20
|
+
*/
|
|
21
|
+
const logBackwardCompatWarning = deprecate(function logBackwardCompatWarning() {}, "disableOriginCheck: true currently also disables CSRF checks. In a future version, disableOriginCheck will ONLY disable URL validation. To keep CSRF disabled, add disableCSRFCheck: true to your config.");
|
|
22
|
+
/**
|
|
23
|
+
* A middleware to validate callbackURL and origin against trustedOrigins.
|
|
24
|
+
* Also handles CSRF protection using Fetch Metadata for first-login scenarios.
|
|
25
|
+
*/
|
|
26
|
+
const originCheckMiddleware = createAuthMiddleware(async (ctx) => {
|
|
27
|
+
if (ctx.request?.method === "GET" || ctx.request?.method === "OPTIONS" || ctx.request?.method === "HEAD" || !ctx.request) return;
|
|
28
|
+
await validateOrigin(ctx);
|
|
29
|
+
if (ctx.context.skipOriginCheck) return;
|
|
30
|
+
const { body, query } = ctx;
|
|
31
|
+
const callbackURL = body?.callbackURL || query?.callbackURL;
|
|
32
|
+
const redirectURL = body?.redirectTo;
|
|
33
|
+
const errorCallbackURL = body?.errorCallbackURL;
|
|
34
|
+
const newUserCallbackURL = body?.newUserCallbackURL;
|
|
35
|
+
const validateURL = (url, label) => {
|
|
36
|
+
if (!url) return;
|
|
37
|
+
if (!ctx.context.isTrustedOrigin(url, { allowRelativePaths: label !== "origin" })) {
|
|
38
|
+
ctx.context.logger.error(`Invalid ${label}: ${url}`);
|
|
39
|
+
ctx.context.logger.info(`If it's a valid URL, please add ${url} to trustedOrigins in your auth config\n`, `Current list of trustedOrigins: ${ctx.context.trustedOrigins}`);
|
|
40
|
+
if (label === "origin") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_ORIGIN);
|
|
41
|
+
if (label === "callbackURL") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_CALLBACK_URL);
|
|
42
|
+
if (label === "redirectURL") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_REDIRECT_URL);
|
|
43
|
+
if (label === "errorCallbackURL") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_ERROR_CALLBACK_URL);
|
|
44
|
+
if (label === "newUserCallbackURL") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_NEW_USER_CALLBACK_URL);
|
|
45
|
+
throw APIError.fromStatus("FORBIDDEN", { message: `Invalid ${label}` });
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
callbackURL && validateURL(callbackURL, "callbackURL");
|
|
49
|
+
redirectURL && validateURL(redirectURL, "redirectURL");
|
|
50
|
+
errorCallbackURL && validateURL(errorCallbackURL, "errorCallbackURL");
|
|
51
|
+
newUserCallbackURL && validateURL(newUserCallbackURL, "newUserCallbackURL");
|
|
52
|
+
});
|
|
53
|
+
const originCheck = (getValue) => createAuthMiddleware(async (ctx) => {
|
|
54
|
+
if (!ctx.request) return;
|
|
55
|
+
if (ctx.context.skipOriginCheck) return;
|
|
56
|
+
const callbackURL = getValue(ctx);
|
|
57
|
+
const validateURL = (url, label) => {
|
|
58
|
+
if (!url) return;
|
|
59
|
+
if (!ctx.context.isTrustedOrigin(url, { allowRelativePaths: label !== "origin" })) {
|
|
60
|
+
ctx.context.logger.error(`Invalid ${label}: ${url}`);
|
|
61
|
+
ctx.context.logger.info(`If it's a valid URL, please add ${url} to trustedOrigins in your auth config\n`, `Current list of trustedOrigins: ${ctx.context.trustedOrigins}`);
|
|
62
|
+
if (label === "origin") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_ORIGIN);
|
|
63
|
+
if (label === "callbackURL") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_CALLBACK_URL);
|
|
64
|
+
if (label === "redirectURL") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_REDIRECT_URL);
|
|
65
|
+
if (label === "errorCallbackURL") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_ERROR_CALLBACK_URL);
|
|
66
|
+
if (label === "newUserCallbackURL") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_NEW_USER_CALLBACK_URL);
|
|
67
|
+
throw APIError.fromStatus("FORBIDDEN", { message: `Invalid ${label}` });
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const callbacks = Array.isArray(callbackURL) ? callbackURL : [callbackURL];
|
|
71
|
+
for (const url of callbacks) validateURL(url, "callbackURL");
|
|
72
|
+
});
|
|
73
|
+
/**
|
|
74
|
+
* Validates origin header against trusted origins.
|
|
75
|
+
* @param ctx - The endpoint context
|
|
76
|
+
* @param forceValidate - If true, always validate origin regardless of cookies/skip flags
|
|
77
|
+
*/
|
|
78
|
+
async function validateOrigin(ctx, forceValidate = false) {
|
|
79
|
+
const headers = ctx.request?.headers;
|
|
80
|
+
if (!headers || !ctx.request) return;
|
|
81
|
+
const originHeader = headers.get("origin") || headers.get("referer") || "";
|
|
82
|
+
const useCookies = headers.has("cookie");
|
|
83
|
+
if (ctx.context.skipCSRFCheck) return;
|
|
84
|
+
if (shouldSkipCSRFForBackwardCompat(ctx)) {
|
|
85
|
+
ctx.context.options.advanced?.disableOriginCheck === true && logBackwardCompatWarning();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const skipOriginCheck = ctx.context.skipOriginCheck;
|
|
89
|
+
if (Array.isArray(skipOriginCheck)) try {
|
|
90
|
+
const basePath = new URL(ctx.context.baseURL).pathname;
|
|
91
|
+
const currentPath = normalizePathname(ctx.request.url, basePath);
|
|
92
|
+
if (skipOriginCheck.some((skipPath) => currentPath.startsWith(skipPath))) return;
|
|
93
|
+
} catch {}
|
|
94
|
+
if (!(forceValidate || useCookies)) return;
|
|
95
|
+
if (!originHeader || originHeader === "null") throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.MISSING_OR_NULL_ORIGIN);
|
|
96
|
+
const trustedOrigins = Array.isArray(ctx.context.options.trustedOrigins) ? ctx.context.trustedOrigins : [...ctx.context.trustedOrigins, ...(await ctx.context.options.trustedOrigins?.(ctx.request))?.filter((v) => Boolean(v)) || []];
|
|
97
|
+
if (!trustedOrigins.some((origin) => matchesOriginPattern(originHeader, origin))) {
|
|
98
|
+
ctx.context.logger.error(`Invalid origin: ${originHeader}`);
|
|
99
|
+
ctx.context.logger.info(`If it's a valid URL, please add ${originHeader} to trustedOrigins in your auth config\n`, `Current list of trustedOrigins: ${trustedOrigins}`);
|
|
100
|
+
throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.INVALID_ORIGIN);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Middleware for CSRF protection using Fetch Metadata headers.
|
|
105
|
+
* This prevents cross-site navigation login attacks while supporting progressive enhancement.
|
|
106
|
+
*/
|
|
107
|
+
const formCsrfMiddleware = createAuthMiddleware(async (ctx) => {
|
|
108
|
+
if (!ctx.request) return;
|
|
109
|
+
await validateFormCsrf(ctx);
|
|
110
|
+
});
|
|
111
|
+
/**
|
|
112
|
+
* Validates CSRF protection for first-login scenarios using Fetch Metadata headers.
|
|
113
|
+
* This prevents cross-site form submission attacks while supporting progressive enhancement.
|
|
114
|
+
*/
|
|
115
|
+
async function validateFormCsrf(ctx) {
|
|
116
|
+
const req = ctx.request;
|
|
117
|
+
if (!req) return;
|
|
118
|
+
if (ctx.context.skipCSRFCheck) return;
|
|
119
|
+
if (shouldSkipCSRFForBackwardCompat(ctx)) return;
|
|
120
|
+
const headers = req.headers;
|
|
121
|
+
if (headers.has("cookie")) return await validateOrigin(ctx);
|
|
122
|
+
const site = headers.get("Sec-Fetch-Site");
|
|
123
|
+
const mode = headers.get("Sec-Fetch-Mode");
|
|
124
|
+
const dest = headers.get("Sec-Fetch-Dest");
|
|
125
|
+
if (Boolean(site && site.trim() || mode && mode.trim() || dest && dest.trim())) {
|
|
126
|
+
if (site === "cross-site" && mode === "navigate") {
|
|
127
|
+
ctx.context.logger.error("Blocked cross-site navigation login attempt (CSRF protection)", {
|
|
128
|
+
secFetchSite: site,
|
|
129
|
+
secFetchMode: mode,
|
|
130
|
+
secFetchDest: dest
|
|
131
|
+
});
|
|
132
|
+
throw APIError.from("FORBIDDEN", BASE_ERROR_CODES.CROSS_SITE_NAVIGATION_LOGIN_BLOCKED);
|
|
133
|
+
}
|
|
134
|
+
return await validateOrigin(ctx, true);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//#endregion
|
|
139
|
+
export { formCsrfMiddleware, originCheck, originCheckMiddleware };
|
|
140
|
+
//# sourceMappingURL=origin-check.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"origin-check.mjs","names":[],"sources":["../../../src/api/middlewares/origin-check.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { createAuthMiddleware } from \"@better-auth/core/api\";\nimport { APIError, BASE_ERROR_CODES } from \"@better-auth/core/error\";\nimport { deprecate } from \"@better-auth/core/utils/deprecate\";\nimport { normalizePathname } from \"@better-auth/core/utils/url\";\nimport { matchesOriginPattern } from \"../../auth/trusted-origins\";\n\n/**\n * Checks if CSRF should be skipped for backward compatibility.\n * Previously, disableOriginCheck also disabled CSRF checks.\n * This maintains that behavior when disableCSRFCheck isn't explicitly set.\n * Only triggers for skipOriginCheck === true, not for path arrays.\n */\nfunction shouldSkipCSRFForBackwardCompat(ctx: GenericEndpointContext): boolean {\n\treturn (\n\t\tctx.context.skipOriginCheck === true &&\n\t\tctx.context.options.advanced?.disableCSRFCheck === undefined\n\t);\n}\n\n/**\n * Logs deprecation warning for users relying on coupled behavior.\n * Only logs if user explicitly set disableOriginCheck (not test environment default).\n */\nconst logBackwardCompatWarning = deprecate(\n\tfunction logBackwardCompatWarning() {},\n\t\"disableOriginCheck: true currently also disables CSRF checks. \" +\n\t\t\"In a future version, disableOriginCheck will ONLY disable URL validation. \" +\n\t\t\"To keep CSRF disabled, add disableCSRFCheck: true to your config.\",\n);\n\n/**\n * A middleware to validate callbackURL and origin against trustedOrigins.\n * Also handles CSRF protection using Fetch Metadata for first-login scenarios.\n */\nexport const originCheckMiddleware = createAuthMiddleware(async (ctx) => {\n\t// Skip origin check for GET, OPTIONS, HEAD requests - we don't mutate state here.\n\tif (\n\t\tctx.request?.method === \"GET\" ||\n\t\tctx.request?.method === \"OPTIONS\" ||\n\t\tctx.request?.method === \"HEAD\" ||\n\t\t!ctx.request\n\t) {\n\t\treturn;\n\t}\n\tawait validateOrigin(ctx);\n\n\tif (ctx.context.skipOriginCheck) {\n\t\treturn;\n\t}\n\n\tconst { body, query } = ctx;\n\tconst callbackURL = body?.callbackURL || query?.callbackURL;\n\tconst redirectURL = body?.redirectTo;\n\tconst errorCallbackURL = body?.errorCallbackURL;\n\tconst newUserCallbackURL = body?.newUserCallbackURL;\n\n\tconst validateURL = (\n\t\turl: string | undefined,\n\t\tlabel:\n\t\t\t| \"origin\"\n\t\t\t| \"callbackURL\"\n\t\t\t| \"redirectURL\"\n\t\t\t| \"errorCallbackURL\"\n\t\t\t| \"newUserCallbackURL\",\n\t) => {\n\t\tif (!url) {\n\t\t\treturn;\n\t\t}\n\t\tconst isTrustedOrigin = ctx.context.isTrustedOrigin(url, {\n\t\t\tallowRelativePaths: label !== \"origin\",\n\t\t});\n\n\t\tif (!isTrustedOrigin) {\n\t\t\tctx.context.logger.error(`Invalid ${label}: ${url}`);\n\t\t\tctx.context.logger.info(\n\t\t\t\t`If it's a valid URL, please add ${url} to trustedOrigins in your auth config\\n`,\n\t\t\t\t`Current list of trustedOrigins: ${ctx.context.trustedOrigins}`,\n\t\t\t);\n\t\t\tif (label === \"origin\") {\n\t\t\t\tthrow APIError.from(\"FORBIDDEN\", BASE_ERROR_CODES.INVALID_ORIGIN);\n\t\t\t}\n\t\t\tif (label === \"callbackURL\") {\n\t\t\t\tthrow APIError.from(\"FORBIDDEN\", BASE_ERROR_CODES.INVALID_CALLBACK_URL);\n\t\t\t}\n\t\t\tif (label === \"redirectURL\") {\n\t\t\t\tthrow APIError.from(\"FORBIDDEN\", BASE_ERROR_CODES.INVALID_REDIRECT_URL);\n\t\t\t}\n\t\t\tif (label === \"errorCallbackURL\") {\n\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\"FORBIDDEN\",\n\t\t\t\t\tBASE_ERROR_CODES.INVALID_ERROR_CALLBACK_URL,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (label === \"newUserCallbackURL\") {\n\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\"FORBIDDEN\",\n\t\t\t\t\tBASE_ERROR_CODES.INVALID_NEW_USER_CALLBACK_URL,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow APIError.fromStatus(\"FORBIDDEN\", {\n\t\t\t\tmessage: `Invalid ${label}`,\n\t\t\t});\n\t\t}\n\t};\n\n\tcallbackURL && validateURL(callbackURL, \"callbackURL\");\n\tredirectURL && validateURL(redirectURL, \"redirectURL\");\n\terrorCallbackURL && validateURL(errorCallbackURL, \"errorCallbackURL\");\n\tnewUserCallbackURL && validateURL(newUserCallbackURL, \"newUserCallbackURL\");\n});\n\nexport const originCheck = (\n\tgetValue: (ctx: GenericEndpointContext) => string | string[],\n) =>\n\tcreateAuthMiddleware(async (ctx) => {\n\t\tif (!ctx.request) {\n\t\t\treturn;\n\t\t}\n\t\tif (ctx.context.skipOriginCheck) {\n\t\t\treturn;\n\t\t}\n\t\tconst callbackURL = getValue(ctx);\n\t\tconst validateURL = (url: string | undefined, label: string) => {\n\t\t\tif (!url) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst isTrustedOrigin = ctx.context.isTrustedOrigin(url, {\n\t\t\t\tallowRelativePaths: label !== \"origin\",\n\t\t\t});\n\n\t\t\tif (!isTrustedOrigin) {\n\t\t\t\tctx.context.logger.error(`Invalid ${label}: ${url}`);\n\t\t\t\tctx.context.logger.info(\n\t\t\t\t\t`If it's a valid URL, please add ${url} to trustedOrigins in your auth config\\n`,\n\t\t\t\t\t`Current list of trustedOrigins: ${ctx.context.trustedOrigins}`,\n\t\t\t\t);\n\t\t\t\tif (label === \"origin\") {\n\t\t\t\t\tthrow APIError.from(\"FORBIDDEN\", BASE_ERROR_CODES.INVALID_ORIGIN);\n\t\t\t\t}\n\t\t\t\tif (label === \"callbackURL\") {\n\t\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\t\"FORBIDDEN\",\n\t\t\t\t\t\tBASE_ERROR_CODES.INVALID_CALLBACK_URL,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (label === \"redirectURL\") {\n\t\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\t\"FORBIDDEN\",\n\t\t\t\t\t\tBASE_ERROR_CODES.INVALID_REDIRECT_URL,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (label === \"errorCallbackURL\") {\n\t\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\t\"FORBIDDEN\",\n\t\t\t\t\t\tBASE_ERROR_CODES.INVALID_ERROR_CALLBACK_URL,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (label === \"newUserCallbackURL\") {\n\t\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\t\"FORBIDDEN\",\n\t\t\t\t\t\tBASE_ERROR_CODES.INVALID_NEW_USER_CALLBACK_URL,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow APIError.fromStatus(\"FORBIDDEN\", {\n\t\t\t\t\tmessage: `Invalid ${label}`,\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\t\tconst callbacks = Array.isArray(callbackURL) ? callbackURL : [callbackURL];\n\t\tfor (const url of callbacks) {\n\t\t\tvalidateURL(url, \"callbackURL\");\n\t\t}\n\t});\n\n/**\n * Validates origin header against trusted origins.\n * @param ctx - The endpoint context\n * @param forceValidate - If true, always validate origin regardless of cookies/skip flags\n */\nasync function validateOrigin(\n\tctx: GenericEndpointContext,\n\tforceValidate = false,\n): Promise<void> {\n\tconst headers = ctx.request?.headers;\n\tif (!headers || !ctx.request) {\n\t\treturn;\n\t}\n\tconst originHeader = headers.get(\"origin\") || headers.get(\"referer\") || \"\";\n\tconst useCookies = headers.has(\"cookie\");\n\n\tif (ctx.context.skipCSRFCheck) {\n\t\treturn;\n\t}\n\n\tif (shouldSkipCSRFForBackwardCompat(ctx)) {\n\t\tctx.context.options.advanced?.disableOriginCheck === true &&\n\t\t\tlogBackwardCompatWarning();\n\t\treturn;\n\t}\n\n\tconst skipOriginCheck = ctx.context.skipOriginCheck;\n\tif (Array.isArray(skipOriginCheck)) {\n\t\ttry {\n\t\t\tconst basePath = new URL(ctx.context.baseURL).pathname;\n\t\t\tconst currentPath = normalizePathname(ctx.request.url, basePath);\n\t\t\tconst shouldSkipPath = skipOriginCheck.some((skipPath) =>\n\t\t\t\tcurrentPath.startsWith(skipPath),\n\t\t\t);\n\t\t\tif (shouldSkipPath) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {\n\t\t\t// If parsing fails, don't skip - continue with validation\n\t\t}\n\t}\n\n\tconst shouldValidate = forceValidate || useCookies;\n\n\tif (!shouldValidate) {\n\t\treturn;\n\t}\n\n\tif (!originHeader || originHeader === \"null\") {\n\t\tthrow APIError.from(\"FORBIDDEN\", BASE_ERROR_CODES.MISSING_OR_NULL_ORIGIN);\n\t}\n\n\tconst trustedOrigins: string[] = Array.isArray(\n\t\tctx.context.options.trustedOrigins,\n\t)\n\t\t? ctx.context.trustedOrigins\n\t\t: [\n\t\t\t\t...ctx.context.trustedOrigins,\n\t\t\t\t...((await ctx.context.options.trustedOrigins?.(ctx.request))?.filter(\n\t\t\t\t\t(v): v is string => Boolean(v),\n\t\t\t\t) || []),\n\t\t\t];\n\n\tconst isTrustedOrigin = trustedOrigins.some((origin) =>\n\t\tmatchesOriginPattern(originHeader, origin),\n\t);\n\tif (!isTrustedOrigin) {\n\t\tctx.context.logger.error(`Invalid origin: ${originHeader}`);\n\t\tctx.context.logger.info(\n\t\t\t`If it's a valid URL, please add ${originHeader} to trustedOrigins in your auth config\\n`,\n\t\t\t`Current list of trustedOrigins: ${trustedOrigins}`,\n\t\t);\n\t\tthrow APIError.from(\"FORBIDDEN\", BASE_ERROR_CODES.INVALID_ORIGIN);\n\t}\n}\n\n/**\n * Middleware for CSRF protection using Fetch Metadata headers.\n * This prevents cross-site navigation login attacks while supporting progressive enhancement.\n */\nexport const formCsrfMiddleware = createAuthMiddleware(async (ctx) => {\n\tconst request = ctx.request;\n\tif (!request) {\n\t\treturn;\n\t}\n\n\tawait validateFormCsrf(ctx);\n});\n\n/**\n * Validates CSRF protection for first-login scenarios using Fetch Metadata headers.\n * This prevents cross-site form submission attacks while supporting progressive enhancement.\n */\nasync function validateFormCsrf(ctx: GenericEndpointContext): Promise<void> {\n\tconst req = ctx.request;\n\tif (!req) {\n\t\treturn;\n\t}\n\n\tif (ctx.context.skipCSRFCheck) {\n\t\treturn;\n\t}\n\n\tif (shouldSkipCSRFForBackwardCompat(ctx)) {\n\t\treturn;\n\t}\n\n\tconst headers = req.headers;\n\tconst hasAnyCookies = headers.has(\"cookie\");\n\n\tif (hasAnyCookies) {\n\t\treturn await validateOrigin(ctx);\n\t}\n\n\tconst site = headers.get(\"Sec-Fetch-Site\");\n\tconst mode = headers.get(\"Sec-Fetch-Mode\");\n\tconst dest = headers.get(\"Sec-Fetch-Dest\");\n\n\tconst hasMetadata = Boolean(\n\t\t(site && site.trim()) || (mode && mode.trim()) || (dest && dest.trim()),\n\t);\n\n\tif (hasMetadata) {\n\t\t// Block cross-site navigation requests (classic CSRF attack pattern)\n\t\tif (site === \"cross-site\" && mode === \"navigate\") {\n\t\t\tctx.context.logger.error(\n\t\t\t\t\"Blocked cross-site navigation login attempt (CSRF protection)\",\n\t\t\t\t{\n\t\t\t\t\tsecFetchSite: site,\n\t\t\t\t\tsecFetchMode: mode,\n\t\t\t\t\tsecFetchDest: dest,\n\t\t\t\t},\n\t\t\t);\n\t\t\tthrow APIError.from(\n\t\t\t\t\"FORBIDDEN\",\n\t\t\t\tBASE_ERROR_CODES.CROSS_SITE_NAVIGATION_LOGIN_BLOCKED,\n\t\t\t);\n\t\t}\n\n\t\treturn await validateOrigin(ctx, true);\n\t}\n\n\t// No cookies, no Fetch Metadata → fallback to old behavior (no validation)\n\treturn;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { wildcardMatch } from "../../utils/wildcard.mjs";
|
|
2
|
+
import { getIp } from "../../utils/get-request-ip.mjs";
|
|
3
|
+
import { safeJSONParse } from "@better-auth/core/utils/json";
|
|
4
|
+
import { normalizePathname } from "@better-auth/core/utils/url";
|
|
5
|
+
import { createRateLimitKey } from "@better-auth/core/utils/ip";
|
|
6
|
+
|
|
7
|
+
//#region src/api/rate-limiter/index.ts
|
|
8
|
+
const memory = /* @__PURE__ */ new Map();
|
|
9
|
+
function shouldRateLimit(max, window, rateLimitData) {
|
|
10
|
+
const now = Date.now();
|
|
11
|
+
const windowInMs = window * 1e3;
|
|
12
|
+
return now - rateLimitData.lastRequest < windowInMs && rateLimitData.count >= max;
|
|
13
|
+
}
|
|
14
|
+
function rateLimitResponse(retryAfter) {
|
|
15
|
+
return new Response(JSON.stringify({ message: "Too many requests. Please try again later." }), {
|
|
16
|
+
status: 429,
|
|
17
|
+
statusText: "Too Many Requests",
|
|
18
|
+
headers: { "X-Retry-After": retryAfter.toString() }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function getRetryAfter(lastRequest, window) {
|
|
22
|
+
const now = Date.now();
|
|
23
|
+
const windowInMs = window * 1e3;
|
|
24
|
+
return Math.ceil((lastRequest + windowInMs - now) / 1e3);
|
|
25
|
+
}
|
|
26
|
+
function createDatabaseStorageWrapper(ctx) {
|
|
27
|
+
const model = "rateLimit";
|
|
28
|
+
const db = ctx.adapter;
|
|
29
|
+
return {
|
|
30
|
+
get: async (key) => {
|
|
31
|
+
const data = (await db.findMany({
|
|
32
|
+
model,
|
|
33
|
+
where: [{
|
|
34
|
+
field: "key",
|
|
35
|
+
value: key
|
|
36
|
+
}]
|
|
37
|
+
}))[0];
|
|
38
|
+
if (typeof data?.lastRequest === "bigint") data.lastRequest = Number(data.lastRequest);
|
|
39
|
+
return data;
|
|
40
|
+
},
|
|
41
|
+
set: async (key, value, _update) => {
|
|
42
|
+
try {
|
|
43
|
+
if (_update) await db.updateMany({
|
|
44
|
+
model,
|
|
45
|
+
where: [{
|
|
46
|
+
field: "key",
|
|
47
|
+
value: key
|
|
48
|
+
}],
|
|
49
|
+
update: {
|
|
50
|
+
count: value.count,
|
|
51
|
+
lastRequest: value.lastRequest
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
else await db.create({
|
|
55
|
+
model,
|
|
56
|
+
data: {
|
|
57
|
+
key,
|
|
58
|
+
count: value.count,
|
|
59
|
+
lastRequest: value.lastRequest
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
} catch (e) {
|
|
63
|
+
ctx.logger.error("Error setting rate limit", e);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function getRateLimitStorage(ctx, rateLimitSettings) {
|
|
69
|
+
if (ctx.options.rateLimit?.customStorage) return ctx.options.rateLimit.customStorage;
|
|
70
|
+
const storage = ctx.rateLimit.storage;
|
|
71
|
+
if (storage === "secondary-storage") return {
|
|
72
|
+
get: async (key) => {
|
|
73
|
+
const data = await ctx.options.secondaryStorage?.get(key);
|
|
74
|
+
return data ? safeJSONParse(data) : null;
|
|
75
|
+
},
|
|
76
|
+
set: async (key, value, _update) => {
|
|
77
|
+
const ttl = rateLimitSettings?.window ?? ctx.options.rateLimit?.window ?? 10;
|
|
78
|
+
await ctx.options.secondaryStorage?.set?.(key, JSON.stringify(value), ttl);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
else if (storage === "memory") return {
|
|
82
|
+
async get(key) {
|
|
83
|
+
const entry = memory.get(key);
|
|
84
|
+
if (!entry) return null;
|
|
85
|
+
if (Date.now() >= entry.expiresAt) {
|
|
86
|
+
memory.delete(key);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
return entry.data;
|
|
90
|
+
},
|
|
91
|
+
async set(key, value, _update) {
|
|
92
|
+
const ttl = rateLimitSettings?.window ?? ctx.options.rateLimit?.window ?? 10;
|
|
93
|
+
const expiresAt = Date.now() + ttl * 1e3;
|
|
94
|
+
memory.set(key, {
|
|
95
|
+
data: value,
|
|
96
|
+
expiresAt
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
return createDatabaseStorageWrapper(ctx);
|
|
101
|
+
}
|
|
102
|
+
let ipWarningLogged = false;
|
|
103
|
+
async function resolveRateLimitConfig(req, ctx) {
|
|
104
|
+
const basePath = new URL(ctx.baseURL).pathname;
|
|
105
|
+
const path = normalizePathname(req.url, basePath);
|
|
106
|
+
let currentWindow = ctx.rateLimit.window;
|
|
107
|
+
let currentMax = ctx.rateLimit.max;
|
|
108
|
+
const ip = getIp(req, ctx.options);
|
|
109
|
+
if (!ip) {
|
|
110
|
+
if (!ipWarningLogged) {
|
|
111
|
+
ctx.logger.warn("Rate limiting skipped: could not determine client IP address. If you're behind a reverse proxy, make sure to configure `trustedProxies` in your auth config.");
|
|
112
|
+
ipWarningLogged = true;
|
|
113
|
+
}
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const key = createRateLimitKey(ip, path);
|
|
117
|
+
const specialRule = getDefaultSpecialRules().find((rule) => rule.pathMatcher(path));
|
|
118
|
+
if (specialRule) {
|
|
119
|
+
currentWindow = specialRule.window;
|
|
120
|
+
currentMax = specialRule.max;
|
|
121
|
+
}
|
|
122
|
+
for (const plugin of ctx.options.plugins || []) if (plugin.rateLimit) {
|
|
123
|
+
const matchedRule = plugin.rateLimit.find((rule) => rule.pathMatcher(path));
|
|
124
|
+
if (matchedRule) {
|
|
125
|
+
currentWindow = matchedRule.window;
|
|
126
|
+
currentMax = matchedRule.max;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (ctx.rateLimit.customRules) {
|
|
131
|
+
const _path = Object.keys(ctx.rateLimit.customRules).find((p) => {
|
|
132
|
+
if (p.includes("*")) return wildcardMatch(p)(path);
|
|
133
|
+
return p === path;
|
|
134
|
+
});
|
|
135
|
+
if (_path) {
|
|
136
|
+
const customRule = ctx.rateLimit.customRules[_path];
|
|
137
|
+
const resolved = typeof customRule === "function" ? await customRule(req, {
|
|
138
|
+
window: currentWindow,
|
|
139
|
+
max: currentMax
|
|
140
|
+
}) : customRule;
|
|
141
|
+
if (resolved) {
|
|
142
|
+
currentWindow = resolved.window;
|
|
143
|
+
currentMax = resolved.max;
|
|
144
|
+
}
|
|
145
|
+
if (resolved === false) return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
key,
|
|
150
|
+
currentWindow,
|
|
151
|
+
currentMax
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
async function onRequestRateLimit(req, ctx) {
|
|
155
|
+
if (!ctx.rateLimit.enabled) return;
|
|
156
|
+
const config = await resolveRateLimitConfig(req, ctx);
|
|
157
|
+
if (!config) return;
|
|
158
|
+
const { key, currentWindow, currentMax } = config;
|
|
159
|
+
const data = await getRateLimitStorage(ctx, { window: currentWindow }).get(key);
|
|
160
|
+
if (data && shouldRateLimit(currentMax, currentWindow, data)) return rateLimitResponse(getRetryAfter(data.lastRequest, currentWindow));
|
|
161
|
+
}
|
|
162
|
+
async function onResponseRateLimit(req, ctx) {
|
|
163
|
+
if (!ctx.rateLimit.enabled) return;
|
|
164
|
+
const config = await resolveRateLimitConfig(req, ctx);
|
|
165
|
+
if (!config) return;
|
|
166
|
+
const { key, currentWindow } = config;
|
|
167
|
+
const storage = getRateLimitStorage(ctx, { window: currentWindow });
|
|
168
|
+
const data = await storage.get(key);
|
|
169
|
+
const now = Date.now();
|
|
170
|
+
if (!data) await storage.set(key, {
|
|
171
|
+
key,
|
|
172
|
+
count: 1,
|
|
173
|
+
lastRequest: now
|
|
174
|
+
});
|
|
175
|
+
else if (now - data.lastRequest > currentWindow * 1e3) await storage.set(key, {
|
|
176
|
+
...data,
|
|
177
|
+
count: 1,
|
|
178
|
+
lastRequest: now
|
|
179
|
+
}, true);
|
|
180
|
+
else await storage.set(key, {
|
|
181
|
+
...data,
|
|
182
|
+
count: data.count + 1,
|
|
183
|
+
lastRequest: now
|
|
184
|
+
}, true);
|
|
185
|
+
}
|
|
186
|
+
function getDefaultSpecialRules() {
|
|
187
|
+
return [{
|
|
188
|
+
pathMatcher(path) {
|
|
189
|
+
return path.startsWith("/sign-in") || path.startsWith("/sign-up") || path.startsWith("/change-password") || path.startsWith("/change-email");
|
|
190
|
+
},
|
|
191
|
+
window: 10,
|
|
192
|
+
max: 3
|
|
193
|
+
}, {
|
|
194
|
+
pathMatcher(path) {
|
|
195
|
+
return path === "/request-password-reset" || path === "/send-verification-email" || path.startsWith("/forget-password") || path === "/email-otp/send-verification-otp" || path === "/email-otp/request-password-reset";
|
|
196
|
+
},
|
|
197
|
+
window: 60,
|
|
198
|
+
max: 3
|
|
199
|
+
}];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
//#endregion
|
|
203
|
+
export { onRequestRateLimit, onResponseRateLimit };
|
|
204
|
+
//# sourceMappingURL=index.mjs.map
|