@zpg6-test-pkgs/better-auth
Version:
The most comprehensive authentication library for TypeScript.
194 lines (190 loc) • 6.36 kB
JavaScript
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 };