mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
112 lines
2.8 KiB
JavaScript
112 lines
2.8 KiB
JavaScript
import passport from 'passport';
|
|
import common from '../../../common';
|
|
import { BadRequest } from '../errors';
|
|
import {
|
|
generateUsername,
|
|
loginRes,
|
|
} from './utils';
|
|
import { model as User } from '../../models/user';
|
|
import { model as EmailUnsubscription } from '../../models/emailUnsubscription';
|
|
import { sendTxn as sendTxnEmail } from '../email';
|
|
|
|
function _passportProfile (network, accessToken) {
|
|
return new Promise((resolve, reject) => {
|
|
passport._strategies[network].userProfile(accessToken, (err, profile) => {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve(profile);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
async function loginSocial (req, res) {
|
|
const existingUser = res.locals.user;
|
|
const accessToken = req.body.authResponse.access_token;
|
|
const network = req.body.network;
|
|
|
|
const isSupportedNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS.find(supportedNetwork => {
|
|
return supportedNetwork.key === network;
|
|
});
|
|
if (!isSupportedNetwork) throw new BadRequest(res.t('unsupportedNetwork'));
|
|
|
|
const profile = await _passportProfile(network, accessToken);
|
|
|
|
let user = await User.findOne({
|
|
[`auth.${network}.id`]: profile.id,
|
|
}, {_id: 1, apiToken: 1, auth: 1}).exec();
|
|
|
|
// User already signed up
|
|
if (user) {
|
|
return loginRes(user, ...arguments);
|
|
}
|
|
|
|
const generatedUsername = generateUsername();
|
|
|
|
user = {
|
|
auth: {
|
|
[network]: {
|
|
id: profile.id,
|
|
emails: profile.emails,
|
|
},
|
|
local: {
|
|
username: generatedUsername,
|
|
lowerCaseUsername: generatedUsername,
|
|
},
|
|
},
|
|
profile: {
|
|
name: profile.displayName || profile.name || profile.username,
|
|
},
|
|
preferences: {
|
|
language: req.language,
|
|
},
|
|
flags: {
|
|
verifiedUsername: true,
|
|
},
|
|
};
|
|
|
|
if (existingUser) {
|
|
existingUser.auth[network] = user.auth[network];
|
|
user = existingUser;
|
|
} else {
|
|
user = new User(user);
|
|
user.registeredThrough = req.headers['x-client']; // Not saved, used to create the correct tasks based on the device used
|
|
}
|
|
|
|
const savedUser = await user.save();
|
|
|
|
if (!existingUser) {
|
|
user.newUser = true;
|
|
}
|
|
|
|
loginRes(user, ...arguments);
|
|
|
|
// Clean previous email preferences
|
|
if (savedUser.auth[network].emails && savedUser.auth[network].emails[0] && savedUser.auth[network].emails[0].value) {
|
|
EmailUnsubscription
|
|
.remove({email: savedUser.auth[network].emails[0].value.toLowerCase()})
|
|
.exec()
|
|
.then(() => {
|
|
if (!existingUser) sendTxnEmail(savedUser, 'welcome');
|
|
}); // eslint-disable-line max-nested-callbacks
|
|
}
|
|
|
|
if (!existingUser) {
|
|
res.analytics.track('register', {
|
|
category: 'acquisition',
|
|
type: network,
|
|
gaLabel: network,
|
|
uuid: savedUser._id,
|
|
headers: req.headers,
|
|
user: savedUser,
|
|
});
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
module.exports = {
|
|
loginSocial,
|
|
};
|