UNPKG

@zpg6-test-pkgs/better-auth

Version:

The most comprehensive authentication library for TypeScript.

194 lines (190 loc) 6.36 kB
import * as z from 'zod/v4'; import { APIError } from 'better-call'; import '../../shared/better-auth.D7aTFyWE.mjs'; import { a as createAuthEndpoint } from '../../shared/better-auth.BfeJWAMn.mjs'; import { s as setSessionCookie } from '../../shared/better-auth.DF-MUmVw.mjs'; import '../../shared/better-auth.n2KFGwjY.mjs'; import '../../shared/better-auth.CMQ3rA-I.mjs'; import '../../shared/better-auth.BjBlybv-.mjs'; import { createRemoteJWKSet, jwtVerify } from 'jose'; import '../../shared/better-auth.CW6D9eSx.mjs'; import '@better-auth/utils/hash'; import '@better-auth/utils/base64'; import '../../crypto/index.mjs'; import '@noble/ciphers/chacha'; import '@noble/ciphers/utils'; import '@noble/ciphers/webcrypto'; import '@noble/hashes/scrypt'; import '@better-auth/utils'; import '@better-auth/utils/hex'; import '@noble/hashes/utils'; import '../../shared/better-auth.B4Qoxdgc.mjs'; import '@better-auth/utils/random'; import '@better-fetch/fetch'; import '../../shared/better-auth.CuS_eDdK.mjs'; import '../../shared/better-auth.DdzSJf-n.mjs'; import 'jose/errors'; import '../../shared/better-auth.BZZKN1g7.mjs'; import '../../shared/better-auth.BUPPRXfK.mjs'; import '@better-auth/utils/hmac'; import '@better-auth/utils/binary'; import 'defu'; function toBoolean(value) { return value === "true" || value === true; } const oneTap = (options) => ({ id: "one-tap", endpoints: { oneTapCallback: createAuthEndpoint( "/one-tap/callback", { method: "POST", body: z.object({ idToken: z.string().meta({ description: "Google ID token, which the client obtains from the One Tap API" }) }), metadata: { openapi: { summary: "One tap callback", description: "Use this endpoint to authenticate with Google One Tap", responses: { 200: { description: "Successful response", content: { "application/json": { schema: { type: "object", properties: { session: { $ref: "#/components/schemas/Session" }, user: { $ref: "#/components/schemas/User" } } } } } }, 400: { description: "Invalid token" } } } } }, async (ctx) => { const { idToken } = ctx.body; let payload; try { const JWKS = createRemoteJWKSet( new URL("https://www.googleapis.com/oauth2/v3/certs") ); const { payload: verifiedPayload } = await jwtVerify( idToken, JWKS, { issuer: ["https://accounts.google.com", "accounts.google.com"], audience: options?.clientId || ctx.context.options.socialProviders?.google?.clientId } ); payload = verifiedPayload; } catch (error) { throw new APIError("BAD_REQUEST", { message: "invalid id token" }); } const { email, email_verified, name, picture, sub } = payload; if (!email) { return ctx.json({ error: "Email not available in token" }); } const user = await ctx.context.internalAdapter.findUserByEmail(email); if (!user) { if (options?.disableSignup) { throw new APIError("BAD_GATEWAY", { message: "User not found" }); } const newUser = await ctx.context.internalAdapter.createOAuthUser( { email, emailVerified: typeof email_verified === "boolean" ? email_verified : toBoolean(email_verified), name, image: picture }, { providerId: "google", accountId: sub }, ctx ); if (!newUser) { throw new APIError("INTERNAL_SERVER_ERROR", { message: "Could not create user" }); } const session2 = await ctx.context.internalAdapter.createSession( newUser.user.id, ctx ); await setSessionCookie(ctx, { user: newUser.user, session: session2 }); return ctx.json({ token: session2.token, user: { id: newUser.user.id, email: newUser.user.email, emailVerified: newUser.user.emailVerified, name: newUser.user.name, image: newUser.user.image, createdAt: newUser.user.createdAt, updatedAt: newUser.user.updatedAt } }); } const account = await ctx.context.internalAdapter.findAccount(sub); if (!account) { const accountLinking = ctx.context.options.account?.accountLinking; const shouldLinkAccount = accountLinking?.enabled && (accountLinking.trustedProviders?.includes("google") || email_verified); if (shouldLinkAccount) { await ctx.context.internalAdapter.linkAccount({ userId: user.user.id, providerId: "google", accountId: sub, scope: "openid,profile,email", idToken }); } else { throw new APIError("UNAUTHORIZED", { message: "Google sub doesn't match" }); } } const session = await ctx.context.internalAdapter.createSession( user.user.id, ctx ); await setSessionCookie(ctx, { user: user.user, session }); return ctx.json({ token: session.token, user: { id: user.user.id, email: user.user.email, emailVerified: user.user.emailVerified, name: user.user.name, image: user.user.image, createdAt: user.user.createdAt, updatedAt: user.user.updatedAt } }); } ) } }); export { oneTap };