first commit
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
const querystring = require('querystring');
|
||||
const axios = require('axios').default;
|
||||
|
||||
const db = require('../models');
|
||||
|
||||
module.exports = {
|
||||
google: {
|
||||
/**
|
||||
* Generates authentication URL
|
||||
* @name oAuth.google.generateAuthURL
|
||||
* @param {{redirect_uri: String, client_id: String}} config
|
||||
* @returns {String} authentication URL
|
||||
*/
|
||||
generateAuthURL(config) {
|
||||
const rootUrl = 'https://accounts.google.com/o/oauth2/v2/auth';
|
||||
|
||||
const options = {
|
||||
redirect_uri: config.redirect_uri,
|
||||
client_id: config.client_id,
|
||||
access_type: 'offline',
|
||||
response_type: 'code',
|
||||
prompt: 'consent',
|
||||
scope: ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email'].join(' '),
|
||||
};
|
||||
|
||||
return `${rootUrl}?${querystring.stringify(options)}`;
|
||||
},
|
||||
/**
|
||||
* Generates authentication Token
|
||||
* @name oAuth.google.generateAuthToken
|
||||
* @param {{auth_code: String, client_id: String, client_secret: String, redirect_uri: String}} config
|
||||
* @returns {Promise.<{{access_token: String, expires_in: String, refresh_token: String, scope: String, token_type: String id_token: String}}>} authentication token
|
||||
*/
|
||||
generateAuthToken(config) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const url = 'https://oauth2.googleapis.com/token';
|
||||
|
||||
const buildQuerystring = querystring.stringify({
|
||||
code: config.auth_code,
|
||||
client_id: config.client_id,
|
||||
client_secret: config.client_secret,
|
||||
redirect_uri: config.redirect_uri,
|
||||
grant_type: 'authorization_code',
|
||||
});
|
||||
|
||||
axios.default
|
||||
.post(url, buildQuerystring, {
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
})
|
||||
.then((response) => resolve(response.data))
|
||||
.catch((error) => reject(error));
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Retrieve user information
|
||||
* @name oAuth.google.getUserInfo
|
||||
* @param {{access_token: String, expires_in: String, refresh_token: String, scope: String, id_token: String}} config
|
||||
* @returns {Promise.<{id: string, email: string, verified_email: true, name: string, given_name: string, family_name: string, picture: string, locale: string}>} user information
|
||||
*/
|
||||
getUserInfo(config, isAPI = false) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
axios
|
||||
.get(
|
||||
`https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${config.access_token}`,
|
||||
isAPI
|
||||
? {}
|
||||
: {
|
||||
headers: {
|
||||
Authorization: `Bearer ${config.id_token}`,
|
||||
},
|
||||
},
|
||||
)
|
||||
.then((response) => resolve(response.data))
|
||||
.catch((error) => reject(error));
|
||||
});
|
||||
},
|
||||
},
|
||||
facebook: {
|
||||
/**
|
||||
* Generates authentication URL
|
||||
* @name oAuth.facebook.generateAuthURL
|
||||
* @param {{redirect_uri: String, client_id: String}} config
|
||||
* @returns {String} authentication URL
|
||||
*/
|
||||
generateAuthURL(config) {
|
||||
const stringifiedParams = querystring.stringify({
|
||||
client_id: config.client_id,
|
||||
redirect_uri: process.env.DYNAMIC_CONFIG_FACEBOOK_REDIRECT_URI,
|
||||
scope: ['email', 'user_friends'].join(','),
|
||||
response_type: 'code',
|
||||
auth_type: 'rerequest',
|
||||
display: 'popup',
|
||||
});
|
||||
|
||||
return `https://www.facebook.com/v4.0/dialog/oauth?${stringifiedParams}`;
|
||||
},
|
||||
/**
|
||||
* Generates authentication Token
|
||||
* @name oAuth.facebook.generateAuthToken
|
||||
* @param {{auth_code: String, client_id: String, client_secret: String, redirect_uri: String}} config
|
||||
* @returns {Promise.<{access_token: String, token_type: String, expires_in: String}>} authentication token
|
||||
*/
|
||||
async generateAuthToken(config) {
|
||||
const url = 'https://graph.facebook.com/v4.0/oauth/access_token';
|
||||
|
||||
const { data } = await axios({
|
||||
url,
|
||||
method: 'GET',
|
||||
params: {
|
||||
code: config.auth_code,
|
||||
client_id: config.client_id,
|
||||
client_secret: config.client_secret,
|
||||
redirect_uri: config.redirect_uri,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
/**
|
||||
* Retrieve user information
|
||||
* @name oAuth.facebook.getUserInfo
|
||||
* @param {{access_token: String, token_type: String, expires_in: String}} config
|
||||
* @returns {Promise.<{id: string, email: string, first_name: string, last_name: string, image: string}>} user information
|
||||
*/
|
||||
async getUserInfo(config) {
|
||||
const { data } = await axios({
|
||||
url: 'https://graph.facebook.com/me',
|
||||
method: 'GET',
|
||||
params: {
|
||||
fields: ['id', 'email', 'first_name', 'last_name'].join(','),
|
||||
access_token: config.access_token,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
},
|
||||
async authenticate(user) {
|
||||
let User;
|
||||
let Credential;
|
||||
try {
|
||||
const isEmailExist = await db.credential.getByField('email', user.email);
|
||||
if (isEmailExist) {
|
||||
// Check status and role
|
||||
if (+isEmailExist.status === 0 || +user.role === +isEmailExist.role) {
|
||||
throw new Error('EMAIL_ADDRESS_NOT_FOUND');
|
||||
}
|
||||
// Check provider type type
|
||||
const type = isEmailExist.type === user.provider;
|
||||
if (!type) {
|
||||
throw new Error('ACCOUNT_IS_REGISTERED_WITH_' + (user.provider === 'n' ? 'EMAIL_AND_PASSWORD' : user.provider === 'g' ? 'GOOGLE' : 'FACEBOOK'));
|
||||
}
|
||||
const userExists = await db.user.getByPK(isEmailExist.user_id);
|
||||
|
||||
if (!userExists) {
|
||||
throw new Error('EMAIL_ADDRESS_NOT_FOUND');
|
||||
}
|
||||
|
||||
return {
|
||||
credential: isEmailExist.id,
|
||||
user: userExists,
|
||||
};
|
||||
}
|
||||
|
||||
User = await db.user.insert(
|
||||
{
|
||||
first_name: user.first_name,
|
||||
last_name: user.last_name,
|
||||
image: user.image,
|
||||
},
|
||||
{ returnAllFields: true },
|
||||
);
|
||||
|
||||
Credential = await db.credential.insert(
|
||||
{
|
||||
user_id: User.id,
|
||||
email: user.email,
|
||||
type: user.provider,
|
||||
role_id: user.role_id,
|
||||
status: 1,
|
||||
},
|
||||
{ returnAllFields: true },
|
||||
);
|
||||
|
||||
return { credential: Credential.id, user: User };
|
||||
} catch (error) {
|
||||
if (User) {
|
||||
User.destroy();
|
||||
}
|
||||
|
||||
if (Credential) {
|
||||
Credential.destroy();
|
||||
}
|
||||
|
||||
throw new Error(error.message);
|
||||
}
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user