From efd1f7ac5e6b8b62f8cf2ff8dfcd819fed7aabe4 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Thu, 28 Nov 2024 08:15:46 +0530 Subject: [PATCH] fix: avoid duplicate email and bring missing base name in invite template Signed-off-by: Pranav C --- .../services/base-users/base-users.service.ts | 76 +++++-- .../base-users/ui/emailTemplates/invite.ts | 4 +- .../ui/emailTemplates/org-invite.ts | 210 ++++++++++++++++++ .../nocodb/src/services/org-users.service.ts | 39 ++-- 4 files changed, 290 insertions(+), 39 deletions(-) create mode 100644 packages/nocodb/src/services/base-users/ui/emailTemplates/org-invite.ts diff --git a/packages/nocodb/src/services/base-users/base-users.service.ts b/packages/nocodb/src/services/base-users/base-users.service.ts index cfece00ceb..9e966fd0fb 100644 --- a/packages/nocodb/src/services/base-users/base-users.service.ts +++ b/packages/nocodb/src/services/base-users/base-users.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { AppEvents, extractRolesObj, @@ -26,6 +26,8 @@ import { sanitiseEmailContent } from '~/utils'; @Injectable() export class BaseUsersService { + private readonly logger = new Logger(BaseUsersService.name); + constructor(protected appHooksService: AppHooksService) {} async userList( @@ -171,17 +173,29 @@ export class BaseUsersService { }); // in case of single user check for smtp failure - // and send back token if failed - if ( - emails.length === 1 && - !(await this.sendInviteEmail(email, invite_token, param.req)) - ) { - return { invite_token, email }; + // and send back token if email not configured + if (emails.length === 1) { + // variable to keep invite mail send status + const mailSendStatus = await this.sendInviteEmail({ + email, + token: invite_token, + req: param.req, + baseName: base.title, + }); + + if (!mailSendStatus) { + return { invite_token, email }; + } } else { - this.sendInviteEmail(email, invite_token, param.req); + await this.sendInviteEmail({ + email, + token: invite_token, + req: param.req, + baseName: base.title, + }); } } catch (e) { - console.log(e); + this.logger.error(e.message, e.stack); if (emails.length === 1) { throw e; } else { @@ -402,7 +416,12 @@ export class BaseUsersService { ); } - await this.sendInviteEmail(user.email, invite_token, param.req); + await this.sendInviteEmail({ + email: user.email, + token: invite_token, + req: param.req, + baseName: base.title, + }); this.appHooksService.emit(AppEvents.PROJECT_USER_RESEND_INVITE, { base, @@ -416,13 +435,32 @@ export class BaseUsersService { return true; } - // todo: refactor the whole function - async sendInviteEmail(email: string, token: string, req: any): Promise { + async sendInviteEmail({ + email, + token, + req, + baseName, + useOrgTemplate, + }: { + email: string; + token: string; + req: NcRequest; + baseName?: string; + useOrgTemplate?: boolean; + }): Promise { try { - const template = ( - await import('~/services/base-users/ui/emailTemplates/invite') - ).default; + let template: string; + // if useOrgTemplate is true then use org template + if (useOrgTemplate) { + template = ( + await import('~/services/base-users/ui/emailTemplates/org-invite') + ).default; + } else { + template = ( + await import('~/services/base-users/ui/emailTemplates/invite') + ).default; + } const emailAdapter = await NcPluginMgrv2.emailAdapter(); if (emailAdapter) { @@ -433,7 +471,7 @@ export class BaseUsersService { signupLink: `${req.ncSiteUrl}${ Noco.getConfig()?.dashboardPath }#/signup/${token}`, - baseName: sanitiseEmailContent(req.body?.baseName), + baseName: sanitiseEmailContent(baseName || req.body?.baseName), roles: sanitiseEmailContent( (req.body?.roles || '') .split(',') @@ -446,10 +484,10 @@ export class BaseUsersService { return true; } } catch (e) { - console.log( - 'Warning : `mailSend` failed, Please configure emailClient configuration.', - e.message, + this.logger.warn( + 'Warning : `mailSend` failed, Please re-configure emailClient configuration.', ); + this.logger.error(e.message, e.stack); throw e; } } diff --git a/packages/nocodb/src/services/base-users/ui/emailTemplates/invite.ts b/packages/nocodb/src/services/base-users/ui/emailTemplates/invite.ts index 284fdf6708..329f07ea86 100644 --- a/packages/nocodb/src/services/base-users/ui/emailTemplates/invite.ts +++ b/packages/nocodb/src/services/base-users/ui/emailTemplates/invite.ts @@ -3,7 +3,7 @@ export default ` - Simple Transactional Email + <%= baseName %> - Invite + + + + + + + + + + + + +`; diff --git a/packages/nocodb/src/services/org-users.service.ts b/packages/nocodb/src/services/org-users.service.ts index d3a386aa13..d11711d18a 100644 --- a/packages/nocodb/src/services/org-users.service.ts +++ b/packages/nocodb/src/services/org-users.service.ts @@ -161,21 +161,23 @@ export class OrgUsersService { // in case of single user check for smtp failure // and send back token if failed - if ( - emails.length === 1 && - !(await this.baseUsersService.sendInviteEmail( - email, - invite_token, - param.req, - )) - ) { - return { invite_token, email }; + if (emails.length === 1) { + if ( + !(await this.baseUsersService.sendInviteEmail({ + email, + token: invite_token, + useOrgTemplate: true, + req: param.req, + })) + ) + return { invite_token, email }; } else { - this.baseUsersService.sendInviteEmail( + await this.baseUsersService.sendInviteEmail({ email, - invite_token, - param.req, - ); + token: invite_token, + req: param.req, + useOrgTemplate: true, + }); } } catch (e) { console.log(e); @@ -234,11 +236,12 @@ export class OrgUsersService { ); } - await this.baseUsersService.sendInviteEmail( - user.email, - invite_token, - param.req, - ); + await this.baseUsersService.sendInviteEmail({ + email: user.email, + token: invite_token, + req: param.req, + useOrgTemplate: true, + }); this.appHooksService.emit(AppEvents.ORG_USER_RESEND_INVITE, { invitedBy: param.req.user,