@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,97 @@
|
|
|
1
|
+
import * as _better_auth_core0 from "@better-auth/core";
|
|
2
|
+
import * as better_call0 from "better-call";
|
|
3
|
+
import * as z from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/plugins/oauth-proxy/index.d.ts
|
|
6
|
+
declare module "@better-auth/core" {
|
|
7
|
+
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
8
|
+
"oauth-proxy": {
|
|
9
|
+
creator: typeof oAuthProxy;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
interface OAuthProxyOptions {
|
|
14
|
+
/**
|
|
15
|
+
* The current URL of the application.
|
|
16
|
+
* The plugin will attempt to infer the current URL from your environment
|
|
17
|
+
* by checking the base URL from popular hosting providers,
|
|
18
|
+
* from the request URL if invoked by a client,
|
|
19
|
+
* or as a fallback, from the `baseURL` in your auth config.
|
|
20
|
+
* If the URL is not inferred correctly, you can provide a value here."
|
|
21
|
+
*/
|
|
22
|
+
currentURL?: string | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* If a request in a production url it won't be proxied.
|
|
25
|
+
*
|
|
26
|
+
* default to `BETTER_AUTH_URL`
|
|
27
|
+
*/
|
|
28
|
+
productionURL?: string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Maximum age in seconds for the encrypted payload.
|
|
31
|
+
* Payloads older than this will be rejected to prevent replay attacks.
|
|
32
|
+
*
|
|
33
|
+
* Keep this value short (e.g., 30-60 seconds) to minimize the window
|
|
34
|
+
* for potential replay attacks while still allowing normal OAuth flows.
|
|
35
|
+
*
|
|
36
|
+
* @default 60 (1 minute)
|
|
37
|
+
*/
|
|
38
|
+
maxAge?: number | undefined;
|
|
39
|
+
}
|
|
40
|
+
declare const oAuthProxy: <O extends OAuthProxyOptions>(opts?: O) => {
|
|
41
|
+
id: "oauth-proxy";
|
|
42
|
+
options: NoInfer<O>;
|
|
43
|
+
endpoints: {
|
|
44
|
+
oAuthProxy: better_call0.StrictEndpoint<"/oauth-proxy-callback", {
|
|
45
|
+
method: "GET";
|
|
46
|
+
operationId: string;
|
|
47
|
+
query: z.ZodObject<{
|
|
48
|
+
callbackURL: z.ZodString;
|
|
49
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>)[];
|
|
52
|
+
metadata: {
|
|
53
|
+
openapi: {
|
|
54
|
+
operationId: string;
|
|
55
|
+
description: string;
|
|
56
|
+
parameters: ({
|
|
57
|
+
in: "query";
|
|
58
|
+
name: string;
|
|
59
|
+
required: true;
|
|
60
|
+
description: string;
|
|
61
|
+
} | {
|
|
62
|
+
in: "query";
|
|
63
|
+
name: string;
|
|
64
|
+
required: false;
|
|
65
|
+
description: string;
|
|
66
|
+
})[];
|
|
67
|
+
responses: {
|
|
68
|
+
302: {
|
|
69
|
+
description: string;
|
|
70
|
+
headers: {
|
|
71
|
+
Location: {
|
|
72
|
+
description: string;
|
|
73
|
+
schema: {
|
|
74
|
+
type: string;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
}, never>;
|
|
83
|
+
};
|
|
84
|
+
hooks: {
|
|
85
|
+
before: {
|
|
86
|
+
matcher(context: _better_auth_core0.HookEndpointContext): boolean;
|
|
87
|
+
handler: (inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>;
|
|
88
|
+
}[];
|
|
89
|
+
after: {
|
|
90
|
+
matcher(context: _better_auth_core0.HookEndpointContext): boolean;
|
|
91
|
+
handler: (inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>;
|
|
92
|
+
}[];
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
//#endregion
|
|
96
|
+
export { OAuthProxyOptions, oAuthProxy };
|
|
97
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { getOrigin } from "../../utils/url.mjs";
|
|
2
|
+
import { originCheck } from "../../api/middlewares/origin-check.mjs";
|
|
3
|
+
import { symmetricDecrypt, symmetricEncrypt } from "../../crypto/index.mjs";
|
|
4
|
+
import { parseSetCookieHeader } from "../../cookies/cookie-utils.mjs";
|
|
5
|
+
import { setSessionCookie } from "../../cookies/index.mjs";
|
|
6
|
+
import { parseGenericState } from "../../state.mjs";
|
|
7
|
+
import { handleOAuthUserInfo } from "../../oauth2/link-account.mjs";
|
|
8
|
+
import "../../api/index.mjs";
|
|
9
|
+
import { parseJSON } from "../../client/parser.mjs";
|
|
10
|
+
import { checkSkipProxy, redirectOnError, resolveCurrentURL, stripTrailingSlash } from "./utils.mjs";
|
|
11
|
+
import { createAuthEndpoint, createAuthMiddleware } from "@better-auth/core/api";
|
|
12
|
+
import * as z from "zod";
|
|
13
|
+
|
|
14
|
+
//#region src/plugins/oauth-proxy/index.ts
|
|
15
|
+
const oauthProxyQuerySchema = z.object({
|
|
16
|
+
callbackURL: z.string().meta({ description: "The URL to redirect to after the proxy" }),
|
|
17
|
+
profile: z.string().optional().meta({ description: "Encrypted OAuth profile data" })
|
|
18
|
+
});
|
|
19
|
+
const oauthCallbackQuerySchema = z.object({
|
|
20
|
+
code: z.string().optional(),
|
|
21
|
+
error: z.string().optional()
|
|
22
|
+
});
|
|
23
|
+
const oAuthProxy = (opts) => {
|
|
24
|
+
const maxAge = opts?.maxAge ?? 60;
|
|
25
|
+
return {
|
|
26
|
+
id: "oauth-proxy",
|
|
27
|
+
options: opts,
|
|
28
|
+
endpoints: { oAuthProxy: createAuthEndpoint("/oauth-proxy-callback", {
|
|
29
|
+
method: "GET",
|
|
30
|
+
operationId: "oauthProxyCallback",
|
|
31
|
+
query: oauthProxyQuerySchema,
|
|
32
|
+
use: [originCheck((ctx) => ctx.query.callbackURL)],
|
|
33
|
+
metadata: { openapi: {
|
|
34
|
+
operationId: "oauthProxyCallback",
|
|
35
|
+
description: "OAuth Proxy Callback",
|
|
36
|
+
parameters: [{
|
|
37
|
+
in: "query",
|
|
38
|
+
name: "callbackURL",
|
|
39
|
+
required: true,
|
|
40
|
+
description: "The URL to redirect to after the proxy"
|
|
41
|
+
}, {
|
|
42
|
+
in: "query",
|
|
43
|
+
name: "profile",
|
|
44
|
+
required: false,
|
|
45
|
+
description: "Encrypted OAuth profile data"
|
|
46
|
+
}],
|
|
47
|
+
responses: { 302: {
|
|
48
|
+
description: "Redirect",
|
|
49
|
+
headers: { Location: {
|
|
50
|
+
description: "The URL to redirect to",
|
|
51
|
+
schema: { type: "string" }
|
|
52
|
+
} }
|
|
53
|
+
} }
|
|
54
|
+
} }
|
|
55
|
+
}, async (ctx) => {
|
|
56
|
+
const defaultErrorURL = ctx.context.options.onAPIError?.errorURL || `${stripTrailingSlash(ctx.context.options.baseURL)}/api/auth/error`;
|
|
57
|
+
const encryptedProfile = ctx.query.profile;
|
|
58
|
+
if (!encryptedProfile) {
|
|
59
|
+
ctx.context.logger.error("OAuth proxy callback missing profile data");
|
|
60
|
+
throw redirectOnError(ctx, defaultErrorURL, "missing_profile");
|
|
61
|
+
}
|
|
62
|
+
let decryptedPayload;
|
|
63
|
+
try {
|
|
64
|
+
decryptedPayload = await symmetricDecrypt({
|
|
65
|
+
key: ctx.context.secret,
|
|
66
|
+
data: encryptedProfile
|
|
67
|
+
});
|
|
68
|
+
} catch (e) {
|
|
69
|
+
ctx.context.logger.error("Failed to decrypt OAuth proxy profile", e);
|
|
70
|
+
throw redirectOnError(ctx, defaultErrorURL, "invalid_profile");
|
|
71
|
+
}
|
|
72
|
+
let payload;
|
|
73
|
+
try {
|
|
74
|
+
payload = parseJSON(decryptedPayload);
|
|
75
|
+
} catch (e) {
|
|
76
|
+
ctx.context.logger.error("Failed to parse OAuth proxy payload", e);
|
|
77
|
+
throw redirectOnError(ctx, defaultErrorURL, "invalid_payload");
|
|
78
|
+
}
|
|
79
|
+
if (typeof payload.timestamp !== "number" || !payload.userInfo || !payload.account || !payload.callbackURL) {
|
|
80
|
+
ctx.context.logger.error("Failed to parse OAuth proxy payload");
|
|
81
|
+
throw redirectOnError(ctx, defaultErrorURL, "invalid_payload");
|
|
82
|
+
}
|
|
83
|
+
const errorURL = payload.errorURL || defaultErrorURL;
|
|
84
|
+
const age = (Date.now() - payload.timestamp) / 1e3;
|
|
85
|
+
if (age > maxAge || age < -10) {
|
|
86
|
+
ctx.context.logger.error(`OAuth proxy payload expired or invalid (age: ${age}s, maxAge: ${maxAge}s)`);
|
|
87
|
+
throw redirectOnError(ctx, errorURL, "payload_expired");
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
await parseGenericState(ctx, payload.state);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
ctx.context.logger.warn("Failed to clean up OAuth state", e);
|
|
93
|
+
}
|
|
94
|
+
const result = await handleOAuthUserInfo(ctx, {
|
|
95
|
+
userInfo: payload.userInfo,
|
|
96
|
+
account: payload.account,
|
|
97
|
+
callbackURL: payload.callbackURL,
|
|
98
|
+
disableSignUp: payload.disableSignUp
|
|
99
|
+
});
|
|
100
|
+
if (result.error || !result.data) {
|
|
101
|
+
ctx.context.logger.error("Failed to create user or session", result.error);
|
|
102
|
+
throw redirectOnError(ctx, errorURL, "user_creation_failed");
|
|
103
|
+
}
|
|
104
|
+
await setSessionCookie(ctx, result.data);
|
|
105
|
+
const finalURL = result.isRegister ? payload.newUserURL || payload.callbackURL : payload.callbackURL;
|
|
106
|
+
throw ctx.redirect(finalURL);
|
|
107
|
+
}) },
|
|
108
|
+
hooks: {
|
|
109
|
+
before: [{
|
|
110
|
+
matcher(context) {
|
|
111
|
+
return !!(context.path?.startsWith("/sign-in/social") || context.path?.startsWith("/sign-in/oauth2"));
|
|
112
|
+
},
|
|
113
|
+
handler: createAuthMiddleware(async (ctx) => {
|
|
114
|
+
if (checkSkipProxy(ctx, opts)) return;
|
|
115
|
+
const currentURL = resolveCurrentURL(ctx, opts);
|
|
116
|
+
const productionURL = opts?.productionURL;
|
|
117
|
+
const originalCallbackURL = ctx.body?.callbackURL || ctx.context.baseURL;
|
|
118
|
+
if (productionURL) {
|
|
119
|
+
const productionBaseURL = `${stripTrailingSlash(productionURL)}${ctx.context.options.basePath || "/api/auth"}`;
|
|
120
|
+
ctx.context.baseURL = productionBaseURL;
|
|
121
|
+
}
|
|
122
|
+
const newCallbackURL = `${stripTrailingSlash(currentURL.origin)}${ctx.context.options.basePath || "/api/auth"}/oauth-proxy-callback?callbackURL=${encodeURIComponent(originalCallbackURL)}`;
|
|
123
|
+
if (!ctx.body) return;
|
|
124
|
+
ctx.body.callbackURL = newCallbackURL;
|
|
125
|
+
})
|
|
126
|
+
}, {
|
|
127
|
+
matcher(context) {
|
|
128
|
+
return context.path === "/callback/:id";
|
|
129
|
+
},
|
|
130
|
+
handler: createAuthMiddleware(async (ctx) => {
|
|
131
|
+
const state = ctx.query?.state || ctx.body?.state;
|
|
132
|
+
if (!state || typeof state !== "string") return;
|
|
133
|
+
let statePackage;
|
|
134
|
+
try {
|
|
135
|
+
statePackage = parseJSON(await symmetricDecrypt({
|
|
136
|
+
key: ctx.context.secret,
|
|
137
|
+
data: state
|
|
138
|
+
}));
|
|
139
|
+
} catch {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (!statePackage.isOAuthProxy || !statePackage.state || !statePackage.stateCookie) {
|
|
143
|
+
ctx.context.logger.warn("Invalid OAuth proxy state package");
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const query = oauthCallbackQuerySchema.safeParse(ctx.query);
|
|
147
|
+
if (!query.success) {
|
|
148
|
+
ctx.context.logger.warn("Invalid OAuth callback query", query.error);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const { code, error } = query.data;
|
|
152
|
+
let stateData;
|
|
153
|
+
try {
|
|
154
|
+
stateData = parseJSON(await symmetricDecrypt({
|
|
155
|
+
key: ctx.context.secret,
|
|
156
|
+
data: statePackage.stateCookie
|
|
157
|
+
}));
|
|
158
|
+
} catch (e) {
|
|
159
|
+
ctx.context.logger.error("Failed to decrypt OAuth proxy state cookie:", e);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const errorURL = stateData.errorURL || ctx.context.options.onAPIError?.errorURL || `${ctx.context.baseURL}/error`;
|
|
163
|
+
if (error) throw redirectOnError(ctx, errorURL, error);
|
|
164
|
+
if (!code) {
|
|
165
|
+
ctx.context.logger.error("OAuth callback missing authorization code");
|
|
166
|
+
throw redirectOnError(ctx, errorURL, "no_code");
|
|
167
|
+
}
|
|
168
|
+
const providerId = ctx.params?.id;
|
|
169
|
+
const provider = ctx.context.socialProviders.find((p) => p.id === providerId);
|
|
170
|
+
if (!provider) {
|
|
171
|
+
ctx.context.logger.error("OAuth provider not found", providerId);
|
|
172
|
+
throw redirectOnError(ctx, errorURL, "oauth_provider_not_found");
|
|
173
|
+
}
|
|
174
|
+
let tokens;
|
|
175
|
+
try {
|
|
176
|
+
tokens = await provider.validateAuthorizationCode({
|
|
177
|
+
code,
|
|
178
|
+
codeVerifier: stateData.codeVerifier,
|
|
179
|
+
redirectURI: `${ctx.context.baseURL}/callback/${provider.id}`
|
|
180
|
+
});
|
|
181
|
+
} catch (e) {
|
|
182
|
+
ctx.context.logger.error("Failed to validate authorization code", e);
|
|
183
|
+
throw redirectOnError(ctx, errorURL, "invalid_code");
|
|
184
|
+
}
|
|
185
|
+
if (!tokens) throw redirectOnError(ctx, errorURL, "invalid_code");
|
|
186
|
+
const userInfo = (await provider.getUserInfo(tokens))?.user;
|
|
187
|
+
if (!userInfo) {
|
|
188
|
+
ctx.context.logger.error("Unable to get user info from provider");
|
|
189
|
+
throw redirectOnError(ctx, errorURL, "unable_to_get_user_info");
|
|
190
|
+
}
|
|
191
|
+
if (!userInfo.email) {
|
|
192
|
+
ctx.context.logger.error("Provider did not return email");
|
|
193
|
+
throw redirectOnError(ctx, errorURL, "email_not_found");
|
|
194
|
+
}
|
|
195
|
+
const proxyCallbackURL = new URL(stateData.callbackURL);
|
|
196
|
+
const finalCallbackURL = proxyCallbackURL.searchParams.get("callbackURL") || stateData.callbackURL;
|
|
197
|
+
const payload = {
|
|
198
|
+
userInfo: {
|
|
199
|
+
id: String(userInfo.id),
|
|
200
|
+
email: userInfo.email,
|
|
201
|
+
name: userInfo.name || "",
|
|
202
|
+
image: userInfo.image,
|
|
203
|
+
emailVerified: userInfo.emailVerified
|
|
204
|
+
},
|
|
205
|
+
account: {
|
|
206
|
+
providerId: provider.id,
|
|
207
|
+
accountId: String(userInfo.id),
|
|
208
|
+
accessToken: tokens.accessToken,
|
|
209
|
+
refreshToken: tokens.refreshToken,
|
|
210
|
+
idToken: tokens.idToken,
|
|
211
|
+
accessTokenExpiresAt: tokens.accessTokenExpiresAt,
|
|
212
|
+
refreshTokenExpiresAt: tokens.refreshTokenExpiresAt,
|
|
213
|
+
scope: tokens.scopes?.join(",")
|
|
214
|
+
},
|
|
215
|
+
state: statePackage.state,
|
|
216
|
+
callbackURL: finalCallbackURL,
|
|
217
|
+
newUserURL: stateData.newUserURL,
|
|
218
|
+
errorURL: stateData.errorURL,
|
|
219
|
+
disableSignUp: provider.disableImplicitSignUp && !stateData.requestSignUp || provider.options?.disableSignUp,
|
|
220
|
+
timestamp: Date.now()
|
|
221
|
+
};
|
|
222
|
+
const encryptedPayload = await symmetricEncrypt({
|
|
223
|
+
key: ctx.context.secret,
|
|
224
|
+
data: JSON.stringify(payload)
|
|
225
|
+
});
|
|
226
|
+
proxyCallbackURL.searchParams.set("profile", encryptedPayload);
|
|
227
|
+
throw ctx.redirect(proxyCallbackURL.toString());
|
|
228
|
+
})
|
|
229
|
+
}],
|
|
230
|
+
after: [{
|
|
231
|
+
matcher(context) {
|
|
232
|
+
return !!(context.path?.startsWith("/sign-in/social") || context.path?.startsWith("/sign-in/oauth2"));
|
|
233
|
+
},
|
|
234
|
+
handler: createAuthMiddleware(async (ctx) => {
|
|
235
|
+
if (checkSkipProxy(ctx, opts)) return;
|
|
236
|
+
const signInResponse = ctx.context.returned;
|
|
237
|
+
if (!signInResponse || typeof signInResponse !== "object" || !("url" in signInResponse)) return;
|
|
238
|
+
const { url: providerURL } = signInResponse;
|
|
239
|
+
if (typeof providerURL !== "string") return;
|
|
240
|
+
const oauthURL = new URL(providerURL);
|
|
241
|
+
const originalState = oauthURL.searchParams.get("state");
|
|
242
|
+
if (!originalState) return;
|
|
243
|
+
let stateCookieValue;
|
|
244
|
+
if (ctx.context.oauthConfig.storeStateStrategy === "cookie") {
|
|
245
|
+
const setCookieHeader = ctx.context.responseHeaders?.get("set-cookie");
|
|
246
|
+
if (setCookieHeader) {
|
|
247
|
+
const parsedCookies = parseSetCookieHeader(setCookieHeader);
|
|
248
|
+
const stateCookie = ctx.context.createAuthCookie("oauth_state");
|
|
249
|
+
stateCookieValue = parsedCookies.get(stateCookie.name)?.value;
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
const verification = await ctx.context.internalAdapter.findVerificationValue(originalState);
|
|
253
|
+
if (verification) stateCookieValue = await symmetricEncrypt({
|
|
254
|
+
key: ctx.context.secret,
|
|
255
|
+
data: verification.value
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (!stateCookieValue) {
|
|
259
|
+
ctx.context.logger.warn("No OAuth state cookie value found");
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
try {
|
|
263
|
+
const statePackage = {
|
|
264
|
+
state: originalState,
|
|
265
|
+
stateCookie: stateCookieValue,
|
|
266
|
+
isOAuthProxy: true
|
|
267
|
+
};
|
|
268
|
+
const encryptedPackage = await symmetricEncrypt({
|
|
269
|
+
key: ctx.context.secret,
|
|
270
|
+
data: JSON.stringify(statePackage)
|
|
271
|
+
});
|
|
272
|
+
oauthURL.searchParams.set("state", encryptedPackage);
|
|
273
|
+
ctx.context.returned = {
|
|
274
|
+
...signInResponse,
|
|
275
|
+
url: oauthURL.toString()
|
|
276
|
+
};
|
|
277
|
+
} catch (e) {
|
|
278
|
+
ctx.context.logger.error("Failed to encrypt OAuth proxy state package:", e);
|
|
279
|
+
}
|
|
280
|
+
})
|
|
281
|
+
}, {
|
|
282
|
+
matcher(context) {
|
|
283
|
+
return context.path === "/callback/:id";
|
|
284
|
+
},
|
|
285
|
+
handler: createAuthMiddleware(async (ctx) => {
|
|
286
|
+
const location = ctx.context.responseHeaders?.get("location");
|
|
287
|
+
if (!location?.includes("/oauth-proxy-callback?callbackURL") || !location.startsWith("http")) return;
|
|
288
|
+
const productionOrigin = getOrigin(opts?.productionURL || ctx.context.options.baseURL || ctx.context.baseURL);
|
|
289
|
+
const locationURL = new URL(location);
|
|
290
|
+
if (locationURL.origin === productionOrigin) {
|
|
291
|
+
const newLocation = locationURL.searchParams.get("callbackURL");
|
|
292
|
+
if (!newLocation) return;
|
|
293
|
+
ctx.setHeader("location", newLocation);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
ctx.context.logger.warn("OAuth proxy: cross-origin callback reached after hook unexpectedly");
|
|
297
|
+
})
|
|
298
|
+
}]
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
//#endregion
|
|
304
|
+
export { oAuthProxy };
|
|
305
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/oauth-proxy/index.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport type { OAuth2Tokens } from \"@better-auth/core/oauth2\";\nimport * as z from \"zod\";\nimport { originCheck } from \"../../api\";\nimport { parseJSON } from \"../../client/parser\";\nimport { setSessionCookie } from \"../../cookies\";\nimport { parseSetCookieHeader } from \"../../cookies/cookie-utils\";\nimport { symmetricDecrypt, symmetricEncrypt } from \"../../crypto\";\nimport { handleOAuthUserInfo } from \"../../oauth2/link-account\";\nimport type { StateData } from \"../../state\";\nimport { parseGenericState } from \"../../state\";\nimport type { Account, User } from \"../../types\";\nimport { getOrigin } from \"../../utils/url\";\nimport {\n\tcheckSkipProxy,\n\tredirectOnError,\n\tresolveCurrentURL,\n\tstripTrailingSlash,\n} from \"./utils\";\n\ndeclare module \"@better-auth/core\" {\n\tinterface BetterAuthPluginRegistry<AuthOptions, Options> {\n\t\t\"oauth-proxy\": {\n\t\t\tcreator: typeof oAuthProxy;\n\t\t};\n\t}\n}\n\nexport interface OAuthProxyOptions {\n\t/**\n\t * The current URL of the application.\n\t * The plugin will attempt to infer the current URL from your environment\n\t * by checking the base URL from popular hosting providers,\n\t * from the request URL if invoked by a client,\n\t * or as a fallback, from the `baseURL` in your auth config.\n\t * If the URL is not inferred correctly, you can provide a value here.\"\n\t */\n\tcurrentURL?: string | undefined;\n\t/**\n\t * If a request in a production url it won't be proxied.\n\t *\n\t * default to `BETTER_AUTH_URL`\n\t */\n\tproductionURL?: string | undefined;\n\t/**\n\t * Maximum age in seconds for the encrypted payload.\n\t * Payloads older than this will be rejected to prevent replay attacks.\n\t *\n\t * Keep this value short (e.g., 30-60 seconds) to minimize the window\n\t * for potential replay attacks while still allowing normal OAuth flows.\n\t *\n\t * @default 60 (1 minute)\n\t */\n\tmaxAge?: number | undefined;\n}\n\n/**\n * Encrypted state package for cross-origin OAuth proxy flow\n * @internal\n */\ntype OAuthProxyStatePackage = {\n\tstate: string;\n\tstateCookie: string;\n\tisOAuthProxy: boolean;\n};\n\n/**\n * Passthrough payload containing OAuth profile data.\n * Used to transfer OAuth credentials from production to preview\n * without creating user/session on production.\n * @internal\n */\ntype PassthroughPayload = {\n\tuserInfo: Omit<User, \"createdAt\" | \"updatedAt\">;\n\taccount: Omit<Account, \"id\" | \"userId\" | \"createdAt\" | \"updatedAt\">;\n\tstate: string;\n\tcallbackURL: string;\n\tnewUserURL?: string;\n\terrorURL?: string;\n\tdisableSignUp?: boolean;\n\ttimestamp: number;\n};\n\nconst oauthProxyQuerySchema = z.object({\n\tcallbackURL: z.string().meta({\n\t\tdescription: \"The URL to redirect to after the proxy\",\n\t}),\n\tprofile: z.string().optional().meta({\n\t\tdescription: \"Encrypted OAuth profile data\",\n\t}),\n});\n\nconst oauthCallbackQuerySchema = z.object({\n\tcode: z.string().optional(),\n\terror: z.string().optional(),\n});\n\nexport const oAuthProxy = <O extends OAuthProxyOptions>(opts?: O) => {\n\tconst maxAge = opts?.maxAge ?? 60; // Default 60 seconds\n\n\treturn {\n\t\tid: \"oauth-proxy\",\n\t\toptions: opts as NoInfer<O>,\n\t\tendpoints: {\n\t\t\toAuthProxy: createAuthEndpoint(\n\t\t\t\t\"/oauth-proxy-callback\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\toperationId: \"oauthProxyCallback\",\n\t\t\t\t\tquery: oauthProxyQuerySchema,\n\t\t\t\t\tuse: [originCheck((ctx) => ctx.query.callbackURL)],\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\toperationId: \"oauthProxyCallback\",\n\t\t\t\t\t\t\tdescription: \"OAuth Proxy Callback\",\n\t\t\t\t\t\t\tparameters: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tin: \"query\",\n\t\t\t\t\t\t\t\t\tname: \"callbackURL\",\n\t\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t\t\tdescription: \"The URL to redirect to after the proxy\",\n\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\t\tin: \"query\",\n\t\t\t\t\t\t\t\t\tname: \"profile\",\n\t\t\t\t\t\t\t\t\trequired: false,\n\t\t\t\t\t\t\t\t\tdescription: \"Encrypted OAuth profile data\",\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t302: {\n\t\t\t\t\t\t\t\t\tdescription: \"Redirect\",\n\t\t\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\t\tLocation: {\n\t\t\t\t\t\t\t\t\t\t\tdescription: \"The URL to redirect to\",\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: \"string\",\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 defaultErrorURL =\n\t\t\t\t\t\tctx.context.options.onAPIError?.errorURL ||\n\t\t\t\t\t\t`${stripTrailingSlash(ctx.context.options.baseURL)}/api/auth/error`;\n\n\t\t\t\t\tconst encryptedProfile = ctx.query.profile;\n\t\t\t\t\tif (!encryptedProfile) {\n\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\"OAuth proxy callback missing profile data\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthrow redirectOnError(ctx, defaultErrorURL, \"missing_profile\");\n\t\t\t\t\t}\n\n\t\t\t\t\t// Decrypt profile payload\n\t\t\t\t\tlet decryptedPayload: string;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tdecryptedPayload = await symmetricDecrypt({\n\t\t\t\t\t\t\tkey: ctx.context.secret,\n\t\t\t\t\t\t\tdata: encryptedProfile,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\"Failed to decrypt OAuth proxy profile\",\n\t\t\t\t\t\t\te,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthrow redirectOnError(ctx, defaultErrorURL, \"invalid_profile\");\n\t\t\t\t\t}\n\n\t\t\t\t\tlet payload: PassthroughPayload;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpayload = parseJSON<PassthroughPayload>(decryptedPayload);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tctx.context.logger.error(\"Failed to parse OAuth proxy payload\", e);\n\t\t\t\t\t\tthrow redirectOnError(ctx, defaultErrorURL, \"invalid_payload\");\n\t\t\t\t\t}\n\n\t\t\t\t\t// Validate required payload fields\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof payload.timestamp !== \"number\" ||\n\t\t\t\t\t\t!payload.userInfo ||\n\t\t\t\t\t\t!payload.account ||\n\t\t\t\t\t\t!payload.callbackURL\n\t\t\t\t\t) {\n\t\t\t\t\t\tctx.context.logger.error(\"Failed to parse OAuth proxy payload\");\n\t\t\t\t\t\tthrow redirectOnError(ctx, defaultErrorURL, \"invalid_payload\");\n\t\t\t\t\t}\n\n\t\t\t\t\tconst errorURL = payload.errorURL || defaultErrorURL;\n\n\t\t\t\t\t// Allow up to 10 seconds of future skew for clock skew\n\t\t\t\t\tconst now = Date.now();\n\t\t\t\t\tconst age = (now - payload.timestamp) / 1000;\n\t\t\t\t\tif (age > maxAge || age < -10) {\n\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t`OAuth proxy payload expired or invalid (age: ${age}s, maxAge: ${maxAge}s)`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, \"payload_expired\");\n\t\t\t\t\t}\n\n\t\t\t\t\t// Clean up OAuth state\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait parseGenericState(ctx, payload.state);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tctx.context.logger.warn(\"Failed to clean up OAuth state\", e);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await handleOAuthUserInfo(ctx, {\n\t\t\t\t\t\tuserInfo: payload.userInfo,\n\t\t\t\t\t\taccount: payload.account,\n\t\t\t\t\t\tcallbackURL: payload.callbackURL,\n\t\t\t\t\t\tdisableSignUp: payload.disableSignUp,\n\t\t\t\t\t});\n\t\t\t\t\tif (result.error || !result.data) {\n\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\"Failed to create user or session\",\n\t\t\t\t\t\t\tresult.error,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, \"user_creation_failed\");\n\t\t\t\t\t}\n\n\t\t\t\t\tawait setSessionCookie(ctx, result.data);\n\n\t\t\t\t\t// Redirect to final callback URL\n\t\t\t\t\tconst finalURL = result.isRegister\n\t\t\t\t\t\t? payload.newUserURL || payload.callbackURL\n\t\t\t\t\t\t: payload.callbackURL;\n\n\t\t\t\t\tthrow ctx.redirect(finalURL);\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\thooks: {\n\t\t\tbefore: [\n\t\t\t\t{\n\t\t\t\t\tmatcher(context) {\n\t\t\t\t\t\treturn !!(\n\t\t\t\t\t\t\tcontext.path?.startsWith(\"/sign-in/social\") ||\n\t\t\t\t\t\t\tcontext.path?.startsWith(\"/sign-in/oauth2\")\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst skipProxy = checkSkipProxy(ctx, opts);\n\t\t\t\t\t\tif (skipProxy) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst currentURL = resolveCurrentURL(ctx, opts);\n\t\t\t\t\t\tconst productionURL = opts?.productionURL;\n\t\t\t\t\t\tconst originalCallbackURL =\n\t\t\t\t\t\t\tctx.body?.callbackURL || ctx.context.baseURL;\n\n\t\t\t\t\t\t// Override baseURL to production so redirect_uri points to production\n\t\t\t\t\t\t// This ensures OAuth provider callbacks go to the production server\n\t\t\t\t\t\tif (productionURL) {\n\t\t\t\t\t\t\tconst productionBaseURL = `${stripTrailingSlash(productionURL)}${ctx.context.options.basePath || \"/api/auth\"}`;\n\t\t\t\t\t\t\tctx.context.baseURL = productionBaseURL;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Construct proxy callback URL\n\t\t\t\t\t\tconst newCallbackURL = `${stripTrailingSlash(currentURL.origin)}${\n\t\t\t\t\t\t\tctx.context.options.basePath || \"/api/auth\"\n\t\t\t\t\t\t}/oauth-proxy-callback?callbackURL=${encodeURIComponent(\n\t\t\t\t\t\t\toriginalCallbackURL,\n\t\t\t\t\t\t)}`;\n\n\t\t\t\t\t\tif (!ctx.body) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tctx.body.callbackURL = newCallbackURL;\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t// Intercept OAuth callback on production to handle passthrough\n\t\t\t\t\tmatcher(context) {\n\t\t\t\t\t\treturn context.path === \"/callback/:id\";\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst state = ctx.query?.state || ctx.body?.state;\n\t\t\t\t\t\tif (!state || typeof state !== \"string\") {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Try to decrypt and parse OAuth proxy state package\n\t\t\t\t\t\tlet statePackage: OAuthProxyStatePackage | undefined;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst decryptedPackage = await symmetricDecrypt({\n\t\t\t\t\t\t\t\tkey: ctx.context.secret,\n\t\t\t\t\t\t\t\tdata: state,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tstatePackage =\n\t\t\t\t\t\t\t\tparseJSON<OAuthProxyStatePackage>(decryptedPackage);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t// Not an OAuth proxy state, continue normally\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!statePackage.isOAuthProxy ||\n\t\t\t\t\t\t\t!statePackage.state ||\n\t\t\t\t\t\t\t!statePackage.stateCookie\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tctx.context.logger.warn(\"Invalid OAuth proxy state package\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst query = oauthCallbackQuerySchema.safeParse(ctx.query);\n\t\t\t\t\t\tif (!query.success) {\n\t\t\t\t\t\t\tctx.context.logger.warn(\n\t\t\t\t\t\t\t\t\"Invalid OAuth callback query\",\n\t\t\t\t\t\t\t\tquery.error,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst { code, error } = query.data;\n\n\t\t\t\t\t\t// Decrypt state to get codeVerifier and callbackURL\n\t\t\t\t\t\tlet stateData: StateData;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst decryptedState = await symmetricDecrypt({\n\t\t\t\t\t\t\t\tkey: ctx.context.secret,\n\t\t\t\t\t\t\t\tdata: statePackage.stateCookie,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tstateData = parseJSON<StateData>(decryptedState);\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\"Failed to decrypt OAuth proxy state cookie:\",\n\t\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst errorURL =\n\t\t\t\t\t\t\tstateData.errorURL ||\n\t\t\t\t\t\t\tctx.context.options.onAPIError?.errorURL ||\n\t\t\t\t\t\t\t`${ctx.context.baseURL}/error`;\n\t\t\t\t\t\tif (error) {\n\t\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, error);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!code) {\n\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\"OAuth callback missing authorization code\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, \"no_code\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Find the OAuth provider\n\t\t\t\t\t\tconst providerId = ctx.params?.id;\n\t\t\t\t\t\tconst provider = ctx.context.socialProviders.find(\n\t\t\t\t\t\t\t(p) => p.id === providerId,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (!provider) {\n\t\t\t\t\t\t\tctx.context.logger.error(\"OAuth provider not found\", providerId);\n\t\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, \"oauth_provider_not_found\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Exchange code for tokens\n\t\t\t\t\t\tlet tokens: OAuth2Tokens | null;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\ttokens = await provider.validateAuthorizationCode({\n\t\t\t\t\t\t\t\tcode,\n\t\t\t\t\t\t\t\tcodeVerifier: stateData.codeVerifier,\n\t\t\t\t\t\t\t\tredirectURI: `${ctx.context.baseURL}/callback/${provider.id}`,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\"Failed to validate authorization code\",\n\t\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, \"invalid_code\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!tokens) {\n\t\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, \"invalid_code\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Get user info from provider\n\t\t\t\t\t\tconst userInfoResult = await provider.getUserInfo(tokens);\n\t\t\t\t\t\tconst userInfo = userInfoResult?.user;\n\n\t\t\t\t\t\tif (!userInfo) {\n\t\t\t\t\t\t\tctx.context.logger.error(\"Unable to get user info from provider\");\n\t\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, \"unable_to_get_user_info\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!userInfo.email) {\n\t\t\t\t\t\t\tctx.context.logger.error(\"Provider did not return email\");\n\t\t\t\t\t\t\tthrow redirectOnError(ctx, errorURL, \"email_not_found\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst proxyCallbackURL = new URL(stateData.callbackURL);\n\t\t\t\t\t\tconst finalCallbackURL =\n\t\t\t\t\t\t\tproxyCallbackURL.searchParams.get(\"callbackURL\") ||\n\t\t\t\t\t\t\tstateData.callbackURL;\n\n\t\t\t\t\t\tconst payload: PassthroughPayload = {\n\t\t\t\t\t\t\tuserInfo: {\n\t\t\t\t\t\t\t\tid: String(userInfo.id),\n\t\t\t\t\t\t\t\temail: userInfo.email,\n\t\t\t\t\t\t\t\tname: userInfo.name || \"\",\n\t\t\t\t\t\t\t\timage: userInfo.image,\n\t\t\t\t\t\t\t\temailVerified: userInfo.emailVerified,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\taccount: {\n\t\t\t\t\t\t\t\tproviderId: provider.id,\n\t\t\t\t\t\t\t\taccountId: String(userInfo.id),\n\t\t\t\t\t\t\t\taccessToken: tokens.accessToken,\n\t\t\t\t\t\t\t\trefreshToken: tokens.refreshToken,\n\t\t\t\t\t\t\t\tidToken: tokens.idToken,\n\t\t\t\t\t\t\t\taccessTokenExpiresAt: tokens.accessTokenExpiresAt,\n\t\t\t\t\t\t\t\trefreshTokenExpiresAt: tokens.refreshTokenExpiresAt,\n\t\t\t\t\t\t\t\tscope: tokens.scopes?.join(\",\"),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstate: statePackage.state,\n\t\t\t\t\t\t\tcallbackURL: finalCallbackURL,\n\t\t\t\t\t\t\tnewUserURL: stateData.newUserURL,\n\t\t\t\t\t\t\terrorURL: stateData.errorURL,\n\t\t\t\t\t\t\tdisableSignUp:\n\t\t\t\t\t\t\t\t(provider.disableImplicitSignUp && !stateData.requestSignUp) ||\n\t\t\t\t\t\t\t\tprovider.options?.disableSignUp,\n\t\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tconst encryptedPayload = await symmetricEncrypt({\n\t\t\t\t\t\t\tkey: ctx.context.secret,\n\t\t\t\t\t\t\tdata: JSON.stringify(payload),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t// Add the profile parameter to proxy callback URL\n\t\t\t\t\t\tproxyCallbackURL.searchParams.set(\"profile\", encryptedPayload);\n\n\t\t\t\t\t\t// Redirect to preview's oauth-proxy-callback with profile data\n\t\t\t\t\t\tthrow ctx.redirect(proxyCallbackURL.toString());\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher(context) {\n\t\t\t\t\t\treturn !!(\n\t\t\t\t\t\t\tcontext.path?.startsWith(\"/sign-in/social\") ||\n\t\t\t\t\t\t\tcontext.path?.startsWith(\"/sign-in/oauth2\")\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst skipProxy = checkSkipProxy(ctx, opts);\n\t\t\t\t\t\tif (skipProxy) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Extract OAuth provider URL from sign-in response\n\t\t\t\t\t\tconst signInResponse = ctx.context.returned;\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!signInResponse ||\n\t\t\t\t\t\t\ttypeof signInResponse !== \"object\" ||\n\t\t\t\t\t\t\t!(\"url\" in signInResponse)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { url: providerURL } = signInResponse;\n\t\t\t\t\t\tif (typeof providerURL !== \"string\") {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Parse provider URL and extract state parameter\n\t\t\t\t\t\tconst oauthURL = new URL(providerURL);\n\t\t\t\t\t\tconst originalState = oauthURL.searchParams.get(\"state\");\n\t\t\t\t\t\tif (!originalState) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Get state value based on storage strategy\n\t\t\t\t\t\tlet stateCookieValue: string | undefined;\n\t\t\t\t\t\tif (ctx.context.oauthConfig.storeStateStrategy === \"cookie\") {\n\t\t\t\t\t\t\t// Cookie mode - extract from response headers\n\t\t\t\t\t\t\tconst headers = ctx.context.responseHeaders;\n\t\t\t\t\t\t\tconst setCookieHeader = headers?.get(\"set-cookie\");\n\t\t\t\t\t\t\tif (setCookieHeader) {\n\t\t\t\t\t\t\t\tconst parsedCookies = parseSetCookieHeader(setCookieHeader);\n\t\t\t\t\t\t\t\tconst stateCookie = ctx.context.createAuthCookie(\"oauth_state\");\n\t\t\t\t\t\t\t\tconst stateCookieAttrs = parsedCookies.get(stateCookie.name);\n\t\t\t\t\t\t\t\tstateCookieValue = stateCookieAttrs?.value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Database mode - read from DB\n\t\t\t\t\t\t\tconst verification =\n\t\t\t\t\t\t\t\tawait ctx.context.internalAdapter.findVerificationValue(\n\t\t\t\t\t\t\t\t\toriginalState,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (verification) {\n\t\t\t\t\t\t\t\t// Encrypt the verification value so it matches cookie mode format\n\t\t\t\t\t\t\t\tstateCookieValue = await symmetricEncrypt({\n\t\t\t\t\t\t\t\t\tkey: ctx.context.secret,\n\t\t\t\t\t\t\t\t\tdata: verification.value,\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 (!stateCookieValue) {\n\t\t\t\t\t\t\tctx.context.logger.warn(\"No OAuth state cookie value found\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Create and encrypt state package\n\t\t\t\t\t\t\tconst statePackage: OAuthProxyStatePackage = {\n\t\t\t\t\t\t\t\tstate: originalState,\n\t\t\t\t\t\t\t\tstateCookie: stateCookieValue,\n\t\t\t\t\t\t\t\tisOAuthProxy: true,\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tconst encryptedPackage = await symmetricEncrypt({\n\t\t\t\t\t\t\t\tkey: ctx.context.secret,\n\t\t\t\t\t\t\t\tdata: JSON.stringify(statePackage),\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t// Replace state parameter with encrypted package\n\t\t\t\t\t\t\toauthURL.searchParams.set(\"state\", encryptedPackage);\n\n\t\t\t\t\t\t\t// Update response with modified URL\n\t\t\t\t\t\t\tctx.context.returned = {\n\t\t\t\t\t\t\t\t...signInResponse,\n\t\t\t\t\t\t\t\turl: oauthURL.toString(),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\t\tctx.context.logger.error(\n\t\t\t\t\t\t\t\t\"Failed to encrypt OAuth proxy state package:\",\n\t\t\t\t\t\t\t\te,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t// Continue without proxy\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) {\n\t\t\t\t\t\treturn context.path === \"/callback/:id\";\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst headers = ctx.context.responseHeaders;\n\t\t\t\t\t\tconst location = headers?.get(\"location\");\n\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t!location?.includes(\"/oauth-proxy-callback?callbackURL\") ||\n\t\t\t\t\t\t\t!location.startsWith(\"http\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst productionURL =\n\t\t\t\t\t\t\topts?.productionURL ||\n\t\t\t\t\t\t\tctx.context.options.baseURL ||\n\t\t\t\t\t\t\tctx.context.baseURL;\n\t\t\t\t\t\tconst productionOrigin = getOrigin(productionURL);\n\n\t\t\t\t\t\tconst locationURL = new URL(location);\n\t\t\t\t\t\tconst locationOrigin = locationURL.origin;\n\n\t\t\t\t\t\t// Same origin: unwrap proxy redirect to original destination\n\t\t\t\t\t\tif (locationOrigin === productionOrigin) {\n\t\t\t\t\t\t\tconst newLocation = locationURL.searchParams.get(\"callbackURL\");\n\t\t\t\t\t\t\tif (!newLocation) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tctx.setHeader(\"location\", newLocation);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Cross-origin should have been handled by before hook\n\t\t\t\t\t\tctx.context.logger.warn(\n\t\t\t\t\t\t\t\"OAuth proxy: cross-origin callback reached after hook unexpectedly\",\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} satisfies BetterAuthPlugin;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { getOrigin } from "../../utils/url.mjs";
|
|
2
|
+
import { env } from "@better-auth/core/env";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/oauth-proxy/utils.ts
|
|
5
|
+
/**
|
|
6
|
+
* Strip trailing slashes from URL to prevent double slashes
|
|
7
|
+
*/
|
|
8
|
+
function stripTrailingSlash(url) {
|
|
9
|
+
if (!url) return "";
|
|
10
|
+
return url.replace(/\/+$/, "");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get base URL from vendor-specific environment variables
|
|
14
|
+
*/
|
|
15
|
+
function getVendorBaseURL() {
|
|
16
|
+
const vercel = env.VERCEL_URL ? `https://${env.VERCEL_URL}` : void 0;
|
|
17
|
+
const netlify = env.NETLIFY_URL;
|
|
18
|
+
const render = env.RENDER_URL;
|
|
19
|
+
const aws = env.AWS_LAMBDA_FUNCTION_NAME;
|
|
20
|
+
const google = env.GOOGLE_CLOUD_FUNCTION_NAME;
|
|
21
|
+
const azure = env.AZURE_FUNCTION_NAME;
|
|
22
|
+
return vercel || netlify || render || aws || google || azure;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the current URL from various sources
|
|
26
|
+
*/
|
|
27
|
+
function resolveCurrentURL(ctx, opts) {
|
|
28
|
+
return new URL(opts?.currentURL || ctx.request?.url || getVendorBaseURL() || ctx.context.baseURL);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if the proxy should be skipped for this request
|
|
32
|
+
*/
|
|
33
|
+
function checkSkipProxy(ctx, opts) {
|
|
34
|
+
if (ctx.request?.headers.get("x-skip-oauth-proxy")) return true;
|
|
35
|
+
const productionURL = opts?.productionURL || env.BETTER_AUTH_URL || ctx.context.baseURL;
|
|
36
|
+
if (!productionURL) return false;
|
|
37
|
+
const currentURL = opts?.currentURL || ctx.request?.url || getVendorBaseURL();
|
|
38
|
+
if (!currentURL) return false;
|
|
39
|
+
return getOrigin(productionURL) === getOrigin(currentURL);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Redirect to error URL with error code
|
|
43
|
+
*/
|
|
44
|
+
function redirectOnError(ctx, errorURL, error) {
|
|
45
|
+
const sep = errorURL.includes("?") ? "&" : "?";
|
|
46
|
+
throw ctx.redirect(`${errorURL}${sep}error=${error}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { checkSkipProxy, redirectOnError, resolveCurrentURL, stripTrailingSlash };
|
|
51
|
+
//# sourceMappingURL=utils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../../../src/plugins/oauth-proxy/utils.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { env } from \"@better-auth/core/env\";\nimport { getOrigin } from \"../../utils/url\";\nimport type { OAuthProxyOptions } from \"./index\";\n\n/**\n * Strip trailing slashes from URL to prevent double slashes\n */\nexport function stripTrailingSlash(url: string | undefined): string {\n\tif (!url) return \"\";\n\treturn url.replace(/\\/+$/, \"\");\n}\n\n/**\n * Get base URL from vendor-specific environment variables\n */\nfunction getVendorBaseURL() {\n\tconst vercel = env.VERCEL_URL ? `https://${env.VERCEL_URL}` : undefined;\n\tconst netlify = env.NETLIFY_URL;\n\tconst render = env.RENDER_URL;\n\tconst aws = env.AWS_LAMBDA_FUNCTION_NAME;\n\tconst google = env.GOOGLE_CLOUD_FUNCTION_NAME;\n\tconst azure = env.AZURE_FUNCTION_NAME;\n\n\treturn vercel || netlify || render || aws || google || azure;\n}\n\n/**\n * Resolve the current URL from various sources\n */\nexport function resolveCurrentURL(\n\tctx: GenericEndpointContext,\n\topts?: OAuthProxyOptions,\n) {\n\treturn new URL(\n\t\topts?.currentURL ||\n\t\t\tctx.request?.url ||\n\t\t\tgetVendorBaseURL() ||\n\t\t\tctx.context.baseURL,\n\t);\n}\n\n/**\n * Check if the proxy should be skipped for this request\n */\nexport function checkSkipProxy(\n\tctx: GenericEndpointContext,\n\topts?: OAuthProxyOptions,\n) {\n\t// If skip proxy header is set, we don't need to proxy\n\tconst skipProxyHeader = ctx.request?.headers.get(\"x-skip-oauth-proxy\");\n\tif (skipProxyHeader) {\n\t\treturn true;\n\t}\n\n\t// Determine production URL (fallback to baseURL if not set)\n\tconst productionURL =\n\t\topts?.productionURL || env.BETTER_AUTH_URL || ctx.context.baseURL;\n\tif (!productionURL) {\n\t\treturn false;\n\t}\n\n\t// Determine current URL from request or vendor env vars\n\tconst currentURL = opts?.currentURL || ctx.request?.url || getVendorBaseURL();\n\tif (!currentURL) {\n\t\treturn false;\n\t}\n\n\tconst productionOrigin = getOrigin(productionURL);\n\tconst currentOrigin = getOrigin(currentURL);\n\n\treturn productionOrigin === currentOrigin;\n}\n\n/**\n * Redirect to error URL with error code\n */\nexport function redirectOnError(\n\tctx: GenericEndpointContext,\n\terrorURL: string,\n\terror: string,\n): never {\n\tconst sep = errorURL.includes(\"?\") ? \"&\" : \"?\";\n\tthrow ctx.redirect(`${errorURL}${sep}error=${error}`);\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,mBAAmB,KAAiC;AACnE,KAAI,CAAC,IAAK,QAAO;AACjB,QAAO,IAAI,QAAQ,QAAQ,GAAG;;;;;AAM/B,SAAS,mBAAmB;CAC3B,MAAM,SAAS,IAAI,aAAa,WAAW,IAAI,eAAe;CAC9D,MAAM,UAAU,IAAI;CACpB,MAAM,SAAS,IAAI;CACnB,MAAM,MAAM,IAAI;CAChB,MAAM,SAAS,IAAI;CACnB,MAAM,QAAQ,IAAI;AAElB,QAAO,UAAU,WAAW,UAAU,OAAO,UAAU;;;;;AAMxD,SAAgB,kBACf,KACA,MACC;AACD,QAAO,IAAI,IACV,MAAM,cACL,IAAI,SAAS,OACb,kBAAkB,IAClB,IAAI,QAAQ,QACb;;;;;AAMF,SAAgB,eACf,KACA,MACC;AAGD,KADwB,IAAI,SAAS,QAAQ,IAAI,qBAAqB,CAErE,QAAO;CAIR,MAAM,gBACL,MAAM,iBAAiB,IAAI,mBAAmB,IAAI,QAAQ;AAC3D,KAAI,CAAC,cACJ,QAAO;CAIR,MAAM,aAAa,MAAM,cAAc,IAAI,SAAS,OAAO,kBAAkB;AAC7E,KAAI,CAAC,WACJ,QAAO;AAMR,QAHyB,UAAU,cAAc,KAC3B,UAAU,WAAW;;;;;AAQ5C,SAAgB,gBACf,KACA,UACA,OACQ;CACR,MAAM,MAAM,SAAS,SAAS,IAAI,GAAG,MAAM;AAC3C,OAAM,IAAI,SAAS,GAAG,WAAW,IAAI,QAAQ,QAAQ"}
|