import { OAuth2Client } from 'google-auth-library' const client = new OAuth2Client( process.env.GOOGLE_CLIENT_ID, process.env.GOOGLE_CLIENT_SECRET, process.env.GOOGLE_REDIRECT_URI || `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:4023'}/api/auth/google/callback` ) export interface GoogleUserInfo { id: string email: string name: string picture?: string given_name?: string family_name?: string verified_email: boolean } export const getGoogleAuthURL = () => { const scopes = ['openid', 'profile', 'email'] return client.generateAuthUrl({ access_type: 'offline', scope: scopes, prompt: 'consent', state: 'google_oauth', }) } export const getGoogleUser = async (code: string): Promise => { const { tokens } = await client.getToken(code) if (!tokens.access_token) { throw new Error('No access token received from Google') } // Get user info from Google const response = await fetch( `https://www.googleapis.com/oauth2/v2/userinfo?access_token=${tokens.access_token}` ) if (!response.ok) { throw new Error('Failed to fetch user info from Google') } const userInfo = (await response.json()) as GoogleUserInfo if (!userInfo.verified_email) { throw new Error('Google email not verified') } return userInfo } export const verifyGoogleToken = async (token: string): Promise => { try { const ticket = await client.verifyIdToken({ idToken: token, audience: process.env.GOOGLE_CLIENT_ID, }) const payload = ticket.getPayload() if (!payload) { throw new Error('Invalid Google token payload') } return { id: payload.sub, email: payload.email!, name: payload.name!, picture: payload.picture, given_name: payload.given_name, family_name: payload.family_name, verified_email: payload.email_verified || false, } } catch (error) { throw new Error('Failed to verify Google token') } } export { client as googleOAuthClient }