diff --git a/TIAM.Core/Consts/TiamConst.cs b/TIAM.Core/Consts/TiamConst.cs index f510be2c..7c0868b7 100644 --- a/TIAM.Core/Consts/TiamConst.cs +++ b/TIAM.Core/Consts/TiamConst.cs @@ -28,7 +28,9 @@ public static class TiamConstClient public static List WelcomeEmailParameters = new List() { "UserName", - "ActivationCode" + "SettingBaseUrl", + "UserId", + "Token" }; public static List ForgotPasswordEmailParameters = new List() diff --git a/TIAM.Services.Server/EmailTemplateHelper.cs b/TIAM.Services.Server/EmailTemplateHelper.cs index fbda0365..15b9f702 100644 --- a/TIAM.Services.Server/EmailTemplateHelper.cs +++ b/TIAM.Services.Server/EmailTemplateHelper.cs @@ -117,5 +117,20 @@ namespace TIAM.Services.Server return EmailTemplateHelper.ReplacePlaceholders(template, placeholders); } + public static string GenerateWelcomeEmail(string userName, string settingBaseUrl, string userId, string token) + { + string template = EmailTemplateHelper.GetTemplate(TiamConstClient.WelcomeEmailTemplateName); + + var placeholders = new Dictionary + { + { TiamConstClient.ForgotPasswordEmailParameters[0], userName }, + { TiamConstClient.ForgotPasswordEmailParameters[1], settingBaseUrl }, + { TiamConstClient.ForgotPasswordEmailParameters[2], userId }, + { TiamConstClient.ForgotPasswordEmailParameters[3], token } + }; + + return EmailTemplateHelper.ReplacePlaceholders(template, placeholders); + } + } } diff --git a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/ForgotPasswordEmailTemplate.html b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/ForgotPasswordEmailTemplate.html index 64c43a24..ef7ff596 100644 --- a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/ForgotPasswordEmailTemplate.html +++ b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/ForgotPasswordEmailTemplate.html @@ -4,10 +4,10 @@ Forgot password -

Dear {{UserName}},

+ Dear {{UserName}},

Please follow the link below to renew your password:

-

Confirm Transfer

+

Renew password

If you did not request this, please disregard this email.

Thank you,
Tour I Am team

diff --git a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/GeneralEmailTemplate.html b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/GeneralEmailTemplate.html index 5350a1fe..230bbda2 100644 --- a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/GeneralEmailTemplate.html +++ b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/GeneralEmailTemplate.html @@ -4,7 +4,7 @@ Welcome -

Hello, {{UserName}}!

+ Hello, {{UserName}}!

You have received a message in the TourIam System:

{{MessageBody}}


diff --git a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/NewTransferEmailTemplate.html b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/NewTransferEmailTemplate.html index ed750c67..a7bdd4bb 100644 --- a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/NewTransferEmailTemplate.html +++ b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/NewTransferEmailTemplate.html @@ -1,7 +1,7 @@  -

Dear {{UserName}},

+ Dear {{UserName}},

We are pleased to inform you that a transfer order has been placed. Below are the details of the transfer:

{{FromAddress}} - {{ToAddress}}

{{Appointment}}

diff --git a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/TransferModifiedEmailTemplate.html b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/TransferModifiedEmailTemplate.html index d035e8c3..a5deadb2 100644 --- a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/TransferModifiedEmailTemplate.html +++ b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/TransferModifiedEmailTemplate.html @@ -4,7 +4,7 @@ Transfer modified -

Hello, {{UserName}}!

+ Hello, {{UserName}}!

Your transfer has been modified.

You can check the details here: {{TransferUrl}}

diff --git a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/WelcomeEmailTemplate.html b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/WelcomeEmailTemplate.html index b39fe651..29bba01d 100644 --- a/TIAM.Services.Server/EmbeddedResources/EmailTemplates/WelcomeEmailTemplate.html +++ b/TIAM.Services.Server/EmbeddedResources/EmailTemplates/WelcomeEmailTemplate.html @@ -4,8 +4,9 @@ Welcome -

