UNPKG

4.84 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.useSignin = useSignin;
7
8var _bcryptNodejs = require('bcrypt-nodejs');
9
10var _bcryptNodejs2 = _interopRequireDefault(_bcryptNodejs);
11
12var _helmet = require('helmet');
13
14var _helmet2 = _interopRequireDefault(_helmet);
15
16var _passport = require('passport');
17
18var _passport2 = _interopRequireDefault(_passport);
19
20var _passportLocal = require('passport-local');
21
22var _shortid = require('shortid');
23
24var _shortid2 = _interopRequireDefault(_shortid);
25
26function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
28var NO_MATCHING_USER = 'NO_MATCHING_USER';
29var INCORRECT_USER_CREDENTIALS = 'INCORRECT_USER_CREDENTIALS';
30
31// from: http://stackoverflow.com/a/46181
32// NOTE: is it good enough?
33/* eslint-disable */
34var VALID_EMAIL_REGEXP = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
35var MIN_PASSWORD_LENGTH = 6;
36var REQUIRED_SIGNUP_FIELDS = ['email', 'password'];
37var globalUserFields = [];
38
39function formatUserForFrontend(user) {
40 // create a modified user object to return to frontend
41 // NOTE: we assume it was a local user sign in, i.e. not via oauth
42 var userCopy = Object.assign({}, user.local, {
43 id: user.id,
44 active: user.active,
45 admin: user.admin,
46 consoleToken: user.consoleToken,
47 vat: user.vat,
48 firstname: user.firstname,
49 lastname: user.lastname,
50 company: user.company
51 });
52 delete userCopy.password;
53 delete userCopy.passwordResetToken;
54 return userCopy;
55}
56
57function signinUser(email, password, usersCollection) {
58 return new Promise(function (resolve, reject) {
59 // try to find matching user and password
60 usersCollection.findOne({ 'local.email': email }).then(function (user) {
61 if (!user) {
62 reject(new Error(NO_MATCHING_USER));
63 return;
64 }
65 return validatePassword(password, user.local.password).then(function (validated) {
66 if (!validated) {
67 reject(new Error(INCORRECT_USER_CREDENTIALS));
68 return;
69 }
70 // correct match, return user
71 resolve(user);
72 });
73 });
74 });
75}
76
77function validatePassword(password, encryptedPassword) {
78 return new Promise(function (resolve, reject) {
79 _bcryptNodejs2.default.compare(password, encryptedPassword, function (err, result) {
80 if (err) {
81 reject(err);
82 return;
83 }
84 return resolve(result);
85 });
86 });
87}
88
89function useSignin(app, config) {
90 // unpack
91 var db = config.db,
92 logger = config.logger,
93 routePath = config.routePath;
94 // users
95
96 var usersCollection = db.collection('users');
97 // strategy
98 var passportLocalStrategy = new _passportLocal.Strategy({
99 usernameField: 'email',
100 passReqToCallback: true // get access to full request in callback
101 }, function (req, email, password, done) {
102 // store the pushed data so we can keep the form populated in case of failure
103 req.flash('signinBody', req.body);
104 signinUser(email, password, usersCollection).then(function (user) {
105 return done(null, user);
106 }).catch(function (err) {
107 if (err.message === NO_MATCHING_USER) {
108 done(null, false, req.flash('signinMessage', 'No matching user found.'));
109 return;
110 }
111 if (err.message === INCORRECT_USER_CREDENTIALS) {
112 done(null, false, req.flash('login', 'Incorrect credentials.'));
113 return;
114 }
115 // TODO: handle this error!
116 logger.warn('[unhandled] ERROR in handleLogin:', err);
117 done(null, false, req.flash('login', 'Login failed.'));
118 });
119 });
120 _passport2.default.use('local-login', passportLocalStrategy);
121 // apis
122 function returnTo(req, res, next) {
123 if (req.body.returnTo) {
124 req.session.returnTo = decodeURIComponent(req.body.returnTo);
125 } else {
126 req.session.returnTo = '/';
127 }
128 next();
129 }
130 // authenticates
131 var localAuthenticate = _passport2.default.authenticate('local-login');
132 var localAuthenticateAndRedirect = _passport2.default.authenticate('local-login', {
133 successReturnToOrRedirect: true,
134 successRedirect: '/',
135 failureRedirect: '/signin',
136 failureFlash: true // allow flash messages
137 });
138 // api
139 app.post(routePath + '/signin', returnTo, localAuthenticateAndRedirect);
140 // if some server problem causes user to try to
141 // reach these endpoints via GET requests from browser
142 app.get(routePath + '/signin', function (req, res) {
143 return res.redirect('/');
144 });
145 // logout
146 app.post(routePath + '/logout', function (req, res) {
147 if (req.user) {
148 req.logout();
149 }
150 res.redirect('/signin');
151 });
152 // return
153 return { localAuthenticate: localAuthenticate,
154 localAuthenticateAndRedirect: localAuthenticateAndRedirect,
155 returnTo: returnTo
156 };
157}
\No newline at end of file