Files
node_task_2/view_models/member_auth_view_model.js
T
2022-04-11 06:32:47 +02:00

225 lines
5.9 KiB
JavaScript

'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}}},<br/>You have requested to reset your password. Please click the link below to reset it.<br/><a href=\"{{{link}}}/{{{reset_token}}}\">Link</a>. <br/>Thanks,<br/> 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;
};