From 877a57043a409b0ea9ed9acc38979ddc8830fbc2 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Mon, 19 Jun 2023 15:36:18 +0200 Subject: [PATCH 1/3] fix(server): sending emails on reset password and registration --- packages/server/src/config/index.ts | 23 +- packages/server/src/jobs/ResetPasswordMail.ts | 26 +- packages/server/src/jobs/SmsNotification.ts | 22 - packages/server/src/jobs/WelcomeSMS.ts | 35 -- packages/server/src/jobs/welcomeEmail.ts | 39 -- packages/server/src/loaders/jobs.ts | 8 +- .../AuthenticationMailMessages.ts | 47 +- .../AuthenticationSMSMessages.ts | 19 - .../Authentication/SendResetPasswordMail.ts | 2 +- .../Authentication/SendWelcomeMail.ts | 28 -- .../server/views/mail/LicenseReceive.html | 411 ------------------ packages/server/views/mail/ResetPassword.html | 6 +- packages/server/views/mail/Welcome.html | 407 ----------------- 13 files changed, 25 insertions(+), 1048 deletions(-) delete mode 100644 packages/server/src/jobs/SmsNotification.ts delete mode 100644 packages/server/src/jobs/WelcomeSMS.ts delete mode 100644 packages/server/src/jobs/welcomeEmail.ts delete mode 100644 packages/server/src/services/Authentication/AuthenticationSMSMessages.ts delete mode 100644 packages/server/src/subscribers/Authentication/SendWelcomeMail.ts delete mode 100644 packages/server/views/mail/LicenseReceive.html delete mode 100644 packages/server/views/mail/Welcome.html diff --git a/packages/server/src/config/index.ts b/packages/server/src/config/index.ts index c32be4bac..ff1fedb6a 100644 --- a/packages/server/src/config/index.ts +++ b/packages/server/src/config/index.ts @@ -95,16 +95,15 @@ module.exports = { * JWT secret. */ jwtSecret: process.env.JWT_SECRET, + + /** + * + */ resetPasswordSeconds: 600, /** - * + * Application base URL. */ - customerSuccess: { - email: 'success@bigcapital.ly', - phoneNumber: '(218) 92 791 8381', - }, - baseURL: process.env.BASE_URL, /** @@ -137,16 +136,6 @@ module.exports = { }, }, - /** - * Users registeration configuration. - */ - registration: { - countries: { - whitelist: ['LY'], - blacklist: [], - }, - }, - /** * Sign-up restrictions */ @@ -167,8 +156,6 @@ module.exports = { browserWSEndpoint: process.env.BROWSER_WS_ENDPOINT, }, - protocol: '', - hostname: '', scheduleComputeItemCost: 'in 5 seconds', /** diff --git a/packages/server/src/jobs/ResetPasswordMail.ts b/packages/server/src/jobs/ResetPasswordMail.ts index f9c3c15ff..193e6bfe6 100644 --- a/packages/server/src/jobs/ResetPasswordMail.ts +++ b/packages/server/src/jobs/ResetPasswordMail.ts @@ -1,38 +1,34 @@ -import { Container, Inject } from 'typedi'; -import AuthenticationService from '@/services/Authentication/AuthApplication'; +import { Container } from 'typedi'; +import AuthenticationMailMesssages from '@/services/Authentication/AuthenticationMailMessages'; -export default class WelcomeEmailJob { +export default class ResetPasswordEmailJob { /** * Constructor method. - * @param {Agenda} agenda + * @param {Agenda} agenda */ constructor(agenda) { agenda.define( 'reset-password-mail', { priority: 'high' }, - this.handler.bind(this), + this.handler.bind(this) ); } /** * Handle send welcome mail job. - * @param {Job} job - * @param {Function} done + * @param {Job} job + * @param {Function} done */ public async handler(job, done: Function): Promise { const { data } = job.attrs; const { user, token } = data; - const Logger = Container.get('logger'); - const authService = Container.get(AuthenticationService); + const authService = Container.get(AuthenticationMailMesssages); - Logger.info(`[send_reset_password] started.`, { data }); - try { - await authService.mailMessages.sendResetPasswordMessage(user, token); - Logger.info(`[send_reset_password] finished.`, { data }); - done() + await authService.sendResetPasswordMessage(user, token); + done(); } catch (error) { - Logger.error(`[send_reset_password] error.`, { data, error }); + console.log(error); done(error); } } diff --git a/packages/server/src/jobs/SmsNotification.ts b/packages/server/src/jobs/SmsNotification.ts deleted file mode 100644 index 65730daff..000000000 --- a/packages/server/src/jobs/SmsNotification.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Container } from 'typedi'; - -export default class SmsNotification { - constructor(agenda) { - agenda.define('sms-notification', { priority: 'high' }, this.handler); - } - - /** - * - * @param {Job}job - */ - async handler(job) { - const { message, to } = job.attrs.data; - const smsClient = Container.get('SMSClient'); - - try { - await smsClient.sendMessage(to, message); - } catch (error) { - done(e); - } - } -} diff --git a/packages/server/src/jobs/WelcomeSMS.ts b/packages/server/src/jobs/WelcomeSMS.ts deleted file mode 100644 index 67a72c368..000000000 --- a/packages/server/src/jobs/WelcomeSMS.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Container, Inject } from 'typedi'; -import AuthenticationService from '@/services/Authentication/AuthApplication'; - -export default class WelcomeSMSJob { - /** - * Constructor method. - * @param {Agenda} agenda - */ - constructor(agenda) { - agenda.define('welcome-sms', { priority: 'high' }, this.handler); - } - - /** - * Handle send welcome mail job. - * @param {Job} job - * @param {Function} done - */ - public async handler(job, done: Function): Promise { - const { tenant, user } = job.attrs.data; - - const Logger = Container.get('logger'); - const authService = Container.get(AuthenticationService); - - Logger.info(`[welcome_sms] started: ${job.attrs.data}`); - - try { - await authService.smsMessages.sendWelcomeMessage(tenant, user); - Logger.info(`[welcome_sms] finished`, { tenant, user }); - done(); - } catch (error) { - Logger.info(`[welcome_sms] error`, { error, tenant, user }); - done(error); - } - } -} diff --git a/packages/server/src/jobs/welcomeEmail.ts b/packages/server/src/jobs/welcomeEmail.ts deleted file mode 100644 index 6b076556a..000000000 --- a/packages/server/src/jobs/welcomeEmail.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Container } from 'typedi'; -import AuthenticationService from '@/services/Authentication/AuthApplication'; - -export default class WelcomeEmailJob { - /** - * Constructor method. - * @param {Agenda} agenda - - */ - constructor(agenda) { - // Welcome mail and SMS message. - agenda.define( - 'welcome-email', - { priority: 'high' }, - this.handler.bind(this), - ); - } - - /** - * Handle send welcome mail job. - * @param {Job} job - * @param {Function} done - */ - public async handler(job, done: Function): Promise { - const { organizationId, user } = job.attrs.data; - const Logger: any = Container.get('logger'); - const authService = Container.get(AuthenticationService); - - Logger.info(`[welcome_mail] started: ${job.attrs.data}`); - - try { - await authService.mailMessages.sendWelcomeMessage(user, organizationId); - Logger.info(`[welcome_mail] finished: ${job.attrs.data}`); - done(); - } catch (error) { - Logger.error(`[welcome_mail] error: ${job.attrs.data}, error: ${error}`); - done(error); - } - } -} diff --git a/packages/server/src/loaders/jobs.ts b/packages/server/src/loaders/jobs.ts index 49acd77c2..4fa3aadb1 100644 --- a/packages/server/src/loaders/jobs.ts +++ b/packages/server/src/loaders/jobs.ts @@ -1,24 +1,18 @@ import Agenda from 'agenda'; -import WelcomeEmailJob from 'jobs/welcomeEmail'; -import WelcomeSMSJob from 'jobs/WelcomeSMS'; import ResetPasswordMailJob from 'jobs/ResetPasswordMail'; import ComputeItemCost from 'jobs/ComputeItemCost'; -import RewriteInvoicesJournalEntries from 'jobs/writeInvoicesJEntries'; +import RewriteInvoicesJournalEntries from 'jobs/WriteInvoicesJEntries'; import UserInviteMailJob from 'jobs/UserInviteMail'; import OrganizationSetupJob from 'jobs/OrganizationSetup'; import OrganizationUpgrade from 'jobs/OrganizationUpgrade'; -import SmsNotification from 'jobs/SmsNotification'; export default ({ agenda }: { agenda: Agenda }) => { - new WelcomeEmailJob(agenda); new ResetPasswordMailJob(agenda); - new WelcomeSMSJob(agenda); new UserInviteMailJob(agenda); new ComputeItemCost(agenda); new RewriteInvoicesJournalEntries(agenda); new OrganizationSetupJob(agenda); new OrganizationUpgrade(agenda); - new SmsNotification(agenda); agenda.start(); }; diff --git a/packages/server/src/services/Authentication/AuthenticationMailMessages.ts b/packages/server/src/services/Authentication/AuthenticationMailMessages.ts index df3cd7ce2..c8c26ea0d 100644 --- a/packages/server/src/services/Authentication/AuthenticationMailMessages.ts +++ b/packages/server/src/services/Authentication/AuthenticationMailMessages.ts @@ -5,59 +5,24 @@ import Mail from '@/lib/Mail'; @Service() export default class AuthenticationMailMesssages { - /** - * Sends welcome message. - * @param {ISystemUser} user - The system user. - * @param {string} organizationName - - * @return {Promise} - */ - async sendWelcomeMessage( - user: ISystemUser, - organizationId: string - ): Promise { - const root = __dirname + '/../../../views/images/bigcapital.png'; - - const mail = new Mail() - .setView('mail/Welcome.html') - .setSubject('Welcome to Bigcapital') - .setTo(user.email) - .setAttachments([ - { - filename: 'bigcapital.png', - path: root, - cid: 'bigcapital_logo', - }, - ]) - .setData({ - firstName: user.firstName, - organizationId, - successPhoneNumber: config.customerSuccess.phoneNumber, - successEmail: config.customerSuccess.email, - }); - - await mail.send(); - } - /** * Sends reset password message. * @param {ISystemUser} user - The system user. * @param {string} token - Reset password token. * @return {Promise} */ - async sendResetPasswordMessage( + public async sendResetPasswordMessage( user: ISystemUser, token: string ): Promise { - const root = __dirname + '/../../../views/images/bigcapital.png'; - - const mail = new Mail() + await new Mail() .setSubject('Bigcapital - Password Reset') .setView('mail/ResetPassword.html') .setTo(user.email) .setAttachments([ { filename: 'bigcapital.png', - path: root, + path: `${global.__views_dir}/images/bigcapital.png`, cid: 'bigcapital_logo', }, ]) @@ -65,9 +30,7 @@ export default class AuthenticationMailMesssages { resetPasswordUrl: `${config.baseURL}/auth/reset_password/${token}`, first_name: user.firstName, last_name: user.lastName, - contact_us_email: config.contactUsMail, - }); - - await mail.send(); + }) + .send(); } } diff --git a/packages/server/src/services/Authentication/AuthenticationSMSMessages.ts b/packages/server/src/services/Authentication/AuthenticationSMSMessages.ts deleted file mode 100644 index 6567d8817..000000000 --- a/packages/server/src/services/Authentication/AuthenticationSMSMessages.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Service, Inject } from 'typedi'; -import { ISystemUser, ITenant } from '@/interfaces'; - -@Service() -export default class AuthenticationSMSMessages { - @Inject('SMSClient') - smsClient: any; - - /** - * Sends welcome sms message. - * @param {ITenant} tenant - * @param {ISystemUser} user - */ - sendWelcomeMessage(tenant: ITenant, user: ISystemUser) { - const message: string = `Hi ${user.firstName}, Welcome to Bigcapital, You've joined the new workspace, if you need any help please don't hesitate to contact us.`; - - return this.smsClient.sendMessage(user.phoneNumber, message); - } -} diff --git a/packages/server/src/subscribers/Authentication/SendResetPasswordMail.ts b/packages/server/src/subscribers/Authentication/SendResetPasswordMail.ts index 4dc7c09b3..935caf8dd 100644 --- a/packages/server/src/subscribers/Authentication/SendResetPasswordMail.ts +++ b/packages/server/src/subscribers/Authentication/SendResetPasswordMail.ts @@ -4,7 +4,7 @@ import events from '@/subscribers/events'; @Service() export default class AuthenticationSubscriber { @Inject('agenda') - agenda: any; + private agenda: any; /** * Attaches events with handlers. diff --git a/packages/server/src/subscribers/Authentication/SendWelcomeMail.ts b/packages/server/src/subscribers/Authentication/SendWelcomeMail.ts deleted file mode 100644 index e692033c1..000000000 --- a/packages/server/src/subscribers/Authentication/SendWelcomeMail.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Service, Inject } from 'typedi'; -import events from '@/subscribers/events'; - -@Service() -export default class AuthSendWelcomeMailSubscriber { - @Inject('agenda') - agenda: any; - - /** - * Attaches events with handlers. - */ - public attach(bus) { - bus.subscribe(events.auth.signUp, this.sendWelcomeEmailOnceUserRegister); - } - - /** - * Sends welcome email once the user register. - */ - private sendWelcomeEmailOnceUserRegister = async (payload) => { - const { tenant, user } = payload; - - // Send welcome mail to the user. - await this.agenda.now('welcome-email', { - organizationId: tenant.organizationId, - user, - }); - }; -} diff --git a/packages/server/views/mail/LicenseReceive.html b/packages/server/views/mail/LicenseReceive.html deleted file mode 100644 index 6a8c721e3..000000000 --- a/packages/server/views/mail/LicenseReceive.html +++ /dev/null @@ -1,411 +0,0 @@ - - - - - - Bigcapital | Reset your password - - - - This is preheader text. Some clients will show this text as a preview. - - - - - - - - - diff --git a/packages/server/views/mail/ResetPassword.html b/packages/server/views/mail/ResetPassword.html index bf9da32ca..fc7cbd624 100644 --- a/packages/server/views/mail/ResetPassword.html +++ b/packages/server/views/mail/ResetPassword.html @@ -391,10 +391,8 @@ -

If you did not make this request, please contact us or ignore this message.

- +

If this was a mistake, just ignore this email and nothing will happen.

+ diff --git a/packages/server/views/mail/Welcome.html b/packages/server/views/mail/Welcome.html deleted file mode 100644 index bdf483df9..000000000 --- a/packages/server/views/mail/Welcome.html +++ /dev/null @@ -1,407 +0,0 @@ - - - - - - Bigcapital | Reset your password - - - - This is preheader text. Some clients will show this text as a preview. - - - - - - - - - From 94ea44b58e002ec796061ccfcdfefaa823fda316 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Mon, 19 Jun 2023 15:55:06 +0200 Subject: [PATCH 2/3] fix(server): change the reigster min password length --- packages/server/src/api/controllers/Authentication.ts | 3 ++- packages/server/src/loaders/eventEmitter.ts | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/server/src/api/controllers/Authentication.ts b/packages/server/src/api/controllers/Authentication.ts index e4d356c04..aae43f4b4 100644 --- a/packages/server/src/api/controllers/Authentication.ts +++ b/packages/server/src/api/controllers/Authentication.ts @@ -92,6 +92,7 @@ export default class AuthenticationController extends BaseController { check('password') .exists() .isString() + .isLength({ min: 6 }) .trim() .escape() .isLength({ max: DATATYPES_LENGTH.STRING }), @@ -106,7 +107,7 @@ export default class AuthenticationController extends BaseController { return [ check('password') .exists() - .isLength({ min: 5 }) + .isLength({ min: 6 }) .custom((value, { req }) => { if (value !== req.body.confirm_password) { throw new Error("Passwords don't match"); diff --git a/packages/server/src/loaders/eventEmitter.ts b/packages/server/src/loaders/eventEmitter.ts index 7915734bd..769085788 100644 --- a/packages/server/src/loaders/eventEmitter.ts +++ b/packages/server/src/loaders/eventEmitter.ts @@ -31,7 +31,6 @@ import OrgBuildSmsNotificationSubscriber from '@/subscribers/Organization/BuildS import PurgeUserAbilityCache from '@/services/Users/PurgeUserAbilityCache'; import ResetLoginThrottleSubscriber from '@/subscribers/Authentication/ResetLoginThrottle'; import AuthenticationSubscriber from '@/subscribers/Authentication/SendResetPasswordMail'; -import AuthSendWelcomeMailSubscriber from '@/subscribers/Authentication/SendWelcomeMail'; import PurgeAuthorizedUserOnceRoleMutate from '@/services/Roles/PurgeAuthorizedUser'; import SendSmsNotificationToCustomer from '@/subscribers/SaleInvoices/SendSmsNotificationToCustomer'; import SendSmsNotificationSaleReceipt from '@/subscribers/SaleReceipt/SendSmsNotificationToCustomer'; @@ -120,7 +119,6 @@ export const susbcribers = () => { PurgeUserAbilityCache, ResetLoginThrottleSubscriber, AuthenticationSubscriber, - AuthSendWelcomeMailSubscriber, PurgeAuthorizedUserOnceRoleMutate, SendSmsNotificationToCustomer, SendSmsNotificationSaleReceipt, From b993fad37fdf9c282c29d92b512fc91280c59450 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Mon, 19 Jun 2023 15:55:20 +0200 Subject: [PATCH 3/3] fix(webapp): change the min password length of reset password --- packages/webapp/src/containers/Authentication/utils.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/webapp/src/containers/Authentication/utils.tsx b/packages/webapp/src/containers/Authentication/utils.tsx index b25dbd079..d73db774a 100644 --- a/packages/webapp/src/containers/Authentication/utils.tsx +++ b/packages/webapp/src/containers/Authentication/utils.tsx @@ -23,11 +23,11 @@ export const RegisterSchema = Yup.object().shape({ first_name: Yup.string().required().label(intl.get('first_name_')), last_name: Yup.string().required().label(intl.get('last_name_')), email: Yup.string().email().required().label(intl.get('email')), - password: Yup.string().min(4).required().label(intl.get('password')), + password: Yup.string().min(6).required().label(intl.get('password')), }); export const ResetPasswordSchema = Yup.object().shape({ - password: Yup.string().min(4).required().label(intl.get('password')), + password: Yup.string().min(6).required().label(intl.get('password')), confirm_password: Yup.string() .oneOf([Yup.ref('password'), null]) .required()