const vnModel = require('vn-loopback/common/models/vn-model'); const LoopBackContext = require('loopback-context'); const {Email} = require('vn-print'); module.exports = function(Self) { vnModel(Self); require('../methods/vn-user/signIn')(Self); require('../methods/vn-user/acl')(Self); require('../methods/vn-user/recover-password')(Self); require('../methods/vn-user/validate-token')(Self); require('../methods/vn-user/privileges')(Self); // Validations Self.validatesFormatOf('email', { message: 'Invalid email', allowNull: true, allowBlank: true, with: /^[\w|.|-]+@[\w|-]+(\.[\w|-]+)*(,[\w|.|-]+@[\w|-]+(\.[\w|-]+)*)*$/ }); Self.validatesUniquenessOf('name', { message: `A client with that Web User name already exists` }); Self.remoteMethod('getCurrentUserData', { description: 'Gets the current user data', accepts: [ { arg: 'ctx', type: 'Object', http: {source: 'context'} } ], returns: { type: 'Object', root: true }, http: { verb: 'GET', path: '/getCurrentUserData' } }); Self.getCurrentUserData = async function(ctx) { let userId = ctx.req.accessToken.userId; return await Self.findById(userId, { fields: ['id', 'name', 'nickname'] }); }; /** * Checks if user has a role. * * @param {Integer} userId The user id * @param {String} name The role name * @param {Object} options Options * @return {Boolean} %true if user has the role, %false otherwise */ Self.hasRole = async function(userId, name, options) { const roles = await Self.getRoles(userId, options); return roles.some(role => role == name); }; /** * Get all user roles. * * @param {Integer} userId The user id * @param {Object} options Options * @return {Object} User role list */ Self.getRoles = async(userId, options) => { const result = await Self.rawSql( `SELECT r.name FROM account.user u JOIN account.roleRole rr ON rr.role = u.role JOIN account.role r ON r.id = rr.inheritsFrom WHERE u.id = ?`, [userId], options); const roles = []; for (const role of result) roles.push(role.name); return roles; }; Self.on('resetPasswordRequest', async function(info) { const loopBackContext = LoopBackContext.getCurrentContext(); const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const headers = httpRequest.headers; const origin = headers.origin; const user = await Self.app.models.VnUser.findById(info.user.id); const params = { recipient: info.email, lang: user.lang, url: `${origin}/#!/reset-password?access_token=${info.accessToken.id}` }; const options = Object.assign({}, info.options); for (const param in options) params[param] = options[param]; const email = new Email(options.emailTemplate, params); return email.send(); }); const _setPassword = Self.setPassword; Self.setPassword = function(id, newPassword, options, cb) { Self.rawSql(`CALL account.user_setPassword(?, ?)`, [id, newPassword]) .then(() => _setPassword.call(this, id, newPassword, options, cb) .then(() => Self.findById(id).updateAttribute('passExpired', null)) ); }; const _changePassword = Self.changePassword; Self.sharedClass._methods.find(method => method.name == 'changePassword').accessScopes = ['change-password']; Self.changePassword = function(id, oldPassword, newPassword, options, cb) { Self.rawSql(`CALL account.user_changePassword(?, ?, ?)`, [id, oldPassword, newPassword]) .then(() => _changePassword.call(this, id, oldPassword, newPassword, options, cb) .then(() => Self.findById(id).updateAttribute('passExpired', null))); }; // FIX THIS Self.afterRemote('prototype.patchAttributes', async(ctx, instance) => { if (!ctx.args || !ctx.args.data.email) return; const models = Self.app.models; const loopBackContext = LoopBackContext.getCurrentContext(); const httpCtx = {req: loopBackContext.active}; const httpRequest = httpCtx.req.http.req; const headers = httpRequest.headers; const origin = headers.origin; const url = origin.split(':'); const userId = ctx.instance.id; const user = await models.VnUser.findById(userId); class Mailer { async send(verifyOptions, cb) { const params = { url: verifyOptions.verifyHref, recipient: verifyOptions.to, lang: ctx.req.getLocale() }; const email = new Email('email-verify', params); email.send(); cb(null, verifyOptions.to); } } const options = { type: 'email', to: instance.email, from: {}, redirect: `${origin}/#!/account/${instance.id}/basic-data?emailConfirmed`, template: false, mailer: new Mailer, host: url[1].split('/')[2], port: url[2], protocol: url[0], user: Self }; await user.verify(options); }); };