merge
This commit is contained in:
commit
4ba61ba048
|
|
@ -3,6 +3,7 @@ using TIAMMobileApp.Services;
|
||||||
using TIAMWebApp.Shared.Application.Interfaces;
|
using TIAMWebApp.Shared.Application.Interfaces;
|
||||||
using DevExpress.Blazor;
|
using DevExpress.Blazor;
|
||||||
using TIAMMobilApp.Services;
|
using TIAMMobilApp.Services;
|
||||||
|
using TIAMWebApp.Shared.Application.Utility;
|
||||||
|
|
||||||
namespace TIAMMobileApp
|
namespace TIAMMobileApp
|
||||||
{
|
{
|
||||||
|
|
@ -35,7 +36,7 @@ namespace TIAMMobileApp
|
||||||
/*Android*/
|
/*Android*/
|
||||||
//client.BaseAddress = new Uri("https://10.0.2.2:7116");
|
//client.BaseAddress = new Uri("https://10.0.2.2:7116");
|
||||||
|
|
||||||
builder.Services.AddScoped(sp => client);
|
builder.Services.AddSingleton(sp => client);
|
||||||
|
|
||||||
builder.Services.AddDevExpressBlazor(configure => configure.BootstrapVersion = BootstrapVersion.v5);
|
builder.Services.AddDevExpressBlazor(configure => configure.BootstrapVersion = BootstrapVersion.v5);
|
||||||
|
|
||||||
|
|
@ -43,7 +44,9 @@ namespace TIAMMobileApp
|
||||||
builder.Services.AddScoped<ITransferDataService, TransferDataService>();
|
builder.Services.AddScoped<ITransferDataService, TransferDataService>();
|
||||||
builder.Services.AddScoped<IPopulationStructureDataProvider, PopulationStructureDataProvider>();
|
builder.Services.AddScoped<IPopulationStructureDataProvider, PopulationStructureDataProvider>();
|
||||||
builder.Services.AddScoped<ISupplierService, SupplierService>();
|
builder.Services.AddScoped<ISupplierService, SupplierService>();
|
||||||
builder.Services.AddSingleton<IUserDataService, UserDataService>();
|
builder.Services.AddScoped<IUserDataService, UserDataService>();
|
||||||
|
builder.Services.AddScoped<ISecureStorageHandler, SecureStorageHandler>();
|
||||||
|
builder.Services.AddScoped<LogToBrowserConsole>();
|
||||||
|
|
||||||
return builder.Build();
|
return builder.Build();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using TIAMWebApp.Shared.Application.Interfaces;
|
||||||
|
using TIAMWebApp.Shared.Application.Models.ClientSide;
|
||||||
|
|
||||||
|
namespace TIAMMobileApp.Services
|
||||||
|
{
|
||||||
|
public class SecureStorageHandler : ISecureStorageHandler
|
||||||
|
{
|
||||||
|
public async Task SaveToSecureStorageAsync(string key, string value)
|
||||||
|
{
|
||||||
|
|
||||||
|
await SecureStorage.SetAsync(key, value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> GetFromSecureStorageAsync(string key)
|
||||||
|
{
|
||||||
|
return await SecureStorage.GetAsync(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Net.Http.Json;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using TIAMWebApp.Shared.Application.Interfaces;
|
using TIAMWebApp.Shared.Application.Interfaces;
|
||||||
using TIAMWebApp.Shared.Application.Models;
|
using TIAMWebApp.Shared.Application.Models;
|
||||||
|
using TIAMWebApp.Shared.Application.Models.ClientSide;
|
||||||
using TIAMWebApp.Shared.Application.Models.PageModels;
|
using TIAMWebApp.Shared.Application.Models.PageModels;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12,12 +13,14 @@ namespace TIAMMobilApp.Services
|
||||||
public class UserDataService : IUserDataService
|
public class UserDataService : IUserDataService
|
||||||
{
|
{
|
||||||
private readonly HttpClient http;
|
private readonly HttpClient http;
|
||||||
public User? User { get; set; } = new User("","","");
|
private readonly ISecureStorageHandler secureStorageHandler;
|
||||||
|
public User? User { get; set; } = new User("", "", "");
|
||||||
public Dictionary<int, string> userRoleTypes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
public Dictionary<int, string> userRoleTypes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||||
|
|
||||||
public UserDataService(HttpClient http)
|
public UserDataService(HttpClient http, ISecureStorageHandler secureStorageHandler)
|
||||||
{
|
{
|
||||||
this.http = http;
|
this.http = http;
|
||||||
|
this.secureStorageHandler = secureStorageHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -40,7 +43,7 @@ namespace TIAMMobilApp.Services
|
||||||
{
|
{
|
||||||
if (User == null)
|
if (User == null)
|
||||||
{
|
{
|
||||||
User = new User("","","");
|
User = new User("", "", "");
|
||||||
User.IsLoggedIn = false;
|
User.IsLoggedIn = false;
|
||||||
User.UserType = UserType.User;
|
User.UserType = UserType.User;
|
||||||
return User;
|
return User;
|
||||||
|
|
@ -50,7 +53,7 @@ namespace TIAMMobilApp.Services
|
||||||
{
|
{
|
||||||
return User;
|
return User;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Mock method for now
|
//Mock method for now
|
||||||
|
|
@ -66,7 +69,8 @@ namespace TIAMMobilApp.Services
|
||||||
return User;
|
return User;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> TestUserApi(int Param) {
|
public async Task<string> TestUserApi(int Param)
|
||||||
|
{
|
||||||
var url = APIUrls.UserTest;
|
var url = APIUrls.UserTest;
|
||||||
var response = await http.PostAsJsonAsync(url, Param);
|
var response = await http.PostAsJsonAsync(url, Param);
|
||||||
var result = await response.Content.ReadAsStringAsync();
|
var result = await response.Content.ReadAsStringAsync();
|
||||||
|
|
@ -75,15 +79,15 @@ namespace TIAMMobilApp.Services
|
||||||
|
|
||||||
public async Task<string> AuthenticateUser(LoginModel loginModel)
|
public async Task<string> AuthenticateUser(LoginModel loginModel)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
string result = string.Empty;
|
|
||||||
var url = APIUrls.AuthenticateUser;
|
|
||||||
|
string result = string.Empty;
|
||||||
|
var url = APIUrls.AuthenticateUser;
|
||||||
|
|
||||||
var response = await http.PostAsJsonAsync(url, loginModel);
|
var response = await http.PostAsJsonAsync(url, loginModel);
|
||||||
|
|
||||||
if(response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
result = await response.Content.ReadAsStringAsync();
|
result = await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +99,7 @@ namespace TIAMMobilApp.Services
|
||||||
//result = await response.Content.ReadAsStringAsync();
|
//result = await response.Content.ReadAsStringAsync();
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(bool isSuccess, string ErrorMessage)> CreateUser(RegistrationModel regModel)
|
public async Task<(bool isSuccess, string ErrorMessage)> CreateUser(RegistrationModel regModel)
|
||||||
|
|
@ -105,7 +109,7 @@ namespace TIAMMobilApp.Services
|
||||||
string result = string.Empty;
|
string result = string.Empty;
|
||||||
var url = APIUrls.CreateUser;
|
var url = APIUrls.CreateUser;
|
||||||
|
|
||||||
var response = await http.PostAsJsonAsync(url, regModel);
|
var response = await http.PostAsJsonAsync(url, regModel);
|
||||||
result = await response.Content.ReadAsStringAsync();
|
result = await response.Content.ReadAsStringAsync();
|
||||||
/*if (response.IsSuccessStatusCode)
|
/*if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
|
@ -122,25 +126,67 @@ namespace TIAMMobilApp.Services
|
||||||
return (isSuccess, result);
|
return (isSuccess, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> RefreshToken()
|
||||||
|
{
|
||||||
|
bool isTokenRefreshed = false;
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
var url = APIUrls.RefreshToken;
|
||||||
|
|
||||||
|
var serializedStr = JsonConvert.SerializeObject(new AuthenticateRequestAndResponse
|
||||||
|
{
|
||||||
|
RefreshToken = Setting.UserBasicDetails.RefreshToken,
|
||||||
|
AccessToken = Setting.UserBasicDetails.AccessToken
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await client.PostAsync(url, new StringContent(serializedStr, Encoding.UTF8, "application/json"));
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
string contentStr = await response.Content.ReadAsStringAsync();
|
||||||
|
var mainResponse = JsonConvert.DeserializeObject<MainResponse>(contentStr);
|
||||||
|
if (mainResponse.IsSuccess)
|
||||||
|
{
|
||||||
|
var tokenDetails = JsonConvert.DeserializeObject<AuthenticateRequestAndResponse>(mainResponse.Content.ToString());
|
||||||
|
Setting.UserBasicDetails.AccessToken = tokenDetails.AccessToken;
|
||||||
|
Setting.UserBasicDetails.RefreshToken = tokenDetails.RefreshToken;
|
||||||
|
|
||||||
|
string userDetailsStr = JsonConvert.SerializeObject(Setting.UserBasicDetails);
|
||||||
|
await secureStorageHandler.SaveToSecureStorageAsync(nameof(Setting.UserBasicDetails), userDetailsStr);
|
||||||
|
isTokenRefreshed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
string msg = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return isTokenRefreshed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Task<Dictionary<int, string>> GetUserRolesAsync(User user)
|
public Task<Dictionary<int, string>> GetUserRolesAsync(User user)
|
||||||
{
|
{
|
||||||
|
|
||||||
//get the user's roles
|
//get the user's roles
|
||||||
int role = User.UserRoles;
|
int role = User.UserRoles;
|
||||||
|
|
||||||
foreach (var roleType in roleTypes)
|
foreach (var roleType in roleTypes)
|
||||||
|
{
|
||||||
|
if ((role & roleType.Id) == roleType.Id)
|
||||||
{
|
{
|
||||||
if ((role & roleType.Id) == roleType.Id)
|
|
||||||
{
|
|
||||||
|
|
||||||
//add the role to the dictionary
|
|
||||||
userRoleTypes.Add(roleType.Id, roleType.RoleName);
|
|
||||||
|
|
||||||
}
|
//add the role to the dictionary
|
||||||
|
userRoleTypes.Add(roleType.Id, roleType.RoleName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Task.FromResult(userRoleTypes);
|
return Task.FromResult(userRoleTypes);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
@page "/";
|
||||||
|
@using TIAMWebApp.Shared.Application.Interfaces
|
||||||
|
@using TIAMWebApp.Shared.Application.Models
|
||||||
|
@using TIAMWebApp.Shared.Application.Utility
|
||||||
|
@using Newtonsoft.Json
|
||||||
|
@using System.IdentityModel.Tokens.Jwt
|
||||||
|
@using TIAMWebApp.Shared.Application.Models.ClientSide
|
||||||
|
@inject NavigationManager NavManager
|
||||||
|
@inject LogToBrowserConsole logToBrowserConsole
|
||||||
|
@inject IUserDataService UserDataService
|
||||||
|
@inject ISecureStorageHandler SecureStorageHandler
|
||||||
|
<h3>AppLaunch</h3>
|
||||||
|
|
||||||
|
Loading....
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
|
||||||
|
protected async override Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
string userDetailsStr = await SecureStorageHandler.GetFromSecureStorageAsync(nameof(Setting.UserBasicDetails));
|
||||||
|
logToBrowserConsole.LogToBC(userDetailsStr);
|
||||||
|
if (!string.IsNullOrWhiteSpace(userDetailsStr))
|
||||||
|
{
|
||||||
|
var userBasicDetail = JsonConvert.DeserializeObject<UserBasicDetails>(userDetailsStr);
|
||||||
|
|
||||||
|
var handler = new JwtSecurityTokenHandler();
|
||||||
|
var jsontoken = handler.ReadToken(userBasicDetail.AccessToken) as JwtSecurityToken;
|
||||||
|
Setting.UserBasicDetails = userBasicDetail;
|
||||||
|
|
||||||
|
if (jsontoken.ValidTo < DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
bool isTokenRefreshed = await UserDataService.RefreshToken();
|
||||||
|
|
||||||
|
if (isTokenRefreshed)
|
||||||
|
{
|
||||||
|
NavManager.NavigateTo("/home");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NavManager.NavigateTo("/login");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NavManager.NavigateTo("/home");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NavManager.NavigateTo("/login");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
Mask="\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*(\d{1,2})"
|
Mask="\+(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*\d\W*(\d{1,2})"
|
||||||
MaskMode="@MaskMode.RegEx">
|
MaskMode="@MaskMode.RegEx">
|
||||||
<DxRegExMaskProperties Placeholder="Placeholder"
|
<DxRegExMaskProperties Placeholder="Placeholder"
|
||||||
PlaceholdersVisible=false/>
|
PlaceholdersVisible=true/>
|
||||||
</DxMaskedInput>
|
</DxMaskedInput>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@page "/"
|
@page "/index"
|
||||||
@using TIAMSharedUI.Shared
|
@using TIAMSharedUI.Shared
|
||||||
|
|
||||||
<PageTitle>Index</PageTitle>
|
<PageTitle>Index</PageTitle>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@page "/login"
|
@page "/login_old"
|
||||||
@using TIAMWebApp.Shared.Application.Interfaces;
|
@using TIAMWebApp.Shared.Application.Interfaces;
|
||||||
@using TIAMWebApp.Shared.Application.Models;
|
@using TIAMWebApp.Shared.Application.Models;
|
||||||
@using TIAMWebApp.Shared.Application.Models.PageModels;
|
@using TIAMWebApp.Shared.Application.Models.PageModels;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,20 @@
|
||||||
@page "/login2"
|
@page "/login"
|
||||||
|
@using System.IdentityModel.Tokens.Jwt;
|
||||||
|
@using System.Security.Claims;
|
||||||
|
@using Newtonsoft.Json.Linq;
|
||||||
|
@using System.Text.Json;
|
||||||
|
@using System.Reflection;
|
||||||
@using TIAMWebApp.Shared.Application.Interfaces;
|
@using TIAMWebApp.Shared.Application.Interfaces;
|
||||||
@using TIAMWebApp.Shared.Application.Models.PageModels;
|
@using TIAMWebApp.Shared.Application.Models.PageModels;
|
||||||
@using TIAMSharedUI.Pages.Components;
|
@using TIAMSharedUI.Pages.Components;
|
||||||
|
@using TIAMWebApp.Shared.Application.Models.ClientSide;
|
||||||
|
@using TIAMWebApp.Shared.Application.Models;
|
||||||
|
@using TIAMWebApp.Shared.Application.Utility;
|
||||||
@inject NavigationManager navManager
|
@inject NavigationManager navManager
|
||||||
|
@inject LogToBrowserConsole logToBrowserConsole
|
||||||
@inject IUserDataService UserDataservice
|
@inject IUserDataService UserDataservice
|
||||||
@inject IJSRuntime jsRuntime
|
@inject IJSRuntime jsRuntime
|
||||||
|
@inject ISecureStorageHandler SecureStorageHandler
|
||||||
|
|
||||||
<PageTitle>Login</PageTitle>
|
<PageTitle>Login</PageTitle>
|
||||||
|
|
||||||
|
|
@ -54,11 +64,11 @@
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
LoginModel loginModel = new();
|
LoginModel loginModel = new();
|
||||||
|
|
||||||
private int currentStep = 1;
|
private int currentStep = 1;
|
||||||
|
|
||||||
bool loggedIn = false;
|
bool loggedIn = false;
|
||||||
|
|
||||||
|
|
||||||
private void GoToNextStep()
|
private void GoToNextStep()
|
||||||
{
|
{
|
||||||
|
|
@ -73,58 +83,80 @@
|
||||||
private async void SubmitLogin()
|
private async void SubmitLogin()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Implement your registration logic here
|
|
||||||
// You can use Email, PhoneNumber, and Password variables
|
|
||||||
// Reset currentStep after successful registration
|
|
||||||
loggedIn = true;
|
|
||||||
currentStep = 1;
|
currentStep = 1;
|
||||||
LogToBrowserConsole("Login started: " + "Email: " + loginModel.Email + ", Password: " + loginModel.Password);
|
logToBrowserConsole.LogToBC("Login started: " + "Email: " + loginModel.Email + ", Password: " + loginModel.Password);
|
||||||
var response = await UserDataservice.AuthenticateUser(loginModel);
|
var response = await UserDataservice.AuthenticateUser(loginModel);
|
||||||
//var response = await UserDataservice.TestUserApi(30);
|
//var response = await UserDataservice.TestUserApi(30);
|
||||||
LogToBrowserConsole("Login started");
|
logToBrowserConsole.LogToBC("Login started");
|
||||||
|
logToBrowserConsole.LogToBC(response);
|
||||||
if (!string.IsNullOrEmpty(response))
|
if (!string.IsNullOrEmpty(response))
|
||||||
{
|
{
|
||||||
LogToBrowserConsole(response);
|
//get token and save to local storage
|
||||||
if (response == "no")
|
//parse to Mainresponse from json string
|
||||||
|
|
||||||
|
|
||||||
|
//var Mainresponse = JsonSerializer.Deserialize<MainResponse>(response);
|
||||||
|
var Mainresponse = JsonSerializer.Deserialize<MainResponse>(response, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||||
|
|
||||||
|
if (Mainresponse != null)
|
||||||
{
|
{
|
||||||
//await App.Current.MainPage.DisplayAlert("Error", "Invalid credentials", "Ok");
|
|
||||||
//display error message via jsinterop
|
//check for bad request
|
||||||
LogToBrowserConsole("Invalid credentials");
|
|
||||||
navManager.NavigateTo("login2");
|
string AuthResponseJson = JsonSerializer.Serialize(Mainresponse.Content);
|
||||||
|
|
||||||
|
var AuthResponse = JsonSerializer.Deserialize<AuthenticationResponse>(AuthResponseJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
||||||
|
|
||||||
|
string accessToken = AuthResponse.AccessToken;
|
||||||
|
|
||||||
|
var handler = new JwtSecurityTokenHandler();
|
||||||
|
var token = handler.ReadJwtToken(accessToken) as JwtSecurityToken;
|
||||||
|
|
||||||
|
string _userId = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.NameId).Value;
|
||||||
|
string _email = token.Claims.First(claim => claim.Type == JwtRegisteredClaimNames.Email).Value;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
if (!Mainresponse.IsSuccess)
|
||||||
|
{
|
||||||
|
//await App.Current.MainPage.DisplayAlert("Error", "Invalid credentials", "Ok");
|
||||||
|
//display error message via jsinterop
|
||||||
|
logToBrowserConsole.LogToBC("Invalid credentials");
|
||||||
|
navManager.NavigateTo("login2");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//await App.Current.MainPage.DisplayAlert("Success", "Successful login", "Ok");
|
||||||
|
//display success message via jsinterop
|
||||||
|
logToBrowserConsole.LogToBC("Successful login");
|
||||||
|
var user = await UserDataservice.IsLoggedInAsync();
|
||||||
|
user.IsLoggedIn = true;
|
||||||
|
|
||||||
|
user.UserType = UserType.Admin;
|
||||||
|
navManager.NavigateTo("home");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(response == "yes")
|
|
||||||
{
|
|
||||||
//await App.Current.MainPage.DisplayAlert("Success", "Successful login", "Ok");
|
|
||||||
//display success message via jsinterop
|
|
||||||
LogToBrowserConsole("Successful login");
|
|
||||||
navManager.NavigateTo("home");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//await App.Current.MainPage.DisplayAlert("Error", "An error occured while trying to login", "Ok");
|
|
||||||
//display error message via jsinterop
|
|
||||||
LogToBrowserConsole("An error occured while trying to login");
|
|
||||||
navManager.NavigateTo("login2");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//api error
|
//api error
|
||||||
//await App.Current.MainPage.DisplayAlert("Error", "An error occured while trying to login", "Ok");
|
//await App.Current.MainPage.DisplayAlert("Error", "An error occured while trying to login", "Ok");
|
||||||
//display error message via jsinterop
|
//display error message via jsinterop
|
||||||
LogToBrowserConsole("An error occured while trying to login");
|
logToBrowserConsole.LogToBC("An error occured while trying to login");
|
||||||
navManager.NavigateTo("login2");
|
navManager.NavigateTo("login2");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LogToBrowserConsole(string message)
|
|
||||||
{
|
|
||||||
jsRuntime.InvokeVoidAsync("console.log", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
@page "/register2"
|
|
||||||
@inject NavigationManager navManager;
|
|
||||||
<PageTitle>Register step 2</PageTitle>
|
|
||||||
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="my-logo">
|
|
||||||
<img src="_content/TIAMSharedUI/images/png-logo-0.png" alt="">
|
|
||||||
</div>
|
|
||||||
<div class="text-center mt-4 name">
|
|
||||||
Let's create your account!
|
|
||||||
</div>
|
|
||||||
<form class="p-3 mt-3">
|
|
||||||
<div class="form-field d-flex align-items-center">
|
|
||||||
<span class="fas fa-key"></span>
|
|
||||||
<input type="password" name="password" id="pwd" placeholder="Password">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a class="btn btn-secondary mt-3" @onclick="back">Previous</a>
|
|
||||||
<a class="btn btn-primary mt-3" @onclick="next">Next</a>
|
|
||||||
</form>
|
|
||||||
<div class="text-center fs-6">
|
|
||||||
Already have an account? <a href="login">Sign in here!</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private void next()
|
|
||||||
{
|
|
||||||
navManager.NavigateTo("register3");
|
|
||||||
}
|
|
||||||
private void back()
|
|
||||||
{
|
|
||||||
navManager.NavigateTo("register");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
.wrapper {
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
@page "/register3"
|
|
||||||
@inject NavigationManager navManager;
|
|
||||||
<PageTitle>Register step 3</PageTitle>
|
|
||||||
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="my-logo">
|
|
||||||
<img src="_content/TIAMSharedUI/images/png-logo-0.png" alt="">
|
|
||||||
</div>
|
|
||||||
<div class="text-center mt-4 name">
|
|
||||||
Let's create your account!
|
|
||||||
</div>
|
|
||||||
<form class="p-3 mt-3">
|
|
||||||
<div class="form-field d-flex align-items-center">
|
|
||||||
<span class="fas fa-key"></span>
|
|
||||||
<input type="password" name="password" id="pwd" placeholder="Confirm password">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a class="btn btn-secondary mt-3" @onclick="back">Previous</a>
|
|
||||||
<a class="btn btn-primary mt-3" @onclick="next">Next</a>
|
|
||||||
</form>
|
|
||||||
<div class="text-center fs-6">
|
|
||||||
Already have an account? <a href="login">Sign in here!</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private void next()
|
|
||||||
{
|
|
||||||
navManager.NavigateTo("register4");
|
|
||||||
}
|
|
||||||
private void back()
|
|
||||||
{
|
|
||||||
navManager.NavigateTo("register2");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
.wrapper {
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
@page "/register4"
|
|
||||||
@inject NavigationManager navManager;
|
|
||||||
<PageTitle>Register step 4</PageTitle>
|
|
||||||
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="my-logo">
|
|
||||||
<img src="_content/TIAMSharedUI/images/png-logo-0.png" alt="">
|
|
||||||
</div>
|
|
||||||
<div class="text-center mt-4 name">
|
|
||||||
Let's create your account!
|
|
||||||
</div>
|
|
||||||
<form class="p-3 mt-3">
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault1" checked>
|
|
||||||
<label class="form-check-label" for="flexRadioDefault1">
|
|
||||||
Customer
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="radio" name="flexRadioDefault" id="flexRadioDefault2" disabled>
|
|
||||||
<label class="form-check-label" for="flexRadioDefault2">
|
|
||||||
Service provider (not available yet)
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input class="form-check-input" type="checkbox" value="" id="flexCheckDefault">
|
|
||||||
<label class="form-check-label" for="flexCheckDefault">
|
|
||||||
I accept the <a href="terms">Terms and Conditions</a> of use.
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<a class="btn btn-secondary mt-3" @onclick="back">Previous</a>
|
|
||||||
<a class="btn btn-primary mt-3" @onclick="next">Next</a>
|
|
||||||
</form>
|
|
||||||
<div class="text-center fs-6">
|
|
||||||
Already have an account? <a href="login">Sign in here!</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private void next()
|
|
||||||
{
|
|
||||||
navManager.NavigateTo("login");
|
|
||||||
}
|
|
||||||
private void back()
|
|
||||||
{
|
|
||||||
navManager.NavigateTo("register3");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
.wrapper {
|
|
||||||
max-width: 400px;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
width: 100%;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-input-element + .card {
|
|
||||||
height: calc(36px + 2*1rem);
|
|
||||||
color: var(--primary);
|
|
||||||
-webkit-box-shadow: none;
|
|
||||||
box-shadow: none;
|
|
||||||
border: 2px solid transparent;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-input-element + .card:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-input-element:checked + .card {
|
|
||||||
border: 2px solid var(--primary);
|
|
||||||
-webkit-transition: border .3s;
|
|
||||||
-o-transition: border .3s;
|
|
||||||
transition: border .3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-input-element:checked + .card::after {
|
|
||||||
content: '\e5ca';
|
|
||||||
color: #AFB8EA;
|
|
||||||
font-family: 'Material Icons';
|
|
||||||
font-size: 24px;
|
|
||||||
-webkit-animation-name: fadeInCheckbox;
|
|
||||||
animation-name: fadeInCheckbox;
|
|
||||||
-webkit-animation-duration: .5s;
|
|
||||||
animation-duration: .5s;
|
|
||||||
-webkit-animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@-webkit-keyframes fadeInCheckbox {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
-webkit-transform: rotateZ(-20deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
-webkit-transform: rotateZ(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeInCheckbox {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: rotateZ(-20deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: rotateZ(0deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,12 +14,9 @@
|
||||||
|
|
||||||
|
|
||||||
<article class="content">
|
<article class="content">
|
||||||
@{
|
|
||||||
if (isUserLoggedIn)
|
<TopRow></TopRow>
|
||||||
{
|
|
||||||
<TopRow></TopRow>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Body
|
@Body
|
||||||
</article>
|
</article>
|
||||||
</main>
|
</main>
|
||||||
|
|
@ -27,7 +24,7 @@
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
bool isUserLoggedIn;
|
/*bool isUserLoggedIn;
|
||||||
int userType = 0;
|
int userType = 0;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
|
|
@ -39,5 +36,5 @@
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo("/login");
|
NavigationManager.NavigateTo("/login");
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,21 @@
|
||||||
@inherits LayoutComponentBase
|
@inherits LayoutComponentBase
|
||||||
@using TIAMWebApp.Shared.Application.Interfaces
|
@using TIAMWebApp.Shared.Application.Interfaces
|
||||||
@using TIAMSharedUI.Pages
|
@using TIAMWebApp.Shared.Application.Models.ClientSide;
|
||||||
@inject IUserDataService UserDataService;
|
@inject IUserDataService UserDataService;
|
||||||
@inject IJSRuntime jsRuntime
|
@inject IJSRuntime jsRuntime
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="my-sidebar">
|
@if (Setting.UserBasicDetails != null)
|
||||||
<NavMenu />
|
{
|
||||||
</div>
|
<div class="my-sidebar">
|
||||||
|
<NavMenu />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
@* <ChooseDestination>
|
|
||||||
</ChooseDestination>
|
|
||||||
*@
|
|
||||||
<article class="content">
|
<article class="content">
|
||||||
@{
|
@{
|
||||||
if(isUserLoggedIn)
|
if(isUserLoggedIn)
|
||||||
|
|
@ -46,16 +48,13 @@
|
||||||
|
|
||||||
protected override void OnAfterRender(bool isFirst)
|
protected override void OnAfterRender(bool isFirst)
|
||||||
{
|
{
|
||||||
LogToBrowserConsole("0 ");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void LogToBrowserConsole(string message)
|
|
||||||
{
|
|
||||||
jsRuntime.InvokeVoidAsync("console.log", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,9 @@
|
||||||
<NavLink class="nav-link" href="counter">
|
<NavLink class="nav-link" href="counter">
|
||||||
Counter
|
Counter
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
|
||||||
<div-- class="nav-item px-3">
|
|
||||||
<NavLink class="nav-link" href="fetchdata">
|
|
||||||
Fetch data
|
|
||||||
</NavLink>
|
|
||||||
</div-->
|
</div-->
|
||||||
|
|
||||||
|
|
||||||
<div class="nav-item px-3">
|
<div class="nav-item px-3">
|
||||||
<NavLink class="nav-link" href="transfer">
|
<NavLink class="nav-link" href="transfer">
|
||||||
Transfer
|
Transfer
|
||||||
|
|
@ -45,6 +42,12 @@
|
||||||
Login
|
Login
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div class="nav-item px-3">
|
||||||
|
<NavLink class="nav-link" href="swagger">
|
||||||
|
Api
|
||||||
|
</NavLink>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
|
using Blazored.LocalStorage;
|
||||||
using DevExpress.Blazor;
|
using DevExpress.Blazor;
|
||||||
using Microsoft.AspNetCore.Components.Web;
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
|
using Microsoft.JSInterop;
|
||||||
using TIAMWebApp.Client;
|
using TIAMWebApp.Client;
|
||||||
using TIAMWebApp.Client.Services;
|
using TIAMWebApp.Client.Services;
|
||||||
using TIAMWebApp.Shared.Application.Interfaces;
|
using TIAMWebApp.Shared.Application.Interfaces;
|
||||||
|
using TIAMWebApp.Shared.Application.Utility;
|
||||||
|
|
||||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||||
builder.RootComponents.Add<App>("#app");
|
builder.RootComponents.Add<App>("#app");
|
||||||
|
|
@ -13,7 +16,15 @@ builder.Services.AddScoped<IWeatherForecastService, WeatherForecastService>();
|
||||||
builder.Services.AddScoped<ITransferDataService, TransferDataService>();
|
builder.Services.AddScoped<ITransferDataService, TransferDataService>();
|
||||||
builder.Services.AddScoped<IPopulationStructureDataProvider, PopulationStructureDataProvider>();
|
builder.Services.AddScoped<IPopulationStructureDataProvider, PopulationStructureDataProvider>();
|
||||||
builder.Services.AddScoped<ISupplierService, SupplierService>();
|
builder.Services.AddScoped<ISupplierService, SupplierService>();
|
||||||
builder.Services.AddSingleton<IUserDataService, UserDataService>();
|
builder.Services.AddScoped<IUserDataService, UserDataService>();
|
||||||
|
builder.Services.AddScoped<ISecureStorageHandler, SecureStorageHandler>();
|
||||||
|
builder.Services.AddScoped<LogToBrowserConsole>();
|
||||||
|
builder.Services.AddBlazoredLocalStorage();
|
||||||
|
//WebSpecific
|
||||||
|
builder.Services.AddScoped<SessionStorageAccessor>();
|
||||||
|
//WebSpecific end
|
||||||
|
|
||||||
|
|
||||||
builder.Services.AddSingleton(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
builder.Services.AddSingleton(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||||
builder.Services.AddDevExpressBlazor(configure => configure.BootstrapVersion = BootstrapVersion.v5);
|
builder.Services.AddDevExpressBlazor(configure => configure.BootstrapVersion = BootstrapVersion.v5);
|
||||||
await builder.Build().RunAsync();
|
await builder.Build().RunAsync();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
using Microsoft.JSInterop;
|
||||||
|
|
||||||
|
namespace TIAMWebApp.Client.Services
|
||||||
|
{
|
||||||
|
public class LocalStorageAccessor : IAsyncDisposable
|
||||||
|
{
|
||||||
|
private Lazy<IJSObjectReference> _accessorJsRef = new();
|
||||||
|
private readonly IJSRuntime _jsRuntime;
|
||||||
|
|
||||||
|
public LocalStorageAccessor(IJSRuntime jsRuntime)
|
||||||
|
{
|
||||||
|
_jsRuntime = jsRuntime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task WaitForReference()
|
||||||
|
{
|
||||||
|
if (_accessorJsRef.IsValueCreated is false)
|
||||||
|
{
|
||||||
|
_accessorJsRef = new(await _jsRuntime.InvokeAsync<IJSObjectReference>("import", "/js/LocalStorageAccessor.js"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
if (_accessorJsRef.IsValueCreated)
|
||||||
|
{
|
||||||
|
await _accessorJsRef.Value.DisposeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
using Blazored.LocalStorage;
|
||||||
|
using TIAMWebApp.Shared.Application.Interfaces;
|
||||||
|
|
||||||
|
namespace TIAMWebApp.Client.Services
|
||||||
|
{
|
||||||
|
public class SecureStorageHandler : ISecureStorageHandler
|
||||||
|
{
|
||||||
|
private readonly SessionStorageAccessor ssa;
|
||||||
|
private readonly ILocalStorageService localStoragService;
|
||||||
|
|
||||||
|
public SecureStorageHandler(SessionStorageAccessor ssa, ILocalStorageService localStorageService)
|
||||||
|
{
|
||||||
|
this.ssa = ssa;
|
||||||
|
this.localStoragService = localStorageService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task SaveToSecureStorageAsync(string key, string value)
|
||||||
|
{
|
||||||
|
await localStoragService.SetItemAsync(key, value);
|
||||||
|
await ssa.SetValueAsync(key, value);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> GetFromSecureStorageAsync(string key)
|
||||||
|
{
|
||||||
|
return await localStoragService.GetItemAsync<string>(key);
|
||||||
|
return await ssa.GetValueAsync<string>(key);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
using Microsoft.JSInterop;
|
||||||
|
|
||||||
|
namespace TIAMWebApp.Client.Services
|
||||||
|
{
|
||||||
|
public class SessionStorageAccessor : IAsyncDisposable
|
||||||
|
{
|
||||||
|
private Lazy<IJSObjectReference> _accessorJsRef = new();
|
||||||
|
private readonly IJSRuntime _jsRuntime;
|
||||||
|
|
||||||
|
public SessionStorageAccessor(IJSRuntime jsRuntime)
|
||||||
|
{
|
||||||
|
_jsRuntime = jsRuntime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task WaitForReference()
|
||||||
|
{
|
||||||
|
if (_accessorJsRef.IsValueCreated is false)
|
||||||
|
{
|
||||||
|
_accessorJsRef = new(await _jsRuntime.InvokeAsync<IJSObjectReference>("import", "/js/SessionStorageAccessor.js"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
if (_accessorJsRef.IsValueCreated)
|
||||||
|
{
|
||||||
|
await _accessorJsRef.Value.DisposeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T> GetValueAsync<T>(string key)
|
||||||
|
{
|
||||||
|
await WaitForReference();
|
||||||
|
var result = await _accessorJsRef.Value.InvokeAsync<T>("get", key);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetValueAsync<T>(string key, T value)
|
||||||
|
{
|
||||||
|
await WaitForReference();
|
||||||
|
await _accessorJsRef.Value.InvokeVoidAsync("set", key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Clear()
|
||||||
|
{
|
||||||
|
await WaitForReference();
|
||||||
|
await _accessorJsRef.Value.InvokeVoidAsync("clear");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RemoveAsync(string key)
|
||||||
|
{
|
||||||
|
await WaitForReference();
|
||||||
|
await _accessorJsRef.Value.InvokeVoidAsync("remove", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Net.Http.Json;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using TIAMWebApp.Shared.Application.Interfaces;
|
using TIAMWebApp.Shared.Application.Interfaces;
|
||||||
using TIAMWebApp.Shared.Application.Models;
|
using TIAMWebApp.Shared.Application.Models;
|
||||||
|
using TIAMWebApp.Shared.Application.Models.ClientSide;
|
||||||
using TIAMWebApp.Shared.Application.Models.PageModels;
|
using TIAMWebApp.Shared.Application.Models.PageModels;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -12,12 +13,14 @@ namespace TIAMWebApp.Client.Services
|
||||||
public class UserDataService : IUserDataService
|
public class UserDataService : IUserDataService
|
||||||
{
|
{
|
||||||
private readonly HttpClient http;
|
private readonly HttpClient http;
|
||||||
public User? User { get; set; } = new User("","","");
|
private readonly ISecureStorageHandler secureStorageHandler;
|
||||||
|
public User? User { get; set; } = new User("", "", "");
|
||||||
public Dictionary<int, string> userRoleTypes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
public Dictionary<int, string> userRoleTypes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||||
|
|
||||||
public UserDataService(HttpClient http)
|
public UserDataService(HttpClient http, ISecureStorageHandler secureStorageHandler)
|
||||||
{
|
{
|
||||||
this.http = http;
|
this.http = http;
|
||||||
|
this.secureStorageHandler = secureStorageHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -40,7 +43,7 @@ namespace TIAMWebApp.Client.Services
|
||||||
{
|
{
|
||||||
if (User == null)
|
if (User == null)
|
||||||
{
|
{
|
||||||
User = new User("","","");
|
User = new User("", "", "");
|
||||||
User.IsLoggedIn = false;
|
User.IsLoggedIn = false;
|
||||||
User.UserType = UserType.User;
|
User.UserType = UserType.User;
|
||||||
return User;
|
return User;
|
||||||
|
|
@ -50,7 +53,7 @@ namespace TIAMWebApp.Client.Services
|
||||||
{
|
{
|
||||||
return User;
|
return User;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Mock method for now
|
//Mock method for now
|
||||||
|
|
@ -66,7 +69,8 @@ namespace TIAMWebApp.Client.Services
|
||||||
return User;
|
return User;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> TestUserApi(int Param) {
|
public async Task<string> TestUserApi(int Param)
|
||||||
|
{
|
||||||
var url = APIUrls.UserTest;
|
var url = APIUrls.UserTest;
|
||||||
var response = await http.PostAsJsonAsync(url, Param);
|
var response = await http.PostAsJsonAsync(url, Param);
|
||||||
var result = await response.Content.ReadAsStringAsync();
|
var result = await response.Content.ReadAsStringAsync();
|
||||||
|
|
@ -75,15 +79,15 @@ namespace TIAMWebApp.Client.Services
|
||||||
|
|
||||||
public async Task<string> AuthenticateUser(LoginModel loginModel)
|
public async Task<string> AuthenticateUser(LoginModel loginModel)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
string result = string.Empty;
|
|
||||||
var url = APIUrls.AuthenticateUser;
|
|
||||||
|
string result = string.Empty;
|
||||||
|
var url = APIUrls.AuthenticateUser;
|
||||||
|
|
||||||
var response = await http.PostAsJsonAsync(url, loginModel);
|
var response = await http.PostAsJsonAsync(url, loginModel);
|
||||||
|
|
||||||
if(response.IsSuccessStatusCode)
|
if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
result = await response.Content.ReadAsStringAsync();
|
result = await response.Content.ReadAsStringAsync();
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +99,7 @@ namespace TIAMWebApp.Client.Services
|
||||||
//result = await response.Content.ReadAsStringAsync();
|
//result = await response.Content.ReadAsStringAsync();
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(bool isSuccess, string ErrorMessage)> CreateUser(RegistrationModel regModel)
|
public async Task<(bool isSuccess, string ErrorMessage)> CreateUser(RegistrationModel regModel)
|
||||||
|
|
@ -105,7 +109,7 @@ namespace TIAMWebApp.Client.Services
|
||||||
string result = string.Empty;
|
string result = string.Empty;
|
||||||
var url = APIUrls.CreateUser;
|
var url = APIUrls.CreateUser;
|
||||||
|
|
||||||
var response = await http.PostAsJsonAsync(url, regModel);
|
var response = await http.PostAsJsonAsync(url, regModel);
|
||||||
result = await response.Content.ReadAsStringAsync();
|
result = await response.Content.ReadAsStringAsync();
|
||||||
/*if (response.IsSuccessStatusCode)
|
/*if (response.IsSuccessStatusCode)
|
||||||
{
|
{
|
||||||
|
|
@ -122,25 +126,67 @@ namespace TIAMWebApp.Client.Services
|
||||||
return (isSuccess, result);
|
return (isSuccess, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> RefreshToken()
|
||||||
|
{
|
||||||
|
bool isTokenRefreshed = false;
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
var url = APIUrls.RefreshToken;
|
||||||
|
|
||||||
|
var serializedStr = JsonConvert.SerializeObject(new AuthenticateRequestAndResponse
|
||||||
|
{
|
||||||
|
RefreshToken = Setting.UserBasicDetails.RefreshToken,
|
||||||
|
AccessToken = Setting.UserBasicDetails.AccessToken
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await client.PostAsync(url, new StringContent(serializedStr, Encoding.UTF8, "application/json"));
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
string contentStr = await response.Content.ReadAsStringAsync();
|
||||||
|
var mainResponse = JsonConvert.DeserializeObject<MainResponse>(contentStr);
|
||||||
|
if (mainResponse.IsSuccess)
|
||||||
|
{
|
||||||
|
var tokenDetails = JsonConvert.DeserializeObject<AuthenticateRequestAndResponse>(mainResponse.Content.ToString());
|
||||||
|
Setting.UserBasicDetails.AccessToken = tokenDetails.AccessToken;
|
||||||
|
Setting.UserBasicDetails.RefreshToken = tokenDetails.RefreshToken;
|
||||||
|
|
||||||
|
string userDetailsStr = JsonConvert.SerializeObject(Setting.UserBasicDetails);
|
||||||
|
await secureStorageHandler.SaveToSecureStorageAsync(nameof(Setting.UserBasicDetails), userDetailsStr);
|
||||||
|
isTokenRefreshed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
string msg = ex.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return isTokenRefreshed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Task<Dictionary<int, string>> GetUserRolesAsync(User user)
|
public Task<Dictionary<int, string>> GetUserRolesAsync(User user)
|
||||||
{
|
{
|
||||||
|
|
||||||
//get the user's roles
|
//get the user's roles
|
||||||
int role = User.UserRoles;
|
int role = User.UserRoles;
|
||||||
|
|
||||||
foreach (var roleType in roleTypes)
|
foreach (var roleType in roleTypes)
|
||||||
|
{
|
||||||
|
if ((role & roleType.Id) == roleType.Id)
|
||||||
{
|
{
|
||||||
if ((role & roleType.Id) == roleType.Id)
|
|
||||||
{
|
|
||||||
|
|
||||||
//add the role to the dictionary
|
|
||||||
userRoleTypes.Add(roleType.Id, roleType.RoleName);
|
|
||||||
|
|
||||||
}
|
//add the role to the dictionary
|
||||||
|
userRoleTypes.Add(roleType.Id, roleType.RoleName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Task.FromResult(userRoleTypes);
|
return Task.FromResult(userRoleTypes);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Blazored.LocalStorage" Version="4.4.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.10" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.10" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.10" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.10" PrivateAssets="all" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
export function get(key) {
|
||||||
|
return window.sessionStorage.getItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function set(key, value) {
|
||||||
|
window.sessionStorage.setItem(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clear() {
|
||||||
|
window.sessionStorage.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function remove(key) {
|
||||||
|
window.sessionStorage.removeItem(key);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
export function get(key) {
|
||||||
|
return window.sessionStorage.getItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function set(key, value) {
|
||||||
|
window.sessionStorage.setItem(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clear() {
|
||||||
|
window.sessionStorage.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function remove(key) {
|
||||||
|
window.sessionStorage.removeItem(key);
|
||||||
|
}
|
||||||
|
|
@ -5,35 +5,48 @@ using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Reflection.Metadata;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Security.Cryptography;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using TIAMWebApp.Shared.Application.Models;
|
using TIAMWebApp.Shared.Application.Models;
|
||||||
using TIAMWebApp.Shared.Application.Models.PageModels;
|
using TIAMWebApp.Shared.Application.Models.PageModels;
|
||||||
|
using TIAMWebApp.Server.Models;
|
||||||
|
using System.Text;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using TIAMWebApp.Server.ModelsTIAMWebApp.Shared.Application.Models;
|
||||||
|
|
||||||
namespace TIAMWebApp.Server.Controllers
|
namespace TIAMWebApp.Server.Controllers
|
||||||
{
|
{
|
||||||
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class UserAPIController : ControllerBase
|
public class UserAPIController : ControllerBase
|
||||||
{
|
{
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||||
PasswordHasher hasher = new PasswordHasher();
|
PasswordHasher hasher = new PasswordHasher();
|
||||||
|
|
||||||
|
|
||||||
private User[] users = new User[]
|
private User[] users = new User[]
|
||||||
{
|
{
|
||||||
new User("test@tiam.hu", "+36701234567", "asd123")
|
new User(new Guid("540271f6-c604-4c16-8160-d5a7cafedf00"), "test@tiam.hu", "+36701234567", "Asdasd123456"),
|
||||||
|
new User(new Guid("4cbaed43-2465-4d99-84f1-c8bc6b7025f7"), "adam@tiam.hu", "+36701234567", "Asdasd987654")
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly ILogger<SupplierAPIController> _logger;
|
private readonly ILogger<UserAPIController> _logger;
|
||||||
|
|
||||||
public UserAPIController(ILogger<SupplierAPIController> logger)
|
public UserAPIController(ILogger<UserAPIController> logger, IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_configuration = configuration;
|
||||||
|
_webHostEnvironment = webHostEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[HttpPost]
|
/*[HttpPost]
|
||||||
[Route("Auth")]
|
[Route("Auth")]
|
||||||
public async Task<IActionResult> AuthenticateUser([FromBody] JsonElement SerializedLoginModel)
|
public async Task<IActionResult> AuthenticateUser([FromBody] JsonElement SerializedLoginModel)
|
||||||
{
|
{
|
||||||
|
|
@ -50,7 +63,7 @@ namespace TIAMWebApp.Server.Controllers
|
||||||
Console.WriteLine(user.Email);
|
Console.WriteLine(user.Email);
|
||||||
Console.WriteLine(user.Password);
|
Console.WriteLine(user.Password);
|
||||||
|
|
||||||
if (user.Email == "test@tiam.hu" && user.Password == "asd123")
|
if (user.Email == "test@tiam.hu" && user.Password == "Asdasd123456")
|
||||||
{
|
{
|
||||||
Console.WriteLine("User authenticated");
|
Console.WriteLine("User authenticated");
|
||||||
return Ok("yes");
|
return Ok("yes");
|
||||||
|
|
@ -62,8 +75,178 @@ namespace TIAMWebApp.Server.Controllers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost("AuthenticateUser")]
|
||||||
|
public async Task<IActionResult> AuthenticateUser([FromBody] JsonElement SerializedLoginModel)
|
||||||
|
{
|
||||||
|
|
||||||
|
var authenticateUser = JObject.Parse(SerializedLoginModel.GetRawText()).ToObject<LoginModel>();
|
||||||
|
|
||||||
|
//check if user exists
|
||||||
|
//var user = await _userManager.FindByNameAsync(authenticateUser.UserName);
|
||||||
|
//if (user == null) return Unauthorized();
|
||||||
|
|
||||||
|
//mocking
|
||||||
|
var user = users.FirstOrDefault(x => x.Email == authenticateUser.Email);
|
||||||
|
|
||||||
|
//check if password is valid
|
||||||
|
//bool isValidUser = await _userManager.CheckPasswordAsync(user, authenticateUser.Password);
|
||||||
|
|
||||||
|
//mocking
|
||||||
|
bool isValidUser = false;
|
||||||
|
|
||||||
|
if (user.Password == authenticateUser.Password)
|
||||||
|
{
|
||||||
|
isValidUser = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValidUser)
|
||||||
|
{
|
||||||
|
Console.WriteLine("User authenticated, let's start JWT");
|
||||||
|
string accessToken = GenerateAccessToken(user);
|
||||||
|
Console.WriteLine("Generate refresh token");
|
||||||
|
var refreshToken = GenerateRefreshToken();
|
||||||
|
user.RefreshToken = refreshToken;
|
||||||
|
//Update user with refreshToken!!
|
||||||
|
//await _userManager.UpdateAsync(user);
|
||||||
|
|
||||||
|
var response = new MainResponse
|
||||||
|
{
|
||||||
|
Content = new AuthenticationResponse
|
||||||
|
{
|
||||||
|
RefreshToken = refreshToken,
|
||||||
|
AccessToken = accessToken
|
||||||
|
},
|
||||||
|
IsSuccess = true,
|
||||||
|
ErrorMessage = ""
|
||||||
|
};
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GenerateAccessToken(User user)
|
||||||
|
{
|
||||||
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
var token = new JwtSecurityToken();
|
||||||
|
Console.WriteLine("----------------------------------------------------------");
|
||||||
|
var keyDetail = Encoding.UTF8.GetBytes(_configuration["JWT:Key"]);
|
||||||
|
Console.WriteLine(_configuration["JWT:Key"]);
|
||||||
|
|
||||||
|
var claims = new List<Claim>
|
||||||
|
{
|
||||||
|
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
||||||
|
new Claim(ClaimTypes.Email, user.Email)
|
||||||
|
};
|
||||||
|
|
||||||
|
var tokenDescriptor = new SecurityTokenDescriptor
|
||||||
|
{
|
||||||
|
Audience = _configuration["JWT:Audience"],
|
||||||
|
Issuer = _configuration["JWT:Issuer"],
|
||||||
|
Expires = DateTime.UtcNow.AddMinutes(30),
|
||||||
|
Subject = new ClaimsIdentity(claims),
|
||||||
|
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(keyDetail), SecurityAlgorithms.HmacSha256Signature)
|
||||||
|
};
|
||||||
|
token = tokenHandler.CreateToken(tokenDescriptor) as JwtSecurityToken;
|
||||||
|
string writtenToken = tokenHandler.WriteToken(token);
|
||||||
|
Console.WriteLine(writtenToken);
|
||||||
|
return writtenToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
[HttpPost("RefreshToken")]
|
||||||
|
public async Task<IActionResult> RefreshToken(RefreshTokenRequest refreshTokenRequest)
|
||||||
|
{
|
||||||
|
var response = new MainResponse();
|
||||||
|
if (refreshTokenRequest is null)
|
||||||
|
{
|
||||||
|
response.ErrorMessage = "Invalid request";
|
||||||
|
return BadRequest(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
var principal = GetPrincipalFromExpiredToken(refreshTokenRequest.AccessToken);
|
||||||
|
|
||||||
|
if (principal != null)
|
||||||
|
{
|
||||||
|
var email = principal.Claims.FirstOrDefault(f => f.Type == ClaimTypes.Email);
|
||||||
|
|
||||||
|
//var user = await _userManager.FindByEmailAsync(email?.Value);
|
||||||
|
var user = users.FirstOrDefault(x => x.Email == email?.Value);
|
||||||
|
|
||||||
|
|
||||||
|
if (user is null || user.RefreshToken != refreshTokenRequest.RefreshToken)
|
||||||
|
{
|
||||||
|
response.ErrorMessage = "Invalid Request";
|
||||||
|
return BadRequest(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
string newAccessToken = GenerateAccessToken(user);
|
||||||
|
string refreshToken = GenerateRefreshToken();
|
||||||
|
|
||||||
|
//mocking - update user with new refreshToken
|
||||||
|
user.RefreshToken = refreshToken;
|
||||||
|
//await _userManager.UpdateAsync(user);
|
||||||
|
|
||||||
|
response.IsSuccess = true;
|
||||||
|
response.Content = new AuthenticationResponse
|
||||||
|
{
|
||||||
|
RefreshToken = refreshToken,
|
||||||
|
AccessToken = newAccessToken
|
||||||
|
};
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound("Invalid Token Found");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ClaimsPrincipal GetPrincipalFromExpiredToken(string token)
|
||||||
|
{
|
||||||
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
|
|
||||||
|
var keyDetail = Encoding.UTF8.GetBytes(_configuration["JWT:Key"]);
|
||||||
|
|
||||||
|
var tokenValidationParameter = new TokenValidationParameters
|
||||||
|
{
|
||||||
|
ValidateIssuer = false,
|
||||||
|
ValidateAudience = false,
|
||||||
|
ValidateLifetime = false,
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
ValidIssuer = _configuration["JWT:Issuer"],
|
||||||
|
ValidAudience = _configuration["JWT:Audience"],
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(keyDetail),
|
||||||
|
};
|
||||||
|
|
||||||
|
SecurityToken securityToken;
|
||||||
|
var principal = tokenHandler.ValidateToken(token, tokenValidationParameter, out securityToken);
|
||||||
|
var jwtSecurityToken = securityToken as JwtSecurityToken;
|
||||||
|
if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
throw new SecurityTokenException("Invalid token");
|
||||||
|
return principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GenerateRefreshToken()
|
||||||
|
{
|
||||||
|
|
||||||
|
var randomNumber = new byte[32];
|
||||||
|
using (var rng = RandomNumberGenerator.Create())
|
||||||
|
{
|
||||||
|
rng.GetBytes(randomNumber);
|
||||||
|
return Convert.ToBase64String(randomNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("CreateUser")]
|
[Route("CreateUser")]
|
||||||
public async Task<IActionResult> CreateUser([FromBody] JsonElement SerializedRegistrationModel)
|
public async Task<IActionResult> CreateUser([FromBody] JsonElement SerializedRegistrationModel)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace TIAMWebApp.Server.Models
|
||||||
|
{
|
||||||
|
|
||||||
|
public class AuthenticateUser
|
||||||
|
{
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string Password { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace TIAMWebApp.Server.Models
|
||||||
|
{
|
||||||
|
public class RefreshTokenRequest
|
||||||
|
{
|
||||||
|
public string AccessToken { get; set; }
|
||||||
|
public string RefreshToken { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,11 +4,13 @@ using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using TIAM.Database.DataLayers;
|
|
||||||
using TIAM.Entities.TransferDestinations;
|
using TIAM.Entities.TransferDestinations;
|
||||||
using TIAM.Database.DbContexts;
|
using TIAM.Database.DbContexts;
|
||||||
using TIAM.Database.DataLayers.TransferDestinations;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using TIAM.Database.DataLayers.Users;
|
using System.Text;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using TIAMWebApp.Shared.Application.Models;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
|
@ -16,9 +18,72 @@ var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
builder.Services.AddControllersWithViews();
|
builder.Services.AddControllersWithViews();
|
||||||
builder.Services.AddRazorPages();
|
builder.Services.AddRazorPages();
|
||||||
//builder.Services.AddDbContext<TransferDestinationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DeveloperDbConnection")));
|
builder.Services.AddDbContext<TransferDestinationDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DeveloperDbConnection")));;
|
||||||
//builder.Services.AddScoped<TiamDalBase<TransferDestinationDbContext>>(x => x.GetService<TransferDestinationDbContext>());
|
|
||||||
builder.Services.AddScoped<UserDal>();
|
builder.Services.AddSwaggerGen(swagger =>
|
||||||
|
{
|
||||||
|
swagger.SwaggerDoc("v1",
|
||||||
|
new OpenApiInfo
|
||||||
|
{
|
||||||
|
Title = "API Title",
|
||||||
|
Version = "V1",
|
||||||
|
Description = "API Description"
|
||||||
|
});
|
||||||
|
|
||||||
|
var securitySchema = new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Description = "Authorization header using the Bearer scheme. Example \"Authorization: Bearer {token}\"",
|
||||||
|
Name = "Authorization",
|
||||||
|
In = ParameterLocation.Header,
|
||||||
|
Type = SecuritySchemeType.Http,
|
||||||
|
Scheme = "Bearer",
|
||||||
|
Reference = new OpenApiReference
|
||||||
|
{
|
||||||
|
Type = ReferenceType.SecurityScheme,
|
||||||
|
Id = "Bearer"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
swagger.AddSecurityDefinition(securitySchema.Reference.Id, securitySchema);
|
||||||
|
swagger.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||||
|
{
|
||||||
|
{securitySchema,Array.Empty<string>() }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.AddAuthentication(f =>
|
||||||
|
{
|
||||||
|
f.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
f.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
}).AddJwtBearer(k =>
|
||||||
|
{
|
||||||
|
var Key = Encoding.UTF8.GetBytes(builder.Configuration["JWT:Key"]);
|
||||||
|
k.SaveToken = true;
|
||||||
|
k.TokenValidationParameters = new TokenValidationParameters
|
||||||
|
{
|
||||||
|
ValidateIssuer = true,
|
||||||
|
ValidateAudience = true,
|
||||||
|
ValidateLifetime = true,
|
||||||
|
ValidateIssuerSigningKey = true,
|
||||||
|
ValidIssuer = builder.Configuration["JWT:Issuer"],
|
||||||
|
ValidAudience = builder.Configuration["JWT:Audience"],
|
||||||
|
IssuerSigningKey = new SymmetricSecurityKey(Key),
|
||||||
|
ClockSkew = TimeSpan.Zero
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
|
||||||
|
builder.Services.ConfigureApplicationCookie(options =>
|
||||||
|
{
|
||||||
|
options.Cookie.HttpOnly = false;
|
||||||
|
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
|
||||||
|
options.LoginPath = "/Login";
|
||||||
|
options.SlidingExpiration = true;
|
||||||
|
});
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|
@ -34,12 +99,21 @@ else
|
||||||
app.UseHsts();
|
app.UseHsts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI(c =>
|
||||||
|
{
|
||||||
|
c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
//app.UseHttpsRedirection();
|
//app.UseHttpsRedirection();
|
||||||
|
|
||||||
app.UseBlazorFrameworkFiles();
|
app.UseBlazorFrameworkFiles();
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseAuthentication();
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
|
||||||
app.MapRazorPages();
|
app.MapRazorPages();
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,13 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="GoogleApi" Version="5.2.4" />
|
<PackageReference Include="GoogleApi" Version="5.2.4" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.14" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.10" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.10" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.13" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.13" />
|
||||||
|
<PackageReference Include="Microsoft.OpenApi" Version="1.6.11" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="6.5.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.5.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,10 @@
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"JWT": {
|
||||||
|
"Key": "Cee4400-rDMFkVvHPufyLDSzbfu2grgRhpepos299IhTLOXsljkcpt3yUR4RRjPQ",
|
||||||
|
"Issuer": "https://localhost:7116",
|
||||||
|
"Audience": "http://localhost:7116"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,10 @@
|
||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*",
|
||||||
|
"JWT": {
|
||||||
|
"Key": "Cee4400-rDMFkVvHPufyLDSzbfu2grgRhpepos299IhTLOXsljkcpt3yUR4RRjPQ",
|
||||||
|
"Issuer": "http://localhost:5000",
|
||||||
|
"Audience": "http://localhost:5000"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TIAMWebApp.Shared.Application.Interfaces
|
||||||
|
{
|
||||||
|
public interface ISecureStorageHandler
|
||||||
|
{
|
||||||
|
public Task SaveToSecureStorageAsync(string key, string value);
|
||||||
|
public Task<string> GetFromSecureStorageAsync(string key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,5 +23,7 @@ namespace TIAMWebApp.Shared.Application.Interfaces
|
||||||
public Task<string> TestUserApi(int Param);
|
public Task<string> TestUserApi(int Param);
|
||||||
|
|
||||||
public Task<Dictionary<int, string>> GetUserRolesAsync(User user);
|
public Task<Dictionary<int, string>> GetUserRolesAsync(User user);
|
||||||
|
|
||||||
|
Task<bool> RefreshToken();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,9 +8,10 @@ namespace TIAMWebApp.Shared.Application.Models
|
||||||
{
|
{
|
||||||
public class APIUrls
|
public class APIUrls
|
||||||
{
|
{
|
||||||
public const string UserTest = "UserAPI/test1";
|
public const string UserTest = "api/UserAPI/test1";
|
||||||
public const string AuthenticateUser = "UserAPI/Auth";
|
public const string AuthenticateUser = "api/UserAPI/AuthenticateUser";
|
||||||
public const string CreateUser = "UserAPI/CreateUser";
|
public const string CreateUser = "api/UserAPI/CreateUser";
|
||||||
|
public const string RefreshToken = "api/UserAPI/RefreshToken";
|
||||||
public const string WeatherForecast = "WeatherForecastAPI";
|
public const string WeatherForecast = "WeatherForecastAPI";
|
||||||
public const string PopulationStructure = "PopulationStructureAPI";
|
public const string PopulationStructure = "PopulationStructureAPI";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
namespace TIAMWebApp.Shared.Application.Models
|
||||||
|
{
|
||||||
|
public class AuthenticateRequestAndResponse
|
||||||
|
{
|
||||||
|
public string AccessToken { get; set; }
|
||||||
|
public string RefreshToken { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace TIAMWebApp.Shared.Application.Models
|
||||||
|
{
|
||||||
|
public class AuthenticationResponse
|
||||||
|
{
|
||||||
|
public string? AccessToken { get; set; }
|
||||||
|
public string? RefreshToken { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TIAMWebApp.Shared.Application.Models.ClientSide
|
||||||
|
{
|
||||||
|
public class Setting
|
||||||
|
{
|
||||||
|
public static UserBasicDetails UserBasicDetails { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TIAMWebApp.Shared.Application.Models.ClientSide
|
||||||
|
{
|
||||||
|
public class UserBasicDetails
|
||||||
|
{
|
||||||
|
public string UserId { get; set; }
|
||||||
|
public string Email { get; set; }
|
||||||
|
public string AccessToken { get; set; }
|
||||||
|
public string RefreshToken { get; set; }
|
||||||
|
|
||||||
|
public UserBasicDetails(string userId, string email, string token, string refreshToken)
|
||||||
|
{
|
||||||
|
UserId = userId;
|
||||||
|
Email = email;
|
||||||
|
AccessToken = token;
|
||||||
|
RefreshToken = refreshToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
using TIAMWebApp.Shared.Application.Models;
|
||||||
|
|
||||||
|
namespace TIAMWebApp.Server.ModelsTIAMWebApp.Shared.Application.Models
|
||||||
|
{
|
||||||
|
public class ErrorResponse
|
||||||
|
{
|
||||||
|
public static MainResponse ReturnErrorResponse(string errorMessage)
|
||||||
|
{
|
||||||
|
return new MainResponse
|
||||||
|
{
|
||||||
|
ErrorMessage = errorMessage,
|
||||||
|
IsSuccess = true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace TIAMWebApp.Shared.Application.Models
|
||||||
|
{
|
||||||
|
public class MainResponse
|
||||||
|
{
|
||||||
|
public bool IsSuccess { get; set; }
|
||||||
|
public string? ErrorMessage { get; set; }
|
||||||
|
public object? Content { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
using System;
|
namespace TIAMWebApp.Shared.Application.Models
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace TIAMWebApp.Shared.Application.Models
|
|
||||||
{
|
{
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public string? Email { get; set; }
|
public string? Email { get; set; }
|
||||||
|
|
@ -15,6 +9,7 @@ namespace TIAMWebApp.Shared.Application.Models
|
||||||
public bool IsLoggedIn { get; set; }
|
public bool IsLoggedIn { get; set; }
|
||||||
public UserType UserType { get; set; }
|
public UserType UserType { get; set; }
|
||||||
public int UserRoles { get; set; }
|
public int UserRoles { get; set; }
|
||||||
|
public string? RefreshToken { get; set; }
|
||||||
public Dictionary<int, string> UserRolesDictionary { get; set; }
|
public Dictionary<int, string> UserRolesDictionary { get; set; }
|
||||||
|
|
||||||
public User(string email, string phonenumber, string password)
|
public User(string email, string phonenumber, string password)
|
||||||
|
|
@ -26,6 +21,15 @@ namespace TIAMWebApp.Shared.Application.Models
|
||||||
UserRolesDictionary = new Dictionary<int, string>();
|
UserRolesDictionary = new Dictionary<int, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public User(Guid id, string email, string phonenumber, string password)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
Email = email;
|
||||||
|
Password = password;
|
||||||
|
PhoneNumber = phonenumber;
|
||||||
|
UserRolesDictionary = new Dictionary<int, string>();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UserType
|
public enum UserType
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.1.39" />
|
||||||
<PackageReference Include="Microsoft.JSInterop" Version="7.0.10" />
|
<PackageReference Include="Microsoft.JSInterop" Version="7.0.10" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,10 @@
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using TIAMWebApp.Shared.Application.Models;
|
|
||||||
|
|
||||||
namespace TIAMWebApp.Shared.Application.Utility
|
namespace TIAMWebApp.Shared.Application.Utility
|
||||||
{
|
{
|
||||||
internal class LogToBrowserConsole
|
public class LogToBrowserConsole
|
||||||
{
|
{
|
||||||
private readonly JSRuntime jsRuntime;
|
private readonly JSRuntime jsRuntime;
|
||||||
|
|
||||||
public LogToBrowserConsole(JSRuntime jSRuntime)
|
|
||||||
{
|
|
||||||
this.jsRuntime = jsRuntime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LogToBC(string message)
|
public void LogToBC(string message)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue