'use strict'; /*Powered By: Manaknightdigital Inc. https://manaknightdigital.com/ Year: 2021*/ /** * Admin Authentication View Model * * @copyright 2021 Manaknightdigital Inc. * @link https://manaknightdigital.com * @license Proprietary Software licensing * @author Ryan Wong */ const { nanoid, customAlphabet } = require('nanoid'); const { Op } = require('sequelize'); const bcrypt = require('bcryptjs'); const db = require('../models'); const MailService = require('../services/MailService'); // const SmsService = require('../services/SmsService'); module.exports = function (entity, pageName = '', success, error) { this.entity = entity; this.success = success || null; this.error = error || null; this.email = ''; this.resetToken = ''; this.get_page_name = () => pageName; this.login_fields = { email: '', password: '' }; this.register_fields = { email: '', first_name: '', last_name: '', password: '', confirm_password: '', }; this.forgot_fields = { email: '' }; this.reset_fields = { password: '', confirm_password: '' }; this.account_verification_fields = { verificationCode: '' }; this.form_fields = { 'first_name': '','last_name': '','credential.email': '','credential.password': '','status': '' } this.google_auth_url = '/member/google/initialize'; this.facebook_auth_url = '/member/facebook/initialize'; this.account_exists = function (email, otherFields={}) { return db.credential.getByFields({ email, status: 1, ...otherFields }); }; this.get_associated_user = function (id) { return this.entity.getByPK(id); }; this.compare_password = function (password, hashedPassword) { return bcrypt.compare(password, hashedPassword); }; this.generate_hash = function (password) { return bcrypt.hash(password, bcrypt.genSaltSync(10)); }; this.create_credential = function ({ ...args }) { return db.credential.insert({ ...args, }); }; this.create_user = function ({ ...args }) { return this.entity.insert({ ...args, }); }; this.destroy_credential = function (id) { return db.credential.realDelete(id); }; this.destroy_user = function (id) { return db.user.realDelete(id); }; this.createResetPasswordEmailTemplateForViews = function (slug) { return db.email.insert({ slug: slug, subject: 'Forgot Password', "tag": "email,reset_token,link", html: `Hi {{{email}}},
You have requested to reset your password. Please click the link below to reset it.
Link.
Thanks,
Admin`, }, { returnAllFields:true }); }; this.initializeMailService = function (email) { MailService.initialize({ hostname: process.env.EMAIL_SMTP_SMTP_HOST, port: process.env.EMAIL_SMTP_SMTP_PORT, username: process.env.EMAIL_SMTP_SMTP_USER, password: process.env.EMAIL_SMTP_SMTP_PASS, from: process.env.MAIL_FROM, to: email, }); }; this.getForgotPasswordMailTemplate = async function (slug) { try { const template = await MailService.template(slug); return template; } catch (error) { if (error === 'TEMPLATE_NOT_FOUND') { const template = await this.createResetPasswordEmailTemplateForViews( slug, ); if (template) { return template; } } return null; } }; this.injectMailTemplate = function (template, payload) { return MailService.inject(template, payload); }; this.sendMail = function (template) { return MailService.send(template); }; this.generateRandomToken = function (size = 32) { return nanoid(size); }; this.saveTokenToDB = function ( token, user_id, issue_at = new Date(), expire_at = Date.now() + 36000000, ) { return db.token.insert({ token, user_id, issue_at, expire_at }); }; this.validateToken = async function (token) { try { const isValid = await db.token.findOne({ where: { token, expire_at: { [Op.gt]: new Date() }, }, }); return isValid; } catch (error) { return false; } }; this.getUserCredential = function (user_id) { return db.credential.findOne({ where: { user_id } }); }; this.updatePassword = function (hashedPassword, credential_id) { return db.credential.edit( { password: hashedPassword, }, credential_id, ); }; this.create2FATemplate = function () { return db.sms.insert({ slug: 'verify', tag: 'code', content: 'Your verification code is {{{code}}}', }); }; this.sendSMS = async function (to, userID, slug = 'verify') { const code = customAlphabet('0123456789', 8)(); try { const template = await SmsService.template(slug); const finalTemplate = SmsService.inject(template, { code }); await this.saveTokenToDB(code, userID); return SmsService.send(to, finalTemplate); } catch (error) { if (error === 'TEMPLATE_NOT_FOUND') { const template = await this.create2FATemplate(); if (template) { const finalTemplate = SmsService.inject(template, { code }); await this.saveTokenToDB(code, userID); return SmsService.send(to, finalTemplate); } throw new Error(error); } throw new Error(error); } }; this.status_mapping = function () { return db.user.status_mapping(); }; this.role_id_mapping = function () { return db.user.role_id_mapping(); }; this.type_mapping = function () { return db.user.type_mapping(); }; this.verify_mapping = function () { return db.user.verify_mapping(); }; this.two_factor_authentication_mapping = function () { return db.user.two_factor_authentication_mapping(); }; this.force_password_change_mapping = function () { return db.user.force_password_change_mapping(); }; return this; };