@hammadj/better-auth 1.5.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/_virtual/rolldown_runtime.mjs +36 -0
- package/dist/adapters/drizzle-adapter/index.d.mts +1 -0
- package/dist/adapters/drizzle-adapter/index.mjs +3 -0
- package/dist/adapters/index.d.mts +23 -0
- package/dist/adapters/index.mjs +13 -0
- package/dist/adapters/index.mjs.map +1 -0
- package/dist/adapters/kysely-adapter/index.d.mts +1 -0
- package/dist/adapters/kysely-adapter/index.mjs +3 -0
- package/dist/adapters/memory-adapter/index.d.mts +1 -0
- package/dist/adapters/memory-adapter/index.mjs +3 -0
- package/dist/adapters/mongodb-adapter/index.d.mts +1 -0
- package/dist/adapters/mongodb-adapter/index.mjs +3 -0
- package/dist/adapters/prisma-adapter/index.d.mts +1 -0
- package/dist/adapters/prisma-adapter/index.mjs +3 -0
- package/dist/api/index.d.mts +40 -0
- package/dist/api/index.mjs +205 -0
- package/dist/api/index.mjs.map +1 -0
- package/dist/api/middlewares/index.d.mts +1 -0
- package/dist/api/middlewares/index.mjs +3 -0
- package/dist/api/middlewares/origin-check.d.mts +17 -0
- package/dist/api/middlewares/origin-check.mjs +140 -0
- package/dist/api/middlewares/origin-check.mjs.map +1 -0
- package/dist/api/rate-limiter/index.mjs +177 -0
- package/dist/api/rate-limiter/index.mjs.map +1 -0
- package/dist/api/routes/account.d.mts +10 -0
- package/dist/api/routes/account.mjs +493 -0
- package/dist/api/routes/account.mjs.map +1 -0
- package/dist/api/routes/callback.d.mts +5 -0
- package/dist/api/routes/callback.mjs +178 -0
- package/dist/api/routes/callback.mjs.map +1 -0
- package/dist/api/routes/email-verification.d.mts +29 -0
- package/dist/api/routes/email-verification.mjs +301 -0
- package/dist/api/routes/email-verification.mjs.map +1 -0
- package/dist/api/routes/error.d.mts +5 -0
- package/dist/api/routes/error.mjs +386 -0
- package/dist/api/routes/error.mjs.map +1 -0
- package/dist/api/routes/index.d.mts +11 -0
- package/dist/api/routes/index.mjs +13 -0
- package/dist/api/routes/ok.d.mts +5 -0
- package/dist/api/routes/ok.mjs +30 -0
- package/dist/api/routes/ok.mjs.map +1 -0
- package/dist/api/routes/password.d.mts +8 -0
- package/dist/api/routes/password.mjs +198 -0
- package/dist/api/routes/password.mjs.map +1 -0
- package/dist/api/routes/session.d.mts +52 -0
- package/dist/api/routes/session.mjs +478 -0
- package/dist/api/routes/session.mjs.map +1 -0
- package/dist/api/routes/sign-in.d.mts +8 -0
- package/dist/api/routes/sign-in.mjs +262 -0
- package/dist/api/routes/sign-in.mjs.map +1 -0
- package/dist/api/routes/sign-out.d.mts +5 -0
- package/dist/api/routes/sign-out.mjs +33 -0
- package/dist/api/routes/sign-out.mjs.map +1 -0
- package/dist/api/routes/sign-up.d.mts +7 -0
- package/dist/api/routes/sign-up.mjs +227 -0
- package/dist/api/routes/sign-up.mjs.map +1 -0
- package/dist/api/routes/update-user.d.mts +12 -0
- package/dist/api/routes/update-user.mjs +493 -0
- package/dist/api/routes/update-user.mjs.map +1 -0
- package/dist/api/state/oauth.d.mts +5 -0
- package/dist/api/state/oauth.mjs +8 -0
- package/dist/api/state/oauth.mjs.map +1 -0
- package/dist/api/state/should-session-refresh.d.mts +13 -0
- package/dist/api/state/should-session-refresh.mjs +16 -0
- package/dist/api/state/should-session-refresh.mjs.map +1 -0
- package/dist/api/to-auth-endpoints.mjs +197 -0
- package/dist/api/to-auth-endpoints.mjs.map +1 -0
- package/dist/auth/base.mjs +44 -0
- package/dist/auth/base.mjs.map +1 -0
- package/dist/auth/full.d.mts +30 -0
- package/dist/auth/full.mjs +32 -0
- package/dist/auth/full.mjs.map +1 -0
- package/dist/auth/minimal.d.mts +12 -0
- package/dist/auth/minimal.mjs +14 -0
- package/dist/auth/minimal.mjs.map +1 -0
- package/dist/auth/trusted-origins.mjs +31 -0
- package/dist/auth/trusted-origins.mjs.map +1 -0
- package/dist/client/broadcast-channel.d.mts +20 -0
- package/dist/client/broadcast-channel.mjs +46 -0
- package/dist/client/broadcast-channel.mjs.map +1 -0
- package/dist/client/config.mjs +90 -0
- package/dist/client/config.mjs.map +1 -0
- package/dist/client/fetch-plugins.mjs +18 -0
- package/dist/client/fetch-plugins.mjs.map +1 -0
- package/dist/client/focus-manager.d.mts +11 -0
- package/dist/client/focus-manager.mjs +32 -0
- package/dist/client/focus-manager.mjs.map +1 -0
- package/dist/client/index.d.mts +30 -0
- package/dist/client/index.mjs +21 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/client/lynx/index.d.mts +62 -0
- package/dist/client/lynx/index.mjs +24 -0
- package/dist/client/lynx/index.mjs.map +1 -0
- package/dist/client/lynx/lynx-store.d.mts +47 -0
- package/dist/client/lynx/lynx-store.mjs +47 -0
- package/dist/client/lynx/lynx-store.mjs.map +1 -0
- package/dist/client/online-manager.d.mts +12 -0
- package/dist/client/online-manager.mjs +35 -0
- package/dist/client/online-manager.mjs.map +1 -0
- package/dist/client/parser.mjs +73 -0
- package/dist/client/parser.mjs.map +1 -0
- package/dist/client/path-to-object.d.mts +57 -0
- package/dist/client/plugins/index.d.mts +58 -0
- package/dist/client/plugins/index.mjs +33 -0
- package/dist/client/plugins/infer-plugin.d.mts +9 -0
- package/dist/client/plugins/infer-plugin.mjs +11 -0
- package/dist/client/plugins/infer-plugin.mjs.map +1 -0
- package/dist/client/proxy.mjs +79 -0
- package/dist/client/proxy.mjs.map +1 -0
- package/dist/client/query.d.mts +23 -0
- package/dist/client/query.mjs +98 -0
- package/dist/client/query.mjs.map +1 -0
- package/dist/client/react/index.d.mts +63 -0
- package/dist/client/react/index.mjs +24 -0
- package/dist/client/react/index.mjs.map +1 -0
- package/dist/client/react/react-store.d.mts +47 -0
- package/dist/client/react/react-store.mjs +47 -0
- package/dist/client/react/react-store.mjs.map +1 -0
- package/dist/client/session-atom.mjs +29 -0
- package/dist/client/session-atom.mjs.map +1 -0
- package/dist/client/session-refresh.d.mts +28 -0
- package/dist/client/session-refresh.mjs +140 -0
- package/dist/client/session-refresh.mjs.map +1 -0
- package/dist/client/solid/index.d.mts +57 -0
- package/dist/client/solid/index.mjs +22 -0
- package/dist/client/solid/index.mjs.map +1 -0
- package/dist/client/solid/solid-store.mjs +24 -0
- package/dist/client/solid/solid-store.mjs.map +1 -0
- package/dist/client/svelte/index.d.mts +63 -0
- package/dist/client/svelte/index.mjs +20 -0
- package/dist/client/svelte/index.mjs.map +1 -0
- package/dist/client/types.d.mts +58 -0
- package/dist/client/vanilla.d.mts +62 -0
- package/dist/client/vanilla.mjs +20 -0
- package/dist/client/vanilla.mjs.map +1 -0
- package/dist/client/vue/index.d.mts +86 -0
- package/dist/client/vue/index.mjs +38 -0
- package/dist/client/vue/index.mjs.map +1 -0
- package/dist/client/vue/vue-store.mjs +26 -0
- package/dist/client/vue/vue-store.mjs.map +1 -0
- package/dist/context/create-context.mjs +211 -0
- package/dist/context/create-context.mjs.map +1 -0
- package/dist/context/helpers.mjs +62 -0
- package/dist/context/helpers.mjs.map +1 -0
- package/dist/context/init-minimal.mjs +20 -0
- package/dist/context/init-minimal.mjs.map +1 -0
- package/dist/context/init.mjs +22 -0
- package/dist/context/init.mjs.map +1 -0
- package/dist/cookies/cookie-utils.d.mts +29 -0
- package/dist/cookies/cookie-utils.mjs +105 -0
- package/dist/cookies/cookie-utils.mjs.map +1 -0
- package/dist/cookies/index.d.mts +67 -0
- package/dist/cookies/index.mjs +264 -0
- package/dist/cookies/index.mjs.map +1 -0
- package/dist/cookies/session-store.d.mts +36 -0
- package/dist/cookies/session-store.mjs +200 -0
- package/dist/cookies/session-store.mjs.map +1 -0
- package/dist/crypto/buffer.d.mts +8 -0
- package/dist/crypto/buffer.mjs +18 -0
- package/dist/crypto/buffer.mjs.map +1 -0
- package/dist/crypto/index.d.mts +27 -0
- package/dist/crypto/index.mjs +38 -0
- package/dist/crypto/index.mjs.map +1 -0
- package/dist/crypto/jwt.d.mts +8 -0
- package/dist/crypto/jwt.mjs +95 -0
- package/dist/crypto/jwt.mjs.map +1 -0
- package/dist/crypto/password.d.mts +12 -0
- package/dist/crypto/password.mjs +36 -0
- package/dist/crypto/password.mjs.map +1 -0
- package/dist/crypto/random.d.mts +5 -0
- package/dist/crypto/random.mjs +8 -0
- package/dist/crypto/random.mjs.map +1 -0
- package/dist/db/adapter-base.d.mts +8 -0
- package/dist/db/adapter-base.mjs +28 -0
- package/dist/db/adapter-base.mjs.map +1 -0
- package/dist/db/adapter-kysely.d.mts +8 -0
- package/dist/db/adapter-kysely.mjs +21 -0
- package/dist/db/adapter-kysely.mjs.map +1 -0
- package/dist/db/field-converter.d.mts +8 -0
- package/dist/db/field-converter.mjs +21 -0
- package/dist/db/field-converter.mjs.map +1 -0
- package/dist/db/field.d.mts +55 -0
- package/dist/db/field.mjs +11 -0
- package/dist/db/field.mjs.map +1 -0
- package/dist/db/get-migration.d.mts +23 -0
- package/dist/db/get-migration.mjs +339 -0
- package/dist/db/get-migration.mjs.map +1 -0
- package/dist/db/get-schema.d.mts +11 -0
- package/dist/db/get-schema.mjs +39 -0
- package/dist/db/get-schema.mjs.map +1 -0
- package/dist/db/index.d.mts +9 -0
- package/dist/db/index.mjs +36 -0
- package/dist/db/index.mjs.map +1 -0
- package/dist/db/internal-adapter.d.mts +14 -0
- package/dist/db/internal-adapter.mjs +616 -0
- package/dist/db/internal-adapter.mjs.map +1 -0
- package/dist/db/schema.d.mts +26 -0
- package/dist/db/schema.mjs +118 -0
- package/dist/db/schema.mjs.map +1 -0
- package/dist/db/to-zod.d.mts +36 -0
- package/dist/db/to-zod.mjs +26 -0
- package/dist/db/to-zod.mjs.map +1 -0
- package/dist/db/verification-token-storage.mjs +28 -0
- package/dist/db/verification-token-storage.mjs.map +1 -0
- package/dist/db/with-hooks.d.mts +33 -0
- package/dist/db/with-hooks.mjs +159 -0
- package/dist/db/with-hooks.mjs.map +1 -0
- package/dist/index.d.mts +52 -0
- package/dist/index.mjs +26 -0
- package/dist/integrations/next-js.d.mts +14 -0
- package/dist/integrations/next-js.mjs +78 -0
- package/dist/integrations/next-js.mjs.map +1 -0
- package/dist/integrations/node.d.mts +13 -0
- package/dist/integrations/node.mjs +16 -0
- package/dist/integrations/node.mjs.map +1 -0
- package/dist/integrations/solid-start.d.mts +23 -0
- package/dist/integrations/solid-start.mjs +17 -0
- package/dist/integrations/solid-start.mjs.map +1 -0
- package/dist/integrations/svelte-kit.d.mts +29 -0
- package/dist/integrations/svelte-kit.mjs +57 -0
- package/dist/integrations/svelte-kit.mjs.map +1 -0
- package/dist/integrations/tanstack-start-solid.d.mts +22 -0
- package/dist/integrations/tanstack-start-solid.mjs +61 -0
- package/dist/integrations/tanstack-start-solid.mjs.map +1 -0
- package/dist/integrations/tanstack-start.d.mts +22 -0
- package/dist/integrations/tanstack-start.mjs +61 -0
- package/dist/integrations/tanstack-start.mjs.map +1 -0
- package/dist/oauth2/index.d.mts +5 -0
- package/dist/oauth2/index.mjs +7 -0
- package/dist/oauth2/link-account.d.mts +31 -0
- package/dist/oauth2/link-account.mjs +144 -0
- package/dist/oauth2/link-account.mjs.map +1 -0
- package/dist/oauth2/state.d.mts +26 -0
- package/dist/oauth2/state.mjs +51 -0
- package/dist/oauth2/state.mjs.map +1 -0
- package/dist/oauth2/utils.d.mts +8 -0
- package/dist/oauth2/utils.mjs +31 -0
- package/dist/oauth2/utils.mjs.map +1 -0
- package/dist/plugins/access/access.d.mts +30 -0
- package/dist/plugins/access/access.mjs +46 -0
- package/dist/plugins/access/access.mjs.map +1 -0
- package/dist/plugins/access/index.d.mts +3 -0
- package/dist/plugins/access/index.mjs +3 -0
- package/dist/plugins/access/types.d.mts +17 -0
- package/dist/plugins/additional-fields/client.d.mts +14 -0
- package/dist/plugins/additional-fields/client.mjs +11 -0
- package/dist/plugins/additional-fields/client.mjs.map +1 -0
- package/dist/plugins/admin/access/index.d.mts +2 -0
- package/dist/plugins/admin/access/index.mjs +3 -0
- package/dist/plugins/admin/access/statement.d.mts +118 -0
- package/dist/plugins/admin/access/statement.mjs +53 -0
- package/dist/plugins/admin/access/statement.mjs.map +1 -0
- package/dist/plugins/admin/admin.d.mts +14 -0
- package/dist/plugins/admin/admin.mjs +95 -0
- package/dist/plugins/admin/admin.mjs.map +1 -0
- package/dist/plugins/admin/client.d.mts +14 -0
- package/dist/plugins/admin/client.mjs +36 -0
- package/dist/plugins/admin/client.mjs.map +1 -0
- package/dist/plugins/admin/error-codes.d.mts +5 -0
- package/dist/plugins/admin/error-codes.mjs +30 -0
- package/dist/plugins/admin/error-codes.mjs.map +1 -0
- package/dist/plugins/admin/has-permission.mjs +16 -0
- package/dist/plugins/admin/has-permission.mjs.map +1 -0
- package/dist/plugins/admin/index.d.mts +3 -0
- package/dist/plugins/admin/index.mjs +3 -0
- package/dist/plugins/admin/routes.mjs +855 -0
- package/dist/plugins/admin/routes.mjs.map +1 -0
- package/dist/plugins/admin/schema.d.mts +6 -0
- package/dist/plugins/admin/schema.mjs +34 -0
- package/dist/plugins/admin/schema.mjs.map +1 -0
- package/dist/plugins/admin/types.d.mts +89 -0
- package/dist/plugins/anonymous/client.d.mts +9 -0
- package/dist/plugins/anonymous/client.mjs +22 -0
- package/dist/plugins/anonymous/client.mjs.map +1 -0
- package/dist/plugins/anonymous/error-codes.d.mts +5 -0
- package/dist/plugins/anonymous/error-codes.mjs +16 -0
- package/dist/plugins/anonymous/error-codes.mjs.map +1 -0
- package/dist/plugins/anonymous/index.d.mts +14 -0
- package/dist/plugins/anonymous/index.mjs +163 -0
- package/dist/plugins/anonymous/index.mjs.map +1 -0
- package/dist/plugins/anonymous/schema.d.mts +5 -0
- package/dist/plugins/anonymous/schema.mjs +11 -0
- package/dist/plugins/anonymous/schema.mjs.map +1 -0
- package/dist/plugins/anonymous/types.d.mts +68 -0
- package/dist/plugins/api-key/adapter.mjs +468 -0
- package/dist/plugins/api-key/adapter.mjs.map +1 -0
- package/dist/plugins/api-key/client.d.mts +9 -0
- package/dist/plugins/api-key/client.mjs +19 -0
- package/dist/plugins/api-key/client.mjs.map +1 -0
- package/dist/plugins/api-key/error-codes.d.mts +5 -0
- package/dist/plugins/api-key/error-codes.mjs +34 -0
- package/dist/plugins/api-key/error-codes.mjs.map +1 -0
- package/dist/plugins/api-key/index.d.mts +17 -0
- package/dist/plugins/api-key/index.mjs +134 -0
- package/dist/plugins/api-key/index.mjs.map +1 -0
- package/dist/plugins/api-key/rate-limit.mjs +74 -0
- package/dist/plugins/api-key/rate-limit.mjs.map +1 -0
- package/dist/plugins/api-key/routes/create-api-key.mjs +252 -0
- package/dist/plugins/api-key/routes/create-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/routes/delete-all-expired-api-keys.mjs +24 -0
- package/dist/plugins/api-key/routes/delete-all-expired-api-keys.mjs.map +1 -0
- package/dist/plugins/api-key/routes/delete-api-key.mjs +74 -0
- package/dist/plugins/api-key/routes/delete-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/routes/get-api-key.mjs +158 -0
- package/dist/plugins/api-key/routes/get-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/routes/index.mjs +71 -0
- package/dist/plugins/api-key/routes/index.mjs.map +1 -0
- package/dist/plugins/api-key/routes/list-api-keys.mjs +194 -0
- package/dist/plugins/api-key/routes/list-api-keys.mjs.map +1 -0
- package/dist/plugins/api-key/routes/update-api-key.mjs +248 -0
- package/dist/plugins/api-key/routes/update-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/routes/verify-api-key.mjs +223 -0
- package/dist/plugins/api-key/routes/verify-api-key.mjs.map +1 -0
- package/dist/plugins/api-key/schema.d.mts +11 -0
- package/dist/plugins/api-key/schema.mjs +130 -0
- package/dist/plugins/api-key/schema.mjs.map +1 -0
- package/dist/plugins/api-key/types.d.mts +346 -0
- package/dist/plugins/bearer/index.d.mts +25 -0
- package/dist/plugins/bearer/index.mjs +66 -0
- package/dist/plugins/bearer/index.mjs.map +1 -0
- package/dist/plugins/captcha/constants.d.mts +10 -0
- package/dist/plugins/captcha/constants.mjs +22 -0
- package/dist/plugins/captcha/constants.mjs.map +1 -0
- package/dist/plugins/captcha/error-codes.mjs +16 -0
- package/dist/plugins/captcha/error-codes.mjs.map +1 -0
- package/dist/plugins/captcha/index.d.mts +14 -0
- package/dist/plugins/captcha/index.mjs +60 -0
- package/dist/plugins/captcha/index.mjs.map +1 -0
- package/dist/plugins/captcha/types.d.mts +28 -0
- package/dist/plugins/captcha/utils.mjs +11 -0
- package/dist/plugins/captcha/utils.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/captchafox.mjs +27 -0
- package/dist/plugins/captcha/verify-handlers/captchafox.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +25 -0
- package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +29 -0
- package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +27 -0
- package/dist/plugins/captcha/verify-handlers/h-captcha.mjs.map +1 -0
- package/dist/plugins/captcha/verify-handlers/index.mjs +6 -0
- package/dist/plugins/custom-session/client.d.mts +10 -0
- package/dist/plugins/custom-session/client.mjs +11 -0
- package/dist/plugins/custom-session/client.mjs.map +1 -0
- package/dist/plugins/custom-session/index.d.mts +26 -0
- package/dist/plugins/custom-session/index.mjs +70 -0
- package/dist/plugins/custom-session/index.mjs.map +1 -0
- package/dist/plugins/device-authorization/client.d.mts +5 -0
- package/dist/plugins/device-authorization/client.mjs +18 -0
- package/dist/plugins/device-authorization/client.mjs.map +1 -0
- package/dist/plugins/device-authorization/error-codes.mjs +21 -0
- package/dist/plugins/device-authorization/error-codes.mjs.map +1 -0
- package/dist/plugins/device-authorization/index.d.mts +28 -0
- package/dist/plugins/device-authorization/index.mjs +50 -0
- package/dist/plugins/device-authorization/index.mjs.map +1 -0
- package/dist/plugins/device-authorization/routes.mjs +510 -0
- package/dist/plugins/device-authorization/routes.mjs.map +1 -0
- package/dist/plugins/device-authorization/schema.mjs +57 -0
- package/dist/plugins/device-authorization/schema.mjs.map +1 -0
- package/dist/plugins/email-otp/client.d.mts +7 -0
- package/dist/plugins/email-otp/client.mjs +18 -0
- package/dist/plugins/email-otp/client.mjs.map +1 -0
- package/dist/plugins/email-otp/error-codes.d.mts +5 -0
- package/dist/plugins/email-otp/error-codes.mjs +12 -0
- package/dist/plugins/email-otp/error-codes.mjs.map +1 -0
- package/dist/plugins/email-otp/index.d.mts +14 -0
- package/dist/plugins/email-otp/index.mjs +108 -0
- package/dist/plugins/email-otp/index.mjs.map +1 -0
- package/dist/plugins/email-otp/otp-token.mjs +29 -0
- package/dist/plugins/email-otp/otp-token.mjs.map +1 -0
- package/dist/plugins/email-otp/routes.mjs +564 -0
- package/dist/plugins/email-otp/routes.mjs.map +1 -0
- package/dist/plugins/email-otp/types.d.mts +74 -0
- package/dist/plugins/email-otp/utils.mjs +17 -0
- package/dist/plugins/email-otp/utils.mjs.map +1 -0
- package/dist/plugins/generic-oauth/client.d.mts +19 -0
- package/dist/plugins/generic-oauth/client.mjs +14 -0
- package/dist/plugins/generic-oauth/client.mjs.map +1 -0
- package/dist/plugins/generic-oauth/error-codes.d.mts +5 -0
- package/dist/plugins/generic-oauth/error-codes.mjs +15 -0
- package/dist/plugins/generic-oauth/error-codes.mjs.map +1 -0
- package/dist/plugins/generic-oauth/index.d.mts +34 -0
- package/dist/plugins/generic-oauth/index.mjs +137 -0
- package/dist/plugins/generic-oauth/index.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/auth0.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/auth0.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/auth0.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/gumroad.d.mts +32 -0
- package/dist/plugins/generic-oauth/providers/gumroad.mjs +60 -0
- package/dist/plugins/generic-oauth/providers/gumroad.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/hubspot.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/hubspot.mjs +60 -0
- package/dist/plugins/generic-oauth/providers/hubspot.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/index.d.mts +9 -0
- package/dist/plugins/generic-oauth/providers/index.mjs +11 -0
- package/dist/plugins/generic-oauth/providers/keycloak.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/keycloak.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/keycloak.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/line.d.mts +55 -0
- package/dist/plugins/generic-oauth/providers/line.mjs +91 -0
- package/dist/plugins/generic-oauth/providers/line.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +66 -0
- package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/okta.d.mts +37 -0
- package/dist/plugins/generic-oauth/providers/okta.mjs +62 -0
- package/dist/plugins/generic-oauth/providers/okta.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/patreon.d.mts +30 -0
- package/dist/plugins/generic-oauth/providers/patreon.mjs +59 -0
- package/dist/plugins/generic-oauth/providers/patreon.mjs.map +1 -0
- package/dist/plugins/generic-oauth/providers/slack.d.mts +30 -0
- package/dist/plugins/generic-oauth/providers/slack.mjs +61 -0
- package/dist/plugins/generic-oauth/providers/slack.mjs.map +1 -0
- package/dist/plugins/generic-oauth/routes.mjs +394 -0
- package/dist/plugins/generic-oauth/routes.mjs.map +1 -0
- package/dist/plugins/generic-oauth/types.d.mts +145 -0
- package/dist/plugins/haveibeenpwned/index.d.mts +21 -0
- package/dist/plugins/haveibeenpwned/index.mjs +56 -0
- package/dist/plugins/haveibeenpwned/index.mjs.map +1 -0
- package/dist/plugins/index.d.mts +68 -0
- package/dist/plugins/index.mjs +51 -0
- package/dist/plugins/jwt/adapter.mjs +27 -0
- package/dist/plugins/jwt/adapter.mjs.map +1 -0
- package/dist/plugins/jwt/client.d.mts +18 -0
- package/dist/plugins/jwt/client.mjs +19 -0
- package/dist/plugins/jwt/client.mjs.map +1 -0
- package/dist/plugins/jwt/index.d.mts +17 -0
- package/dist/plugins/jwt/index.mjs +202 -0
- package/dist/plugins/jwt/index.mjs.map +1 -0
- package/dist/plugins/jwt/schema.d.mts +5 -0
- package/dist/plugins/jwt/schema.mjs +23 -0
- package/dist/plugins/jwt/schema.mjs.map +1 -0
- package/dist/plugins/jwt/sign.d.mts +57 -0
- package/dist/plugins/jwt/sign.mjs +66 -0
- package/dist/plugins/jwt/sign.mjs.map +1 -0
- package/dist/plugins/jwt/types.d.mts +194 -0
- package/dist/plugins/jwt/utils.d.mts +42 -0
- package/dist/plugins/jwt/utils.mjs +64 -0
- package/dist/plugins/jwt/utils.mjs.map +1 -0
- package/dist/plugins/jwt/verify.d.mts +12 -0
- package/dist/plugins/jwt/verify.mjs +46 -0
- package/dist/plugins/jwt/verify.mjs.map +1 -0
- package/dist/plugins/last-login-method/client.d.mts +18 -0
- package/dist/plugins/last-login-method/client.mjs +32 -0
- package/dist/plugins/last-login-method/client.mjs.map +1 -0
- package/dist/plugins/last-login-method/index.d.mts +52 -0
- package/dist/plugins/last-login-method/index.mjs +77 -0
- package/dist/plugins/last-login-method/index.mjs.map +1 -0
- package/dist/plugins/magic-link/client.d.mts +5 -0
- package/dist/plugins/magic-link/client.mjs +11 -0
- package/dist/plugins/magic-link/client.mjs.map +1 -0
- package/dist/plugins/magic-link/index.d.mts +61 -0
- package/dist/plugins/magic-link/index.mjs +167 -0
- package/dist/plugins/magic-link/index.mjs.map +1 -0
- package/dist/plugins/magic-link/utils.mjs +12 -0
- package/dist/plugins/magic-link/utils.mjs.map +1 -0
- package/dist/plugins/mcp/authorize.mjs +133 -0
- package/dist/plugins/mcp/authorize.mjs.map +1 -0
- package/dist/plugins/mcp/index.d.mts +46 -0
- package/dist/plugins/mcp/index.mjs +717 -0
- package/dist/plugins/mcp/index.mjs.map +1 -0
- package/dist/plugins/multi-session/client.d.mts +8 -0
- package/dist/plugins/multi-session/client.mjs +20 -0
- package/dist/plugins/multi-session/client.mjs.map +1 -0
- package/dist/plugins/multi-session/error-codes.d.mts +5 -0
- package/dist/plugins/multi-session/error-codes.mjs +8 -0
- package/dist/plugins/multi-session/error-codes.mjs.map +1 -0
- package/dist/plugins/multi-session/index.d.mts +22 -0
- package/dist/plugins/multi-session/index.mjs +172 -0
- package/dist/plugins/multi-session/index.mjs.map +1 -0
- package/dist/plugins/oauth-proxy/index.d.mts +39 -0
- package/dist/plugins/oauth-proxy/index.mjs +305 -0
- package/dist/plugins/oauth-proxy/index.mjs.map +1 -0
- package/dist/plugins/oauth-proxy/utils.mjs +44 -0
- package/dist/plugins/oauth-proxy/utils.mjs.map +1 -0
- package/dist/plugins/oidc-provider/authorize.mjs +194 -0
- package/dist/plugins/oidc-provider/authorize.mjs.map +1 -0
- package/dist/plugins/oidc-provider/client.d.mts +8 -0
- package/dist/plugins/oidc-provider/client.mjs +11 -0
- package/dist/plugins/oidc-provider/client.mjs.map +1 -0
- package/dist/plugins/oidc-provider/error.mjs +17 -0
- package/dist/plugins/oidc-provider/error.mjs.map +1 -0
- package/dist/plugins/oidc-provider/index.d.mts +32 -0
- package/dist/plugins/oidc-provider/index.mjs +1093 -0
- package/dist/plugins/oidc-provider/index.mjs.map +1 -0
- package/dist/plugins/oidc-provider/schema.d.mts +26 -0
- package/dist/plugins/oidc-provider/schema.mjs +132 -0
- package/dist/plugins/oidc-provider/schema.mjs.map +1 -0
- package/dist/plugins/oidc-provider/types.d.mts +517 -0
- package/dist/plugins/oidc-provider/utils/prompt.mjs +19 -0
- package/dist/plugins/oidc-provider/utils/prompt.mjs.map +1 -0
- package/dist/plugins/oidc-provider/utils.mjs +15 -0
- package/dist/plugins/oidc-provider/utils.mjs.map +1 -0
- package/dist/plugins/one-tap/client.d.mts +159 -0
- package/dist/plugins/one-tap/client.mjs +214 -0
- package/dist/plugins/one-tap/client.mjs.map +1 -0
- package/dist/plugins/one-tap/index.d.mts +27 -0
- package/dist/plugins/one-tap/index.mjs +96 -0
- package/dist/plugins/one-tap/index.mjs.map +1 -0
- package/dist/plugins/one-time-token/client.d.mts +7 -0
- package/dist/plugins/one-time-token/client.mjs +11 -0
- package/dist/plugins/one-time-token/client.mjs.map +1 -0
- package/dist/plugins/one-time-token/index.d.mts +53 -0
- package/dist/plugins/one-time-token/index.mjs +82 -0
- package/dist/plugins/one-time-token/index.mjs.map +1 -0
- package/dist/plugins/one-time-token/utils.mjs +12 -0
- package/dist/plugins/one-time-token/utils.mjs.map +1 -0
- package/dist/plugins/open-api/generator.d.mts +115 -0
- package/dist/plugins/open-api/generator.mjs +315 -0
- package/dist/plugins/open-api/generator.mjs.map +1 -0
- package/dist/plugins/open-api/index.d.mts +45 -0
- package/dist/plugins/open-api/index.mjs +67 -0
- package/dist/plugins/open-api/index.mjs.map +1 -0
- package/dist/plugins/open-api/logo.mjs +15 -0
- package/dist/plugins/open-api/logo.mjs.map +1 -0
- package/dist/plugins/organization/access/index.d.mts +2 -0
- package/dist/plugins/organization/access/index.mjs +3 -0
- package/dist/plugins/organization/access/statement.d.mts +249 -0
- package/dist/plugins/organization/access/statement.mjs +81 -0
- package/dist/plugins/organization/access/statement.mjs.map +1 -0
- package/dist/plugins/organization/adapter.d.mts +205 -0
- package/dist/plugins/organization/adapter.mjs +624 -0
- package/dist/plugins/organization/adapter.mjs.map +1 -0
- package/dist/plugins/organization/call.mjs +19 -0
- package/dist/plugins/organization/call.mjs.map +1 -0
- package/dist/plugins/organization/client.d.mts +151 -0
- package/dist/plugins/organization/client.mjs +107 -0
- package/dist/plugins/organization/client.mjs.map +1 -0
- package/dist/plugins/organization/error-codes.d.mts +5 -0
- package/dist/plugins/organization/error-codes.mjs +65 -0
- package/dist/plugins/organization/error-codes.mjs.map +1 -0
- package/dist/plugins/organization/has-permission.mjs +35 -0
- package/dist/plugins/organization/has-permission.mjs.map +1 -0
- package/dist/plugins/organization/index.d.mts +5 -0
- package/dist/plugins/organization/index.mjs +4 -0
- package/dist/plugins/organization/organization.d.mts +252 -0
- package/dist/plugins/organization/organization.mjs +428 -0
- package/dist/plugins/organization/organization.mjs.map +1 -0
- package/dist/plugins/organization/permission.d.mts +26 -0
- package/dist/plugins/organization/permission.mjs +16 -0
- package/dist/plugins/organization/permission.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-access-control.d.mts +11 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs +656 -0
- package/dist/plugins/organization/routes/crud-access-control.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-invites.d.mts +16 -0
- package/dist/plugins/organization/routes/crud-invites.mjs +555 -0
- package/dist/plugins/organization/routes/crud-invites.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-members.d.mts +13 -0
- package/dist/plugins/organization/routes/crud-members.mjs +473 -0
- package/dist/plugins/organization/routes/crud-members.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-org.d.mts +13 -0
- package/dist/plugins/organization/routes/crud-org.mjs +447 -0
- package/dist/plugins/organization/routes/crud-org.mjs.map +1 -0
- package/dist/plugins/organization/routes/crud-team.d.mts +15 -0
- package/dist/plugins/organization/routes/crud-team.mjs +676 -0
- package/dist/plugins/organization/routes/crud-team.mjs.map +1 -0
- package/dist/plugins/organization/schema.d.mts +376 -0
- package/dist/plugins/organization/schema.mjs +68 -0
- package/dist/plugins/organization/schema.mjs.map +1 -0
- package/dist/plugins/organization/types.d.mts +733 -0
- package/dist/plugins/phone-number/client.d.mts +8 -0
- package/dist/plugins/phone-number/client.mjs +20 -0
- package/dist/plugins/phone-number/client.mjs.map +1 -0
- package/dist/plugins/phone-number/error-codes.d.mts +5 -0
- package/dist/plugins/phone-number/error-codes.mjs +21 -0
- package/dist/plugins/phone-number/error-codes.mjs.map +1 -0
- package/dist/plugins/phone-number/index.d.mts +14 -0
- package/dist/plugins/phone-number/index.mjs +49 -0
- package/dist/plugins/phone-number/index.mjs.map +1 -0
- package/dist/plugins/phone-number/routes.mjs +459 -0
- package/dist/plugins/phone-number/routes.mjs.map +1 -0
- package/dist/plugins/phone-number/schema.d.mts +5 -0
- package/dist/plugins/phone-number/schema.mjs +20 -0
- package/dist/plugins/phone-number/schema.mjs.map +1 -0
- package/dist/plugins/phone-number/types.d.mts +118 -0
- package/dist/plugins/siwe/client.d.mts +5 -0
- package/dist/plugins/siwe/client.mjs +11 -0
- package/dist/plugins/siwe/client.mjs.map +1 -0
- package/dist/plugins/siwe/error-codes.mjs +13 -0
- package/dist/plugins/siwe/error-codes.mjs.map +1 -0
- package/dist/plugins/siwe/index.d.mts +26 -0
- package/dist/plugins/siwe/index.mjs +261 -0
- package/dist/plugins/siwe/index.mjs.map +1 -0
- package/dist/plugins/siwe/schema.d.mts +5 -0
- package/dist/plugins/siwe/schema.mjs +32 -0
- package/dist/plugins/siwe/schema.mjs.map +1 -0
- package/dist/plugins/siwe/types.d.mts +44 -0
- package/dist/plugins/two-factor/backup-codes/index.d.mts +91 -0
- package/dist/plugins/two-factor/backup-codes/index.mjs +277 -0
- package/dist/plugins/two-factor/backup-codes/index.mjs.map +1 -0
- package/dist/plugins/two-factor/client.d.mts +17 -0
- package/dist/plugins/two-factor/client.mjs +37 -0
- package/dist/plugins/two-factor/client.mjs.map +1 -0
- package/dist/plugins/two-factor/constant.mjs +8 -0
- package/dist/plugins/two-factor/constant.mjs.map +1 -0
- package/dist/plugins/two-factor/error-code.d.mts +5 -0
- package/dist/plugins/two-factor/error-code.mjs +18 -0
- package/dist/plugins/two-factor/error-code.mjs.map +1 -0
- package/dist/plugins/two-factor/index.d.mts +19 -0
- package/dist/plugins/two-factor/index.mjs +207 -0
- package/dist/plugins/two-factor/index.mjs.map +1 -0
- package/dist/plugins/two-factor/otp/index.d.mts +96 -0
- package/dist/plugins/two-factor/otp/index.mjs +199 -0
- package/dist/plugins/two-factor/otp/index.mjs.map +1 -0
- package/dist/plugins/two-factor/schema.d.mts +5 -0
- package/dist/plugins/two-factor/schema.mjs +36 -0
- package/dist/plugins/two-factor/schema.mjs.map +1 -0
- package/dist/plugins/two-factor/totp/index.d.mts +81 -0
- package/dist/plugins/two-factor/totp/index.mjs +157 -0
- package/dist/plugins/two-factor/totp/index.mjs.map +1 -0
- package/dist/plugins/two-factor/types.d.mts +65 -0
- package/dist/plugins/two-factor/utils.mjs +12 -0
- package/dist/plugins/two-factor/utils.mjs.map +1 -0
- package/dist/plugins/two-factor/verify-two-factor.mjs +76 -0
- package/dist/plugins/two-factor/verify-two-factor.mjs.map +1 -0
- package/dist/plugins/username/client.d.mts +7 -0
- package/dist/plugins/username/client.mjs +18 -0
- package/dist/plugins/username/client.mjs.map +1 -0
- package/dist/plugins/username/error-codes.d.mts +5 -0
- package/dist/plugins/username/error-codes.mjs +17 -0
- package/dist/plugins/username/error-codes.mjs.map +1 -0
- package/dist/plugins/username/index.d.mts +74 -0
- package/dist/plugins/username/index.mjs +237 -0
- package/dist/plugins/username/index.mjs.map +1 -0
- package/dist/plugins/username/schema.d.mts +9 -0
- package/dist/plugins/username/schema.mjs +26 -0
- package/dist/plugins/username/schema.mjs.map +1 -0
- package/dist/social-providers/index.d.mts +1 -0
- package/dist/social-providers/index.mjs +3 -0
- package/dist/state.d.mts +42 -0
- package/dist/state.mjs +107 -0
- package/dist/state.mjs.map +1 -0
- package/dist/test-utils/headers.d.mts +9 -0
- package/dist/test-utils/headers.mjs +24 -0
- package/dist/test-utils/headers.mjs.map +1 -0
- package/dist/test-utils/index.d.mts +3 -0
- package/dist/test-utils/index.mjs +4 -0
- package/dist/test-utils/test-instance.d.mts +181 -0
- package/dist/test-utils/test-instance.mjs +210 -0
- package/dist/test-utils/test-instance.mjs.map +1 -0
- package/dist/types/adapter.d.mts +24 -0
- package/dist/types/api.d.mts +62 -0
- package/dist/types/auth.d.mts +30 -0
- package/dist/types/helper.d.mts +21 -0
- package/dist/types/index.d.mts +11 -0
- package/dist/types/index.mjs +1 -0
- package/dist/types/models.d.mts +17 -0
- package/dist/types/plugins.d.mts +16 -0
- package/dist/utils/boolean.mjs +8 -0
- package/dist/utils/boolean.mjs.map +1 -0
- package/dist/utils/constants.mjs +6 -0
- package/dist/utils/constants.mjs.map +1 -0
- package/dist/utils/date.mjs +8 -0
- package/dist/utils/date.mjs.map +1 -0
- package/dist/utils/get-request-ip.d.mts +7 -0
- package/dist/utils/get-request-ip.mjs +23 -0
- package/dist/utils/get-request-ip.mjs.map +1 -0
- package/dist/utils/hashing.mjs +21 -0
- package/dist/utils/hashing.mjs.map +1 -0
- package/dist/utils/hide-metadata.d.mts +7 -0
- package/dist/utils/hide-metadata.mjs +6 -0
- package/dist/utils/hide-metadata.mjs.map +1 -0
- package/dist/utils/index.d.mts +3 -0
- package/dist/utils/index.mjs +5 -0
- package/dist/utils/is-api-error.d.mts +7 -0
- package/dist/utils/is-api-error.mjs +11 -0
- package/dist/utils/is-api-error.mjs.map +1 -0
- package/dist/utils/is-atom.mjs +8 -0
- package/dist/utils/is-atom.mjs.map +1 -0
- package/dist/utils/is-promise.mjs +8 -0
- package/dist/utils/is-promise.mjs.map +1 -0
- package/dist/utils/middleware-response.mjs +6 -0
- package/dist/utils/middleware-response.mjs.map +1 -0
- package/dist/utils/password.mjs +26 -0
- package/dist/utils/password.mjs.map +1 -0
- package/dist/utils/plugin-helper.mjs +17 -0
- package/dist/utils/plugin-helper.mjs.map +1 -0
- package/dist/utils/shim.mjs +24 -0
- package/dist/utils/shim.mjs.map +1 -0
- package/dist/utils/time.d.mts +49 -0
- package/dist/utils/time.mjs +100 -0
- package/dist/utils/time.mjs.map +1 -0
- package/dist/utils/url.mjs +92 -0
- package/dist/utils/url.mjs.map +1 -0
- package/dist/utils/wildcard.mjs +108 -0
- package/dist/utils/wildcard.mjs.map +1 -0
- package/package.json +601 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { ClientFetchOption } from "@better-auth/core";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/one-tap/client.d.ts
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
googleScriptInitialized?: boolean | undefined;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
interface GsiButtonConfiguration {
|
|
10
|
+
/**
|
|
11
|
+
* The button type: icon, or standard button.
|
|
12
|
+
*/
|
|
13
|
+
type: "standard" | "icon";
|
|
14
|
+
/**
|
|
15
|
+
* The button theme. For example, filled_blue or filled_black.
|
|
16
|
+
* outline A standard button theme:
|
|
17
|
+
* filled_blue A blue-filled button theme:
|
|
18
|
+
* filled_black A black-filled button theme:
|
|
19
|
+
*/
|
|
20
|
+
theme?: "outline" | "filled_blue" | "filled_black";
|
|
21
|
+
/**
|
|
22
|
+
* The button size. For example, small or large.
|
|
23
|
+
*/
|
|
24
|
+
size?: "small" | "medium" | "large";
|
|
25
|
+
/**
|
|
26
|
+
* The button text. The default value is signin_with.
|
|
27
|
+
* There are no visual differences for the text of icon buttons that
|
|
28
|
+
* have different text attributes. The only exception is when the
|
|
29
|
+
* text is read for screen accessibility.
|
|
30
|
+
*
|
|
31
|
+
* signin_with The button text is “Sign in with Google”:
|
|
32
|
+
* signup_with The button text is “Sign up with Google”:
|
|
33
|
+
* continue_with The button text is “Continue with Google”:
|
|
34
|
+
* signup_with The button text is “Sign in”:
|
|
35
|
+
*/
|
|
36
|
+
text?: "signin_with" | "signup_with" | "continue_with" | "signin";
|
|
37
|
+
/**
|
|
38
|
+
* The button shape. The default value is rectangular.
|
|
39
|
+
*/
|
|
40
|
+
shape?: "rectangular" | "pill" | "circle" | "square";
|
|
41
|
+
/**
|
|
42
|
+
* The alignment of the Google logo. The default value is left.
|
|
43
|
+
* This attribute only applies to the standard button type.
|
|
44
|
+
*/
|
|
45
|
+
logo_alignment?: "left" | "center";
|
|
46
|
+
/**
|
|
47
|
+
* The minimum button width, in pixels. The maximum width is 400
|
|
48
|
+
* pixels.
|
|
49
|
+
*/
|
|
50
|
+
width?: number;
|
|
51
|
+
/**
|
|
52
|
+
* The pre-set locale of the button text. If it's not set, the
|
|
53
|
+
* browser's default locale or the Google session user’s preference
|
|
54
|
+
* is used.
|
|
55
|
+
*/
|
|
56
|
+
locale?: string;
|
|
57
|
+
/**
|
|
58
|
+
* You can define a JavaScript function to be called when the
|
|
59
|
+
* Sign in with Google button is clicked.
|
|
60
|
+
*/
|
|
61
|
+
click_listener?: () => void;
|
|
62
|
+
/**
|
|
63
|
+
* Optional, as multiple Sign in with Google buttons can be
|
|
64
|
+
* rendered on the same page, you can assign each button with a
|
|
65
|
+
* unique string. The same string would return along with the ID
|
|
66
|
+
* token, so you can identify which button user clicked to sign in.
|
|
67
|
+
*/
|
|
68
|
+
state?: string;
|
|
69
|
+
}
|
|
70
|
+
interface GoogleOneTapOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Google client ID
|
|
73
|
+
*/
|
|
74
|
+
clientId: string;
|
|
75
|
+
/**
|
|
76
|
+
* Auto select the account if the user is already signed in
|
|
77
|
+
*/
|
|
78
|
+
autoSelect?: boolean | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Cancel the flow when the user taps outside the prompt
|
|
81
|
+
*
|
|
82
|
+
* Note: To use this option, disable `promptOptions.fedCM`
|
|
83
|
+
*/
|
|
84
|
+
cancelOnTapOutside?: boolean | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* The mode to use for the Google One Tap flow
|
|
87
|
+
*
|
|
88
|
+
* popup: Use a popup window
|
|
89
|
+
* redirect: Redirect the user to the Google One Tap flow
|
|
90
|
+
*
|
|
91
|
+
* @default "popup"
|
|
92
|
+
*/
|
|
93
|
+
uxMode?: ("popup" | "redirect") | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* The context to use for the Google One Tap flow.
|
|
96
|
+
*
|
|
97
|
+
* @see {@link https://developers.google.com/identity/gsi/web/reference/js-reference}
|
|
98
|
+
* @default "signin"
|
|
99
|
+
*/
|
|
100
|
+
context?: ("signin" | "signup" | "use") | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* Additional configuration options to pass to the Google One Tap API.
|
|
103
|
+
*/
|
|
104
|
+
additionalOptions?: Record<string, any> | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Configuration options for the prompt and exponential backoff behavior.
|
|
107
|
+
*/
|
|
108
|
+
promptOptions?: {
|
|
109
|
+
/**
|
|
110
|
+
* Base delay (in milliseconds) for exponential backoff.
|
|
111
|
+
* @default 1000
|
|
112
|
+
*/
|
|
113
|
+
baseDelay?: number;
|
|
114
|
+
/**
|
|
115
|
+
* Maximum number of prompt attempts before calling onPromptNotification.
|
|
116
|
+
* @default 5
|
|
117
|
+
*/
|
|
118
|
+
maxAttempts?: number;
|
|
119
|
+
/**
|
|
120
|
+
* Whether to support FedCM (Federated Credential Management) support.
|
|
121
|
+
*
|
|
122
|
+
* @see {@link https://developer.chrome.com/docs/identity/fedcm/overview}
|
|
123
|
+
* @default true
|
|
124
|
+
*/
|
|
125
|
+
fedCM?: boolean | undefined;
|
|
126
|
+
} | undefined;
|
|
127
|
+
}
|
|
128
|
+
interface GoogleOneTapActionOptions extends Omit<GoogleOneTapOptions, "clientId" | "promptOptions"> {
|
|
129
|
+
fetchOptions?: ClientFetchOption | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Callback URL.
|
|
132
|
+
*/
|
|
133
|
+
callbackURL?: string | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* Optional callback that receives the prompt notification if (or when) the prompt is dismissed or skipped.
|
|
136
|
+
* This lets you render an alternative UI (e.g. a Google Sign-In button) to restart the process.
|
|
137
|
+
*/
|
|
138
|
+
onPromptNotification?: ((notification?: any | undefined) => void) | undefined;
|
|
139
|
+
nonce?: string | undefined;
|
|
140
|
+
/**
|
|
141
|
+
* Button mode configuration. When provided, renders a "Sign In with Google" button
|
|
142
|
+
* instead of showing the One Tap prompt.
|
|
143
|
+
*/
|
|
144
|
+
button?: {
|
|
145
|
+
/**
|
|
146
|
+
* The HTML element or CSS selector where the button should be rendered.
|
|
147
|
+
* If a string is provided, it will be used as a CSS selector.
|
|
148
|
+
*/
|
|
149
|
+
container: HTMLElement | string;
|
|
150
|
+
/**
|
|
151
|
+
* Button configuration options
|
|
152
|
+
*/
|
|
153
|
+
config?: GsiButtonConfiguration | undefined;
|
|
154
|
+
} | undefined;
|
|
155
|
+
}
|
|
156
|
+
declare const oneTapClient: (options: GoogleOneTapOptions) => BetterAuthClientPlugin;
|
|
157
|
+
//#endregion
|
|
158
|
+
export { GoogleOneTapActionOptions, GoogleOneTapOptions, GsiButtonConfiguration, oneTapClient };
|
|
159
|
+
//# sourceMappingURL=client.d.mts.map
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
//#region src/plugins/one-tap/client.ts
|
|
2
|
+
let isRequestInProgress = null;
|
|
3
|
+
function isFedCMSupported() {
|
|
4
|
+
return typeof window !== "undefined" && "IdentityCredential" in window;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Reasons that should NOT trigger a retry.
|
|
8
|
+
* @see https://developers.google.com/identity/gsi/web/reference/js-reference
|
|
9
|
+
*/
|
|
10
|
+
const noRetryReasons = {
|
|
11
|
+
dismissed: ["credential_returned", "cancel_called"],
|
|
12
|
+
skipped: ["user_cancel", "tap_outside"]
|
|
13
|
+
};
|
|
14
|
+
const oneTapClient = (options) => {
|
|
15
|
+
return {
|
|
16
|
+
id: "one-tap",
|
|
17
|
+
fetchPlugins: [{
|
|
18
|
+
id: "fedcm-signout-handle",
|
|
19
|
+
name: "FedCM Sign-Out Handler",
|
|
20
|
+
hooks: { async onResponse(ctx) {
|
|
21
|
+
if (!ctx.request.url.toString().includes("/sign-out")) return;
|
|
22
|
+
if (options.promptOptions?.fedCM === false || !isFedCMSupported()) return;
|
|
23
|
+
navigator.credentials.preventSilentAccess();
|
|
24
|
+
} }
|
|
25
|
+
}],
|
|
26
|
+
getActions: ($fetch, _) => {
|
|
27
|
+
return { oneTap: async (opts, fetchOptions) => {
|
|
28
|
+
if (isRequestInProgress && !isRequestInProgress.signal.aborted) {
|
|
29
|
+
console.warn("A Google One Tap request is already in progress. Please wait.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (typeof window === "undefined" || !window.document) {
|
|
33
|
+
console.warn("Google One Tap is only available in browser environments");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (opts?.button) {
|
|
37
|
+
await loadGoogleScript();
|
|
38
|
+
const container = typeof opts.button.container === "string" ? document.querySelector(opts.button.container) : opts.button.container;
|
|
39
|
+
if (!container) {
|
|
40
|
+
console.error("Google One Tap: Button container not found", opts.button.container);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
async function callback(idToken) {
|
|
44
|
+
await $fetch("/one-tap/callback", {
|
|
45
|
+
method: "POST",
|
|
46
|
+
body: { idToken },
|
|
47
|
+
...opts?.fetchOptions,
|
|
48
|
+
...fetchOptions
|
|
49
|
+
});
|
|
50
|
+
if (!opts?.fetchOptions && !fetchOptions || opts?.callbackURL) window.location.href = opts?.callbackURL ?? "/";
|
|
51
|
+
}
|
|
52
|
+
const { autoSelect, cancelOnTapOutside, context } = opts ?? {};
|
|
53
|
+
const contextValue = context ?? options.context ?? "signin";
|
|
54
|
+
window.google?.accounts.id.initialize({
|
|
55
|
+
client_id: options.clientId,
|
|
56
|
+
callback: async (response) => {
|
|
57
|
+
try {
|
|
58
|
+
await callback(response.credential);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error("Error during button callback:", error);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
auto_select: autoSelect,
|
|
64
|
+
cancel_on_tap_outside: cancelOnTapOutside,
|
|
65
|
+
context: contextValue,
|
|
66
|
+
ux_mode: opts?.uxMode || "popup",
|
|
67
|
+
nonce: opts?.nonce,
|
|
68
|
+
itp_support: true,
|
|
69
|
+
...options.additionalOptions
|
|
70
|
+
});
|
|
71
|
+
window.google?.accounts.id.renderButton(container, opts.button.config ?? { type: "icon" });
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
async function callback(idToken) {
|
|
75
|
+
await $fetch("/one-tap/callback", {
|
|
76
|
+
method: "POST",
|
|
77
|
+
body: { idToken },
|
|
78
|
+
...opts?.fetchOptions,
|
|
79
|
+
...fetchOptions
|
|
80
|
+
});
|
|
81
|
+
if (!opts?.fetchOptions && !fetchOptions || opts?.callbackURL) window.location.href = opts?.callbackURL ?? "/";
|
|
82
|
+
}
|
|
83
|
+
const { autoSelect, cancelOnTapOutside, context } = opts ?? {};
|
|
84
|
+
const contextValue = context ?? options.context ?? "signin";
|
|
85
|
+
const clients = {
|
|
86
|
+
fedCM: async () => {
|
|
87
|
+
try {
|
|
88
|
+
const identityCredential = await navigator.credentials.get({
|
|
89
|
+
identity: {
|
|
90
|
+
context: contextValue,
|
|
91
|
+
providers: [{
|
|
92
|
+
configURL: "https://accounts.google.com/gsi/fedcm.json",
|
|
93
|
+
clientId: options.clientId,
|
|
94
|
+
nonce: opts?.nonce
|
|
95
|
+
}]
|
|
96
|
+
},
|
|
97
|
+
mediation: autoSelect ? "optional" : "required",
|
|
98
|
+
signal: isRequestInProgress?.signal
|
|
99
|
+
});
|
|
100
|
+
if (!identityCredential?.token) {
|
|
101
|
+
opts?.onPromptNotification?.(void 0);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
await callback(identityCredential.token);
|
|
106
|
+
return;
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error("Error during FedCM callback:", error);
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
} catch (error) {
|
|
112
|
+
if (error?.code && (error.code === 19 || error.code === 20)) {
|
|
113
|
+
opts?.onPromptNotification?.(void 0);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
oneTap: () => {
|
|
120
|
+
return new Promise((resolve, reject) => {
|
|
121
|
+
let isResolved = false;
|
|
122
|
+
const baseDelay = options.promptOptions?.baseDelay ?? 1e3;
|
|
123
|
+
const maxAttempts = options.promptOptions?.maxAttempts ?? 5;
|
|
124
|
+
window.google?.accounts.id.initialize({
|
|
125
|
+
client_id: options.clientId,
|
|
126
|
+
callback: async (response) => {
|
|
127
|
+
isResolved = true;
|
|
128
|
+
try {
|
|
129
|
+
await callback(response.credential);
|
|
130
|
+
resolve();
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error("Error during One Tap callback:", error);
|
|
133
|
+
reject(error);
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
auto_select: autoSelect,
|
|
137
|
+
cancel_on_tap_outside: cancelOnTapOutside,
|
|
138
|
+
context: contextValue,
|
|
139
|
+
ux_mode: opts?.uxMode || "popup",
|
|
140
|
+
nonce: opts?.nonce,
|
|
141
|
+
itp_support: true,
|
|
142
|
+
...options.additionalOptions
|
|
143
|
+
});
|
|
144
|
+
const handlePrompt = (attempt) => {
|
|
145
|
+
if (isResolved) return;
|
|
146
|
+
window.google?.accounts.id.prompt((notification) => {
|
|
147
|
+
if (isResolved) return;
|
|
148
|
+
if (notification.isDismissedMoment && notification.isDismissedMoment()) {
|
|
149
|
+
const reason = notification.getDismissedReason?.();
|
|
150
|
+
if (noRetryReasons.dismissed.includes(reason)) {
|
|
151
|
+
opts?.onPromptNotification?.(notification);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (attempt < maxAttempts) {
|
|
155
|
+
const delay = Math.pow(2, attempt) * baseDelay;
|
|
156
|
+
setTimeout(() => handlePrompt(attempt + 1), delay);
|
|
157
|
+
} else opts?.onPromptNotification?.(notification);
|
|
158
|
+
} else if (notification.isSkippedMoment && notification.isSkippedMoment()) {
|
|
159
|
+
const reason = notification.getSkippedReason?.();
|
|
160
|
+
if (noRetryReasons.skipped.includes(reason)) {
|
|
161
|
+
opts?.onPromptNotification?.(notification);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (attempt < maxAttempts) {
|
|
165
|
+
const delay = Math.pow(2, attempt) * baseDelay;
|
|
166
|
+
setTimeout(() => handlePrompt(attempt + 1), delay);
|
|
167
|
+
} else opts?.onPromptNotification?.(notification);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
handlePrompt(0);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
if (isRequestInProgress) isRequestInProgress?.abort();
|
|
176
|
+
isRequestInProgress = new AbortController();
|
|
177
|
+
try {
|
|
178
|
+
const client = options.promptOptions?.fedCM === false || !isFedCMSupported() ? "oneTap" : "fedCM";
|
|
179
|
+
if (client === "oneTap") await loadGoogleScript();
|
|
180
|
+
await clients[client]();
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error("Error during Google One Tap flow:", error);
|
|
183
|
+
throw error;
|
|
184
|
+
} finally {
|
|
185
|
+
isRequestInProgress = null;
|
|
186
|
+
}
|
|
187
|
+
} };
|
|
188
|
+
},
|
|
189
|
+
getAtoms($fetch) {
|
|
190
|
+
return {};
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
const loadGoogleScript = () => {
|
|
195
|
+
return new Promise((resolve) => {
|
|
196
|
+
if (window.googleScriptInitialized) {
|
|
197
|
+
resolve();
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const script = document.createElement("script");
|
|
201
|
+
script.src = "https://accounts.google.com/gsi/client";
|
|
202
|
+
script.async = true;
|
|
203
|
+
script.defer = true;
|
|
204
|
+
script.onload = () => {
|
|
205
|
+
window.googleScriptInitialized = true;
|
|
206
|
+
resolve();
|
|
207
|
+
};
|
|
208
|
+
document.head.appendChild(script);
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
//#endregion
|
|
213
|
+
export { oneTapClient };
|
|
214
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../../../src/plugins/one-tap/client.ts"],"sourcesContent":["/// <reference types=\"@types/google.accounts\" />\nimport type {\n\tBetterAuthClientPlugin,\n\tClientFetchOption,\n} from \"@better-auth/core\";\n\ndeclare global {\n\tinterface Window {\n\t\tgoogleScriptInitialized?: boolean | undefined;\n\t}\n}\n\nexport interface GsiButtonConfiguration {\n\t/**\n\t * The button type: icon, or standard button.\n\t */\n\ttype: \"standard\" | \"icon\";\n\n\t/**\n\t * The button theme. For example, filled_blue or filled_black.\n\t * outline A standard button theme:\n\t * filled_blue A blue-filled button theme:\n\t * filled_black A black-filled button theme:\n\t */\n\ttheme?: \"outline\" | \"filled_blue\" | \"filled_black\";\n\n\t/**\n\t * The button size. For example, small or large.\n\t */\n\tsize?: \"small\" | \"medium\" | \"large\";\n\n\t/**\n\t * The button text. The default value is signin_with.\n\t * There are no visual differences for the text of icon buttons that\n\t * have different text attributes. The only exception is when the\n\t * text is read for screen accessibility.\n\t *\n\t * signin_with The button text is “Sign in with Google”:\n\t * signup_with The button text is “Sign up with Google”:\n\t * continue_with The button text is “Continue with Google”:\n\t * signup_with The button text is “Sign in”:\n\t */\n\ttext?: \"signin_with\" | \"signup_with\" | \"continue_with\" | \"signin\";\n\n\t/**\n\t * The button shape. The default value is rectangular.\n\t */\n\tshape?: \"rectangular\" | \"pill\" | \"circle\" | \"square\";\n\n\t/**\n\t * The alignment of the Google logo. The default value is left.\n\t * This attribute only applies to the standard button type.\n\t */\n\tlogo_alignment?: \"left\" | \"center\";\n\n\t/**\n\t * The minimum button width, in pixels. The maximum width is 400\n\t * pixels.\n\t */\n\twidth?: number;\n\n\t/**\n\t * The pre-set locale of the button text. If it's not set, the\n\t * browser's default locale or the Google session user’s preference\n\t * is used.\n\t */\n\tlocale?: string;\n\n\t/**\n\t * You can define a JavaScript function to be called when the\n\t * Sign in with Google button is clicked.\n\t */\n\tclick_listener?: () => void;\n\n\t/**\n\t * Optional, as multiple Sign in with Google buttons can be\n\t * rendered on the same page, you can assign each button with a\n\t * unique string. The same string would return along with the ID\n\t * token, so you can identify which button user clicked to sign in.\n\t */\n\tstate?: string;\n}\n\nexport interface GoogleOneTapOptions {\n\t/**\n\t * Google client ID\n\t */\n\tclientId: string;\n\t/**\n\t * Auto select the account if the user is already signed in\n\t */\n\tautoSelect?: boolean | undefined;\n\t/**\n\t * Cancel the flow when the user taps outside the prompt\n\t *\n\t * Note: To use this option, disable `promptOptions.fedCM`\n\t */\n\tcancelOnTapOutside?: boolean | undefined;\n\t/**\n\t * The mode to use for the Google One Tap flow\n\t *\n\t * popup: Use a popup window\n\t * redirect: Redirect the user to the Google One Tap flow\n\t *\n\t * @default \"popup\"\n\t */\n\tuxMode?: (\"popup\" | \"redirect\") | undefined;\n\t/**\n\t * The context to use for the Google One Tap flow.\n\t *\n\t * @see {@link https://developers.google.com/identity/gsi/web/reference/js-reference}\n\t * @default \"signin\"\n\t */\n\tcontext?: (\"signin\" | \"signup\" | \"use\") | undefined;\n\t/**\n\t * Additional configuration options to pass to the Google One Tap API.\n\t */\n\tadditionalOptions?: Record<string, any> | undefined;\n\t/**\n\t * Configuration options for the prompt and exponential backoff behavior.\n\t */\n\tpromptOptions?:\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * Base delay (in milliseconds) for exponential backoff.\n\t\t\t\t * @default 1000\n\t\t\t\t */\n\t\t\t\tbaseDelay?: number;\n\t\t\t\t/**\n\t\t\t\t * Maximum number of prompt attempts before calling onPromptNotification.\n\t\t\t\t * @default 5\n\t\t\t\t */\n\t\t\t\tmaxAttempts?: number;\n\t\t\t\t/**\n\t\t\t\t * Whether to support FedCM (Federated Credential Management) support.\n\t\t\t\t *\n\t\t\t\t * @see {@link https://developer.chrome.com/docs/identity/fedcm/overview}\n\t\t\t\t * @default true\n\t\t\t\t */\n\t\t\t\tfedCM?: boolean | undefined;\n\t\t }\n\t\t| undefined;\n}\n\nexport interface GoogleOneTapActionOptions\n\textends Omit<GoogleOneTapOptions, \"clientId\" | \"promptOptions\"> {\n\tfetchOptions?: ClientFetchOption | undefined;\n\t/**\n\t * Callback URL.\n\t */\n\tcallbackURL?: string | undefined;\n\t/**\n\t * Optional callback that receives the prompt notification if (or when) the prompt is dismissed or skipped.\n\t * This lets you render an alternative UI (e.g. a Google Sign-In button) to restart the process.\n\t */\n\tonPromptNotification?: ((notification?: any | undefined) => void) | undefined;\n\tnonce?: string | undefined;\n\t/**\n\t * Button mode configuration. When provided, renders a \"Sign In with Google\" button\n\t * instead of showing the One Tap prompt.\n\t */\n\tbutton?:\n\t\t| {\n\t\t\t\t/**\n\t\t\t\t * The HTML element or CSS selector where the button should be rendered.\n\t\t\t\t * If a string is provided, it will be used as a CSS selector.\n\t\t\t\t */\n\t\t\t\tcontainer: HTMLElement | string;\n\t\t\t\t/**\n\t\t\t\t * Button configuration options\n\t\t\t\t */\n\t\t\t\tconfig?: GsiButtonConfiguration | undefined;\n\t\t }\n\t\t| undefined;\n}\n\ninterface IdentityCredential {\n\treadonly configURL: string;\n\treadonly isAutoSelected: boolean;\n\ttoken: string;\n}\n\nlet isRequestInProgress: AbortController | null = null;\n\nfunction isFedCMSupported() {\n\treturn typeof window !== \"undefined\" && \"IdentityCredential\" in window;\n}\n\n/**\n * Reasons that should NOT trigger a retry.\n * @see https://developers.google.com/identity/gsi/web/reference/js-reference\n */\nconst noRetryReasons = {\n\tdismissed: [\"credential_returned\", \"cancel_called\"],\n\tskipped: [\"user_cancel\", \"tap_outside\"],\n} as const;\n\nexport const oneTapClient = (options: GoogleOneTapOptions) => {\n\treturn {\n\t\tid: \"one-tap\",\n\t\tfetchPlugins: [\n\t\t\t{\n\t\t\t\tid: \"fedcm-signout-handle\",\n\t\t\t\tname: \"FedCM Sign-Out Handler\",\n\t\t\t\thooks: {\n\t\t\t\t\tasync onResponse(ctx) {\n\t\t\t\t\t\tif (!ctx.request.url.toString().includes(\"/sign-out\")) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (options.promptOptions?.fedCM === false || !isFedCMSupported()) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnavigator.credentials.preventSilentAccess();\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tgetActions: ($fetch, _) => {\n\t\t\treturn {\n\t\t\t\toneTap: async (\n\t\t\t\t\topts?: GoogleOneTapActionOptions | undefined,\n\t\t\t\t\tfetchOptions?: ClientFetchOption | undefined,\n\t\t\t\t) => {\n\t\t\t\t\tif (isRequestInProgress && !isRequestInProgress.signal.aborted) {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\"A Google One Tap request is already in progress. Please wait.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (typeof window === \"undefined\" || !window.document) {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\"Google One Tap is only available in browser environments\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Button mode: render a button instead of showing the prompt\n\t\t\t\t\tif (opts?.button) {\n\t\t\t\t\t\tawait loadGoogleScript();\n\n\t\t\t\t\t\tconst container =\n\t\t\t\t\t\t\ttypeof opts.button.container === \"string\"\n\t\t\t\t\t\t\t\t? document.querySelector<HTMLElement>(opts.button.container)\n\t\t\t\t\t\t\t\t: opts.button.container;\n\n\t\t\t\t\t\tif (!container) {\n\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t\"Google One Tap: Button container not found\",\n\t\t\t\t\t\t\t\topts.button.container,\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\tasync function callback(idToken: string) {\n\t\t\t\t\t\t\tawait $fetch(\"/one-tap/callback\", {\n\t\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\t\tbody: { idToken },\n\t\t\t\t\t\t\t\t...opts?.fetchOptions,\n\t\t\t\t\t\t\t\t...fetchOptions,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif ((!opts?.fetchOptions && !fetchOptions) || opts?.callbackURL) {\n\t\t\t\t\t\t\t\twindow.location.href = opts?.callbackURL ?? \"/\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst { autoSelect, cancelOnTapOutside, context } = opts ?? {};\n\t\t\t\t\t\tconst contextValue = context ?? options.context ?? \"signin\";\n\n\t\t\t\t\t\twindow.google?.accounts.id.initialize({\n\t\t\t\t\t\t\tclient_id: options.clientId,\n\t\t\t\t\t\t\tcallback: async (response: { credential: string }) => {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait callback(response.credential);\n\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\tconsole.error(\"Error during button callback:\", error);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tauto_select: autoSelect,\n\t\t\t\t\t\t\tcancel_on_tap_outside: cancelOnTapOutside,\n\t\t\t\t\t\t\tcontext: contextValue,\n\t\t\t\t\t\t\tux_mode: opts?.uxMode || \"popup\",\n\t\t\t\t\t\t\tnonce: opts?.nonce,\n\t\t\t\t\t\t\titp_support: true,\n\t\t\t\t\t\t\t...options.additionalOptions,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\twindow.google?.accounts.id.renderButton(\n\t\t\t\t\t\t\tcontainer,\n\t\t\t\t\t\t\topts.button.config ?? {\n\t\t\t\t\t\t\t\ttype: \"icon\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tasync function callback(idToken: string) {\n\t\t\t\t\t\tawait $fetch(\"/one-tap/callback\", {\n\t\t\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\t\t\tbody: { idToken },\n\t\t\t\t\t\t\t...opts?.fetchOptions,\n\t\t\t\t\t\t\t...fetchOptions,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif ((!opts?.fetchOptions && !fetchOptions) || opts?.callbackURL) {\n\t\t\t\t\t\t\twindow.location.href = opts?.callbackURL ?? \"/\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { autoSelect, cancelOnTapOutside, context } = opts ?? {};\n\t\t\t\t\tconst contextValue = context ?? options.context ?? \"signin\";\n\t\t\t\t\tconst clients = {\n\t\t\t\t\t\tfedCM: async () => {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst identityCredential = (await navigator.credentials.get({\n\t\t\t\t\t\t\t\t\tidentity: {\n\t\t\t\t\t\t\t\t\t\tcontext: contextValue,\n\t\t\t\t\t\t\t\t\t\tproviders: [\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tconfigURL: \"https://accounts.google.com/gsi/fedcm.json\",\n\t\t\t\t\t\t\t\t\t\t\t\tclientId: options.clientId,\n\t\t\t\t\t\t\t\t\t\t\t\tnonce: opts?.nonce,\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\tmediation: autoSelect ? \"optional\" : \"required\",\n\t\t\t\t\t\t\t\t\tsignal: isRequestInProgress?.signal,\n\t\t\t\t\t\t\t\t} as any)) as IdentityCredential | null;\n\n\t\t\t\t\t\t\t\tif (!identityCredential?.token) {\n\t\t\t\t\t\t\t\t\t// Notify the caller that the prompt resulted in no token.\n\t\t\t\t\t\t\t\t\topts?.onPromptNotification?.(undefined);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tawait callback(identityCredential.token);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\tconsole.error(\"Error during FedCM callback:\", error);\n\t\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\t\tif (error?.code && (error.code === 19 || error.code === 20)) {\n\t\t\t\t\t\t\t\t\t// Notify the caller that the prompt was closed/dismissed.\n\t\t\t\t\t\t\t\t\topts?.onPromptNotification?.(undefined);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthrow error;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\toneTap: () => {\n\t\t\t\t\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\t\t\t\t\tlet isResolved = false;\n\t\t\t\t\t\t\t\tconst baseDelay = options.promptOptions?.baseDelay ?? 1000;\n\t\t\t\t\t\t\t\tconst maxAttempts = options.promptOptions?.maxAttempts ?? 5;\n\n\t\t\t\t\t\t\t\twindow.google?.accounts.id.initialize({\n\t\t\t\t\t\t\t\t\tclient_id: options.clientId,\n\t\t\t\t\t\t\t\t\tcallback: async (response: { credential: string }) => {\n\t\t\t\t\t\t\t\t\t\tisResolved = true;\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tawait callback(response.credential);\n\t\t\t\t\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.error(\"Error during One Tap callback:\", error);\n\t\t\t\t\t\t\t\t\t\t\treject(error);\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\tauto_select: autoSelect,\n\t\t\t\t\t\t\t\t\tcancel_on_tap_outside: cancelOnTapOutside,\n\t\t\t\t\t\t\t\t\tcontext: contextValue,\n\t\t\t\t\t\t\t\t\tux_mode: opts?.uxMode || \"popup\",\n\t\t\t\t\t\t\t\t\tnonce: opts?.nonce,\n\t\t\t\t\t\t\t\t\t/**\n\t\t\t\t\t\t\t\t\t * @see {@link https://developers.google.com/identity/gsi/web/guides/overview}\n\t\t\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t\t\titp_support: true,\n\n\t\t\t\t\t\t\t\t\t...options.additionalOptions,\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tconst handlePrompt = (attempt: number) => {\n\t\t\t\t\t\t\t\t\tif (isResolved) return;\n\n\t\t\t\t\t\t\t\t\twindow.google?.accounts.id.prompt((notification: any) => {\n\t\t\t\t\t\t\t\t\t\tif (isResolved) return;\n\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tnotification.isDismissedMoment &&\n\t\t\t\t\t\t\t\t\t\t\tnotification.isDismissedMoment()\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tconst reason = notification.getDismissedReason?.();\n\t\t\t\t\t\t\t\t\t\t\tif (noRetryReasons.dismissed.includes(reason)) {\n\t\t\t\t\t\t\t\t\t\t\t\topts?.onPromptNotification?.(notification);\n\t\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (attempt < maxAttempts) {\n\t\t\t\t\t\t\t\t\t\t\t\tconst delay = Math.pow(2, attempt) * baseDelay;\n\t\t\t\t\t\t\t\t\t\t\t\tsetTimeout(() => handlePrompt(attempt + 1), delay);\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\topts?.onPromptNotification?.(notification);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\t\t\t\t\tnotification.isSkippedMoment &&\n\t\t\t\t\t\t\t\t\t\t\tnotification.isSkippedMoment()\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tconst reason = notification.getSkippedReason?.();\n\t\t\t\t\t\t\t\t\t\t\tif (noRetryReasons.skipped.includes(reason)) {\n\t\t\t\t\t\t\t\t\t\t\t\topts?.onPromptNotification?.(notification);\n\t\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif (attempt < maxAttempts) {\n\t\t\t\t\t\t\t\t\t\t\t\tconst delay = Math.pow(2, attempt) * baseDelay;\n\t\t\t\t\t\t\t\t\t\t\t\tsetTimeout(() => handlePrompt(attempt + 1), delay);\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\topts?.onPromptNotification?.(notification);\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\n\t\t\t\t\t\t\t\thandlePrompt(0);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\n\t\t\t\t\tif (isRequestInProgress) {\n\t\t\t\t\t\tisRequestInProgress?.abort();\n\t\t\t\t\t}\n\t\t\t\t\tisRequestInProgress = new AbortController();\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst client =\n\t\t\t\t\t\t\toptions.promptOptions?.fedCM === false || !isFedCMSupported()\n\t\t\t\t\t\t\t\t? \"oneTap\"\n\t\t\t\t\t\t\t\t: \"fedCM\";\n\t\t\t\t\t\tif (client === \"oneTap\") {\n\t\t\t\t\t\t\tawait loadGoogleScript();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait clients[client]();\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconsole.error(\"Error during Google One Tap flow:\", error);\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tisRequestInProgress = null;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tgetAtoms($fetch) {\n\t\t\treturn {};\n\t\t},\n\t} satisfies BetterAuthClientPlugin;\n};\n\nconst loadGoogleScript = (): Promise<void> => {\n\treturn new Promise((resolve) => {\n\t\tif (window.googleScriptInitialized) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\n\t\tconst script = document.createElement(\"script\");\n\t\tscript.src = \"https://accounts.google.com/gsi/client\";\n\t\tscript.async = true;\n\t\tscript.defer = true;\n\t\tscript.onload = () => {\n\t\t\twindow.googleScriptInitialized = true;\n\t\t\tresolve();\n\t\t};\n\t\tdocument.head.appendChild(script);\n\t});\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/plugins/one-tap/index.d.ts
|
|
2
|
+
declare module "@better-auth/core" {
|
|
3
|
+
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
4
|
+
"one-tap": {
|
|
5
|
+
creator: typeof oneTap;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
interface OneTapOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Disable the signup flow
|
|
12
|
+
*
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
15
|
+
disableSignup?: boolean | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Google Client ID
|
|
18
|
+
*
|
|
19
|
+
* If a client ID is provided in the social provider configuration,
|
|
20
|
+
* it will be used.
|
|
21
|
+
*/
|
|
22
|
+
clientId?: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
declare const oneTap: (options?: OneTapOptions | undefined) => BetterAuthPlugin;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { OneTapOptions, oneTap };
|
|
27
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { parseUserOutput } from "../../db/schema.mjs";
|
|
2
|
+
import { setSessionCookie } from "../../cookies/index.mjs";
|
|
3
|
+
import { APIError } from "../../api/index.mjs";
|
|
4
|
+
import { toBoolean } from "../../utils/boolean.mjs";
|
|
5
|
+
import { createAuthEndpoint } from "@better-auth/core/api";
|
|
6
|
+
import * as z from "zod";
|
|
7
|
+
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
8
|
+
|
|
9
|
+
//#region src/plugins/one-tap/index.ts
|
|
10
|
+
const oneTapCallbackBodySchema = z.object({ idToken: z.string().meta({ description: "Google ID token, which the client obtains from the One Tap API" }) });
|
|
11
|
+
const oneTap = (options) => ({
|
|
12
|
+
id: "one-tap",
|
|
13
|
+
endpoints: { oneTapCallback: createAuthEndpoint("/one-tap/callback", {
|
|
14
|
+
method: "POST",
|
|
15
|
+
body: oneTapCallbackBodySchema,
|
|
16
|
+
metadata: { openapi: {
|
|
17
|
+
summary: "One tap callback",
|
|
18
|
+
description: "Use this endpoint to authenticate with Google One Tap",
|
|
19
|
+
responses: {
|
|
20
|
+
200: {
|
|
21
|
+
description: "Successful response",
|
|
22
|
+
content: { "application/json": { schema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
session: { $ref: "#/components/schemas/Session" },
|
|
26
|
+
user: { $ref: "#/components/schemas/User" }
|
|
27
|
+
}
|
|
28
|
+
} } }
|
|
29
|
+
},
|
|
30
|
+
400: { description: "Invalid token" }
|
|
31
|
+
}
|
|
32
|
+
} }
|
|
33
|
+
}, async (ctx) => {
|
|
34
|
+
const { idToken } = ctx.body;
|
|
35
|
+
let payload;
|
|
36
|
+
try {
|
|
37
|
+
const { payload: verifiedPayload } = await jwtVerify(idToken, createRemoteJWKSet(new URL("https://www.googleapis.com/oauth2/v3/certs")), {
|
|
38
|
+
issuer: ["https://accounts.google.com", "accounts.google.com"],
|
|
39
|
+
audience: options?.clientId || ctx.context.options.socialProviders?.google?.clientId
|
|
40
|
+
});
|
|
41
|
+
payload = verifiedPayload;
|
|
42
|
+
} catch {
|
|
43
|
+
throw new APIError("BAD_REQUEST", { message: "invalid id token" });
|
|
44
|
+
}
|
|
45
|
+
const { email, email_verified, name, picture, sub } = payload;
|
|
46
|
+
if (!email) return ctx.json({ error: "Email not available in token" });
|
|
47
|
+
const user = await ctx.context.internalAdapter.findUserByEmail(email);
|
|
48
|
+
if (!user) {
|
|
49
|
+
if (options?.disableSignup) throw new APIError("BAD_GATEWAY", { message: "User not found" });
|
|
50
|
+
const newUser = await ctx.context.internalAdapter.createOAuthUser({
|
|
51
|
+
email,
|
|
52
|
+
emailVerified: typeof email_verified === "boolean" ? email_verified : toBoolean(email_verified),
|
|
53
|
+
name,
|
|
54
|
+
image: picture
|
|
55
|
+
}, {
|
|
56
|
+
providerId: "google",
|
|
57
|
+
accountId: sub
|
|
58
|
+
});
|
|
59
|
+
if (!newUser) throw new APIError("INTERNAL_SERVER_ERROR", { message: "Could not create user" });
|
|
60
|
+
const session = await ctx.context.internalAdapter.createSession(newUser.user.id);
|
|
61
|
+
await setSessionCookie(ctx, {
|
|
62
|
+
user: newUser.user,
|
|
63
|
+
session
|
|
64
|
+
});
|
|
65
|
+
return ctx.json({
|
|
66
|
+
token: session.token,
|
|
67
|
+
user: parseUserOutput(ctx.context.options, newUser.user)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (!await ctx.context.internalAdapter.findAccount(sub)) {
|
|
71
|
+
const accountLinking = ctx.context.options.account?.accountLinking;
|
|
72
|
+
if (accountLinking?.enabled !== false && (accountLinking?.trustedProviders?.includes("google") || email_verified)) await ctx.context.internalAdapter.linkAccount({
|
|
73
|
+
userId: user.user.id,
|
|
74
|
+
providerId: "google",
|
|
75
|
+
accountId: sub,
|
|
76
|
+
scope: "openid,profile,email",
|
|
77
|
+
idToken
|
|
78
|
+
});
|
|
79
|
+
else throw new APIError("UNAUTHORIZED", { message: "Google sub doesn't match" });
|
|
80
|
+
}
|
|
81
|
+
const session = await ctx.context.internalAdapter.createSession(user.user.id);
|
|
82
|
+
await setSessionCookie(ctx, {
|
|
83
|
+
user: user.user,
|
|
84
|
+
session
|
|
85
|
+
});
|
|
86
|
+
return ctx.json({
|
|
87
|
+
token: session.token,
|
|
88
|
+
user: parseUserOutput(ctx.context.options, user.user)
|
|
89
|
+
});
|
|
90
|
+
}) },
|
|
91
|
+
options
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
//#endregion
|
|
95
|
+
export { oneTap };
|
|
96
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/one-tap/index.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"@better-auth/core\";\nimport { createAuthEndpoint } from \"@better-auth/core/api\";\nimport { createRemoteJWKSet, jwtVerify } from \"jose\";\nimport * as z from \"zod\";\nimport { APIError } from \"../../api\";\nimport { setSessionCookie } from \"../../cookies\";\nimport { parseUserOutput } from \"../../db/schema\";\nimport { toBoolean } from \"../../utils/boolean\";\n\ndeclare module \"@better-auth/core\" {\n\tinterface BetterAuthPluginRegistry<AuthOptions, Options> {\n\t\t\"one-tap\": {\n\t\t\tcreator: typeof oneTap;\n\t\t};\n\t}\n}\n\nexport interface OneTapOptions {\n\t/**\n\t * Disable the signup flow\n\t *\n\t * @default false\n\t */\n\tdisableSignup?: boolean | undefined;\n\t/**\n\t * Google Client ID\n\t *\n\t * If a client ID is provided in the social provider configuration,\n\t * it will be used.\n\t */\n\tclientId?: string | undefined;\n}\n\nconst oneTapCallbackBodySchema = z.object({\n\tidToken: z.string().meta({\n\t\tdescription:\n\t\t\t\"Google ID token, which the client obtains from the One Tap API\",\n\t}),\n});\n\nexport const oneTap = (options?: OneTapOptions | undefined) =>\n\t({\n\t\tid: \"one-tap\",\n\t\tendpoints: {\n\t\t\toneTapCallback: createAuthEndpoint(\n\t\t\t\t\"/one-tap/callback\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: oneTapCallbackBodySchema,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tsummary: \"One tap callback\",\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Use this endpoint to authenticate with Google One Tap\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\t\t\tdescription: \"Successful response\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsession: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$ref: \"#/components/schemas/Session\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tuser: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$ref: \"#/components/schemas/User\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t400: {\n\t\t\t\t\t\t\t\t\tdescription: \"Invalid token\",\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 { idToken } = ctx.body;\n\t\t\t\t\tlet payload: any;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst JWKS = createRemoteJWKSet(\n\t\t\t\t\t\t\tnew URL(\"https://www.googleapis.com/oauth2/v3/certs\"),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst { payload: verifiedPayload } = await jwtVerify(\n\t\t\t\t\t\t\tidToken,\n\t\t\t\t\t\t\tJWKS,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tissuer: [\"https://accounts.google.com\", \"accounts.google.com\"],\n\t\t\t\t\t\t\t\taudience:\n\t\t\t\t\t\t\t\t\toptions?.clientId ||\n\t\t\t\t\t\t\t\t\tctx.context.options.socialProviders?.google?.clientId,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tpayload = verifiedPayload;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"invalid id token\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst { email, email_verified, name, picture, sub } = payload;\n\t\t\t\t\tif (!email) {\n\t\t\t\t\t\treturn ctx.json({ error: \"Email not available in token\" });\n\t\t\t\t\t}\n\n\t\t\t\t\tconst user = await ctx.context.internalAdapter.findUserByEmail(email);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\tif (options?.disableSignup) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_GATEWAY\", {\n\t\t\t\t\t\t\t\tmessage: \"User not found\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst newUser = await ctx.context.internalAdapter.createOAuthUser(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\temail,\n\t\t\t\t\t\t\t\temailVerified:\n\t\t\t\t\t\t\t\t\ttypeof email_verified === \"boolean\"\n\t\t\t\t\t\t\t\t\t\t? email_verified\n\t\t\t\t\t\t\t\t\t\t: toBoolean(email_verified),\n\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\timage: picture,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tproviderId: \"google\",\n\t\t\t\t\t\t\t\taccountId: sub,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (!newUser) {\n\t\t\t\t\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\t\t\t\t\tmessage: \"Could not create user\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst session = await ctx.context.internalAdapter.createSession(\n\t\t\t\t\t\t\tnewUser.user.id,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait setSessionCookie(ctx, {\n\t\t\t\t\t\t\tuser: newUser.user,\n\t\t\t\t\t\t\tsession,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\t\ttoken: session.token,\n\t\t\t\t\t\t\tuser: parseUserOutput(ctx.context.options, newUser.user),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst account = await ctx.context.internalAdapter.findAccount(sub);\n\t\t\t\t\tif (!account) {\n\t\t\t\t\t\tconst accountLinking = ctx.context.options.account?.accountLinking;\n\t\t\t\t\t\tconst shouldLinkAccount =\n\t\t\t\t\t\t\taccountLinking?.enabled !== false &&\n\t\t\t\t\t\t\t(accountLinking?.trustedProviders?.includes(\"google\") ||\n\t\t\t\t\t\t\t\temail_verified);\n\t\t\t\t\t\tif (shouldLinkAccount) {\n\t\t\t\t\t\t\tawait ctx.context.internalAdapter.linkAccount({\n\t\t\t\t\t\t\t\tuserId: user.user.id,\n\t\t\t\t\t\t\t\tproviderId: \"google\",\n\t\t\t\t\t\t\t\taccountId: sub,\n\t\t\t\t\t\t\t\tscope: \"openid,profile,email\",\n\t\t\t\t\t\t\t\tidToken,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Google sub doesn't match\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst session = await ctx.context.internalAdapter.createSession(\n\t\t\t\t\t\tuser.user.id,\n\t\t\t\t\t);\n\n\t\t\t\t\tawait setSessionCookie(ctx, {\n\t\t\t\t\t\tuser: user.user,\n\t\t\t\t\t\tsession,\n\t\t\t\t\t});\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\ttoken: session.token,\n\t\t\t\t\t\tuser: parseUserOutput(ctx.context.options, user.user),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\toptions,\n\t}) satisfies BetterAuthPlugin;\n"],"mappings":";;;;;;;;;AAiCA,MAAM,2BAA2B,EAAE,OAAO,EACzC,SAAS,EAAE,QAAQ,CAAC,KAAK,EACxB,aACC,kEACD,CAAC,EACF,CAAC;AAEF,MAAa,UAAU,aACrB;CACA,IAAI;CACJ,WAAW,EACV,gBAAgB,mBACf,qBACA;EACC,QAAQ;EACR,MAAM;EACN,UAAU,EACT,SAAS;GACR,SAAS;GACT,aACC;GACD,WAAW;IACV,KAAK;KACJ,aAAa;KACb,SAAS,EACR,oBAAoB,EACnB,QAAQ;MACP,MAAM;MACN,YAAY;OACX,SAAS,EACR,MAAM,gCACN;OACD,MAAM,EACL,MAAM,6BACN;OACD;MACD,EACD,EACD;KACD;IACD,KAAK,EACJ,aAAa,iBACb;IACD;GACD,EACD;EACD,EACD,OAAO,QAAQ;EACd,MAAM,EAAE,YAAY,IAAI;EACxB,IAAI;AACJ,MAAI;GAIH,MAAM,EAAE,SAAS,oBAAoB,MAAM,UAC1C,SAJY,mBACZ,IAAI,IAAI,6CAA6C,CACrD,EAIA;IACC,QAAQ,CAAC,+BAA+B,sBAAsB;IAC9D,UACC,SAAS,YACT,IAAI,QAAQ,QAAQ,iBAAiB,QAAQ;IAC9C,CACD;AACD,aAAU;UACH;AACP,SAAM,IAAI,SAAS,eAAe,EACjC,SAAS,oBACT,CAAC;;EAEH,MAAM,EAAE,OAAO,gBAAgB,MAAM,SAAS,QAAQ;AACtD,MAAI,CAAC,MACJ,QAAO,IAAI,KAAK,EAAE,OAAO,gCAAgC,CAAC;EAG3D,MAAM,OAAO,MAAM,IAAI,QAAQ,gBAAgB,gBAAgB,MAAM;AACrE,MAAI,CAAC,MAAM;AACV,OAAI,SAAS,cACZ,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,kBACT,CAAC;GAEH,MAAM,UAAU,MAAM,IAAI,QAAQ,gBAAgB,gBACjD;IACC;IACA,eACC,OAAO,mBAAmB,YACvB,iBACA,UAAU,eAAe;IAC7B;IACA,OAAO;IACP,EACD;IACC,YAAY;IACZ,WAAW;IACX,CACD;AACD,OAAI,CAAC,QACJ,OAAM,IAAI,SAAS,yBAAyB,EAC3C,SAAS,yBACT,CAAC;GAEH,MAAM,UAAU,MAAM,IAAI,QAAQ,gBAAgB,cACjD,QAAQ,KAAK,GACb;AACD,SAAM,iBAAiB,KAAK;IAC3B,MAAM,QAAQ;IACd;IACA,CAAC;AACF,UAAO,IAAI,KAAK;IACf,OAAO,QAAQ;IACf,MAAM,gBAAgB,IAAI,QAAQ,SAAS,QAAQ,KAAK;IACxD,CAAC;;AAGH,MAAI,CADY,MAAM,IAAI,QAAQ,gBAAgB,YAAY,IAAI,EACpD;GACb,MAAM,iBAAiB,IAAI,QAAQ,QAAQ,SAAS;AAKpD,OAHC,gBAAgB,YAAY,UAC3B,gBAAgB,kBAAkB,SAAS,SAAS,IACpD,gBAED,OAAM,IAAI,QAAQ,gBAAgB,YAAY;IAC7C,QAAQ,KAAK,KAAK;IAClB,YAAY;IACZ,WAAW;IACX,OAAO;IACP;IACA,CAAC;OAEF,OAAM,IAAI,SAAS,gBAAgB,EAClC,SAAS,4BACT,CAAC;;EAGJ,MAAM,UAAU,MAAM,IAAI,QAAQ,gBAAgB,cACjD,KAAK,KAAK,GACV;AAED,QAAM,iBAAiB,KAAK;GAC3B,MAAM,KAAK;GACX;GACA,CAAC;AACF,SAAO,IAAI,KAAK;GACf,OAAO,QAAQ;GACf,MAAM,gBAAgB,IAAI,QAAQ,SAAS,KAAK,KAAK;GACrD,CAAC;GAEH,EACD;CACD;CACA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../../../src/plugins/one-time-token/client.ts"],"sourcesContent":["import type { BetterAuthClientPlugin } from \"@better-auth/core\";\nimport type { oneTimeToken } from \"./index\";\n\nexport const oneTimeTokenClient = () => {\n\treturn {\n\t\tid: \"one-time-token\",\n\t\t$InferServerPlugin: {} as ReturnType<typeof oneTimeToken>,\n\t} satisfies BetterAuthClientPlugin;\n};\n\nexport type { OneTimeTokenOptions } from \"./index\";\n"],"mappings":";AAGA,MAAa,2BAA2B;AACvC,QAAO;EACN,IAAI;EACJ,oBAAoB,EAAE;EACtB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Session, User } from "../../types/models.mjs";
|
|
2
|
+
import "../../types/index.mjs";
|
|
3
|
+
import { GenericEndpointContext } from "@better-auth/core";
|
|
4
|
+
|
|
5
|
+
//#region src/plugins/one-time-token/index.d.ts
|
|
6
|
+
declare module "@better-auth/core" {
|
|
7
|
+
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
8
|
+
"one-time-token": {
|
|
9
|
+
creator: typeof oneTimeToken;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
interface OneTimeTokenOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Expires in minutes
|
|
16
|
+
*
|
|
17
|
+
* @default 3
|
|
18
|
+
*/
|
|
19
|
+
expiresIn?: number | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Only allow server initiated requests
|
|
22
|
+
*/
|
|
23
|
+
disableClientRequest?: boolean | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Generate a custom token
|
|
26
|
+
*/
|
|
27
|
+
generateToken?: ((session: {
|
|
28
|
+
user: User & Record<string, any>;
|
|
29
|
+
session: Session & Record<string, any>;
|
|
30
|
+
}, ctx: GenericEndpointContext) => Promise<string>) | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Disable setting the session cookie when the token is verified
|
|
33
|
+
*/
|
|
34
|
+
disableSetSessionCookie?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* This option allows you to configure how the token is stored in your database.
|
|
37
|
+
* Note: This will not affect the token that's sent, it will only affect the token stored in your database.
|
|
38
|
+
*
|
|
39
|
+
* @default "plain"
|
|
40
|
+
*/
|
|
41
|
+
storeToken?: ("plain" | "hashed" | {
|
|
42
|
+
type: "custom-hasher";
|
|
43
|
+
hash: (token: string) => Promise<string>;
|
|
44
|
+
}) | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Set the OTT header on new sessions
|
|
47
|
+
*/
|
|
48
|
+
setOttHeaderOnNewSession?: boolean;
|
|
49
|
+
}
|
|
50
|
+
declare const oneTimeToken: (options?: OneTimeTokenOptions | undefined) => BetterAuthPlugin;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { OneTimeTokenOptions, oneTimeToken };
|
|
53
|
+
//# sourceMappingURL=index.d.mts.map
|