UNPKG

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