Hello, {{UserName}}!

+ Hello, {{UserName}}!

Thank you for joining us.

-

Your activation code is: {{ActivationCode}}

+

Renew password

+

If you did not request this, please disregard this email.

\ No newline at end of file diff --git a/TIAMMobileApp/Services/UserDataServiceMobile.cs b/TIAMMobileApp/Services/UserDataServiceMobile.cs index 60875624..432247db 100644 --- a/TIAMMobileApp/Services/UserDataServiceMobile.cs +++ b/TIAMMobileApp/Services/UserDataServiceMobile.cs @@ -372,6 +372,18 @@ namespace TIAMMobileApp.Services return result; } + public async Task SendWelcomeMail(string emailAddress) + { + _logger.Info("SendWelcomeMail() called"); + + var url = $"{Setting.ApiBaseUrl}/{APIUrls.SendWelcomeMail}"; + var response = await _http.PostAsJsonAsync(url, emailAddress); + var success = await response.Content.ReadFromJsonAsync(); + + _logger.Detail($"SendForgottenPasswordMail(): {success.ToString()}"); + return success; + } + //public Task> GetUserRolesAsync(UserModel userModel) //{ // //TODO Finish this diff --git a/TIAMSharedUI/Pages/EditTransfers.razor b/TIAMSharedUI/Pages/EditTransfers.razor index d6717565..48d7fd2e 100644 --- a/TIAMSharedUI/Pages/EditTransfers.razor +++ b/TIAMSharedUI/Pages/EditTransfers.razor @@ -163,11 +163,24 @@ else
Contact driver
-
Cancel
+ @{ + if (_transfer.TransferStatusType != TransferStatusType.UserCanceled) + { +
Cancel
+ } + } +
- Pay -
-
Modify
+ @{ + if(_transfer.Price != null || _transfer.Price != 0) + { + Pay +
+ } + } + + @*
Modify
*@ +
Modify
@@ -232,7 +245,7 @@ else - + @@ -366,7 +379,13 @@ else } showResultMessage = true; _logger.Info($"Submitted nested form: {result.GetType().FullName}"); - + + } + + private async Task CancelTransfer() + { + _transfer.TransferStatusType = TransferStatusType.UserCanceled; + var result = await UpdateTransfer(true); } private async Task Pay() @@ -436,6 +455,11 @@ else } } } + else + { + //does a user exist with this userId? + await UserDataService.SetEmailConfirmed(transferUser.Id); + } } } @@ -497,7 +521,8 @@ else { try { - var responseTransfer = await transferDataService.UpdateTransferAsync(_transfer); + // var responseTransfer = await transferDataService.UpdateTransferAsync(_transfer); + var responseTransfer = await _adminSignalRClient.PostDataAsync(SignalRTags.UpdateTransfer, _transfer); if (responseTransfer != null) { return responseTransfer; diff --git a/TIAMSharedUI/Pages/Login.razor b/TIAMSharedUI/Pages/Login.razor index 68799f62..d727dcc5 100644 --- a/TIAMSharedUI/Pages/Login.razor +++ b/TIAMSharedUI/Pages/Login.razor @@ -57,6 +57,7 @@ } } *@ +

@resultMessage

No account yet? Sign up here!
diff --git a/TIAMSharedUI/Pages/Login.razor.cs b/TIAMSharedUI/Pages/Login.razor.cs index 123c8abc..67bb9660 100644 --- a/TIAMSharedUI/Pages/Login.razor.cs +++ b/TIAMSharedUI/Pages/Login.razor.cs @@ -47,7 +47,8 @@ namespace TIAMSharedUI.Pages public string TitleText { get; set; } = "dda,mnd,amn,a"; private int _currentStep = 1; bool _loggedIn = false; - + private string messageClass = ""; + private string resultMessage = ""; private void GoToNextStep() { @@ -80,42 +81,43 @@ namespace TIAMSharedUI.Pages if (mainResponse != null) { - //check for bad request - //TODO: fix hacky solution - string authResponseJson = JsonSerializer.Serialize(mainResponse.Content); - - var authResponse = JsonSerializer.Deserialize(authResponseJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); - - string accessToken = authResponse.AccessToken; - - var token = ProcessToken(accessToken); - - string userId = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value; - string email = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value; - - var myId = Guid.Parse(userId); - //userDataService.User.Email = _email; - - var userBasicDetails = new UserBasicDetails(userId, email, authResponse.AccessToken, authResponse.RefreshToken); - - string userBasicDetailsJson = JsonSerializer.Serialize(userBasicDetails); - - - //save to local storage - await secureStorageHandler.SaveToSecureStorageAsync(nameof(Setting.UserBasicDetails), userBasicDetailsJson); - - await AuthStateProvider.GetAuthenticationStateAsync(); - - if (!mainResponse.IsSuccess) { //await App.Current.MainPage.DisplayAlert("Error", "Invalid credentials", "Ok"); //display error message via jsinterop BrowserConsoleLogWriter.Info("Invalid credentials"); - navManager.NavigateTo("login"); + messageClass = "text-danger"; + resultMessage = "Invalid credentials"; + await InvokeAsync(StateHasChanged); + //navManager.NavigateTo("login"); } else { + string authResponseJson = JsonSerializer.Serialize(mainResponse.Content); + + var authResponse = JsonSerializer.Deserialize(authResponseJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + + string accessToken = authResponse.AccessToken; + + var token = ProcessToken(accessToken); + + string userId = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value; + string email = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value; + + var myId = Guid.Parse(userId); + //userDataService.User.Email = _email; + + var userBasicDetails = new UserBasicDetails(userId, email, authResponse.AccessToken, authResponse.RefreshToken); + + string userBasicDetailsJson = JsonSerializer.Serialize(userBasicDetails); + + + //save to local storage + await secureStorageHandler.SaveToSecureStorageAsync(nameof(Setting.UserBasicDetails), userBasicDetailsJson); + + await AuthStateProvider.GetAuthenticationStateAsync(); + + //await App.Current.MainPage.DisplayAlert("Success", "Successful login", "Ok"); //display success message via jsinterop BrowserConsoleLogWriter.Info("Successful login"); @@ -129,7 +131,8 @@ namespace TIAMSharedUI.Pages componentUpdateService.CallRequestRefreshAll(); return Task.CompletedTask; }, user.UserId).Forget(); - + messageClass = "text-success"; + resultMessage = "Successful login"; SaveToSessionInfo(user).Forget(); navManager.NavigateTo("/"); } diff --git a/TIAMSharedUI/Pages/Register.razor b/TIAMSharedUI/Pages/Register.razor index ec8af7cf..6e04b22b 100644 --- a/TIAMSharedUI/Pages/Register.razor +++ b/TIAMSharedUI/Pages/Register.razor @@ -105,14 +105,13 @@ currentStep = 1; var response = await UserDataservice.CreateUser(regModel); - LogToBrowserConsole("Registration started: " + "Email: " + regModel.Email + "PhoneNumber: " + regModel.PhoneNumber + "Password: " + regModel.Password); - - if (response.isSuccess) { //await App.Current.MainPage.DisplayAlert("Error", "Invalid credentials", "Ok"); //display error message via jsinterop LogToBrowserConsole(response.ErrorMessage); + var validateUser = await UserDataservice.SendWelcomeMail(regModel.Email!); + navManager.NavigateTo("/login"); } else if (!response.isSuccess) diff --git a/TIAMSharedUI/Pages/User/SysAdmins/ManageTransfers.razor b/TIAMSharedUI/Pages/User/SysAdmins/ManageTransfers.razor index 284ccac9..63ba02b4 100644 --- a/TIAMSharedUI/Pages/User/SysAdmins/ManageTransfers.razor +++ b/TIAMSharedUI/Pages/User/SysAdmins/ManageTransfers.razor @@ -171,7 +171,7 @@ @editFormContext.GetEditor("FromAddress") - + - + @editFormContext.GetEditor("PassengerCount") - + + @editFormContext.GetEditor("Payed") - + @editFormContext.GetEditor("TransferStatusType") + + @editFormContext.GetEditor("Price") + diff --git a/TIAMSharedUI/Pages/ValidateEmail.razor b/TIAMSharedUI/Pages/ValidateEmail.razor new file mode 100644 index 00000000..5a434efe --- /dev/null +++ b/TIAMSharedUI/Pages/ValidateEmail.razor @@ -0,0 +1,85 @@ +@page "/validate/{userId}/{renewToken}" +@inherits BasePageComponent +@using TIAM.Models.Dtos.Users +@using TIAM.Services +@using TIAMSharedUI.Shared.Components.BaseComponents +@using BlazorAnimation +@using TIAMWebApp.Shared.Application.Interfaces +@using TIAMWebApp.Shared.Application.Models.PageModels; +@using TIAMSharedUI.Pages.Components; +@using TIAMSharedUI.Pages.User.CardComponents +@using TIAMWebApp.Shared.Application.Services +@inject IUserDataService UserDataService +@inject AdminSignalRClient AdminSignalRClient + +Validate Email + +
+

Validate email

+

Let's validate your email!

+
+ + +
+
+
+ +
+ +

@resultMsg

+ +
+
+
+ +
+
+ +@code { + [Parameter] public string? userId { get; set; } = ""; + [Parameter] public string? renewToken { get; set; } = ""; + + private bool isFormHidden = true; + string resultMsg = ""; + private UserModelDtoDetail? user = new UserModelDtoDetail(); + + protected override async Task OnInitializedAsync() + { + + if (userId != null && renewToken != null) + { + string msg = await UserDataService.ValidateForgotPasswordToken(Guid.Parse(userId), renewToken); + if (msg == "Success") + { + + var result = await UserDataService.SetEmailConfirmed(Guid.Parse(userId)); + if (result) + { + resultMsg = "Email validated, you can now login"; + } + else + { + resultMsg = "Oops, something went wrong"; + } + } + else + { + + resultMsg = msg; + } + } + await base.OnInitializedAsync(); + } + + protected override async Task OnParametersSetAsync() + { + + + //validate Token + + await base.OnParametersSetAsync(); + } + + + +} diff --git a/TIAMWebApp/Client/Services/UserDataServiceWeb.cs b/TIAMWebApp/Client/Services/UserDataServiceWeb.cs index a263f9db..ed70444e 100644 --- a/TIAMWebApp/Client/Services/UserDataServiceWeb.cs +++ b/TIAMWebApp/Client/Services/UserDataServiceWeb.cs @@ -379,6 +379,18 @@ namespace TIAMWebApp.Client.Services return result; } + public async Task SendWelcomeMail(string emailAddress) + { + _logger.Info("SendWelcomeMail() called"); + + var url = $"{Setting.ApiBaseUrl}/{APIUrls.SendWelcomeMail}"; + var response = await _http.PostAsJsonAsync(url, emailAddress); + var success = await response.Content.ReadFromJsonAsync(); + + _logger.Detail($"SendForgottenPasswordMail(): {success.ToString()}"); + return success; + } + /*public Task> GetUserRolesAsync(UserModel userModel) { //TODO: finish this diff --git a/TIAMWebApp/Server/Controllers/UserAPIController.cs b/TIAMWebApp/Server/Controllers/UserAPIController.cs index 06c1d433..09e86ed8 100644 --- a/TIAMWebApp/Server/Controllers/UserAPIController.cs +++ b/TIAMWebApp/Server/Controllers/UserAPIController.cs @@ -479,7 +479,7 @@ namespace TIAMWebApp.Server.Controllers message.Message.ContextId = user.Id; message.Message.ContextType = MessageContextType.System; message.Message.SenderId = Guid.Empty; - message.Message.Recipients.Add(new EmailRecipient(Guid.NewGuid(), user.Id, Guid.NewGuid(), email)); + message.Message.Recipients.Add(new EmailRecipient(Guid.NewGuid(), user.Id, message.Message.Id, email)); message.Message.Text = EmailTemplateHelper.GenerateForgotPasswordEmail( user.FullName, @@ -573,6 +573,62 @@ namespace TIAMWebApp.Server.Controllers return false; } + [AllowAnonymous] + [HttpPost] + [Route(APIUrls.SendWelcomeMailRouteName)] + public async Task SendWelcomeMail([FromBody] string email) + { + _logger.Info($"SendWelcomeMail called with id: {email}"); + + var user = await userDal.GetUserByEmailAsync(email, false); + if (user == null) + { + return false; + } + else + { + //create new token for the user + //user.ConfirmToken = Guid.NewGuid().ToString("N"); + user.ConfirmToken = AcCharsGenerator.NewToken(); + _logger.Debug($"Generated token for user: {user.ConfirmToken}"); + var result = await adminDal.UpdateUserAsync(user); + _logger.Debug($"Saved token for user: {result.ConfirmToken}"); + //send email + var message = new MessageSenderModel(); + message.Message = new EmailMessage(); + message.Message.EmailAddress = email; + message.Message.Id = Guid.NewGuid(); + message.MessageType = MessageTypesEnum.email; + message.Message.Subject = "[Tour I Am] Validate your email"; + message.Message.ContextId = user.Id; + message.Message.ContextType = MessageContextType.System; + message.Message.SenderId = Guid.Empty; + message.Message.Recipients.Add(new EmailRecipient(Guid.NewGuid(), user.Id, message.Message.Id, email)); + + message.Message.Text = EmailTemplateHelper.GenerateWelcomeEmail( + user.FullName, + Setting.BaseUrl, + user.Id.ToString(), + user.ConfirmToken); + _logger.Info(message.Message.Text); + var messageElement = message.Message; + Console.WriteLine(message.Message); + var mailResult = await messageSenderService.SendMessageAsync(messageElement, (int)message.MessageType); + await adminDal.AddEmailMessageAsync(messageElement); + _logger.Info("SendEmail result: " + mailResult); + //----------------- + if (mailResult == HttpStatusCode.OK.ToString()) + { + await adminDal.AddEmailMessageAsync(messageElement); + return true; + } + else + { + return false; + } + } + } + } } \ No newline at end of file diff --git a/TIAMWebApp/Shared/Interfaces/IUserDataService.cs b/TIAMWebApp/Shared/Interfaces/IUserDataService.cs index db20a8f0..f2d44f5f 100644 --- a/TIAMWebApp/Shared/Interfaces/IUserDataService.cs +++ b/TIAMWebApp/Shared/Interfaces/IUserDataService.cs @@ -32,5 +32,7 @@ namespace TIAMWebApp.Shared.Application.Interfaces public Task ValidateForgotPasswordToken(Guid userId, string token); public Task SetEmailConfirmed(Guid userId); + + public Task SendWelcomeMail(string emailAddress); } } \ No newline at end of file diff --git a/TIAMWebApp/Shared/Models/APIUrls.cs b/TIAMWebApp/Shared/Models/APIUrls.cs index b77b76ff..2ef5b7c0 100644 --- a/TIAMWebApp/Shared/Models/APIUrls.cs +++ b/TIAMWebApp/Shared/Models/APIUrls.cs @@ -69,6 +69,9 @@ namespace TIAMWebApp.Shared.Application.Models public const string SendForgottenPasswordMailRouteName = "SendForgottenPasswordMail"; public const string SendForgottenPasswordMail = UserAPI + SendForgottenPasswordMailRouteName; + public const string SendWelcomeMailRouteName = "SendWelcomeMail"; + public const string SendWelcomeMail = UserAPI + SendWelcomeMailRouteName; + public const string ValidateForgottenPasswordTokenRouteName = "ValidateForgottenPasswordToken"; public const string ValidateForgottenPasswordToken = UserAPI + ValidateForgottenPasswordTokenRouteName;