initial commit
This commit is contained in:
82
lib/google-oauth.ts
Normal file
82
lib/google-oauth.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
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<GoogleUserInfo> => {
|
||||
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<GoogleUserInfo> => {
|
||||
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 }
|
||||
Reference in New Issue
Block a user