diff --git a/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs b/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs index dcefd6256c..742b4a2cb6 100644 --- a/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs +++ b/src/Core/AdminConsole/Services/Implementations/OrganizationService.cs @@ -1277,7 +1277,7 @@ public class OrganizationService : IOrganizationService orgUser.Email = null; await _eventService.LogOrganizationUserEventAsync(orgUser, EventType.OrganizationUser_Confirmed); - await _mailService.SendOrganizationConfirmedEmailAsync(organization.DisplayName(), user.Email); + await _mailService.SendOrganizationConfirmedEmailAsync(organization.DisplayName(), user.Email, orgUser.AccessSecretsManager); await DeleteAndPushUserRegistrationAsync(organizationId, user.Id); succeededUsers.Add(orgUser); result.Add(Tuple.Create(orgUser, "")); diff --git a/src/Core/Models/Mail/OrganizationUserInvitedViewModel.cs b/src/Core/Models/Mail/OrganizationUserInvitedViewModel.cs index 0fc65d91ef..f34f414ce8 100644 --- a/src/Core/Models/Mail/OrganizationUserInvitedViewModel.cs +++ b/src/Core/Models/Mail/OrganizationUserInvitedViewModel.cs @@ -22,14 +22,18 @@ public class OrganizationUserInvitedViewModel : BaseTitleContactUsMailModel return new OrganizationUserInvitedViewModel { TitleFirst = orgInvitesInfo.IsFreeOrg ? freeOrgTitle : "Join ", - TitleSecondBold = orgInvitesInfo.IsFreeOrg ? string.Empty : CoreHelpers.SanitizeForEmail(orgInvitesInfo.OrganizationName, false), + TitleSecondBold = + orgInvitesInfo.IsFreeOrg + ? string.Empty + : CoreHelpers.SanitizeForEmail(orgInvitesInfo.OrganizationName, false), TitleThird = orgInvitesInfo.IsFreeOrg ? string.Empty : " on Bitwarden and start securing your passwords!", OrganizationName = CoreHelpers.SanitizeForEmail(orgInvitesInfo.OrganizationName, false) + orgUser.Status, Email = WebUtility.UrlEncode(orgUser.Email), OrganizationId = orgUser.OrganizationId.ToString(), OrganizationUserId = orgUser.Id.ToString(), Token = WebUtility.UrlEncode(expiringToken.Token), - ExpirationDate = $"{expiringToken.ExpirationDate.ToLongDateString()} {expiringToken.ExpirationDate.ToShortTimeString()} UTC", + ExpirationDate = + $"{expiringToken.ExpirationDate.ToLongDateString()} {expiringToken.ExpirationDate.ToShortTimeString()} UTC", OrganizationNameUrlEncoded = WebUtility.UrlEncode(orgInvitesInfo.OrganizationName), WebVaultUrl = globalSettings.BaseServiceUri.VaultWithHash, SiteName = globalSettings.SiteName, diff --git a/src/Core/Services/IMailService.cs b/src/Core/Services/IMailService.cs index 9300e1b131..30c28ddd73 100644 --- a/src/Core/Services/IMailService.cs +++ b/src/Core/Services/IMailService.cs @@ -24,8 +24,8 @@ public interface IMailService Task SendOrganizationInviteEmailsAsync(OrganizationInvitesInfo orgInvitesInfo); Task SendOrganizationMaxSeatLimitReachedEmailAsync(Organization organization, int maxSeatCount, IEnumerable ownerEmails); Task SendOrganizationAutoscaledEmailAsync(Organization organization, int initialSeatCount, IEnumerable ownerEmails); - Task SendOrganizationAcceptedEmailAsync(Organization organization, string userIdentifier, IEnumerable adminEmails); - Task SendOrganizationConfirmedEmailAsync(string organizationName, string email); + Task SendOrganizationAcceptedEmailAsync(Organization organization, string userIdentifier, IEnumerable adminEmails, bool hasAccessSecretsManager = false); + Task SendOrganizationConfirmedEmailAsync(string organizationName, string email, bool hasAccessSecretsManager = false); Task SendOrganizationUserRemovedForPolicyTwoStepEmailAsync(string organizationName, string email); Task SendPasswordlessSignInAsync(string returnUrl, string token, string email); Task SendInvoiceUpcoming( diff --git a/src/Core/Services/Implementations/HandlebarsMailService.cs b/src/Core/Services/Implementations/HandlebarsMailService.cs index 19407af0d1..93f427c362 100644 --- a/src/Core/Services/Implementations/HandlebarsMailService.cs +++ b/src/Core/Services/Implementations/HandlebarsMailService.cs @@ -173,7 +173,7 @@ public class HandlebarsMailService : IMailService } public async Task SendOrganizationAcceptedEmailAsync(Organization organization, string userIdentifier, - IEnumerable adminEmails) + IEnumerable adminEmails, bool hasAccessSecretsManager = false) { var message = CreateDefaultMessage($"Action Required: {userIdentifier} Needs to Be Confirmed", adminEmails); var model = new OrganizationUserAcceptedViewModel @@ -189,7 +189,7 @@ public class HandlebarsMailService : IMailService await _mailDeliveryService.SendEmailAsync(message); } - public async Task SendOrganizationConfirmedEmailAsync(string organizationName, string email) + public async Task SendOrganizationConfirmedEmailAsync(string organizationName, string email, bool hasAccessSecretsManager = false) { var message = CreateDefaultMessage($"You Have Been Confirmed To {organizationName}", email); var model = new OrganizationUserConfirmedViewModel @@ -198,7 +198,9 @@ public class HandlebarsMailService : IMailService TitleSecondBold = CoreHelpers.SanitizeForEmail(organizationName, false), TitleThird = "!", OrganizationName = CoreHelpers.SanitizeForEmail(organizationName, false), - WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash, + WebVaultUrl = hasAccessSecretsManager + ? _globalSettings.BaseServiceUri.VaultWithHashAndSecretManagerProduct + : _globalSettings.BaseServiceUri.VaultWithHash, SiteName = _globalSettings.SiteName }; await AddMessageContentAsync(message, "OrganizationUserConfirmed", model); @@ -216,6 +218,7 @@ public class HandlebarsMailService : IMailService var messageModels = orgInvitesInfo.OrgUserTokenPairs.Select(orgUserTokenPair => { + var orgUserInviteViewModel = OrganizationUserInvitedViewModel.CreateFromInviteInfo( orgInvitesInfo, orgUserTokenPair.OrgUser, orgUserTokenPair.Token, _globalSettings); return CreateMessage(orgUserTokenPair.OrgUser.Email, orgUserInviteViewModel); @@ -256,7 +259,7 @@ public class HandlebarsMailService : IMailService var message = CreateDefaultMessage("Welcome to Bitwarden!", userEmail); var model = new BaseMailModel { - WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash, + WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHashAndSecretManagerProduct, SiteName = _globalSettings.SiteName }; await AddMessageContentAsync(message, "TrialInitiation", model); diff --git a/src/Core/Services/NoopImplementations/NoopMailService.cs b/src/Core/Services/NoopImplementations/NoopMailService.cs index b6dbdc6acb..4bf15488c4 100644 --- a/src/Core/Services/NoopImplementations/NoopMailService.cs +++ b/src/Core/Services/NoopImplementations/NoopMailService.cs @@ -43,12 +43,13 @@ public class NoopMailService : IMailService return Task.FromResult(0); } - public Task SendOrganizationAcceptedEmailAsync(Organization organization, string userIdentifier, IEnumerable adminEmails) + public Task SendOrganizationAcceptedEmailAsync(Organization organization, string userIdentifier, + IEnumerable adminEmails, bool hasAccessSecretsManager = false) { return Task.FromResult(0); } - public Task SendOrganizationConfirmedEmailAsync(string organizationName, string email) + public Task SendOrganizationConfirmedEmailAsync(string organizationName, string email, bool hasAccessSecretsManager = false) { return Task.FromResult(0); } diff --git a/src/Core/Settings/GlobalSettings.cs b/src/Core/Settings/GlobalSettings.cs index 0739a4c81a..84037a0a1c 100644 --- a/src/Core/Settings/GlobalSettings.cs +++ b/src/Core/Settings/GlobalSettings.cs @@ -146,6 +146,7 @@ public class GlobalSettings : IGlobalSettings public string CloudRegion { get; set; } public string Vault { get; set; } public string VaultWithHash => $"{Vault}/#"; + public string VaultWithHashAndSecretManagerProduct => $"{Vault}/#/sm"; public string Api { diff --git a/src/Core/Settings/IBaseServiceUriSettings.cs b/src/Core/Settings/IBaseServiceUriSettings.cs index 0acb504a2b..0c2ed15f66 100644 --- a/src/Core/Settings/IBaseServiceUriSettings.cs +++ b/src/Core/Settings/IBaseServiceUriSettings.cs @@ -6,6 +6,7 @@ public interface IBaseServiceUriSettings string CloudRegion { get; set; } string Vault { get; set; } string VaultWithHash { get; } + string VaultWithHashAndSecretManagerProduct { get; } string Api { get; set; } public string Identity { get; set; } public string Admin { get; set; }