2018-01-12 15:20:13 +01:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Module dependencies.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Public node modules.
|
|
|
|
const _ = require('lodash');
|
2018-01-23 09:30:25 +01:00
|
|
|
const request = require('request');
|
2018-01-12 15:20:13 +01:00
|
|
|
|
2019-04-05 16:11:09 +02:00
|
|
|
// Purest strategies.<
|
2018-01-12 15:20:13 +01:00
|
|
|
const Purest = require('purest');
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Connect thanks to a third-party provider.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {String} provider
|
|
|
|
* @param {String} access_token
|
|
|
|
*
|
|
|
|
* @return {*}
|
|
|
|
*/
|
|
|
|
|
2018-01-23 09:30:25 +01:00
|
|
|
exports.connect = (provider, query) => {
|
2018-04-30 18:26:56 +02:00
|
|
|
const access_token = query.access_token || query.code || query.oauth_token;
|
2018-01-23 09:30:25 +01:00
|
|
|
|
2018-01-12 15:20:13 +01:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
if (!access_token) {
|
2019-10-12 22:35:39 +02:00
|
|
|
return reject([null, { message: 'No access_token.' }]);
|
2018-01-12 15:20:13 +01:00
|
|
|
}
|
2018-01-25 11:53:22 +01:00
|
|
|
|
|
|
|
// Get the profile.
|
|
|
|
getProfile(provider, query, async (err, profile) => {
|
|
|
|
if (err) {
|
2019-10-12 22:35:39 +02:00
|
|
|
return reject([null, err]);
|
2018-01-25 11:53:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// We need at least the mail.
|
|
|
|
if (!profile.email) {
|
2019-10-12 22:35:39 +02:00
|
|
|
return reject([null, { message: 'Email was not available.' }]);
|
2018-01-25 13:43:07 +01:00
|
|
|
}
|
|
|
|
|
2018-01-25 12:26:09 +01:00
|
|
|
try {
|
2019-07-15 23:16:50 +02:00
|
|
|
const users = await strapi.query('user', 'users-permissions').find({
|
|
|
|
email: profile.email,
|
2019-02-03 13:49:55 +01:00
|
|
|
});
|
2018-01-25 11:53:22 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
const advanced = await strapi
|
|
|
|
.store({
|
|
|
|
environment: '',
|
|
|
|
type: 'plugin',
|
|
|
|
name: 'users-permissions',
|
|
|
|
key: 'advanced',
|
|
|
|
})
|
|
|
|
.get();
|
2018-02-01 18:12:38 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
if (
|
|
|
|
_.isEmpty(_.find(users, { provider })) &&
|
|
|
|
!advanced.allow_register
|
|
|
|
) {
|
|
|
|
return resolve([
|
|
|
|
null,
|
|
|
|
[{ messages: [{ id: 'Auth.advanced.allow_register' }] }],
|
|
|
|
'Register action is actualy not available.',
|
|
|
|
]);
|
2018-01-25 12:26:09 +01:00
|
|
|
}
|
2018-01-25 11:53:22 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
const user = _.find(users, { provider });
|
2018-02-14 17:02:44 +01:00
|
|
|
|
|
|
|
if (!_.isEmpty(user)) {
|
2018-01-25 15:48:56 +01:00
|
|
|
return resolve([user, null]);
|
2018-01-25 12:26:09 +01:00
|
|
|
}
|
2018-01-25 11:53:22 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
if (
|
|
|
|
!_.isEmpty(_.find(users, user => user.provider !== provider)) &&
|
|
|
|
advanced.unique_email
|
|
|
|
) {
|
|
|
|
return resolve([
|
|
|
|
null,
|
|
|
|
[{ messages: [{ id: 'Auth.form.error.email.taken' }] }],
|
|
|
|
'Email is already taken.',
|
|
|
|
]);
|
2018-01-25 12:26:09 +01:00
|
|
|
}
|
2018-01-25 11:53:22 +01:00
|
|
|
|
2018-06-12 19:19:10 +02:00
|
|
|
// Retrieve default role.
|
2019-07-15 23:16:50 +02:00
|
|
|
const defaultRole = await strapi
|
|
|
|
.query('role', 'users-permissions')
|
|
|
|
.findOne({ type: advanced.default_role }, []);
|
2018-01-25 16:37:35 +01:00
|
|
|
|
2018-01-29 17:12:49 +01:00
|
|
|
// Create the new user.
|
|
|
|
const params = _.assign(profile, {
|
|
|
|
provider: provider,
|
2019-08-13 16:31:29 +02:00
|
|
|
role: defaultRole.id,
|
2019-11-06 09:56:31 +01:00
|
|
|
confirmed: true,
|
2018-01-29 17:12:49 +01:00
|
|
|
});
|
2018-01-25 11:53:22 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
const createdUser = await strapi
|
|
|
|
.query('user', 'users-permissions')
|
|
|
|
.create(params);
|
2018-01-25 11:53:22 +01:00
|
|
|
|
2018-01-29 17:12:49 +01:00
|
|
|
return resolve([createdUser, null]);
|
2018-01-25 12:26:09 +01:00
|
|
|
} catch (err) {
|
|
|
|
reject([null, err]);
|
2018-01-25 11:53:22 +01:00
|
|
|
}
|
|
|
|
});
|
2018-01-12 15:20:13 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper to get profiles
|
|
|
|
*
|
|
|
|
* @param {String} provider
|
|
|
|
* @param {Function} callback
|
|
|
|
*/
|
|
|
|
|
2018-02-01 18:12:38 +01:00
|
|
|
const getProfile = async (provider, query, callback) => {
|
2018-04-30 18:26:56 +02:00
|
|
|
const access_token = query.access_token || query.code || query.oauth_token;
|
2018-01-23 09:30:25 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
const grant = await strapi
|
|
|
|
.store({
|
|
|
|
environment: '',
|
|
|
|
type: 'plugin',
|
|
|
|
name: 'users-permissions',
|
|
|
|
key: 'grant',
|
|
|
|
})
|
|
|
|
.get();
|
2018-02-01 18:12:38 +01:00
|
|
|
|
2018-01-12 15:20:13 +01:00
|
|
|
switch (provider) {
|
2018-07-29 17:43:45 -07:00
|
|
|
case 'discord': {
|
|
|
|
const discord = new Purest({
|
|
|
|
provider: 'discord',
|
|
|
|
config: {
|
2019-07-15 23:16:50 +02:00
|
|
|
discord: {
|
2018-07-29 17:43:45 -07:00
|
|
|
'https://discordapp.com/api/': {
|
2019-07-15 23:16:50 +02:00
|
|
|
__domain: {
|
|
|
|
auth: {
|
|
|
|
auth: { bearer: '[0]' },
|
|
|
|
},
|
2018-07-29 17:43:45 -07:00
|
|
|
},
|
|
|
|
'{endpoint}': {
|
2019-07-15 23:16:50 +02:00
|
|
|
__path: {
|
|
|
|
alias: '__default',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2018-07-29 17:43:45 -07:00
|
|
|
});
|
2019-07-15 23:16:50 +02:00
|
|
|
discord
|
|
|
|
.query()
|
|
|
|
.get('users/@me')
|
|
|
|
.auth(access_token)
|
|
|
|
.request((err, res, body) => {
|
|
|
|
if (err) {
|
|
|
|
callback(err);
|
|
|
|
} else {
|
|
|
|
// Combine username and discriminator because discord username is not unique
|
|
|
|
var username = `${body.username}#${body.discriminator}`;
|
|
|
|
callback(null, {
|
|
|
|
username: username,
|
|
|
|
email: body.email,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2018-07-29 17:43:45 -07:00
|
|
|
break;
|
|
|
|
}
|
2018-04-30 18:26:56 +02:00
|
|
|
case 'facebook': {
|
2018-01-25 15:04:42 +01:00
|
|
|
const facebook = new Purest({
|
2019-07-15 23:16:50 +02:00
|
|
|
provider: 'facebook',
|
2018-01-25 15:04:42 +01:00
|
|
|
});
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
facebook
|
|
|
|
.query()
|
|
|
|
.get('me?fields=name,email')
|
|
|
|
.auth(access_token)
|
|
|
|
.request((err, res, body) => {
|
|
|
|
if (err) {
|
|
|
|
callback(err);
|
|
|
|
} else {
|
|
|
|
callback(null, {
|
|
|
|
username: body.name,
|
|
|
|
email: body.email,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2018-01-12 15:20:13 +01:00
|
|
|
break;
|
2018-04-30 18:26:56 +02:00
|
|
|
}
|
|
|
|
case 'google': {
|
2019-07-12 19:46:09 +02:00
|
|
|
const config = {
|
2019-07-18 19:28:52 +02:00
|
|
|
google: {
|
|
|
|
'https://www.googleapis.com': {
|
|
|
|
__domain: {
|
|
|
|
auth: {
|
|
|
|
auth: { bearer: '[0]' },
|
|
|
|
},
|
2019-07-12 19:46:09 +02:00
|
|
|
},
|
2019-07-18 19:28:52 +02:00
|
|
|
'{endpoint}': {
|
|
|
|
__path: {
|
|
|
|
alias: '__default',
|
|
|
|
},
|
2019-07-12 19:46:09 +02:00
|
|
|
},
|
2019-07-18 19:28:52 +02:00
|
|
|
'oauth/[version]/{endpoint}': {
|
|
|
|
__path: {
|
|
|
|
alias: 'oauth',
|
|
|
|
version: 'v3',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
const google = new Purest({ provider: 'google', config });
|
2018-01-25 15:04:42 +01:00
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
google
|
2019-07-18 19:28:52 +02:00
|
|
|
.query('oauth')
|
|
|
|
.get('tokeninfo')
|
|
|
|
.qs({ access_token })
|
2019-07-15 23:16:50 +02:00
|
|
|
.request((err, res, body) => {
|
|
|
|
if (err) {
|
|
|
|
callback(err);
|
|
|
|
} else {
|
|
|
|
callback(null, {
|
2019-07-18 19:28:52 +02:00
|
|
|
username: body.email.split('@')[0],
|
|
|
|
email: body.email,
|
2019-07-15 23:16:50 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2018-01-12 15:20:13 +01:00
|
|
|
break;
|
2018-04-30 18:26:56 +02:00
|
|
|
}
|
|
|
|
case 'github': {
|
2018-01-25 15:04:42 +01:00
|
|
|
const github = new Purest({
|
|
|
|
provider: 'github',
|
|
|
|
defaults: {
|
|
|
|
headers: {
|
2019-07-15 23:16:50 +02:00
|
|
|
'user-agent': 'strapi',
|
|
|
|
},
|
|
|
|
},
|
2018-01-25 15:04:42 +01:00
|
|
|
});
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
request.post(
|
|
|
|
{
|
|
|
|
url: 'https://github.com/login/oauth/access_token',
|
|
|
|
form: {
|
|
|
|
client_id: grant.github.key,
|
|
|
|
client_secret: grant.github.secret,
|
|
|
|
code: access_token,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
(err, res, body) => {
|
|
|
|
github
|
|
|
|
.query()
|
|
|
|
.get('user')
|
|
|
|
.auth(body.split('&')[0].split('=')[1])
|
2019-10-12 22:43:44 +02:00
|
|
|
.request((err, res, userbody) => {
|
2019-07-15 23:16:50 +02:00
|
|
|
if (err) {
|
2019-10-12 22:43:44 +02:00
|
|
|
return callback(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is the public email on the github profile
|
|
|
|
if (userbody.email) {
|
|
|
|
return callback(null, {
|
|
|
|
username: userbody.login,
|
|
|
|
email: userbody.email,
|
2019-07-15 23:16:50 +02:00
|
|
|
});
|
|
|
|
}
|
2019-10-12 22:43:44 +02:00
|
|
|
|
|
|
|
// Get the email with Github's user/emails API
|
|
|
|
github
|
|
|
|
.query()
|
|
|
|
.get('user/emails')
|
|
|
|
.auth(body.split('&')[0].split('=')[1])
|
|
|
|
.request((err, res, emailsbody) => {
|
|
|
|
if (err) {
|
|
|
|
return callback(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
return callback(null, {
|
|
|
|
username: userbody.login,
|
|
|
|
email: Array.isArray(emailsbody)
|
|
|
|
? emailsbody.find(email => email.primary === true).email
|
|
|
|
: null,
|
|
|
|
});
|
|
|
|
});
|
2018-01-23 09:30:25 +01:00
|
|
|
});
|
2019-07-15 23:16:50 +02:00
|
|
|
}
|
|
|
|
);
|
2018-01-12 15:20:13 +01:00
|
|
|
break;
|
2018-04-30 18:26:56 +02:00
|
|
|
}
|
2018-07-22 22:03:29 -04:00
|
|
|
case 'microsoft': {
|
|
|
|
const microsoft = new Purest({
|
|
|
|
provider: 'microsoft',
|
2019-07-15 23:16:50 +02:00
|
|
|
config: {
|
|
|
|
microsoft: {
|
2018-07-22 22:03:29 -04:00
|
|
|
'https://graph.microsoft.com': {
|
2019-07-15 23:16:50 +02:00
|
|
|
__domain: {
|
|
|
|
auth: {
|
|
|
|
auth: { bearer: '[0]' },
|
|
|
|
},
|
2018-07-22 22:03:29 -04:00
|
|
|
},
|
|
|
|
'[version]/{endpoint}': {
|
2019-07-15 23:16:50 +02:00
|
|
|
__path: {
|
|
|
|
alias: '__default',
|
|
|
|
version: 'v1.0',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2018-07-22 22:03:29 -04:00
|
|
|
});
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
microsoft
|
|
|
|
.query()
|
|
|
|
.get('me')
|
|
|
|
.auth(access_token)
|
|
|
|
.request((err, res, body) => {
|
|
|
|
if (err) {
|
|
|
|
callback(err);
|
|
|
|
} else {
|
|
|
|
callback(null, {
|
|
|
|
username: body.userPrincipalName,
|
|
|
|
email: body.userPrincipalName,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2018-07-22 22:03:29 -04:00
|
|
|
break;
|
|
|
|
}
|
2018-04-30 18:26:56 +02:00
|
|
|
case 'twitter': {
|
2018-01-25 15:04:42 +01:00
|
|
|
const twitter = new Purest({
|
|
|
|
provider: 'twitter',
|
2018-02-01 18:12:38 +01:00
|
|
|
key: grant.twitter.key,
|
2019-07-15 23:16:50 +02:00
|
|
|
secret: grant.twitter.secret,
|
2018-01-25 15:04:42 +01:00
|
|
|
});
|
|
|
|
|
2019-07-15 23:16:50 +02:00
|
|
|
twitter
|
|
|
|
.query()
|
|
|
|
.get('account/verify_credentials')
|
|
|
|
.auth(access_token, query.access_secret)
|
|
|
|
.qs({ screen_name: query['raw[screen_name]'], include_email: 'true' })
|
|
|
|
.request((err, res, body) => {
|
|
|
|
if (err) {
|
|
|
|
callback(err);
|
|
|
|
} else {
|
|
|
|
callback(null, {
|
|
|
|
username: body.screen_name,
|
|
|
|
email: body.email,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2018-01-12 15:20:13 +01:00
|
|
|
break;
|
2018-04-30 18:26:56 +02:00
|
|
|
}
|
2019-09-06 09:14:42 +02:00
|
|
|
case 'instagram': {
|
|
|
|
const instagram = new Purest({
|
|
|
|
provider: 'instagram',
|
|
|
|
key: grant.instagram.key,
|
2019-09-27 16:26:09 +02:00
|
|
|
secret: grant.instagram.secret,
|
2019-09-06 09:14:42 +02:00
|
|
|
});
|
2019-09-27 16:26:09 +02:00
|
|
|
|
|
|
|
instagram
|
|
|
|
.query()
|
|
|
|
.get('users/self')
|
|
|
|
.qs({ access_token })
|
|
|
|
.request((err, res, body) => {
|
|
|
|
if (err) {
|
|
|
|
callback(err);
|
|
|
|
} else {
|
|
|
|
callback(null, {
|
|
|
|
username: body.data.username,
|
|
|
|
email: `${body.data.username}@strapi.io`, // dummy email as Instagram does not provide user email
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2019-09-06 09:14:42 +02:00
|
|
|
break;
|
|
|
|
}
|
2018-01-12 15:20:13 +01:00
|
|
|
default:
|
|
|
|
callback({
|
2019-07-15 23:16:50 +02:00
|
|
|
message: 'Unknown provider.',
|
2018-01-12 15:20:13 +01:00
|
|
|
});
|
|
|
|
break;
|
|
|
|
}
|
2018-04-30 18:26:56 +02:00
|
|
|
};
|