Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/Core/Platform/Mail/HandlebarsMailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1194,7 +1194,7 @@ public async Task SendEmergencyAccessInviteEmailAsync(EmergencyAccess emergencyA
var message = CreateDefaultMessage($"Emergency Access Contact Invite", emergencyAccess.Email);
var model = new EmergencyAccessInvitedViewModel
{
Name = CoreHelpers.SanitizeForEmail(name),
Name = CoreHelpers.SanitizeForEmail(name, false),
Email = WebUtility.UrlEncode(emergencyAccess.Email),
Id = emergencyAccess.Id.ToString(),
Token = WebUtility.UrlEncode(token),
Expand Down Expand Up @@ -1225,7 +1225,7 @@ public async Task SendEmergencyAccessConfirmedEmailAsync(string grantorName, str
var message = CreateDefaultMessage($"You Have Been Confirmed as Emergency Access Contact", email);
var model = new EmergencyAccessConfirmedViewModel
{
Name = CoreHelpers.SanitizeForEmail(grantorName),
Name = CoreHelpers.SanitizeForEmail(grantorName, false),
WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash,
SiteName = _globalSettings.SiteName
};
Expand All @@ -1242,7 +1242,7 @@ public async Task SendEmergencyAccessRecoveryInitiated(EmergencyAccess emergency

var model = new EmergencyAccessRecoveryViewModel
{
Name = CoreHelpers.SanitizeForEmail(initiatingName),
Name = CoreHelpers.SanitizeForEmail(initiatingName, false),
Action = emergencyAccess.Type.ToString(),
DaysLeft = emergencyAccess.WaitTimeDays - Convert.ToInt32((remainingTime).TotalDays),
};
Expand All @@ -1256,7 +1256,7 @@ public async Task SendEmergencyAccessRecoveryApproved(EmergencyAccess emergencyA
var message = CreateDefaultMessage("Emergency Access Approved", email);
var model = new EmergencyAccessApprovedViewModel
{
Name = CoreHelpers.SanitizeForEmail(approvingName),
Name = CoreHelpers.SanitizeForEmail(approvingName, false),
};
await AddMessageContentAsync(message, "Auth.EmergencyAccessApproved", model);
message.Category = "EmergencyAccessApproved";
Expand All @@ -1268,7 +1268,7 @@ public async Task SendEmergencyAccessRecoveryRejected(EmergencyAccess emergencyA
var message = CreateDefaultMessage("Emergency Access Rejected", email);
var model = new EmergencyAccessRejectedViewModel
{
Name = CoreHelpers.SanitizeForEmail(rejectingName),
Name = CoreHelpers.SanitizeForEmail(rejectingName, false),
};
await AddMessageContentAsync(message, "Auth.EmergencyAccessRejected", model);
message.Category = "EmergencyAccessRejected";
Expand All @@ -1283,7 +1283,7 @@ public async Task SendEmergencyAccessRecoveryReminder(EmergencyAccess emergencyA

var model = new EmergencyAccessRecoveryViewModel
{
Name = CoreHelpers.SanitizeForEmail(initiatingName),
Name = CoreHelpers.SanitizeForEmail(initiatingName, false),
Action = emergencyAccess.Type.ToString(),
DaysLeft = emergencyAccess.WaitTimeDays - Convert.ToInt32((remainingTime).TotalDays),
};
Expand All @@ -1297,7 +1297,7 @@ public async Task SendEmergencyAccessRecoveryTimedOut(EmergencyAccess emergencyA
var message = CreateDefaultMessage("Emergency Access Granted", email);
var model = new EmergencyAccessRecoveryTimedOutViewModel
{
Name = CoreHelpers.SanitizeForEmail(initiatingName),
Name = CoreHelpers.SanitizeForEmail(initiatingName, false),
Action = emergencyAccess.Type.ToString(),
};
await AddMessageContentAsync(message, "Auth.EmergencyAccessRecoveryTimedOut", model);
Expand Down
38 changes: 38 additions & 0 deletions test/Core.Test/Services/HandlebarsMailServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,42 @@ public void GetCloudVaultSubscriptionUrl_ResolvesPerRegion(string cloudRegion, s
// Assert
Assert.StartsWith(expectedVaultBase, result);
}

[Theory]
[InlineData(nameof(HandlebarsMailService.SendEmergencyAccessConfirmedEmailAsync))]
[InlineData(nameof(HandlebarsMailService.SendEmergencyAccessRecoveryApproved))]
[InlineData(nameof(HandlebarsMailService.SendEmergencyAccessRecoveryReminder))]
public async Task EmergencyAccessEmails_ShouldEncodeNamesOnlyOnce(string methodName)
{
// Arrange
const string name = "Alice & Bob";
const string email = "recipient@example.com";
var emergencyAccess = new EmergencyAccess
{
Type = EmergencyAccessType.Takeover,
RecoveryInitiatedDate = DateTime.UtcNow.AddHours(-1),
WaitTimeDays = 2,
};

// Act
switch (methodName)
{
case nameof(HandlebarsMailService.SendEmergencyAccessConfirmedEmailAsync):
await _sut.SendEmergencyAccessConfirmedEmailAsync(name, email);
break;
case nameof(HandlebarsMailService.SendEmergencyAccessRecoveryApproved):
await _sut.SendEmergencyAccessRecoveryApproved(emergencyAccess, name, email);
break;
case nameof(HandlebarsMailService.SendEmergencyAccessRecoveryReminder):
await _sut.SendEmergencyAccessRecoveryReminder(emergencyAccess, name, email);
break;
default:
throw new ArgumentOutOfRangeException(nameof(methodName), methodName, null);
}

// Assert
await _mailDeliveryService.Received(1).SendEmailAsync(Arg.Is<MailMessage>(m =>
m.HtmlContent.Contains("Alice &amp; Bob") &&
!m.HtmlContent.Contains("Alice &amp;amp; Bob")));
}
}
Loading