summaryrefslogtreecommitdiff
path: root/src/account/google.ts
blob: 2194a18517eb522d13430abd5c2c343eca015865 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import * as jose from "jose";
import { logger } from "../lib/pino";

const googleJwks = jose.createRemoteJWKSet(
  new URL("https://www.googleapis.com/oauth2/v3/certs"),
);

export interface GoogleUserProfile {
  email: string;
  emailVerified: boolean;
  subject: string;
}

export async function verifyGoogleIdToken(
  token: string,
): Promise<GoogleUserProfile> {
  const googleClientId = process.env.GOOGLE_CLIENT_ID;

  if (!googleClientId) {
    logger.error("GOOGLE_CLIENT_ID environment variable not set");
    throw new Error("GOOGLE_CLIENT_ID not configured");
  }

  const { payload } = await jose.jwtVerify(token, googleJwks, {
    issuer: ["https://accounts.google.com", "accounts.google.com"],
    audience: googleClientId,
  });

  if (typeof payload.email !== "string" || payload.email.length === 0) {
    throw new Error("Google token is missing email");
  }

  if (typeof payload.sub !== "string" || payload.sub.length === 0) {
    throw new Error("Google token is missing subject");
  }

  return {
    email: payload.email,
    emailVerified: payload.email_verified === true,
    subject: payload.sub,
  };
}