UNPKG

apollo-passport-local-strategy

Version:

Local strategy using email address and hashed, bcrypted password

482 lines (383 loc) 15.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var resolvers = { RootMutation: { apCreateUserEmailPassword: function apCreateUserEmailPassword(root, _ref) { var input = _ref.input; var existing, reducedInput, expirationLength, verificationToken, user, userId, onBeforeStoreRegisteredUser, onCreateUserEnd; return regeneratorRuntime.async(function apCreateUserEmailPassword$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return regeneratorRuntime.awrap(this.db.fetchUserByEmail(input.email)); case 2: existing = _context.sent; reducedInput = Object.assign({}, input); delete reducedInput.email; delete reducedInput.password; if (!(existing && existing.services && Object.keys(existing.services).length > 0)) { _context.next = 8; break; } return _context.abrupt("return", { token: "", error: "E-mail already registered" }); case 8: expirationLength = this.strategies.local.tokensExpirationLength.verification; _context.next = 11; return regeneratorRuntime.awrap(this.generateVerificationToken(expirationLength)); case 11: verificationToken = _context.sent; _context.t0 = Object; _context.t1 = reducedInput; _context.t2 = [{ value: input.email }]; _context.next = 17; return regeneratorRuntime.awrap(this.hashPassword(input.password)); case 17: _context.t3 = _context.sent; _context.t4 = { bcrypt: _context.t3 }; _context.t5 = { password: _context.t4 }; _context.t6 = verificationToken.token; _context.t7 = verificationToken.expiration; _context.t8 = { emails: _context.t2, services: _context.t5, verificationToken: _context.t6, verificationTokenExpiration: _context.t7, verified: false }; user = _context.t0.assign.call(_context.t0, _context.t1, _context.t8); userId = void 0; onBeforeStoreRegisteredUser = this.onBeforeStoreRegisteredUser; if (onBeforeStoreRegisteredUser && typeof onBeforeStoreRegisteredUser === 'function') { onBeforeStoreRegisteredUser(user); } _context.prev = 27; if (existing) { _context.next = 34; break; } _context.next = 31; return regeneratorRuntime.awrap(this.createUser(user)); case 31: userId = _context.sent; _context.next = 37; break; case 34: userId = existing._id; user.dateRegistered = new Date(); this.db.updateUser(userId, user); case 37: _context.next = 42; break; case 39: _context.prev = 39; _context.t9 = _context["catch"](27); return _context.abrupt("return", { error: _context.t9.message, token: "" }); case 42: // XXX correct id field? // user.id = userId; onCreateUserEnd = this.onCreateUserEnd; if (onCreateUserEnd && typeof onCreateUserEnd === 'function') { onCreateUserEnd(user); } return _context.abrupt("return", { error: "", token: '' }); case 45: case "end": return _context.stop(); } } }, null, this, [[27, 39]]); }, apVerifyAccount: function apVerifyAccount(root, _ref2) { var userId = _ref2.userId, verificationToken = _ref2.verificationToken; var user, err, onVerifyAccountEnd; return regeneratorRuntime.async(function apVerifyAccount$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.next = 2; return regeneratorRuntime.awrap(this.db.fetchUserById(userId)); case 2: user = _context2.sent; err = {}; if (user) { _context2.next = 6; break; } return _context2.abrupt("return", { errCode: 'USER_NOT_EXIST', errMessage: 'No such user id' }); case 6: if (!(!user.verificationToken && user.resetPassToken)) { _context2.next = 8; break; } return _context2.abrupt("return", { errCode: 'RESET_PASS_IN_PROGRESS', errMessage: 'Reset password is in progress' }); case 8: if (!(user.verificationToken !== verificationToken)) { _context2.next = 10; break; } return _context2.abrupt("return", { errCode: 'TOKEN_NOT_VALID', errMessage: 'Verification token not valid' }); case 10: if (!(Date.now() > user.verificationTokenExpiration)) { _context2.next = 12; break; } return _context2.abrupt("return", { errCode: 'TOKEN_EXPIRED', errMessage: 'Verification token expired' }); case 12: onVerifyAccountEnd = this.onVerifyAccountEnd; if (onVerifyAccountEnd && typeof onVerifyAccountEnd === 'function') { onVerifyAccountEnd(user); } this.db.verifyUserAccount(userId); case 15: case "end": return _context2.stop(); } } }, null, this); }, apRecoverPasswordRequest: function apRecoverPasswordRequest(root, _ref3) { var email = _ref3.email; var user, expirationLength, _ref4, token, expiration, updatedUser, onRecoverPasswordRequestEnd; return regeneratorRuntime.async(function apRecoverPasswordRequest$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return regeneratorRuntime.awrap(this.db.fetchUserByEmail(email)); case 2: user = _context3.sent; if (user) { _context3.next = 5; break; } return _context3.abrupt("return", 'No such user email'); case 5: expirationLength = this.strategies.local.tokensExpirationLength.resetPass; _context3.next = 8; return regeneratorRuntime.awrap(this.generateVerificationToken(expirationLength)); case 8: _ref4 = _context3.sent; token = _ref4.token; expiration = _ref4.expiration; _context3.next = 13; return regeneratorRuntime.awrap(this.db.addResetPasswordToken(user._id, token, expiration)); case 13: _context3.next = 15; return regeneratorRuntime.awrap(this.db.fetchUserById(user._id)); case 15: updatedUser = _context3.sent; onRecoverPasswordRequestEnd = this.onRecoverPasswordRequestEnd; if (onRecoverPasswordRequestEnd && typeof onRecoverPasswordRequestEnd === 'function') { onRecoverPasswordRequestEnd(updatedUser); } return _context3.abrupt("return", ''); case 19: case "end": return _context3.stop(); } } }, null, this); }, apRecoverPassword: function apRecoverPassword(root, _ref5, context) { var userId = _ref5.userId, token = _ref5.token, newPassword = _ref5.newPassword; var user, onRecoverPasswordEnd; return regeneratorRuntime.async(function apRecoverPassword$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.next = 2; return regeneratorRuntime.awrap(this.db.fetchUserById(userId)); case 2: user = _context4.sent; if (user) { _context4.next = 5; break; } return _context4.abrupt("return", 'No such userId'); case 5: if (user.resetPassToken) { _context4.next = 7; break; } return _context4.abrupt("return", 'Password reset has not been initialized'); case 7: if (!(user.resetPassToken !== token)) { _context4.next = 9; break; } return _context4.abrupt("return", 'Reset password token not valid'); case 9: if (!(Date.now() > user.resetPassTokenExpiration)) { _context4.next = 11; break; } return _context4.abrupt("return", 'Reset password token expired'); case 11: _context4.prev = 11; _context4.t0 = regeneratorRuntime; _context4.t1 = this.db; _context4.t2 = userId; _context4.next = 17; return regeneratorRuntime.awrap(this.hashPassword(newPassword)); case 17: _context4.t3 = _context4.sent; _context4.t4 = { bcrypt: _context4.t3 }; _context4.t5 = _context4.t1.assertUserServiceData.call(_context4.t1, _context4.t2, 'password', _context4.t4); _context4.next = 22; return _context4.t0.awrap.call(_context4.t0, _context4.t5); case 22: _context4.next = 24; return regeneratorRuntime.awrap(this.db.verifyUserAccount(userId, 'verified', 'resetPassToken', 'resetPassTokenExpiration')); case 24: _context4.next = 29; break; case 26: _context4.prev = 26; _context4.t6 = _context4["catch"](11); return _context4.abrupt("return", _context4.t6.message); case 29: onRecoverPasswordEnd = this.onRecoverPasswordEnd; if (onRecoverPasswordEnd && typeof onRecoverPasswordEnd === 'function') { onRecoverPasswordEnd(user); } return _context4.abrupt("return", ""); case 32: case "end": return _context4.stop(); } } }, null, this, [[11, 26]]); }, apLoginEmailPassword: function apLoginEmailPassword(root, args) { var _this = this; return new Promise(function (resolve, reject) { _this.passport.authenticate('local', function (err, user, info) { if (err) return reject(err); if (!user || info) return resolve({ error: info, token: "" }); var onLoginEnd = _this.onLoginEnd; if (onLoginEnd && typeof onLoginEnd === 'function') { onLoginEnd(user); } resolve({ error: "", token: _this.createTokenFromUser(user) }); })({ query: args }); // fake req.query using args from graphQL }); }, apUpdateUserPassword: function apUpdateUserPassword(root, _ref6, context) { var userId = _ref6.userId, oldPassword = _ref6.oldPassword, newPassword = _ref6.newPassword; var user, storedPassword, match, onUpdatePasswordEnd; return regeneratorRuntime.async(function apUpdateUserPassword$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: if (context && context.auth && context.auth.userId === userId) { _context5.next = 2; break; } return _context5.abrupt("return", "Not logged in as " + userId); case 2: _context5.next = 4; return regeneratorRuntime.awrap(this.db.fetchUserById(userId)); case 4: user = _context5.sent; if (user) { _context5.next = 7; break; } return _context5.abrupt("return", 'No such userId'); case 7: console.log(user); storedPassword = user && user.services && user.services.password && user.services.password.bcrypt; console.log('storedPassword', storedPassword); // TODO allow no password only if email set. allow email as part of query? if (!storedPassword) { _context5.next = 19; break; } _context5.next = 13; return regeneratorRuntime.awrap(this.comparePassword(oldPassword, storedPassword)); case 13: match = _context5.sent; console.log('match', match); if (match) { _context5.next = 17; break; } return _context5.abrupt("return", "Invalid old password"); case 17: _context5.next = 20; break; case 19: return _context5.abrupt("return", "No old password set"); case 20: _context5.prev = 20; _context5.t0 = regeneratorRuntime; _context5.t1 = this.db; _context5.t2 = userId; _context5.next = 26; return regeneratorRuntime.awrap(this.hashPassword(newPassword)); case 26: _context5.t3 = _context5.sent; _context5.t4 = { bcrypt: _context5.t3 }; _context5.t5 = _context5.t1.assertUserServiceData.call(_context5.t1, _context5.t2, 'password', _context5.t4); _context5.next = 31; return _context5.t0.awrap.call(_context5.t0, _context5.t5); case 31: _context5.next = 36; break; case 33: _context5.prev = 33; _context5.t6 = _context5["catch"](20); return _context5.abrupt("return", _context5.t6.message); case 36: onUpdatePasswordEnd = this.onUpdatePasswordEnd; if (onUpdatePasswordEnd && typeof onUpdatePasswordEnd === 'function') { onUpdatePasswordEnd(user); } return _context5.abrupt("return", ""); case 39: case "end": return _context5.stop(); } } }, null, this, [[20, 33]]); } } }; exports.default = resolvers;