From 14d22e5f1291f62081b3779c655c7cc20e878f94 Mon Sep 17 00:00:00 2001 From: Simon Larsen Date: Wed, 27 Sep 2023 09:24:43 +0100 Subject: [PATCH] harden invite emails --- Accounts/src/Utils/Login.ts | 2 +- CommonServer/Services/TeamMemberService.ts | 17 +++++++++++++---- Identity/API/Authentication.ts | 4 ++-- Notification/Templates/InviteMember.hbs | 18 +++++++++++++++--- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Accounts/src/Utils/Login.ts b/Accounts/src/Utils/Login.ts index 3c94217fff..0ac0685e40 100644 --- a/Accounts/src/Utils/Login.ts +++ b/Accounts/src/Utils/Login.ts @@ -21,7 +21,7 @@ export default abstract class LoginUtil { UserUtil.setAccessToken(token); UserUtil.setEmail(user.email as Email); UserUtil.setUserId(user.id as ObjectID); - UserUtil.setName(user.name as Name); + UserUtil.setName(user.name || new Name('')); UserUtil.setIsMasterAdmin(user.isMasterAdmin as boolean); Analytics.userAuth(user.email!); diff --git a/CommonServer/Services/TeamMemberService.ts b/CommonServer/Services/TeamMemberService.ts index 061800d3f4..38ee3ab846 100644 --- a/CommonServer/Services/TeamMemberService.ts +++ b/CommonServer/Services/TeamMemberService.ts @@ -16,7 +16,7 @@ import QueryHelper from '../Types/Database/QueryHelper'; import LIMIT_MAX from 'Common/Types/Database/LimitMax'; import ProjectService from './ProjectService'; import { IsBillingEnabled } from '../EnvironmentConfig'; -import { DashboardRoute } from 'Common/ServiceRoute'; +import { AccountsRoute } from 'Common/ServiceRoute'; import DatabaseConfig from '../DatabaseConfig'; import BillingService from './BillingService'; import SubscriptionPlan from 'Common/Types/Billing/SubscriptionPlan'; @@ -78,7 +78,10 @@ export class TeamMemberService extends DatabaseService { isRoot: true, }); + let isNewUser: boolean = false; + if (!user) { + isNewUser = true; user = await UserService.createByEmail(email, { isRoot: true, }); @@ -106,11 +109,17 @@ export class TeamMemberService extends DatabaseService { toEmail: email, templateType: EmailTemplateType.InviteMember, vars: { - dashboardUrl: new URL( + signInLink: URL.fromString(new URL( httpProtocol, host, - DashboardRoute - ).toString(), + AccountsRoute + ).toString()).toString(), + registerLink: URL.fromString(new URL( + httpProtocol, + host, + AccountsRoute + ).toString()).addRoute("/register").addQueryParam("email", email.toString()).toString(), + isNewUser: isNewUser.toString(), projectName: project.name!, homeUrl: new URL(httpProtocol, host).toString(), }, diff --git a/Identity/API/Authentication.ts b/Identity/API/Authentication.ts index 503ff248a2..e14cc51557 100644 --- a/Identity/API/Authentication.ts +++ b/Identity/API/Authentication.ts @@ -230,7 +230,7 @@ router.post( }, }); - if (alreadySavedUser) { + if (alreadySavedUser && alreadySavedUser.password) { const token: string = ObjectID.generate().toString(); await UserService.updateOneBy({ query: { @@ -274,7 +274,7 @@ router.post( req, res, new BadDataException( - `No user is registered with ${user.email?.toString()}` + `No user is registered with ${user.email?.toString()}. Please sign up for a new account.` ) ); } catch (err) { diff --git a/Notification/Templates/InviteMember.hbs b/Notification/Templates/InviteMember.hbs index c9ad0fbd12..c8abf930c3 100644 --- a/Notification/Templates/InviteMember.hbs +++ b/Notification/Templates/InviteMember.hbs @@ -4,12 +4,24 @@ {{> EmailTitle title=(concat "You have been invited to " projectName) }} -{{> InfoBlock info="Please click on the 'Go to dashboard' button below to see all your invitations and manage them."}} +{{#ifCond isNewUser "true"}} +{{> InfoBlock info="Please sign up to a new account to accept this invitation"}} -{{> ButtonBlock buttonUrl=dashboardUrl buttonText="Go to Dashboard"}} +{{> ButtonBlock buttonUrl=registerLink buttonText="Sign up to a new account"}} {{> InfoBlock info="You can also copy and paste this link:"}} -{{> InfoBlock info=dashboardUrl}} +{{> InfoBlock info=registerLink}} +{{/ifCond}} + +{{#ifCond isNewUser "false"}} +{{> InfoBlock info="Please sign in to your account to see all your invitations and manage them."}} + +{{> ButtonBlock buttonUrl=signInLink buttonText="Sign in to OneUptime"}} + +{{> InfoBlock info="You can also copy and paste this link:"}} +{{> InfoBlock info=signInLink}} +{{/ifCond}} + {{> InfoBlock info="If you have not signed up to OneUptime so far. You'll be redirected to the account sign up page to sign up first."}}