← back to AbramsOS

lib/google-oauth.js

50 lines

const { google } = require('googleapis');

const SCOPES = [
  'https://www.googleapis.com/auth/gmail.readonly',
  'https://www.googleapis.com/auth/drive.readonly',
  'https://www.googleapis.com/auth/userinfo.email',
];

function client() {
  const id = process.env.GOOGLE_OAUTH_ABRAMSOS_CLIENT_ID;
  const secret = process.env.GOOGLE_OAUTH_ABRAMSOS_CLIENT_SECRET;
  const redirect = process.env.GOOGLE_OAUTH_ABRAMSOS_REDIRECT_URI;
  if (!id || !secret || !redirect) {
    throw new Error('Google OAuth env vars not configured. Set GOOGLE_OAUTH_ABRAMSOS_{CLIENT_ID,CLIENT_SECRET,REDIRECT_URI} via /secrets.');
  }
  return new google.auth.OAuth2(id, secret, redirect);
}

function authUrl(state) {
  return client().generateAuthUrl({
    access_type: 'offline',
    prompt: 'consent',
    scope: SCOPES,
    state,
  });
}

async function exchange(code) {
  const c = client();
  const { tokens } = await c.getToken(code);
  c.setCredentials(tokens);
  const oauth2 = google.oauth2({ version: 'v2', auth: c });
  const me = await oauth2.userinfo.get();
  return {
    refreshToken: tokens.refresh_token,
    accessToken: tokens.access_token,
    expiryDate: tokens.expiry_date,
    email: me.data.email,
    sub: me.data.id,
  };
}

function clientFor(refreshToken) {
  const c = client();
  c.setCredentials({ refresh_token: refreshToken });
  return c;
}

module.exports = { SCOPES, authUrl, exchange, clientFor };