From ecac279ae416ebbad8387a7b99d0c33da71a0414 Mon Sep 17 00:00:00 2001 From: Francis Pion Date: Tue, 7 May 2024 00:05:06 -0400 Subject: [PATCH] Fixed SMS sending. (#24) --- .../Accounts/Commands/SignInCommandHandler.cs | 4 ++-- .../Accounts/IMessageService.cs | 5 +++-- .../IdentityServices/MessageService.cs | 21 +++++++++++++------ .../Accounts/Commands/SignInCommandTests.cs | 6 +++--- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/backend/src/Logitar.Master.Application/Accounts/Commands/SignInCommandHandler.cs b/backend/src/Logitar.Master.Application/Accounts/Commands/SignInCommandHandler.cs index 9256a96..72de8a6 100644 --- a/backend/src/Logitar.Master.Application/Accounts/Commands/SignInCommandHandler.cs +++ b/backend/src/Logitar.Master.Application/Accounts/Commands/SignInCommandHandler.cs @@ -76,7 +76,7 @@ private async Task HandleCredentialsAsync(Credentials crede }; SentMessages sentMessages = user == null ? await _messageService.SendAsync(Templates.AccountAuthentication, email, locale, variables, cancellationToken) - : await _messageService.SendAsync(Templates.AccountAuthentication, user, locale, variables, cancellationToken); + : await _messageService.SendAsync(Templates.AccountAuthentication, user, ContactType.Email, locale, variables, cancellationToken); SentMessage sentMessage = sentMessages.ToSentMessage(email); return SignInCommandResult.AuthenticationLinkSent(sentMessage); } @@ -122,7 +122,7 @@ private async Task SendMultiFactorAuthenticationMessageAsyn ["OneTimePassword"] = oneTimePassword.Password }; string template = Templates.GetMultiFactorAuthentication(contactType); - SentMessages sentMessages = await _messageService.SendAsync(template, user, locale, variables, cancellationToken); + SentMessages sentMessages = await _messageService.SendAsync(template, user, contactType, locale, variables, cancellationToken); SentMessage sentMessage = sentMessages.ToSentMessage(contact); return SignInCommandResult.RequireOneTimePasswordValidation(oneTimePassword, sentMessage); } diff --git a/backend/src/Logitar.Master.Application/Accounts/IMessageService.cs b/backend/src/Logitar.Master.Application/Accounts/IMessageService.cs index 33353ae..08f8147 100644 --- a/backend/src/Logitar.Master.Application/Accounts/IMessageService.cs +++ b/backend/src/Logitar.Master.Application/Accounts/IMessageService.cs @@ -1,4 +1,5 @@ -using Logitar.Portal.Contracts.Messages; +using Logitar.Master.Contracts.Accounts; +using Logitar.Portal.Contracts.Messages; using Logitar.Portal.Contracts.Users; namespace Logitar.Master.Application.Accounts; @@ -7,5 +8,5 @@ public interface IMessageService { Task SendAsync(string template, Email email, string? locale = null, Dictionary? variables = null, CancellationToken cancellationToken = default); Task SendAsync(string template, Phone phone, string? locale = null, Dictionary? variables = null, CancellationToken cancellationToken = default); - Task SendAsync(string template, User user, string? locale = null, Dictionary? variables = null, CancellationToken cancellationToken = default); + Task SendAsync(string template, User user, ContactType contactType, string? locale = null, Dictionary? variables = null, CancellationToken cancellationToken = default); } diff --git a/backend/src/Logitar.Master.Infrastructure/IdentityServices/MessageService.cs b/backend/src/Logitar.Master.Infrastructure/IdentityServices/MessageService.cs index 4d2d1a1..6c199c5 100644 --- a/backend/src/Logitar.Master.Infrastructure/IdentityServices/MessageService.cs +++ b/backend/src/Logitar.Master.Infrastructure/IdentityServices/MessageService.cs @@ -1,17 +1,22 @@ using Logitar.Master.Application.Accounts; +using Logitar.Master.Contracts.Accounts; using Logitar.Portal.Contracts; using Logitar.Portal.Contracts.Messages; using Logitar.Portal.Contracts.Users; +using Microsoft.Extensions.Configuration; namespace Logitar.Master.Infrastructure.IdentityServices; internal class MessageService : IMessageService { private readonly IMessageClient _messageClient; + private readonly Guid _phoneSenderId; - public MessageService(IMessageClient messageClient) + public MessageService(IConfiguration configuration, IMessageClient messageClient) { _messageClient = messageClient; + _phoneSenderId = configuration.GetSection("Portal").GetValue("PhoneSenderId") + ?? throw new ArgumentException("The configuration key 'Portal:PhoneSenderId' is required.", nameof(configuration)); } public async Task SendAsync(string template, Email email, string? locale, Dictionary? variables, CancellationToken cancellationToken) @@ -21,7 +26,7 @@ public async Task SendAsync(string template, Email email, string? Type = RecipientType.To, Address = email.Address }; - return await SendAsync(template, recipient, locale, variables, cancellationToken); + return await SendAsync(template, recipient, ContactType.Email, locale, variables, cancellationToken); } public async Task SendAsync(string template, Phone phone, string? locale, Dictionary? variables, CancellationToken cancellationToken) @@ -31,25 +36,29 @@ public async Task SendAsync(string template, Phone phone, string? Type = RecipientType.To, PhoneNumber = phone.E164Formatted }; - return await SendAsync(template, recipient, locale, variables, cancellationToken); + return await SendAsync(template, recipient, ContactType.Phone, locale, variables, cancellationToken); } - public async Task SendAsync(string template, User user, string? locale, Dictionary? variables, CancellationToken cancellationToken) + public async Task SendAsync(string template, User user, ContactType contactType, string? locale, Dictionary? variables, CancellationToken cancellationToken) { RecipientPayload recipient = new() { Type = RecipientType.To, UserId = user.Id }; - return await SendAsync(template, recipient, locale, variables, cancellationToken); + return await SendAsync(template, recipient, contactType, locale, variables, cancellationToken); } - private async Task SendAsync(string template, RecipientPayload recipient, string? locale, IEnumerable>? variables, CancellationToken cancellationToken) + private async Task SendAsync(string template, RecipientPayload recipient, ContactType contactType, string? locale, IEnumerable>? variables, CancellationToken cancellationToken) { SendMessagePayload payload = new(template) { Locale = locale }; + if (contactType == ContactType.Phone) + { + payload.SenderId = _phoneSenderId; + } payload.Recipients.Add(recipient); if (variables != null) { diff --git a/backend/tests/Logitar.Master.IntegrationTests/Application/Accounts/Commands/SignInCommandTests.cs b/backend/tests/Logitar.Master.IntegrationTests/Application/Accounts/Commands/SignInCommandTests.cs index 24be04c..f9fe403 100644 --- a/backend/tests/Logitar.Master.IntegrationTests/Application/Accounts/Commands/SignInCommandTests.cs +++ b/backend/tests/Logitar.Master.IntegrationTests/Application/Accounts/Commands/SignInCommandTests.cs @@ -224,7 +224,7 @@ public async Task It_should_send_a_Multi_Factor_Authentication_email_message() OneTimePasswordService.Setup(x => x.CreateAsync(user, "MultiFactorAuthentication", CancellationToken)).ReturnsAsync(oneTimePassword); SentMessages sentMessages = new([Guid.NewGuid()]); - MessageService.Setup(x => x.SendAsync("MultiFactorAuthenticationEmail", user, payload.Locale, + MessageService.Setup(x => x.SendAsync("MultiFactorAuthenticationEmail", user, ContactType.Email, payload.Locale, It.Is>(v => v.Count == 1 && v["OneTimePassword"] == oneTimePassword.Password), CancellationToken) ).ReturnsAsync(sentMessages); @@ -262,7 +262,7 @@ public async Task It_should_send_a_Multi_Factor_Authentication_Sms_message() OneTimePasswordService.Setup(x => x.CreateAsync(user, "MultiFactorAuthentication", CancellationToken)).ReturnsAsync(oneTimePassword); SentMessages sentMessages = new([Guid.NewGuid()]); - MessageService.Setup(x => x.SendAsync("MultiFactorAuthenticationPhone", user, payload.Locale, + MessageService.Setup(x => x.SendAsync("MultiFactorAuthenticationPhone", user, ContactType.Phone, payload.Locale, It.Is>(v => v.Count == 1 && v["OneTimePassword"] == oneTimePassword.Password), CancellationToken) ).ReturnsAsync(sentMessages); @@ -320,7 +320,7 @@ public async Task It_should_send_an_authentication_link_when_the_user_does_not_h }; SentMessages sentMessages = new([Guid.NewGuid()]); - MessageService.Setup(x => x.SendAsync("AccountAuthentication", user, payload.Locale, + MessageService.Setup(x => x.SendAsync("AccountAuthentication", user, ContactType.Email, payload.Locale, It.Is>(v => v.Count == 1 && v["Token"] == createdToken.Token), CancellationToken) ).ReturnsAsync(sentMessages);