Files
jambonz-api-server/lib/utils/oauth-utils.js
Dave Horton ed51d8b13f merge of features from hosted branch (#7)
major merge of features from the hosted branch that was created temporarily during the initial launch of jambonz.org
2021-06-17 15:56:21 -04:00

113 lines
3.9 KiB
JavaScript

const assert = require('assert');
const bent = require('bent');
const postJSON = bent('POST', 'json', 200);
const getJSON = bent('GET', 'json', 200);
const {emailSimpleText} = require('./email-utils');
const {DbErrorForbidden} = require('../utils/errors');
const doGithubAuth = async(logger, payload) => {
assert.ok(process.env.GITHUB_CLIENT_SECRET, 'env var GITHUB_CLIENT_SECRET is required');
try {
/* exchange the code for an access token */
const obj = await postJSON('https://github.com/login/oauth/access_token', {
client_id: payload.oauth2_client_id,
client_secret: process.env.GITHUB_CLIENT_SECRET,
code: payload.oauth2_code,
state: payload.oauth2_state,
redirect_uri: payload.oauth2_redirect_uri
});
if (!obj.access_token) {
logger.error({obj}, 'Error retrieving access_token from github');
if (obj.error === 'bad_verification_code') throw new Error('bad verification code');
throw new Error(obj.error || 'error retrieving access_token');
}
logger.debug({obj}, 'got response from github for access_token');
/* use the access token to get basic public info as well as primary email */
const userDetails = await getJSON('https://api.github.com/user', null, {
Authorization: `Bearer ${obj.access_token}`,
Accept: 'application/json',
'User-Agent': 'jambonz 1.0'
});
const emails = await getJSON('https://api.github.com/user/emails', null, {
Authorization: `Bearer ${obj.access_token}`,
Accept: 'application/json',
'User-Agent': 'jambonz 1.0'
});
const primary = emails.find((e) => e.primary);
if (primary) Object.assign(userDetails, {
email: primary.email,
email_validated: primary.validated
});
logger.info({userDetails}, 'retrieved user details from github');
return userDetails;
} catch (err) {
logger.info({err}, 'Error authenticating via github');
throw new DbErrorForbidden(err.message);
}
};
const doGoogleAuth = async(logger, payload) => {
assert.ok(process.env.GOOGLE_OAUTH_CLIENT_SECRET, 'env var GOOGLE_OAUTH_CLIENT_SECRET is required');
try {
/* exchange the code for an access token */
const obj = await postJSON('https://oauth2.googleapis.com/token', {
client_id: payload.oauth2_client_id,
client_secret: process.env.GOOGLE_OAUTH_CLIENT_SECRET,
code: payload.oauth2_code,
state: payload.oauth2_state,
redirect_uri: payload.oauth2_redirect_uri,
grant_type: 'authorization_code'
});
if (!obj.access_token) {
logger.error({obj}, 'Error retrieving access_token from github');
if (obj.error === 'bad_verification_code') throw new Error('bad verification code');
throw new Error(obj.error || 'error retrieving access_token');
}
logger.debug({obj}, 'got response from google for access_token');
/* use the access token to get basic public info as well as primary email */
const userDetails = await getJSON('https://www.googleapis.com/oauth2/v2/userinfo', null, {
Authorization: `Bearer ${obj.access_token}`,
Accept: 'application/json',
'User-Agent': 'jambonz 1.0'
});
logger.info({userDetails}, 'retrieved user details from google');
return userDetails;
} catch (err) {
logger.info({err}, 'Error authenticating via google');
throw new DbErrorForbidden(err.message);
}
};
const doLocalAuth = async(logger, payload) => {
const {name, email, password, email_activation_code} = payload;
const text = `Hi there
Welcome to jambonz! Your account activation code is ${email_activation_code}
Best,
The jambonz team`;
if ('test' !== process.env.NODE_ENV || process.env.MAILGUN_API_KEY) {
await emailSimpleText(logger, email, 'Account activation code', text);
}
return {
name,
email,
password,
email_activation_code
};
};
module.exports = {
doGithubAuth,
doGoogleAuth,
doLocalAuth
};