passport login error handling
This commit is contained in:
parent
c758fee082
commit
81e1d50aae
|
@ -12,9 +12,9 @@ import { Strategy as FacebookStrategy } from 'passport-facebook';
|
||||||
import { Strategy as VkontakteStrategy } from 'passport-vkontakte';
|
import { Strategy as VkontakteStrategy } from 'passport-vkontakte';
|
||||||
import { OAuth2Strategy as GoogleStrategy } from 'passport-google-oauth';
|
import { OAuth2Strategy as GoogleStrategy } from 'passport-google-oauth';
|
||||||
|
|
||||||
|
import logger from './logger';
|
||||||
import { sanitizeName } from '../utils/validation';
|
import { sanitizeName } from '../utils/validation';
|
||||||
|
|
||||||
import logger from './logger';
|
|
||||||
import { User, RegUser } from '../data/models';
|
import { User, RegUser } from '../data/models';
|
||||||
import { auth } from './config';
|
import { auth } from './config';
|
||||||
import { compareToHash } from '../utils/hash';
|
import { compareToHash } from '../utils/hash';
|
||||||
|
@ -50,37 +50,44 @@ passport.use(new JsonStrategy({
|
||||||
usernameProp: 'nameoremail',
|
usernameProp: 'nameoremail',
|
||||||
passwordProp: 'password',
|
passwordProp: 'password',
|
||||||
}, (nameoremail, password, done) => {
|
}, (nameoremail, password, done) => {
|
||||||
// Decide if email or name by the occurance of @
|
try {
|
||||||
// this is why we don't allow @ in usernames
|
// Decide if email or name by the occurance of @
|
||||||
// NOTE: could allow @ in the future by making an OR query,
|
// this is why we don't allow @ in usernames
|
||||||
// but i guess nobody really cares.
|
// NOTE: could allow @ in the future by making an OR query,
|
||||||
// https://sequelize.org/master/manual/querying.html
|
// but i guess nobody really cares.
|
||||||
const query = (nameoremail.indexOf('@') !== -1) ? { email: nameoremail } : { name: nameoremail };
|
// https://sequelize.org/master/manual/querying.html
|
||||||
RegUser.findOne({ where: query }).then((reguser) => {
|
const query = (nameoremail.indexOf('@') !== -1)
|
||||||
if (!reguser) {
|
? { email: nameoremail }
|
||||||
return done(null, false, { message: 'Name or Email does not exist!' });
|
: { name: nameoremail };
|
||||||
}
|
RegUser.findOne({ where: query }).then((reguser) => {
|
||||||
if (!compareToHash(password, reguser.password)) {
|
if (!reguser) {
|
||||||
return done(null, false, { message: 'Incorrect password!' });
|
return done(null, false, { message: 'Name or Email does not exist!' });
|
||||||
}
|
}
|
||||||
const user = new User(reguser.id);
|
if (!compareToHash(password, reguser.password)) {
|
||||||
user.regUser = reguser;
|
return done(null, false, { message: 'Incorrect password!' });
|
||||||
user.updateLogInTimestamp();
|
}
|
||||||
return done(null, user);
|
const user = new User(reguser.id);
|
||||||
});
|
user.regUser = reguser;
|
||||||
|
user.updateLogInTimestamp();
|
||||||
|
return done(null, user);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OAuth SignIns, mail based
|
* OAuth SignIns, mail based
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
async function oauth_login(email, name, discordid = null) {
|
async function oauthLogin(email, name, discordid = null) {
|
||||||
name = sanitizeName(name);
|
name = sanitizeName(name);
|
||||||
let reguser = await RegUser.findOne({ where: { email } });
|
let reguser = await RegUser.findOne({ where: { email } });
|
||||||
if (!reguser) {
|
if (!reguser) {
|
||||||
reguser = await RegUser.findOne({ where: { name } });
|
reguser = await RegUser.findOne({ where: { name } });
|
||||||
while (reguser) {
|
while (reguser) {
|
||||||
// name is taken by someone else
|
// name is taken by someone else
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
name = `${name.substring(0, 15)}-${Math.random().toString(36).substring(2, 10)}`;
|
name = `${name.substring(0, 15)}-${Math.random().toString(36).substring(2, 10)}`;
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
reguser = await RegUser.findOne({ where: { name } });
|
reguser = await RegUser.findOne({ where: { name } });
|
||||||
|
@ -109,10 +116,14 @@ passport.use(new FacebookStrategy({
|
||||||
proxy: true,
|
proxy: true,
|
||||||
profileFields: ['displayName', 'email'],
|
profileFields: ['displayName', 'email'],
|
||||||
}, async (req, accessToken, refreshToken, profile, done) => {
|
}, async (req, accessToken, refreshToken, profile, done) => {
|
||||||
const { displayName: name, emails } = profile;
|
try {
|
||||||
const email = emails[0].value;
|
const { displayName: name, emails } = profile;
|
||||||
const user = await oauth_login(email, name);
|
const email = emails[0].value;
|
||||||
done(null, user);
|
const user = await oauthLogin(email, name);
|
||||||
|
done(null, user);
|
||||||
|
} catch (err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,11 +134,20 @@ passport.use(new DiscordStrategy({
|
||||||
callbackURL: '/api/auth/discord/return',
|
callbackURL: '/api/auth/discord/return',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
}, async (accessToken, refreshToken, profile, done) => {
|
}, async (accessToken, refreshToken, profile, done) => {
|
||||||
// TODO get discord id
|
try {
|
||||||
console.log({ profile, refreshToken, accessToken });
|
logger.info({ profile, refreshToken, accessToken });
|
||||||
const { id, email, username: name } = profile;
|
const { id, email, username: name } = profile;
|
||||||
const user = await oauth_login(email, name, id);
|
if (!email) {
|
||||||
done(null, user);
|
done(null, false, {
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
message: 'Sorry, you can not use discord login with an discord account that does not have email set.',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const user = await oauthLogin(email, name, id);
|
||||||
|
done(null, user);
|
||||||
|
} catch (err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,10 +158,14 @@ passport.use(new GoogleStrategy({
|
||||||
callbackURL: '/api/auth/google/return',
|
callbackURL: '/api/auth/google/return',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
}, async (accessToken, refreshToken, profile, done) => {
|
}, async (accessToken, refreshToken, profile, done) => {
|
||||||
const { displayName: name, emails } = profile;
|
try {
|
||||||
const email = emails[0].value;
|
const { displayName: name, emails } = profile;
|
||||||
const user = await oauth_login(email, name);
|
const email = emails[0].value;
|
||||||
done(null, user);
|
const user = await oauthLogin(email, name);
|
||||||
|
done(null, user);
|
||||||
|
} catch (err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -152,28 +176,34 @@ passport.use(new RedditStrategy({
|
||||||
callbackURL: '/api/auth/reddit/return',
|
callbackURL: '/api/auth/reddit/return',
|
||||||
proxy: true,
|
proxy: true,
|
||||||
}, async (accessToken, refreshToken, profile, done) => {
|
}, async (accessToken, refreshToken, profile, done) => {
|
||||||
console.log({ profile, refreshToken, accessToken });
|
try {
|
||||||
const redditid = profile.id;
|
logger.info({ profile, refreshToken, accessToken });
|
||||||
let name = sanitizeName(profile.name);
|
const redditid = profile.id;
|
||||||
// reddit needs an own login strategy based on its id,
|
let name = sanitizeName(profile.name);
|
||||||
// because we can not access it's mail
|
// reddit needs an own login strategy based on its id,
|
||||||
let reguser = await RegUser.findOne({ where: { redditid } });
|
// because we can not access it's mail
|
||||||
if (!reguser) {
|
let reguser = await RegUser.findOne({ where: { redditid } });
|
||||||
reguser = await RegUser.findOne({ where: { name } });
|
if (!reguser) {
|
||||||
while (reguser) {
|
|
||||||
// name is taken by someone else
|
|
||||||
name = `${name.substring(0, 15)}-${Math.random().toString(36).substring(2, 10)}`;
|
|
||||||
reguser = await RegUser.findOne({ where: { name } });
|
reguser = await RegUser.findOne({ where: { name } });
|
||||||
|
while (reguser) {
|
||||||
|
// name is taken by someone else
|
||||||
|
// eslint-disable-next-line max-len
|
||||||
|
name = `${name.substring(0, 15)}-${Math.random().toString(36).substring(2, 10)}`;
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
reguser = await RegUser.findOne({ where: { name } });
|
||||||
|
}
|
||||||
|
reguser = await RegUser.create({
|
||||||
|
name,
|
||||||
|
verified: 1,
|
||||||
|
redditid,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
reguser = await RegUser.create({
|
const user = new User(reguser.id);
|
||||||
name,
|
user.regUser = reguser;
|
||||||
verified: 1,
|
done(null, user);
|
||||||
redditid,
|
} catch (err) {
|
||||||
});
|
done(err);
|
||||||
}
|
}
|
||||||
const user = new User(reguser.id);
|
|
||||||
user.regUser = reguser;
|
|
||||||
done(null, user);
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,11 +216,15 @@ passport.use(new VkontakteStrategy({
|
||||||
scope: ['email'],
|
scope: ['email'],
|
||||||
profileFields: ['displayName', 'email'],
|
profileFields: ['displayName', 'email'],
|
||||||
}, async (accessToken, refreshToken, params, profile, done) => {
|
}, async (accessToken, refreshToken, params, profile, done) => {
|
||||||
console.log(profile);
|
try {
|
||||||
const { displayName: name } = profile;
|
logger.info(profile);
|
||||||
const { email } = params;
|
const { displayName: name } = profile;
|
||||||
const user = await oauth_login(email, name);
|
const { email } = params;
|
||||||
done(null, user);
|
const user = await oauthLogin(email, name);
|
||||||
|
done(null, user);
|
||||||
|
} catch (err) {
|
||||||
|
done(err);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,10 @@ export default (passport) => {
|
||||||
'Content-Type': 'text/html',
|
'Content-Type': 'text/html',
|
||||||
});
|
});
|
||||||
const host = getHostFromRequest(req);
|
const host = getHostFromRequest(req);
|
||||||
const index = getHtml('OAuth Authentification', 'LogIn failed :(, please try again later or register a new account with Mail.', host);
|
// eslint-disable-next-line max-len
|
||||||
|
const text = 'LogIn failed :(, please try again later or register a new account with mail.';
|
||||||
|
const message = (req.session) ? req.session.flash : text;
|
||||||
|
const index = getHtml('OAuth Authentification', message, host);
|
||||||
res.status(200).send(index);
|
res.status(200).send(index);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -105,7 +108,13 @@ export default (passport) => {
|
||||||
logger.info(`User ${user.id} logged in with mail/password.`);
|
logger.info(`User ${user.id} logged in with mail/password.`);
|
||||||
|
|
||||||
req.logIn(user, async (e) => {
|
req.logIn(user, async (e) => {
|
||||||
if (e) { res.json({ success: false, errors: ['Failed to establish session. Please try again later :('] }); return; }
|
if (e) {
|
||||||
|
res.json({
|
||||||
|
success: false,
|
||||||
|
errors: ['Failed to establish session. Please try again later :('],
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
user.ip = req.user.ip;
|
user.ip = req.user.ip;
|
||||||
const me = await getMe(user);
|
const me = await getMe(user);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user