WebJamApps/web-jam-back

View on GitHub
src/auth/google.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
import superagent from 'superagent';
import Debug from 'debug';

const debug = Debug('web-jam-back:auth/google');

const accessTokenUrl = 'https://accounts.google.com/o/oauth2/token';
const peopleApiUrl = 'https://people.googleapis.com/v1/people/me?personFields=names%2CemailAddresses';

export interface GoogleAuthenticateResponse {
  emailAddresses: { value: string }[];
  names: { displayName: string }[];
}

async function authenticate(req: { body: { redirectUri: string; code: string; clientId: string; }; }): Promise<GoogleAuthenticateResponse> {
  let reUri = req.body.redirectUri, token, profile;
  if (reUri && reUri.includes('localhost')) {
    reUri = reUri.replace('https', 'http');
  }
  const params = {
    code: req.body.code,
    client_id: req.body.clientId,
    client_secret: process.env.GoogleClientSecret,
    redirect_uri: reUri,
    grant_type: 'authorization_code',
  };
  try { // Step 1. Exchange authorization code for access token.
    token = await superagent.post(accessTokenUrl).type('form').send(params).set('Accept', 'application/json');
    debug(token.body);
  } catch (e) { debug(e); return Promise.reject(e); }
  try { // Step 2. Retrieve profile information about the current user.
    profile = await superagent.get(peopleApiUrl).set({ Authorization: `Bearer ${token.body.access_token}`, Accept: 'application/json' });
  } catch (e) {
    const eMessage = (e as Error).message;
    debug(eMessage);
    throw new Error(`Failed to receive google profile information, ${eMessage}`);
  }
  if (profile === null || profile === undefined || profile.body.emailAddresses === null || profile.body.emailAddresses === undefined) {
    throw new Error('Failed to retrieve a proper user profile from Google');
  }
  return profile.body;
}

export default { authenticate };