@masheev/better-auth 0.0.0-stage → 1.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +20 -0
- package/README.md +31 -2
- package/TYPE-PATCH-NOTICE.md +9 -0
- package/TYPE-PATCH-PROVENANCE.json +267 -0
- package/dist/_virtual/_rolldown/runtime.mjs +27 -0
- package/dist/adapters/drizzle-adapter/index.d.mts +1 -0
- package/dist/adapters/drizzle-adapter/index.mjs +2 -0
- package/dist/adapters/index.d.mts +26 -0
- package/dist/adapters/index.mjs +9 -0
- package/dist/adapters/kysely-adapter/index.d.mts +1 -0
- package/dist/adapters/kysely-adapter/index.mjs +2 -0
- package/dist/adapters/memory-adapter/index.d.mts +1 -0
- package/dist/adapters/memory-adapter/index.mjs +2 -0
- package/dist/adapters/mongodb-adapter/index.d.mts +1 -0
- package/dist/adapters/mongodb-adapter/index.mjs +2 -0
- package/dist/adapters/prisma-adapter/index.d.mts +1 -0
- package/dist/adapters/prisma-adapter/index.mjs +2 -0
- package/dist/api/dispatch.d.mts +34 -0
- package/dist/api/dispatch.mjs +275 -0
- package/dist/api/index.d.mts +4053 -0
- package/dist/api/index.mjs +220 -0
- package/dist/api/middlewares/authorization.d.mts +69 -0
- package/dist/api/middlewares/authorization.mjs +78 -0
- package/dist/api/middlewares/index.d.mts +2 -0
- package/dist/api/middlewares/origin-check.d.mts +17 -0
- package/dist/api/middlewares/origin-check.mjs +155 -0
- package/dist/api/rate-limiter/index.mjs +318 -0
- package/dist/api/routes/account.d.mts +413 -0
- package/dist/api/routes/account.mjs +619 -0
- package/dist/api/routes/callback.d.mts +32 -0
- package/dist/api/routes/callback.mjs +261 -0
- package/dist/api/routes/email-verification.d.mts +160 -0
- package/dist/api/routes/email-verification.mjs +324 -0
- package/dist/api/routes/error.d.mts +27 -0
- package/dist/api/routes/error.mjs +387 -0
- package/dist/api/routes/index.d.mts +12 -0
- package/dist/api/routes/ok.d.mts +35 -0
- package/dist/api/routes/ok.mjs +27 -0
- package/dist/api/routes/password.d.mts +182 -0
- package/dist/api/routes/password.mjs +206 -0
- package/dist/api/routes/session.d.mts +450 -0
- package/dist/api/routes/session.mjs +481 -0
- package/dist/api/routes/sign-in.d.mts +186 -0
- package/dist/api/routes/sign-in.mjs +368 -0
- package/dist/api/routes/sign-out.d.mts +51 -0
- package/dist/api/routes/sign-out.mjs +96 -0
- package/dist/api/routes/sign-up.d.mts +159 -0
- package/dist/api/routes/sign-up.mjs +275 -0
- package/dist/api/routes/update-session.d.mts +74 -0
- package/dist/api/routes/update-session.mjs +57 -0
- package/dist/api/routes/update-user.d.mts +428 -0
- package/dist/api/routes/update-user.mjs +522 -0
- package/dist/api/state/oauth.d.mts +53 -0
- package/dist/api/state/oauth.mjs +38 -0
- package/dist/api/state/should-session-refresh.d.mts +12 -0
- package/dist/api/state/should-session-refresh.mjs +13 -0
- package/dist/api/to-auth-endpoints.mjs +60 -0
- package/dist/auth/base.mjs +66 -0
- package/dist/auth/full.d.mts +28 -0
- package/dist/auth/full.mjs +29 -0
- package/dist/auth/minimal.d.mts +10 -0
- package/dist/auth/minimal.mjs +11 -0
- package/dist/auth/trusted-origins.mjs +106 -0
- package/dist/client/broadcast-channel.d.mts +19 -0
- package/dist/client/broadcast-channel.mjs +44 -0
- package/dist/client/config.d.mts +90 -0
- package/dist/client/config.mjs +113 -0
- package/dist/client/equality.d.mts +19 -0
- package/dist/client/equality.mjs +42 -0
- package/dist/client/fetch-plugins.mjs +17 -0
- package/dist/client/focus-manager.d.mts +10 -0
- package/dist/client/focus-manager.mjs +30 -0
- package/dist/client/index.d.mts +35 -0
- package/dist/client/index.mjs +22 -0
- package/dist/client/lynx/index.d.mts +43 -0
- package/dist/client/lynx/index.mjs +22 -0
- package/dist/client/lynx/lynx-store.d.mts +46 -0
- package/dist/client/lynx/lynx-store.mjs +44 -0
- package/dist/client/online-manager.d.mts +11 -0
- package/dist/client/online-manager.mjs +33 -0
- package/dist/client/parser.d.mts +10 -0
- package/dist/client/parser.mjs +70 -0
- package/dist/client/path-to-object.d.mts +113 -0
- package/dist/client/plugins/index.d.mts +44 -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/proxy.mjs +78 -0
- package/dist/client/query.d.mts +23 -0
- package/dist/client/query.mjs +124 -0
- package/dist/client/react/index.d.mts +44 -0
- package/dist/client/react/index.mjs +22 -0
- package/dist/client/react/react-store.d.mts +46 -0
- package/dist/client/react/react-store.mjs +44 -0
- package/dist/client/session-atom.d.mts +11 -0
- package/dist/client/session-atom.mjs +178 -0
- package/dist/client/session-refresh.d.mts +20 -0
- package/dist/client/session-refresh.mjs +131 -0
- package/dist/client/solid/index.d.mts +44 -0
- package/dist/client/solid/index.mjs +22 -0
- package/dist/client/solid/solid-store.mjs +21 -0
- package/dist/client/svelte/index.d.mts +44 -0
- package/dist/client/svelte/index.mjs +18 -0
- package/dist/client/types.d.mts +51 -0
- package/dist/client/vanilla.d.mts +42 -0
- package/dist/client/vanilla.mjs +18 -0
- package/dist/client/vue/index.d.mts +67 -0
- package/dist/client/vue/index.mjs +54 -0
- package/dist/client/vue/vue-store.mjs +23 -0
- package/dist/context/create-context.mjs +235 -0
- package/dist/context/helpers.mjs +158 -0
- package/dist/context/init-minimal.mjs +17 -0
- package/dist/context/init.mjs +19 -0
- package/dist/context/secret-utils.mjs +53 -0
- package/dist/context/store-capabilities.mjs +12 -0
- package/dist/cookies/cache.mjs +33 -0
- package/dist/cookies/cookie-utils.d.mts +72 -0
- package/dist/cookies/cookie-utils.mjs +203 -0
- package/dist/cookies/index.d.mts +124 -0
- package/dist/cookies/index.mjs +350 -0
- package/dist/cookies/jwt.mjs +44 -0
- package/dist/cookies/session-store.d.mts +32 -0
- package/dist/cookies/session-store.mjs +183 -0
- package/dist/crypto/buffer.d.mts +7 -0
- package/dist/crypto/buffer.mjs +16 -0
- package/dist/crypto/index.d.mts +32 -0
- package/dist/crypto/index.mjs +69 -0
- package/dist/crypto/jwt.d.mts +9 -0
- package/dist/crypto/jwt.mjs +141 -0
- package/dist/crypto/password.d.mts +13 -0
- package/dist/crypto/password.mjs +14 -0
- package/dist/crypto/random.d.mts +4 -0
- package/dist/crypto/random.mjs +5 -0
- package/dist/db/adapter-base.d.mts +7 -0
- package/dist/db/adapter-base.mjs +25 -0
- package/dist/db/adapter-kysely.d.mts +7 -0
- package/dist/db/adapter-kysely.mjs +17 -0
- package/dist/db/field-converter.d.mts +7 -0
- package/dist/db/field-converter.mjs +19 -0
- package/dist/db/field.d.mts +41 -0
- package/dist/db/get-migration.d.mts +56 -0
- package/dist/db/get-migration.mjs +685 -0
- package/dist/db/get-schema.d.mts +13 -0
- package/dist/db/get-schema.mjs +39 -0
- package/dist/db/index.d.mts +10 -0
- package/dist/db/index.mjs +35 -0
- package/dist/db/internal-adapter.d.mts +14 -0
- package/dist/db/internal-adapter.mjs +951 -0
- package/dist/db/revoke-unproven-account-access.d.mts +21 -0
- package/dist/db/revoke-unproven-account-access.mjs +58 -0
- package/dist/db/schema.d.mts +62 -0
- package/dist/db/schema.mjs +161 -0
- package/dist/db/to-zod.d.mts +35 -0
- package/dist/db/to-zod.mjs +23 -0
- package/dist/db/verification-token-storage.mjs +25 -0
- package/dist/db/with-hooks.d.mts +37 -0
- package/dist/db/with-hooks.mjs +255 -0
- package/dist/index.d.mts +30 -0
- package/dist/index.mjs +17 -0
- package/dist/integrations/cookie-plugin-guard.mjs +18 -0
- package/dist/integrations/next-js.d.mts +29 -0
- package/dist/integrations/next-js.mjs +105 -0
- package/dist/integrations/node.d.mts +11 -0
- package/dist/integrations/node.mjs +13 -0
- package/dist/integrations/solid-start.d.mts +22 -0
- package/dist/integrations/solid-start.mjs +15 -0
- package/dist/integrations/svelte-kit.d.mts +38 -0
- package/dist/integrations/svelte-kit.mjs +57 -0
- package/dist/integrations/tanstack-start-solid.d.mts +33 -0
- package/dist/integrations/tanstack-start-solid.mjs +57 -0
- package/dist/integrations/tanstack-start.d.mts +33 -0
- package/dist/integrations/tanstack-start.mjs +57 -0
- package/dist/oauth2/account-key.mjs +43 -0
- package/dist/oauth2/errors.mjs +49 -0
- package/dist/oauth2/index.d.mts +5 -0
- package/dist/oauth2/index.mjs +5 -0
- package/dist/oauth2/link-account.d.mts +96 -0
- package/dist/oauth2/link-account.mjs +329 -0
- package/dist/oauth2/state.d.mts +54 -0
- package/dist/oauth2/state.mjs +67 -0
- package/dist/oauth2/utils.d.mts +11 -0
- package/dist/oauth2/utils.mjs +33 -0
- package/dist/package.mjs +4 -0
- package/dist/plugins/access/access.d.mts +17 -0
- package/dist/plugins/access/access.mjs +78 -0
- package/dist/plugins/access/index.d.mts +3 -0
- package/dist/plugins/access/index.mjs +2 -0
- package/dist/plugins/access/types.d.mts +24 -0
- package/dist/plugins/additional-fields/client.d.mts +100 -0
- package/dist/plugins/additional-fields/client.mjs +11 -0
- package/dist/plugins/admin/access/index.d.mts +2 -0
- package/dist/plugins/admin/access/index.mjs +2 -0
- package/dist/plugins/admin/access/statement.d.mts +51 -0
- package/dist/plugins/admin/access/statement.mjs +52 -0
- package/dist/plugins/admin/admin.d.mts +911 -0
- package/dist/plugins/admin/admin.mjs +89 -0
- package/dist/plugins/admin/client.d.mts +81 -0
- package/dist/plugins/admin/client.mjs +39 -0
- package/dist/plugins/admin/error-codes.d.mts +30 -0
- package/dist/plugins/admin/error-codes.mjs +29 -0
- package/dist/plugins/admin/has-permission.mjs +12 -0
- package/dist/plugins/admin/index.d.mts +3 -0
- package/dist/plugins/admin/index.mjs +2 -0
- package/dist/plugins/admin/routes.mjs +919 -0
- package/dist/plugins/admin/schema.d.mts +40 -0
- package/dist/plugins/admin/schema.mjs +33 -0
- package/dist/plugins/admin/types.d.mts +88 -0
- package/dist/plugins/anonymous/client.d.mts +32 -0
- package/dist/plugins/anonymous/client.mjs +21 -0
- package/dist/plugins/anonymous/error-codes.d.mts +15 -0
- package/dist/plugins/anonymous/error-codes.mjs +14 -0
- package/dist/plugins/anonymous/index.d.mts +175 -0
- package/dist/plugins/anonymous/index.mjs +219 -0
- package/dist/plugins/anonymous/schema.d.mts +15 -0
- package/dist/plugins/anonymous/schema.mjs +9 -0
- package/dist/plugins/anonymous/types.d.mts +65 -0
- package/dist/plugins/bearer/index.d.mts +45 -0
- package/dist/plugins/bearer/index.mjs +74 -0
- package/dist/plugins/captcha/constants.d.mts +9 -0
- package/dist/plugins/captcha/constants.mjs +27 -0
- package/dist/plugins/captcha/error-codes.mjs +13 -0
- package/dist/plugins/captcha/index.d.mts +27 -0
- package/dist/plugins/captcha/index.mjs +79 -0
- package/dist/plugins/captcha/types.d.mts +52 -0
- package/dist/plugins/captcha/utils.mjs +9 -0
- package/dist/plugins/captcha/verify-handlers/captchafox.mjs +27 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +47 -0
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +32 -0
- package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +27 -0
- package/dist/plugins/custom-session/client.d.mts +17 -0
- package/dist/plugins/custom-session/client.mjs +7 -0
- package/dist/plugins/custom-session/index.d.mts +73 -0
- package/dist/plugins/custom-session/index.mjs +65 -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/error-codes.mjs +19 -0
- package/dist/plugins/device-authorization/index.d.mts +558 -0
- package/dist/plugins/device-authorization/index.mjs +87 -0
- package/dist/plugins/device-authorization/routes.d.mts +32 -0
- package/dist/plugins/device-authorization/routes.mjs +725 -0
- package/dist/plugins/device-authorization/schema.d.mts +18 -0
- package/dist/plugins/device-authorization/schema.mjs +63 -0
- package/dist/plugins/email-otp/client.d.mts +21 -0
- package/dist/plugins/email-otp/client.mjs +17 -0
- package/dist/plugins/email-otp/error-codes.d.mts +10 -0
- package/dist/plugins/email-otp/error-codes.mjs +9 -0
- package/dist/plugins/email-otp/index.d.mts +551 -0
- package/dist/plugins/email-otp/index.mjs +145 -0
- package/dist/plugins/email-otp/otp-token.mjs +55 -0
- package/dist/plugins/email-otp/routes.mjs +784 -0
- package/dist/plugins/email-otp/types.d.mts +109 -0
- package/dist/plugins/email-otp/utils.mjs +17 -0
- package/dist/plugins/generic-oauth/error-codes.mjs +8 -0
- package/dist/plugins/generic-oauth/index.d.mts +52 -0
- package/dist/plugins/generic-oauth/index.mjs +279 -0
- package/dist/plugins/generic-oauth/providers/auth0.d.mts +36 -0
- package/dist/plugins/generic-oauth/providers/auth0.mjs +49 -0
- package/dist/plugins/generic-oauth/providers/gumroad.d.mts +31 -0
- package/dist/plugins/generic-oauth/providers/gumroad.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/hubspot.d.mts +36 -0
- package/dist/plugins/generic-oauth/providers/hubspot.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/index.d.mts +10 -0
- package/dist/plugins/generic-oauth/providers/keycloak.d.mts +36 -0
- package/dist/plugins/generic-oauth/providers/keycloak.mjs +47 -0
- package/dist/plugins/generic-oauth/providers/line.d.mts +54 -0
- package/dist/plugins/generic-oauth/providers/line.mjs +93 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.d.mts +39 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +104 -0
- package/dist/plugins/generic-oauth/providers/okta.d.mts +36 -0
- package/dist/plugins/generic-oauth/providers/okta.mjs +47 -0
- package/dist/plugins/generic-oauth/providers/patreon.d.mts +29 -0
- package/dist/plugins/generic-oauth/providers/patreon.mjs +61 -0
- package/dist/plugins/generic-oauth/providers/slack.d.mts +29 -0
- package/dist/plugins/generic-oauth/providers/slack.mjs +63 -0
- package/dist/plugins/generic-oauth/providers/yandex.d.mts +29 -0
- package/dist/plugins/generic-oauth/providers/yandex.mjs +67 -0
- package/dist/plugins/generic-oauth/types.d.mts +268 -0
- package/dist/plugins/haveibeenpwned/index.d.mts +63 -0
- package/dist/plugins/haveibeenpwned/index.mjs +81 -0
- package/dist/plugins/index.d.mts +69 -0
- package/dist/plugins/index.mjs +49 -0
- package/dist/plugins/jwt/adapter.mjs +68 -0
- package/dist/plugins/jwt/client.d.mts +41 -0
- package/dist/plugins/jwt/client.mjs +19 -0
- package/dist/plugins/jwt/cookie-cache.mjs +77 -0
- package/dist/plugins/jwt/index.d.mts +246 -0
- package/dist/plugins/jwt/index.mjs +214 -0
- package/dist/plugins/jwt/schema.d.mts +33 -0
- package/dist/plugins/jwt/schema.mjs +29 -0
- package/dist/plugins/jwt/sign.d.mts +128 -0
- package/dist/plugins/jwt/sign.mjs +130 -0
- package/dist/plugins/jwt/types.d.mts +256 -0
- package/dist/plugins/jwt/utils.d.mts +41 -0
- package/dist/plugins/jwt/utils.mjs +64 -0
- package/dist/plugins/jwt/verify.d.mts +11 -0
- package/dist/plugins/jwt/verify.mjs +45 -0
- package/dist/plugins/last-login-method/client.d.mts +48 -0
- package/dist/plugins/last-login-method/client.mjs +48 -0
- package/dist/plugins/last-login-method/index.d.mts +127 -0
- package/dist/plugins/last-login-method/index.mjs +98 -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/index.d.mts +213 -0
- package/dist/plugins/magic-link/index.mjs +208 -0
- package/dist/plugins/magic-link/utils.mjs +9 -0
- package/dist/plugins/multi-session/client.d.mts +19 -0
- package/dist/plugins/multi-session/client.mjs +19 -0
- package/dist/plugins/multi-session/error-codes.d.mts +8 -0
- package/dist/plugins/multi-session/error-codes.mjs +5 -0
- package/dist/plugins/multi-session/index.d.mts +212 -0
- package/dist/plugins/multi-session/index.mjs +217 -0
- package/dist/plugins/oauth-popup/client.d.mts +82 -0
- package/dist/plugins/oauth-popup/client.mjs +203 -0
- package/dist/plugins/oauth-popup/constants.d.mts +11 -0
- package/dist/plugins/oauth-popup/constants.mjs +11 -0
- package/dist/plugins/oauth-popup/error-codes.d.mts +11 -0
- package/dist/plugins/oauth-popup/error-codes.mjs +10 -0
- package/dist/plugins/oauth-popup/index.d.mts +67 -0
- package/dist/plugins/oauth-popup/index.mjs +232 -0
- package/dist/plugins/oauth-popup/types.d.mts +30 -0
- package/dist/plugins/oauth-proxy/index.d.mts +130 -0
- package/dist/plugins/oauth-proxy/index.mjs +407 -0
- package/dist/plugins/oauth-proxy/utils.mjs +55 -0
- package/dist/plugins/one-tap/client.d.mts +174 -0
- package/dist/plugins/one-tap/client.mjs +208 -0
- package/dist/plugins/one-tap/index.d.mts +82 -0
- package/dist/plugins/one-tap/index.mjs +100 -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/index.d.mts +132 -0
- package/dist/plugins/one-time-token/index.mjs +107 -0
- package/dist/plugins/one-time-token/utils.mjs +9 -0
- package/dist/plugins/open-api/generator.d.mts +126 -0
- package/dist/plugins/open-api/generator.mjs +557 -0
- package/dist/plugins/open-api/index.d.mts +97 -0
- package/dist/plugins/open-api/index.mjs +65 -0
- package/dist/plugins/open-api/logo.mjs +13 -0
- package/dist/plugins/organization/access/index.d.mts +2 -0
- package/dist/plugins/organization/access/index.mjs +2 -0
- package/dist/plugins/organization/access/statement.d.mts +113 -0
- package/dist/plugins/organization/access/statement.mjs +77 -0
- package/dist/plugins/organization/adapter.d.mts +815 -0
- package/dist/plugins/organization/adapter.mjs +813 -0
- package/dist/plugins/organization/call.mjs +15 -0
- package/dist/plugins/organization/client.d.mts +375 -0
- package/dist/plugins/organization/client.mjs +104 -0
- package/dist/plugins/organization/error-codes.d.mts +66 -0
- package/dist/plugins/organization/error-codes.mjs +65 -0
- package/dist/plugins/organization/has-permission.d.mts +17 -0
- package/dist/plugins/organization/has-permission.mjs +34 -0
- package/dist/plugins/organization/index.d.mts +6 -0
- package/dist/plugins/organization/index.mjs +4 -0
- package/dist/plugins/organization/organization.d.mts +420 -0
- package/dist/plugins/organization/organization.mjs +886 -0
- package/dist/plugins/organization/permission.d.mts +15 -0
- package/dist/plugins/organization/permission.mjs +14 -0
- package/dist/plugins/organization/routes/crud-access-control.d.mts +511 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs +674 -0
- package/dist/plugins/organization/routes/crud-invites.d.mts +1154 -0
- package/dist/plugins/organization/routes/crud-invites.mjs +602 -0
- package/dist/plugins/organization/routes/crud-members.d.mts +1057 -0
- package/dist/plugins/organization/routes/crud-members.mjs +518 -0
- package/dist/plugins/organization/routes/crud-org.d.mts +918 -0
- package/dist/plugins/organization/routes/crud-org.mjs +455 -0
- package/dist/plugins/organization/routes/crud-team.d.mts +1238 -0
- package/dist/plugins/organization/routes/crud-team.mjs +766 -0
- package/dist/plugins/organization/schema.d.mts +390 -0
- package/dist/plugins/organization/schema.mjs +65 -0
- package/dist/plugins/organization/types.d.mts +691 -0
- package/dist/plugins/phone-number/client.d.mts +31 -0
- package/dist/plugins/phone-number/client.mjs +19 -0
- package/dist/plugins/phone-number/error-codes.d.mts +19 -0
- package/dist/plugins/phone-number/error-codes.mjs +18 -0
- package/dist/plugins/phone-number/index.d.mts +360 -0
- package/dist/plugins/phone-number/index.mjs +57 -0
- package/dist/plugins/phone-number/routes.mjs +529 -0
- package/dist/plugins/phone-number/schema.d.mts +22 -0
- package/dist/plugins/phone-number/schema.mjs +18 -0
- package/dist/plugins/phone-number/types.d.mts +116 -0
- package/dist/plugins/siwe/client.d.mts +14 -0
- package/dist/plugins/siwe/client.mjs +15 -0
- package/dist/plugins/siwe/index.d.mts +62 -0
- package/dist/plugins/siwe/index.mjs +272 -0
- package/dist/plugins/siwe/parse-message.mjs +60 -0
- package/dist/plugins/siwe/schema.d.mts +35 -0
- package/dist/plugins/siwe/schema.mjs +30 -0
- package/dist/plugins/siwe/types.d.mts +43 -0
- package/dist/plugins/test-utils/auth-helpers.mjs +33 -0
- package/dist/plugins/test-utils/cookie-builder.mjs +55 -0
- package/dist/plugins/test-utils/db-helpers.mjs +65 -0
- package/dist/plugins/test-utils/factories.mjs +38 -0
- package/dist/plugins/test-utils/index.d.mts +73 -0
- package/dist/plugins/test-utils/index.mjs +97 -0
- package/dist/plugins/test-utils/otp-sink.mjs +21 -0
- package/dist/plugins/test-utils/types.d.mts +51 -0
- package/dist/plugins/two-factor/backup-codes/index.d.mts +291 -0
- package/dist/plugins/two-factor/backup-codes/index.mjs +341 -0
- package/dist/plugins/two-factor/client.d.mts +76 -0
- package/dist/plugins/two-factor/client.mjs +41 -0
- package/dist/plugins/two-factor/constant.mjs +6 -0
- package/dist/plugins/two-factor/error-code.d.mts +20 -0
- package/dist/plugins/two-factor/error-code.mjs +19 -0
- package/dist/plugins/two-factor/index.d.mts +720 -0
- package/dist/plugins/two-factor/index.mjs +349 -0
- package/dist/plugins/two-factor/otp/index.d.mts +216 -0
- package/dist/plugins/two-factor/otp/index.mjs +252 -0
- package/dist/plugins/two-factor/schema.d.mts +59 -0
- package/dist/plugins/two-factor/schema.mjs +53 -0
- package/dist/plugins/two-factor/totp/index.d.mts +219 -0
- package/dist/plugins/two-factor/totp/index.mjs +230 -0
- package/dist/plugins/two-factor/types.d.mts +111 -0
- package/dist/plugins/two-factor/utils.mjs +9 -0
- package/dist/plugins/two-factor/verify-two-factor.mjs +205 -0
- package/dist/plugins/username/client.d.mts +38 -0
- package/dist/plugins/username/client.mjs +17 -0
- package/dist/plugins/username/error-codes.d.mts +16 -0
- package/dist/plugins/username/error-codes.mjs +15 -0
- package/dist/plugins/username/index.d.mts +326 -0
- package/dist/plugins/username/index.mjs +312 -0
- package/dist/plugins/username/schema.d.mts +50 -0
- package/dist/plugins/username/schema.mjs +25 -0
- package/dist/social-providers/index.d.mts +1 -0
- package/dist/social-providers/index.mjs +2 -0
- package/dist/state.d.mts +48 -0
- package/dist/state.mjs +149 -0
- package/dist/test-utils/headers.d.mts +8 -0
- package/dist/test-utils/headers.mjs +17 -0
- package/dist/test-utils/http-test-instance.d.mts +413 -0
- package/dist/test-utils/http-test-instance.mjs +107 -0
- package/dist/test-utils/index.d.mts +4 -0
- package/dist/test-utils/index.mjs +4 -0
- package/dist/test-utils/test-instance.d.mts +56 -0
- package/dist/test-utils/test-instance.mjs +242 -0
- package/dist/types/adapter.d.mts +2 -0
- package/dist/types/api.d.mts +28 -0
- package/dist/types/auth.d.mts +32 -0
- package/dist/types/helper.d.mts +26 -0
- package/dist/types/index.d.mts +10 -0
- package/dist/types/index.mjs +1 -0
- package/dist/types/models.d.mts +10 -0
- package/dist/types/plugins.d.mts +19 -0
- package/dist/utils/boolean.mjs +6 -0
- package/dist/utils/constants.mjs +4 -0
- package/dist/utils/date.mjs +6 -0
- package/dist/utils/hashing.mjs +18 -0
- package/dist/utils/hide-metadata.d.mts +6 -0
- package/dist/utils/hide-metadata.mjs +4 -0
- package/dist/utils/index.d.mts +4 -0
- package/dist/utils/is-api-error.d.mts +2 -0
- package/dist/utils/is-api-error.mjs +2 -0
- package/dist/utils/is-atom.mjs +6 -0
- package/dist/utils/is-promise.mjs +6 -0
- package/dist/utils/middleware-response.mjs +7 -0
- package/dist/utils/password.mjs +32 -0
- package/dist/utils/plugin-helper.mjs +14 -0
- package/dist/utils/request.mjs +23 -0
- package/dist/utils/shim.mjs +22 -0
- package/dist/utils/time.d.mts +48 -0
- package/dist/utils/time.mjs +98 -0
- package/dist/utils/url.d.mts +78 -0
- package/dist/utils/url.mjs +238 -0
- package/dist/utils/validate-user-info.mjs +44 -0
- package/dist/utils/wildcard.mjs +106 -0
- package/dist/version.mjs +5 -0
- package/package.json +595 -3
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
//#region src/cookies/cookie-utils.ts
|
|
2
|
+
function tryDecode(str) {
|
|
3
|
+
if (str.indexOf("%") === -1) return str;
|
|
4
|
+
try {
|
|
5
|
+
return decodeURIComponent(str);
|
|
6
|
+
} catch {
|
|
7
|
+
return str;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
const SECURE_COOKIE_PREFIX = "__Secure-";
|
|
11
|
+
const HOST_COOKIE_PREFIX = "__Host-";
|
|
12
|
+
/**
|
|
13
|
+
* Remove __Secure- or __Host- prefix from cookie name.
|
|
14
|
+
*/
|
|
15
|
+
function stripSecureCookiePrefix(cookieName) {
|
|
16
|
+
if (cookieName.startsWith("__Secure-")) return cookieName.slice(9);
|
|
17
|
+
if (cookieName.startsWith("__Host-")) return cookieName.slice(7);
|
|
18
|
+
return cookieName;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Split a comma-joined `Set-Cookie` header string into individual cookies.
|
|
22
|
+
*/
|
|
23
|
+
function splitSetCookieHeader(setCookie) {
|
|
24
|
+
if (!setCookie) return [];
|
|
25
|
+
const result = [];
|
|
26
|
+
let start = 0;
|
|
27
|
+
let i = 0;
|
|
28
|
+
while (i < setCookie.length) {
|
|
29
|
+
if (setCookie[i] === ",") {
|
|
30
|
+
let j = i + 1;
|
|
31
|
+
while (j < setCookie.length && setCookie[j] === " ") j++;
|
|
32
|
+
while (j < setCookie.length && setCookie[j] !== "=" && setCookie[j] !== ";" && setCookie[j] !== ",") j++;
|
|
33
|
+
if (j < setCookie.length && setCookie[j] === "=") {
|
|
34
|
+
const part = setCookie.slice(start, i).trim();
|
|
35
|
+
if (part) result.push(part);
|
|
36
|
+
start = i + 1;
|
|
37
|
+
while (start < setCookie.length && setCookie[start] === " ") start++;
|
|
38
|
+
i = start;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
i++;
|
|
43
|
+
}
|
|
44
|
+
const last = setCookie.slice(start).trim();
|
|
45
|
+
if (last) result.push(last);
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
function parseSetCookieHeader(setCookie) {
|
|
49
|
+
const cookies = /* @__PURE__ */ new Map();
|
|
50
|
+
splitSetCookieHeader(setCookie).forEach((cookieString) => {
|
|
51
|
+
const [nameValue, ...attributes] = cookieString.split(";").map((part) => part.trim());
|
|
52
|
+
const [name, ...valueParts] = (nameValue || "").split("=");
|
|
53
|
+
const value = unquoteCookieValue(valueParts.join("="));
|
|
54
|
+
if (!name) return;
|
|
55
|
+
const attrObj = { value: tryDecode(value) };
|
|
56
|
+
attributes.forEach((attribute) => {
|
|
57
|
+
const [attrName, ...attrValueParts] = attribute.split("=");
|
|
58
|
+
const attrValue = attrValueParts.join("=");
|
|
59
|
+
const normalizedAttrName = attrName.trim().toLowerCase();
|
|
60
|
+
switch (normalizedAttrName) {
|
|
61
|
+
case "max-age":
|
|
62
|
+
attrObj["max-age"] = attrValue ? parseInt(attrValue.trim(), 10) : void 0;
|
|
63
|
+
break;
|
|
64
|
+
case "expires":
|
|
65
|
+
attrObj.expires = attrValue ? new Date(attrValue.trim()) : void 0;
|
|
66
|
+
break;
|
|
67
|
+
case "domain":
|
|
68
|
+
attrObj.domain = attrValue ? attrValue.trim() : void 0;
|
|
69
|
+
break;
|
|
70
|
+
case "path":
|
|
71
|
+
attrObj.path = attrValue ? attrValue.trim() : void 0;
|
|
72
|
+
break;
|
|
73
|
+
case "secure":
|
|
74
|
+
attrObj.secure = true;
|
|
75
|
+
break;
|
|
76
|
+
case "httponly":
|
|
77
|
+
attrObj.httponly = true;
|
|
78
|
+
break;
|
|
79
|
+
case "samesite":
|
|
80
|
+
attrObj.samesite = attrValue ? attrValue.trim().toLowerCase() : void 0;
|
|
81
|
+
break;
|
|
82
|
+
case "partitioned":
|
|
83
|
+
attrObj.partitioned = true;
|
|
84
|
+
break;
|
|
85
|
+
default:
|
|
86
|
+
attrObj[normalizedAttrName] = attrValue ? attrValue.trim() : true;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
cookies.set(name, attrObj);
|
|
91
|
+
});
|
|
92
|
+
return cookies;
|
|
93
|
+
}
|
|
94
|
+
function toCookieOptions(attributes) {
|
|
95
|
+
return {
|
|
96
|
+
maxAge: attributes["max-age"],
|
|
97
|
+
expires: attributes.expires,
|
|
98
|
+
domain: attributes.domain,
|
|
99
|
+
path: attributes.path,
|
|
100
|
+
secure: attributes.secure,
|
|
101
|
+
httpOnly: attributes.httponly,
|
|
102
|
+
sameSite: attributes.samesite,
|
|
103
|
+
partitioned: attributes.partitioned
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Cookie-name token char set per RFC 7230 §3.2.6.
|
|
108
|
+
*
|
|
109
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
|
|
110
|
+
*/
|
|
111
|
+
const cookieNameRegex = /^[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E\x5F\x60\x61-\x7A\x7C\x7E]+$/;
|
|
112
|
+
/**
|
|
113
|
+
* Cookie-value char set per RFC 6265 §4.1.1, plus space and comma.
|
|
114
|
+
*
|
|
115
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1
|
|
116
|
+
* @see https://github.com/golang/go/issues/7243
|
|
117
|
+
*/
|
|
118
|
+
const cookieValueRegex = /^[\x20\x21\x23-\x3A\x3C-\x5B\x5D-\x7E]*$/;
|
|
119
|
+
/**
|
|
120
|
+
* Strip surrounding double-quotes per RFC 6265 §4.1.1 quoted-string form.
|
|
121
|
+
*
|
|
122
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1
|
|
123
|
+
*/
|
|
124
|
+
function unquoteCookieValue(value) {
|
|
125
|
+
if (value.length < 2 || !value.startsWith("\"") || !value.endsWith("\"")) return value;
|
|
126
|
+
return value.slice(1, -1);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Trim leading/trailing OWS (space / horizontal tab) per RFC 7230 §3.2.3.
|
|
130
|
+
* Narrower than `String.prototype.trim()`, which strips CR/LF and other
|
|
131
|
+
* whitespace and would let CTLs escape `cookieValueRegex`.
|
|
132
|
+
*
|
|
133
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.3
|
|
134
|
+
*/
|
|
135
|
+
function trimOWS(s) {
|
|
136
|
+
let start = 0;
|
|
137
|
+
let end = s.length;
|
|
138
|
+
while (start < end) {
|
|
139
|
+
const c = s.charCodeAt(start);
|
|
140
|
+
if (c !== 32 && c !== 9) break;
|
|
141
|
+
start++;
|
|
142
|
+
}
|
|
143
|
+
while (end > start) {
|
|
144
|
+
const c = s.charCodeAt(end - 1);
|
|
145
|
+
if (c !== 32 && c !== 9) break;
|
|
146
|
+
end--;
|
|
147
|
+
}
|
|
148
|
+
return start === 0 && end === s.length ? s : s.slice(start, end);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Tolerates `;` separators without the SP that RFC 6265 §4.2.1 mandates,
|
|
152
|
+
* since proxies and runtimes commonly strip it. Silently drops entries
|
|
153
|
+
* whose name violates RFC 7230 token or whose value violates RFC 6265
|
|
154
|
+
* cookie-octet (plus space and comma). Strips optional surrounding
|
|
155
|
+
* double-quotes per RFC 6265 §4.1.1.
|
|
156
|
+
*/
|
|
157
|
+
function parseCookies(cookie) {
|
|
158
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
159
|
+
if (cookie.length < 2) return cookieMap;
|
|
160
|
+
for (const chunk of cookie.split(";")) {
|
|
161
|
+
const eq = chunk.indexOf("=");
|
|
162
|
+
if (eq === -1) continue;
|
|
163
|
+
const key = trimOWS(chunk.slice(0, eq));
|
|
164
|
+
const val = unquoteCookieValue(trimOWS(chunk.slice(eq + 1)));
|
|
165
|
+
if (cookieNameRegex.test(key) && cookieValueRegex.test(val)) cookieMap.set(key, tryDecode(val));
|
|
166
|
+
}
|
|
167
|
+
return cookieMap;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Add or replace a cookie in the request `Cookie` header.
|
|
171
|
+
*
|
|
172
|
+
* Cookie pairs are joined with `; `, but `headers.append("cookie", ...)`
|
|
173
|
+
* joins with `, ` in some runtimes (e.g. Deno, Cloudflare Workers) and
|
|
174
|
+
* breaks downstream cookie parsing. This builds the header value via
|
|
175
|
+
* parse-mutate-serialize.
|
|
176
|
+
*/
|
|
177
|
+
function setRequestCookie(headers, name, value) {
|
|
178
|
+
const cookieMap = parseCookies(headers.get("cookie") || "");
|
|
179
|
+
if (cookieNameRegex.test(name)) cookieMap.set(name, value);
|
|
180
|
+
headers.set("cookie", Array.from(cookieMap, ([k, v]) => `${k}=${encodeURIComponent(v)}`).join("; "));
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Merge `Set-Cookie` header values into the target's `Cookie` header.
|
|
184
|
+
* Mutates `target`.
|
|
185
|
+
*
|
|
186
|
+
* Name/value-level merge only. RFC 6265 §5 user-agent semantics
|
|
187
|
+
* (expiration, domain/path scoping, ordering) are out of scope. Suitable
|
|
188
|
+
* for single-request proxy, middleware, and test contexts.
|
|
189
|
+
*/
|
|
190
|
+
function applySetCookies(target, setCookieValues) {
|
|
191
|
+
const cookieMap = parseCookies(target.get("cookie") || "");
|
|
192
|
+
for (const setCookie of setCookieValues) for (const [name, attr] of parseSetCookieHeader(setCookie)) if (cookieNameRegex.test(name)) cookieMap.set(name, attr.value);
|
|
193
|
+
target.set("cookie", Array.from(cookieMap, ([k, v]) => `${k}=${encodeURIComponent(v)}`).join("; "));
|
|
194
|
+
}
|
|
195
|
+
function setCookieToHeader(headers) {
|
|
196
|
+
return (context) => {
|
|
197
|
+
const setCookieHeader = context.response.headers.get("set-cookie");
|
|
198
|
+
if (!setCookieHeader) return;
|
|
199
|
+
applySetCookies(headers, [setCookieHeader]);
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
203
|
+
export { HOST_COOKIE_PREFIX, SECURE_COOKIE_PREFIX, applySetCookies, cookieNameRegex, parseCookies, parseSetCookieHeader, setCookieToHeader, setRequestCookie, splitSetCookieHeader, stripSecureCookiePrefix, toCookieOptions };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Session, User } from "../types/models.mjs";
|
|
2
|
+
import { CookieAttributes, HOST_COOKIE_PREFIX, SECURE_COOKIE_PREFIX, applySetCookies, cookieNameRegex, parseCookies, parseSetCookieHeader, setCookieToHeader, setRequestCookie, splitSetCookieHeader, stripSecureCookiePrefix, toCookieOptions } from "./cookie-utils.mjs";
|
|
3
|
+
import { createSessionStore, getAccountCookie, getChunkedCookie, setAccountCookie } from "./session-store.mjs";
|
|
4
|
+
import { Awaitable, BetterAuthCookie, BetterAuthCookies, BetterAuthOptions, CookieCachePayload, GenericEndpointContext } from "@better-auth/core";
|
|
5
|
+
import * as _$better_call0 from "better-call";
|
|
6
|
+
import { CookieOptions } from "better-call";
|
|
7
|
+
import { JSONWebKeySet } from "jose";
|
|
8
|
+
|
|
9
|
+
//#region src/cookies/index.d.ts
|
|
10
|
+
declare function createCookieGetter(options: BetterAuthOptions): (cookieName: string, overrideAttributes?: Partial<CookieOptions>) => {
|
|
11
|
+
name: string;
|
|
12
|
+
attributes: {
|
|
13
|
+
domain?: string;
|
|
14
|
+
expires?: Date;
|
|
15
|
+
httpOnly: boolean;
|
|
16
|
+
maxAge?: number;
|
|
17
|
+
path: string;
|
|
18
|
+
secure: boolean;
|
|
19
|
+
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
20
|
+
partitioned?: boolean;
|
|
21
|
+
prefix?: _$better_call0.CookiePrefixOptions;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
declare function getCookies(options: BetterAuthOptions): {
|
|
25
|
+
sessionToken: {
|
|
26
|
+
name: string;
|
|
27
|
+
attributes: {
|
|
28
|
+
domain?: string;
|
|
29
|
+
expires?: Date;
|
|
30
|
+
httpOnly: boolean;
|
|
31
|
+
maxAge?: number;
|
|
32
|
+
path: string;
|
|
33
|
+
secure: boolean;
|
|
34
|
+
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
35
|
+
partitioned?: boolean;
|
|
36
|
+
prefix?: _$better_call0.CookiePrefixOptions;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* This cookie is used to store the session data in the cookie
|
|
41
|
+
* This is useful for when you want to cache the session in the cookie
|
|
42
|
+
*/
|
|
43
|
+
sessionData: {
|
|
44
|
+
name: string;
|
|
45
|
+
attributes: {
|
|
46
|
+
domain?: string;
|
|
47
|
+
expires?: Date;
|
|
48
|
+
httpOnly: boolean;
|
|
49
|
+
maxAge?: number;
|
|
50
|
+
path: string;
|
|
51
|
+
secure: boolean;
|
|
52
|
+
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
53
|
+
partitioned?: boolean;
|
|
54
|
+
prefix?: _$better_call0.CookiePrefixOptions;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
dontRememberToken: {
|
|
58
|
+
name: string;
|
|
59
|
+
attributes: {
|
|
60
|
+
domain?: string;
|
|
61
|
+
expires?: Date;
|
|
62
|
+
httpOnly: boolean;
|
|
63
|
+
maxAge?: number;
|
|
64
|
+
path: string;
|
|
65
|
+
secure: boolean;
|
|
66
|
+
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
67
|
+
partitioned?: boolean;
|
|
68
|
+
prefix?: _$better_call0.CookiePrefixOptions;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
accountData: {
|
|
72
|
+
name: string;
|
|
73
|
+
attributes: {
|
|
74
|
+
domain?: string;
|
|
75
|
+
expires?: Date;
|
|
76
|
+
httpOnly: boolean;
|
|
77
|
+
maxAge?: number;
|
|
78
|
+
path: string;
|
|
79
|
+
secure: boolean;
|
|
80
|
+
sameSite: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
81
|
+
partitioned?: boolean;
|
|
82
|
+
prefix?: _$better_call0.CookiePrefixOptions;
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
declare function setCookieCache(ctx: GenericEndpointContext, session: {
|
|
87
|
+
session: Session & Record<string, unknown>;
|
|
88
|
+
user: User;
|
|
89
|
+
}, dontRememberMe: boolean): Promise<void>;
|
|
90
|
+
declare function decodeCookieCache(ctx: GenericEndpointContext, value: string): Promise<{
|
|
91
|
+
session: CookieCachePayload;
|
|
92
|
+
expiresAt: number;
|
|
93
|
+
} | null>;
|
|
94
|
+
declare function setSessionCookie(ctx: GenericEndpointContext, session: {
|
|
95
|
+
session: Session & Record<string, unknown>;
|
|
96
|
+
user: User;
|
|
97
|
+
}, dontRememberMe?: boolean | undefined, overrides?: Partial<CookieOptions> | undefined): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Expires a cookie by setting `maxAge: 0` while preserving its attributes
|
|
100
|
+
*/
|
|
101
|
+
declare function expireCookie(ctx: GenericEndpointContext, cookie: BetterAuthCookie): void;
|
|
102
|
+
declare function deleteSessionCookie(ctx: GenericEndpointContext, skipDontRememberMe?: boolean | undefined): void;
|
|
103
|
+
type EligibleCookies = (string & {}) | (keyof BetterAuthCookies & {});
|
|
104
|
+
declare const getSessionCookie: (request: Request | Headers, config?: {
|
|
105
|
+
cookiePrefix?: string;
|
|
106
|
+
cookieName?: string;
|
|
107
|
+
path?: string;
|
|
108
|
+
} | undefined) => string | null;
|
|
109
|
+
type CookieCacheVersion = string | ((session: CookieCachePayload["session"], user: CookieCachePayload["user"]) => Awaitable<string>);
|
|
110
|
+
declare const getCookieCache: <S extends CookieCachePayload = CookieCachePayload>(request: Request | Headers, config?: {
|
|
111
|
+
cookiePrefix?: string;
|
|
112
|
+
cookieName?: string;
|
|
113
|
+
isSecure?: boolean;
|
|
114
|
+
secret?: string;
|
|
115
|
+
strategy?: "compact" | "jwt" | "jwe";
|
|
116
|
+
jwt?: {
|
|
117
|
+
jwks?: JSONWebKeySet;
|
|
118
|
+
issuer?: string;
|
|
119
|
+
audience?: string;
|
|
120
|
+
} | undefined;
|
|
121
|
+
version?: CookieCacheVersion;
|
|
122
|
+
} | undefined) => Promise<S | null>;
|
|
123
|
+
//#endregion
|
|
124
|
+
export { CookieAttributes, EligibleCookies, HOST_COOKIE_PREFIX, SECURE_COOKIE_PREFIX, applySetCookies, cookieNameRegex, createCookieGetter, createSessionStore, decodeCookieCache, deleteSessionCookie, expireCookie, getAccountCookie, getChunkedCookie, getCookieCache, getCookies, getSessionCookie, parseCookies, parseSetCookieHeader, setAccountCookie, setCookieCache, setCookieToHeader, setRequestCookie, setSessionCookie, splitSetCookieHeader, stripSecureCookiePrefix, toCookieOptions };
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { isDynamicBaseURLConfig } from "../utils/url.mjs";
|
|
2
|
+
import { shouldBindAccountCookieToSessionUser } from "../context/store-capabilities.mjs";
|
|
3
|
+
import { signJWT, symmetricDecodeJWT, symmetricEncodeJWT, verifyJWT } from "../crypto/jwt.mjs";
|
|
4
|
+
import { parseUserOutput } from "../db/schema.mjs";
|
|
5
|
+
import { getDate } from "../utils/date.mjs";
|
|
6
|
+
import { isPromise } from "../utils/is-promise.mjs";
|
|
7
|
+
import { sec } from "../utils/time.mjs";
|
|
8
|
+
import { parseCompactCookieCache, parseCookieCachePayload } from "./cache.mjs";
|
|
9
|
+
import { HOST_COOKIE_PREFIX, SECURE_COOKIE_PREFIX, applySetCookies, cookieNameRegex, parseCookies, parseSetCookieHeader, setCookieToHeader, setRequestCookie, splitSetCookieHeader, stripSecureCookiePrefix, toCookieOptions } from "./cookie-utils.mjs";
|
|
10
|
+
import { verifySessionCookieJwtWithJwks } from "./jwt.mjs";
|
|
11
|
+
import { createAccountStore, createSessionStore, getAccountCookie, getChunkedCookie, setAccountCookie } from "./session-store.mjs";
|
|
12
|
+
import { env, isProduction } from "@better-auth/core/env";
|
|
13
|
+
import { BetterAuthError } from "@better-auth/core/error";
|
|
14
|
+
import { safeJSONParse } from "@better-auth/core/utils/json";
|
|
15
|
+
import { filterOutputFields } from "@better-auth/core/utils/db";
|
|
16
|
+
import { base64Url } from "@better-auth/utils/base64";
|
|
17
|
+
import { binary } from "@better-auth/utils/binary";
|
|
18
|
+
import { createHMAC } from "@better-auth/utils/hmac";
|
|
19
|
+
//#region src/cookies/index.ts
|
|
20
|
+
function createCookieGetter(options) {
|
|
21
|
+
const baseURLString = typeof options.baseURL === "string" ? options.baseURL : void 0;
|
|
22
|
+
const dynamicProtocol = typeof options.baseURL === "object" && options.baseURL !== null ? options.baseURL.protocol : void 0;
|
|
23
|
+
const secureCookiePrefix = (options.advanced?.useSecureCookies !== void 0 ? options.advanced?.useSecureCookies : dynamicProtocol === "https" ? true : dynamicProtocol === "http" ? false : baseURLString ? baseURLString.startsWith("https://") : isProduction) ? SECURE_COOKIE_PREFIX : "";
|
|
24
|
+
const crossSubdomainEnabled = !!options.advanced?.crossSubDomainCookies?.enabled;
|
|
25
|
+
const domain = crossSubdomainEnabled ? options.advanced?.crossSubDomainCookies?.domain || (baseURLString ? new URL(baseURLString).hostname : void 0) : void 0;
|
|
26
|
+
if (crossSubdomainEnabled && !domain && !isDynamicBaseURLConfig(options.baseURL)) throw new BetterAuthError("baseURL is required when crossSubdomainCookies are enabled.");
|
|
27
|
+
function createCookie(cookieName, overrideAttributes = {}) {
|
|
28
|
+
const prefix = options.advanced?.cookiePrefix || "better-auth";
|
|
29
|
+
const name = options.advanced?.cookies?.[cookieName]?.name || `${prefix}.${cookieName}`;
|
|
30
|
+
const attributes = options.advanced?.cookies?.[cookieName]?.attributes ?? {};
|
|
31
|
+
return {
|
|
32
|
+
name: `${secureCookiePrefix}${name}`,
|
|
33
|
+
attributes: {
|
|
34
|
+
secure: !!secureCookiePrefix,
|
|
35
|
+
sameSite: "lax",
|
|
36
|
+
path: "/",
|
|
37
|
+
httpOnly: true,
|
|
38
|
+
...crossSubdomainEnabled ? { domain } : {},
|
|
39
|
+
...options.advanced?.defaultCookieAttributes,
|
|
40
|
+
...overrideAttributes,
|
|
41
|
+
...attributes
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return createCookie;
|
|
46
|
+
}
|
|
47
|
+
function getCookies(options) {
|
|
48
|
+
const createCookie = createCookieGetter(options);
|
|
49
|
+
const sessionToken = createCookie("session_token", { maxAge: options.session?.expiresIn || sec("7d") });
|
|
50
|
+
const sessionData = createCookie("session_data", { maxAge: options.session?.cookieCache?.maxAge || 300 });
|
|
51
|
+
const accountData = createCookie("account_data", { maxAge: options.session?.cookieCache?.maxAge || 300 });
|
|
52
|
+
const dontRememberToken = createCookie("dont_remember");
|
|
53
|
+
return {
|
|
54
|
+
sessionToken: {
|
|
55
|
+
name: sessionToken.name,
|
|
56
|
+
attributes: sessionToken.attributes
|
|
57
|
+
},
|
|
58
|
+
/**
|
|
59
|
+
* This cookie is used to store the session data in the cookie
|
|
60
|
+
* This is useful for when you want to cache the session in the cookie
|
|
61
|
+
*/
|
|
62
|
+
sessionData: {
|
|
63
|
+
name: sessionData.name,
|
|
64
|
+
attributes: sessionData.attributes
|
|
65
|
+
},
|
|
66
|
+
dontRememberToken: {
|
|
67
|
+
name: dontRememberToken.name,
|
|
68
|
+
attributes: dontRememberToken.attributes
|
|
69
|
+
},
|
|
70
|
+
accountData: {
|
|
71
|
+
name: accountData.name,
|
|
72
|
+
attributes: accountData.attributes
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
async function setCookieCache(ctx, session, dontRememberMe) {
|
|
77
|
+
if (!ctx.context.options.session?.cookieCache?.enabled) return;
|
|
78
|
+
const filteredSession = filterOutputFields(session.session, ctx.context.options.session?.additionalFields);
|
|
79
|
+
const filteredUser = parseUserOutput(ctx.context.options, session.user);
|
|
80
|
+
const versionConfig = ctx.context.options.session?.cookieCache?.version;
|
|
81
|
+
let version = "1";
|
|
82
|
+
if (versionConfig) {
|
|
83
|
+
if (typeof versionConfig === "string") version = versionConfig;
|
|
84
|
+
else if (typeof versionConfig === "function") {
|
|
85
|
+
const result = versionConfig(session.session, session.user);
|
|
86
|
+
version = isPromise(result) ? await result : result;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const sessionData = {
|
|
90
|
+
session: filteredSession,
|
|
91
|
+
user: filteredUser,
|
|
92
|
+
updatedAt: Date.now(),
|
|
93
|
+
version
|
|
94
|
+
};
|
|
95
|
+
const options = {
|
|
96
|
+
...ctx.context.authCookies.sessionData.attributes,
|
|
97
|
+
maxAge: dontRememberMe ? void 0 : ctx.context.authCookies.sessionData.attributes.maxAge
|
|
98
|
+
};
|
|
99
|
+
const expiresAtDate = getDate(options.maxAge || 60, "sec").getTime();
|
|
100
|
+
const strategy = ctx.context.options.session?.cookieCache?.strategy || "compact";
|
|
101
|
+
let data;
|
|
102
|
+
if (strategy === "jwe") data = await symmetricEncodeJWT(sessionData, ctx.context.secretConfig, "better-auth-session", options.maxAge || 300);
|
|
103
|
+
else if (strategy === "jwt") {
|
|
104
|
+
const cookieCacheSigner = ctx.context.sessionConfig.cookieCacheSigner;
|
|
105
|
+
data = cookieCacheSigner ? await cookieCacheSigner.sign(ctx, sessionData, options.maxAge || 300) : await signJWT(sessionData, ctx.context.secret, options.maxAge || 300);
|
|
106
|
+
} else data = base64Url.encode(JSON.stringify({
|
|
107
|
+
session: sessionData,
|
|
108
|
+
expiresAt: expiresAtDate,
|
|
109
|
+
signature: await createHMAC("SHA-256", "base64urlnopad").sign(ctx.context.secret, JSON.stringify({
|
|
110
|
+
...sessionData,
|
|
111
|
+
expiresAt: expiresAtDate
|
|
112
|
+
}))
|
|
113
|
+
}), { padding: false });
|
|
114
|
+
const sessionStore = createSessionStore(ctx.context.authCookies.sessionData.name, options, ctx);
|
|
115
|
+
sessionStore.setCookies(sessionStore.chunk(data, options));
|
|
116
|
+
if (ctx.context.options.account?.storeAccountCookie && !hasPendingSetCookie(ctx, ctx.context.authCookies.accountData.name)) {
|
|
117
|
+
const accountData = await getAccountCookie(ctx);
|
|
118
|
+
if (accountData) if (!shouldBindAccountCookieToSessionUser(ctx.context.options) || accountData.userId === session.user.id) await setAccountCookie(ctx, accountData);
|
|
119
|
+
else {
|
|
120
|
+
expireCookie(ctx, ctx.context.authCookies.accountData);
|
|
121
|
+
const accountStore = createAccountStore(ctx.context.authCookies.accountData.name, ctx.context.authCookies.accountData.attributes, ctx);
|
|
122
|
+
accountStore.setCookies(accountStore.clean());
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function decodeCookieCache(ctx, value) {
|
|
127
|
+
const strategy = ctx.context.options.session?.cookieCache?.strategy || "compact";
|
|
128
|
+
if (strategy === "jwe") {
|
|
129
|
+
const decoded = await symmetricDecodeJWT(value, ctx.context.secretConfig, "better-auth-session");
|
|
130
|
+
const payload = parseCookieCachePayload(decoded);
|
|
131
|
+
if (!payload) return null;
|
|
132
|
+
return {
|
|
133
|
+
session: payload,
|
|
134
|
+
expiresAt: decoded?.exp ? decoded.exp * 1e3 : Date.now()
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (strategy === "jwt") {
|
|
138
|
+
const cookieCacheSigner = ctx.context.sessionConfig.cookieCacheSigner;
|
|
139
|
+
if (cookieCacheSigner) {
|
|
140
|
+
const verified = await cookieCacheSigner.verify(ctx, value);
|
|
141
|
+
if (!verified) return null;
|
|
142
|
+
return {
|
|
143
|
+
session: verified.payload,
|
|
144
|
+
expiresAt: verified.expiresAt
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const decoded = await verifyJWT(value, ctx.context.secret);
|
|
148
|
+
const payload = parseCookieCachePayload(decoded);
|
|
149
|
+
if (!payload) return null;
|
|
150
|
+
return {
|
|
151
|
+
session: payload,
|
|
152
|
+
expiresAt: decoded?.exp ? decoded.exp * 1e3 : Date.now()
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const parsed = parseCompactCookieCache(safeJSONParse(binary.decode(base64Url.decode(value))));
|
|
156
|
+
if (!parsed) return null;
|
|
157
|
+
if (!await createHMAC("SHA-256", "base64urlnopad").verify(ctx.context.secret, JSON.stringify({
|
|
158
|
+
...parsed.session,
|
|
159
|
+
expiresAt: parsed.expiresAt
|
|
160
|
+
}), parsed.signature)) return null;
|
|
161
|
+
const payload = parseCookieCachePayload(parsed.session);
|
|
162
|
+
return payload ? {
|
|
163
|
+
session: payload,
|
|
164
|
+
expiresAt: parsed.expiresAt
|
|
165
|
+
} : null;
|
|
166
|
+
}
|
|
167
|
+
async function setSessionCookie(ctx, session, dontRememberMe, overrides) {
|
|
168
|
+
const dontRememberMeCookie = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
|
|
169
|
+
dontRememberMe = dontRememberMe !== void 0 ? dontRememberMe : !!dontRememberMeCookie;
|
|
170
|
+
const options = ctx.context.authCookies.sessionToken.attributes;
|
|
171
|
+
const maxAge = dontRememberMe ? void 0 : ctx.context.sessionConfig.expiresIn;
|
|
172
|
+
await ctx.setSignedCookie(ctx.context.authCookies.sessionToken.name, session.session.token, ctx.context.secret, {
|
|
173
|
+
...options,
|
|
174
|
+
maxAge,
|
|
175
|
+
...overrides
|
|
176
|
+
});
|
|
177
|
+
if (dontRememberMe) await ctx.setSignedCookie(ctx.context.authCookies.dontRememberToken.name, "true", ctx.context.secret, ctx.context.authCookies.dontRememberToken.attributes);
|
|
178
|
+
await setCookieCache(ctx, session, dontRememberMe);
|
|
179
|
+
ctx.context.setNewSession(session);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Remove any prior `Set-Cookie` entries on the current response whose cookie
|
|
183
|
+
* name matches `cookieName` or any chunked variant (`${cookieName}.0`, etc.).
|
|
184
|
+
*
|
|
185
|
+
* Prevents a valid cookie value from leaking on the wire when the same cookie
|
|
186
|
+
* is set and then expired within a single request (e.g. `/sign-in/email`
|
|
187
|
+
* writes credential session cookies and the 2FA after-hook expires them).
|
|
188
|
+
* Browsers honor the expiring entry, but anything reading the raw response
|
|
189
|
+
* headers — proxy/LB logs, server-side SDK consumers, observability tools —
|
|
190
|
+
* sees the earlier valid value and could replay it (bypassing the 2FA gate
|
|
191
|
+
* when the cookie cache is enabled).
|
|
192
|
+
*
|
|
193
|
+
* Scrubs both the local middleware scope's `responseHeaders` and the outer
|
|
194
|
+
* endpoint scope's `ctx.context.responseHeaders`, because plugin after-hooks
|
|
195
|
+
* run in a fresh local scope while accumulated response headers live on the
|
|
196
|
+
* outer one. `scoped.context` is required by {@link GenericEndpointContext}
|
|
197
|
+
* but unit-test mocks pass a minimal object via `as any`, so we use optional
|
|
198
|
+
* chaining defensively. The `Set` collapses the case where both scopes
|
|
199
|
+
* reference the same `Headers`.
|
|
200
|
+
*/
|
|
201
|
+
function removeSetCookieEntries(ctx, cookieName) {
|
|
202
|
+
const scoped = ctx;
|
|
203
|
+
const targets = /* @__PURE__ */ new Set();
|
|
204
|
+
if (scoped.responseHeaders) targets.add(scoped.responseHeaders);
|
|
205
|
+
if (scoped.context?.responseHeaders) targets.add(scoped.context.responseHeaders);
|
|
206
|
+
const exact = `${cookieName}=`;
|
|
207
|
+
const chunk = `${cookieName}.`;
|
|
208
|
+
for (const headers of targets) {
|
|
209
|
+
const existing = typeof headers.getSetCookie === "function" ? headers.getSetCookie() : splitSetCookieHeader(headers.get("set-cookie") || "");
|
|
210
|
+
if (!existing.length) continue;
|
|
211
|
+
const survivors = existing.filter((entry) => !entry.startsWith(exact) && !entry.startsWith(chunk));
|
|
212
|
+
if (survivors.length === existing.length) continue;
|
|
213
|
+
headers.delete("set-cookie");
|
|
214
|
+
for (const entry of survivors) headers.append("set-cookie", entry);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Whether the response already has a pending `Set-Cookie` for `cookieName`
|
|
219
|
+
* or a chunked variant.
|
|
220
|
+
*/
|
|
221
|
+
function hasPendingSetCookie(ctx, cookieName) {
|
|
222
|
+
const scoped = ctx;
|
|
223
|
+
const targets = /* @__PURE__ */ new Set();
|
|
224
|
+
if (scoped.responseHeaders) targets.add(scoped.responseHeaders);
|
|
225
|
+
if (scoped.context?.responseHeaders) targets.add(scoped.context.responseHeaders);
|
|
226
|
+
const exact = `${cookieName}=`;
|
|
227
|
+
const chunk = `${cookieName}.`;
|
|
228
|
+
for (const headers of targets) if ((typeof headers.getSetCookie === "function" ? headers.getSetCookie() : splitSetCookieHeader(headers.get("set-cookie") || "")).some((entry) => entry.startsWith(exact) || entry.startsWith(chunk))) return true;
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Expires a cookie by setting `maxAge: 0` while preserving its attributes
|
|
233
|
+
*/
|
|
234
|
+
function expireCookie(ctx, cookie) {
|
|
235
|
+
removeSetCookieEntries(ctx, cookie.name);
|
|
236
|
+
ctx.setCookie(cookie.name, "", {
|
|
237
|
+
...cookie.attributes,
|
|
238
|
+
maxAge: 0
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function deleteSessionCookie(ctx, skipDontRememberMe) {
|
|
242
|
+
expireCookie(ctx, ctx.context.authCookies.sessionToken);
|
|
243
|
+
expireCookie(ctx, ctx.context.authCookies.sessionData);
|
|
244
|
+
if (ctx.context.options.account?.storeAccountCookie) {
|
|
245
|
+
expireCookie(ctx, ctx.context.authCookies.accountData);
|
|
246
|
+
const accountStore = createAccountStore(ctx.context.authCookies.accountData.name, ctx.context.authCookies.accountData.attributes, ctx);
|
|
247
|
+
const cleanCookies = accountStore.clean();
|
|
248
|
+
accountStore.setCookies(cleanCookies);
|
|
249
|
+
}
|
|
250
|
+
if (ctx.context.oauthConfig.storeStateStrategy === "cookie") expireCookie(ctx, ctx.context.createAuthCookie("oauth_state"));
|
|
251
|
+
const sessionStore = createSessionStore(ctx.context.authCookies.sessionData.name, ctx.context.authCookies.sessionData.attributes, ctx);
|
|
252
|
+
const cleanCookies = sessionStore.clean();
|
|
253
|
+
sessionStore.setCookies(cleanCookies);
|
|
254
|
+
if (!skipDontRememberMe) expireCookie(ctx, ctx.context.authCookies.dontRememberToken);
|
|
255
|
+
}
|
|
256
|
+
function isEmbeddedSessionExpired(session) {
|
|
257
|
+
if (!session?.expiresAt) return false;
|
|
258
|
+
const expiresAt = new Date(session.expiresAt).getTime();
|
|
259
|
+
return Number.isFinite(expiresAt) && expiresAt < Date.now();
|
|
260
|
+
}
|
|
261
|
+
const getSessionCookie = (request, config) => {
|
|
262
|
+
const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
|
|
263
|
+
if (!cookies) return null;
|
|
264
|
+
const { cookieName = "session_token", cookiePrefix = "better-auth" } = config || {};
|
|
265
|
+
const parsedCookie = parseCookies(cookies);
|
|
266
|
+
const getCookie = (name) => parsedCookie.get(`__Secure-${name}`) ?? parsedCookie.get(name);
|
|
267
|
+
const sessionToken = getCookie(`${cookiePrefix}.${cookieName}`) || getCookie(`${cookiePrefix}-${cookieName}`);
|
|
268
|
+
if (sessionToken) return sessionToken;
|
|
269
|
+
return null;
|
|
270
|
+
};
|
|
271
|
+
async function matchesVersion(payload, version) {
|
|
272
|
+
const expectedVersion = typeof version === "string" ? version : await version(payload.session, payload.user);
|
|
273
|
+
return (payload.version || "1") === expectedVersion;
|
|
274
|
+
}
|
|
275
|
+
const getCookieCache = async (request, config) => {
|
|
276
|
+
const cookies = (request instanceof Headers || !("headers" in request) ? request : request.headers).get("cookie");
|
|
277
|
+
if (!cookies) return null;
|
|
278
|
+
const { cookieName = "session_data", cookiePrefix = "better-auth" } = config || {};
|
|
279
|
+
const name = config?.isSecure !== void 0 ? config.isSecure ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}` : isProduction ? `${SECURE_COOKIE_PREFIX}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`;
|
|
280
|
+
const parsedCookie = parseCookies(cookies);
|
|
281
|
+
let sessionData = parsedCookie.get(name);
|
|
282
|
+
if (!sessionData) {
|
|
283
|
+
const chunks = [];
|
|
284
|
+
for (const [cookieName, value] of parsedCookie.entries()) if (cookieName.startsWith(name + ".")) {
|
|
285
|
+
const parts = cookieName.split(".");
|
|
286
|
+
const indexStr = parts[parts.length - 1];
|
|
287
|
+
const index = parseInt(indexStr || "0", 10);
|
|
288
|
+
if (!isNaN(index)) chunks.push({
|
|
289
|
+
index,
|
|
290
|
+
value
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
if (chunks.length > 0) {
|
|
294
|
+
chunks.sort((a, b) => a.index - b.index);
|
|
295
|
+
sessionData = chunks.map((c) => c.value).join("");
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (sessionData) {
|
|
299
|
+
const strategy = config?.strategy || "compact";
|
|
300
|
+
if (strategy === "jwe") {
|
|
301
|
+
const secret = config?.secret || env.BETTER_AUTH_SECRET;
|
|
302
|
+
if (!secret) throw new BetterAuthError("getCookieCache requires a secret to be provided. Either pass it as an option or set the BETTER_AUTH_SECRET environment variable");
|
|
303
|
+
const payload = parseCookieCachePayload(await symmetricDecodeJWT(sessionData, secret, "better-auth-session"));
|
|
304
|
+
if (!payload) return null;
|
|
305
|
+
if (config?.version) {
|
|
306
|
+
if (!await matchesVersion(payload, config.version)) return null;
|
|
307
|
+
}
|
|
308
|
+
if (isEmbeddedSessionExpired(payload.session)) return null;
|
|
309
|
+
return payload;
|
|
310
|
+
} else if (strategy === "jwt") {
|
|
311
|
+
const jwks = config?.jwt?.jwks;
|
|
312
|
+
let payload;
|
|
313
|
+
if (jwks) payload = await verifySessionCookieJwtWithJwks(sessionData, jwks, {
|
|
314
|
+
issuer: config?.jwt?.issuer,
|
|
315
|
+
audience: config?.jwt?.audience
|
|
316
|
+
});
|
|
317
|
+
else {
|
|
318
|
+
const secret = config?.secret || env.BETTER_AUTH_SECRET;
|
|
319
|
+
if (!secret) throw new BetterAuthError("getCookieCache requires a secret to be provided. Either pass it as an option or set the BETTER_AUTH_SECRET environment variable");
|
|
320
|
+
payload = parseCookieCachePayload(await verifyJWT(sessionData, secret));
|
|
321
|
+
}
|
|
322
|
+
if (!payload) return null;
|
|
323
|
+
if (config?.version) {
|
|
324
|
+
if (!await matchesVersion(payload, config.version)) return null;
|
|
325
|
+
}
|
|
326
|
+
if (isEmbeddedSessionExpired(payload.session)) return null;
|
|
327
|
+
return payload;
|
|
328
|
+
} else {
|
|
329
|
+
const secret = config?.secret || env.BETTER_AUTH_SECRET;
|
|
330
|
+
if (!secret) throw new BetterAuthError("getCookieCache requires a secret to be provided. Either pass it as an option or set the BETTER_AUTH_SECRET environment variable");
|
|
331
|
+
const sessionDataPayload = parseCompactCookieCache(safeJSONParse(binary.decode(base64Url.decode(sessionData))));
|
|
332
|
+
if (!sessionDataPayload) return null;
|
|
333
|
+
if (!await createHMAC("SHA-256", "base64urlnopad").verify(secret, JSON.stringify({
|
|
334
|
+
...sessionDataPayload.session,
|
|
335
|
+
expiresAt: sessionDataPayload.expiresAt
|
|
336
|
+
}), sessionDataPayload.signature)) return null;
|
|
337
|
+
const payload = parseCookieCachePayload(sessionDataPayload.session);
|
|
338
|
+
if (!payload) return null;
|
|
339
|
+
if (config?.version) {
|
|
340
|
+
if (!await matchesVersion(payload, config.version)) return null;
|
|
341
|
+
}
|
|
342
|
+
if (typeof sessionDataPayload.expiresAt === "number" && sessionDataPayload.expiresAt < Date.now()) return null;
|
|
343
|
+
if (isEmbeddedSessionExpired(payload.session)) return null;
|
|
344
|
+
return payload;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return null;
|
|
348
|
+
};
|
|
349
|
+
//#endregion
|
|
350
|
+
export { HOST_COOKIE_PREFIX, SECURE_COOKIE_PREFIX, applySetCookies, cookieNameRegex, createCookieGetter, createSessionStore, decodeCookieCache, deleteSessionCookie, expireCookie, getAccountCookie, getChunkedCookie, getCookieCache, getCookies, getSessionCookie, parseCookies, parseSetCookieHeader, setAccountCookie, setCookieCache, setCookieToHeader, setRequestCookie, setSessionCookie, splitSetCookieHeader, stripSecureCookiePrefix, toCookieOptions };
|