const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.remoteMethod('validateAuth', { description: 'Login a user with username/email and password', accepts: [ { arg: 'user', type: 'String', description: 'The user name or email', required: true }, { arg: 'password', type: 'String', description: 'The password' }, { arg: 'code', type: 'String', description: 'The auth code' } ], returns: { type: 'object', root: true }, http: { path: `/validate-auth`, verb: 'POST' } }); Self.validateAuth = async(username, password, code, options) => { const myOptions = {}; if (typeof options == 'object') Object.assign(myOptions, options); const token = Self.validateLogin(username, password); await Self.validateCode(username, code, myOptions); return token; }; Self.validateCode = async(username, code, myOptions) => { const {AuthCode} = Self.app.models; const authCode = await AuthCode.findOne({ where: { code: code } }, myOptions); const expired = authCode && Date.vnNow() > authCode.expires; if (!authCode || expired) throw new UserError('Invalid or expired verification code'); const user = await Self.findById(authCode.userFk, { fields: ['name', 'twoFactor'] }, myOptions); if (user.name.toLowerCase() !== username.toLowerCase()) throw new UserError('Authentication failed'); await authCode.destroy(myOptions); }; };