feat: Add user management invite links without SMTP set up (#5084)

* feat: update n8n-users-list to no longer use preset list of actions

* feat: prepared users settings for invite links feature

* refactor: Return invite link URLs when inviting users (#5079)

* refactor: Return invite link URLs when inviting users

* test: Refactor and add tests to mailer

* feat: Add FE inviteAcceptUrl integration (#5085)

* feat: update n8n-users-list to no longer use preset list of actions

* feat: prepared users settings for invite links feature

* feat: add integration with new inviteAcceptUrl changes

* feat: Add inviteAcceptUrl to user list for pending users

Co-authored-by: Alex Grozav <alex@grozav.com>

* fix conflicts

* fix lint issue

* test: Make sure inviteAcceptUrl is defined

* feat: update smtp setup suggestion

* feat: add invite link summary when inviting multiple users

* refactor: Add telemetry flag for when email is sent

* fix: add email_sent correctly to telemetry event

* feat: move SMTP info-tip to invite modal

Co-authored-by: Omar Ajoue <krynble@gmail.com>
This commit is contained in:
Alex Grozav
2023-01-05 17:10:08 +02:00
committed by GitHub
parent 11a46a4cbc
commit 2327563c44
22 changed files with 419 additions and 247 deletions

View File

@@ -44,57 +44,52 @@ export class UserManagementMailer {
constructor() {
// Other implementations can be used in the future.
if (config.getEnv('userManagement.emails.mode') === 'smtp') {
if (
config.getEnv('userManagement.emails.mode') === 'smtp' &&
config.getEnv('userManagement.emails.smtp.host') !== ''
) {
this.mailer = new NodeMailer();
}
}
async verifyConnection(): Promise<void> {
if (!this.mailer) return Promise.reject();
if (!this.mailer) throw new Error('No mailer configured.');
return this.mailer.verifyConnection();
}
async invite(inviteEmailData: InviteEmailData): Promise<SendEmailResult> {
if (!this.mailer) return Promise.reject();
const template = await getTemplate('invite');
const result = await this.mailer.sendMail({
const result = await this.mailer?.sendMail({
emailRecipients: inviteEmailData.email,
subject: 'You have been invited to n8n',
body: template(inviteEmailData),
});
// If mailer does not exist it means mail has been disabled.
return result ?? { success: true };
// No error, just say no email was sent.
return result ?? { emailSent: false };
}
async passwordReset(passwordResetData: PasswordResetData): Promise<SendEmailResult> {
if (!this.mailer) return Promise.reject();
const template = await getTemplate('passwordReset');
const result = await this.mailer.sendMail({
const result = await this.mailer?.sendMail({
emailRecipients: passwordResetData.email,
subject: 'n8n password reset',
body: template(passwordResetData),
});
// If mailer does not exist it means mail has been disabled.
return result ?? { success: true };
// No error, just say no email was sent.
return result ?? { emailSent: false };
}
}
let mailerInstance: UserManagementMailer | undefined;
export async function getInstance(): Promise<UserManagementMailer> {
export function getInstance(): UserManagementMailer {
if (mailerInstance === undefined) {
mailerInstance = new UserManagementMailer();
try {
await mailerInstance.verifyConnection();
} catch (error) {
mailerInstance = undefined;
throw error;
}
}
return mailerInstance;
}