import {google} from 'googleapis';
import {OAuth2Client} from 'google-auth-library';
import type {OAuthCredentials, OAuthTokens} from '../oauth.js';
const SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
export class OAuthHandler {
private readonly credentials: OAuthCredentials;
constructor(credentials: OAuthCredentials) {
this.credentials = credentials;
}
createOAuth2Client(tokens?: OAuthTokens): OAuth2Client {
const client = new google.auth.OAuth2(
this.credentials.client_id,
this.credentials.client_secret,
this.credentials.redirect_uri
);
if (tokens) {
client.setCredentials(tokens);
}
return client;
}
generateAuthUrl(state: string): string {
const client = this.createOAuth2Client();
return client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
prompt: 'consent',
state,
});
}
async exchangeCodeForTokens(code: string): Promise<OAuthTokens> {
const client = this.createOAuth2Client();
const {tokens} = await client.getToken(code);
return tokens as OAuthTokens;
}
async getUserInfo(tokens: OAuthTokens): Promise<{ email: string }> {
const client = this.createOAuth2Client(tokens);
const gmail = google.gmail({version: 'v1', auth: client});
const profile = await gmail.users.getProfile({userId: 'me'});
if (!profile.data.emailAddress) {
throw new Error('Gmail profile missing email address');
}
return {email: profile.data.emailAddress};
}
}