diff --git a/App.razor b/App.razor
index 843f201..b8905ee 100644
--- a/App.razor
+++ b/App.razor
@@ -1,4 +1,42 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+ Not found
+
+ Sorry, there's nothing at this address.
+
+
+
+
+
+@*
+
+
+
+
+
+
+ Not found
+
+ Sorry, there's nothing at this address.
+
+
+
+*@
+
+
+@*
@@ -8,4 +46,4 @@
Sorry, there's nothing at this address.
-
\ No newline at end of file
+*@
\ No newline at end of file
diff --git a/Data/LoginData.cs b/Data/LoginData.cs
new file mode 100644
index 0000000..9ea831c
--- /dev/null
+++ b/Data/LoginData.cs
@@ -0,0 +1,8 @@
+namespace KWWebInvApp.Data
+{
+ public class LoginData
+ {
+ public string username { get; set; }
+ public string password { get; set; }
+ }
+}
diff --git a/Data/UserServices.cs b/Data/UserServices.cs
deleted file mode 100644
index e2f138b..0000000
--- a/Data/UserServices.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace KWWebInvApp.Data
-{
- public class UserServices
- {
- public UserInfoServices.userinfo? CurrentUser { get; set; } = null;
-
- public bool IsAuthenticated()
- {
- if (CurrentUser == null) return false;
- else return true;
- }
- }
-}
diff --git a/Pages/BranchMaintenance/InventoryCorrection.razor b/Pages/BranchMaintenance/InventoryCorrection.razor
index b847b67..b12810e 100644
--- a/Pages/BranchMaintenance/InventoryCorrection.razor
+++ b/Pages/BranchMaintenance/InventoryCorrection.razor
@@ -1,8 +1,12 @@
@page "/brmaintenance/invtycorrection"
+
+@attribute [Authorize]
+
@using KWWebInvApp.Data;
+@using KWWebInvApp.Services;
@inject IDialogService DialogService;
-@inject UserServices userService;
+@inject IAuthenticationService AuthenticationStateService;
Branch Inventory Correction
Branch Inventory Correction
@@ -138,8 +142,10 @@ else
disableStatusGetRecord = true;
disableStatusSave = true;
+ var currentUser = await AuthenticationStateService.GetAuthenticatedUserAsync();
+
branchItemLedger = await branchItemLedgerServiceClient.GetRemoteDataByBrCodeModelnoAsync(selectedBranch, modelNo);
- newRemarks = $"Manually edit by {userService?.CurrentUser?.fullName}. {DateTime.Now:MM/dd/yyyy hh:mm:sstt}";
+ newRemarks = $"Manually edit by {currentUser?.fullName}. {DateTime.Now:MM/dd/yyyy hh:mm:sstt}";
disableStatusGetRecord = false;
disableStatusSave = false;
@@ -153,7 +159,9 @@ else
disableStatusGetRecord = true;
disableStatusSave = true;
- branchItemLedger.remarks = $"|Manually edit by {userService?.CurrentUser?.fullName}. {DateTime.Now:MM/dd/yyyy hh:mm:sstt} [{branchItemLedger.beginningqty} {branchItemLedger.inqty} {branchItemLedger.outqty} {branchItemLedger.sales} {branchItemLedger.adjustment} {branchItemLedger.endingqty}]";
+ var currentUser = await AuthenticationStateService.GetAuthenticatedUserAsync();
+
+ branchItemLedger.remarks = $"|Manually edit by {currentUser?.fullName}. {DateTime.Now:MM/dd/yyyy hh:mm:sstt} [{branchItemLedger.beginningqty} {branchItemLedger.inqty} {branchItemLedger.outqty} {branchItemLedger.sales} {branchItemLedger.adjustment} {branchItemLedger.endingqty}]";
int result = await branchItemLedgerServiceClient.UpdateRemoteBranchItemLedgerAsync(branchItemLedger);
if(result > 0)
diff --git a/Pages/Index.razor b/Pages/Index.razor
index 04e2e56..67296c7 100644
--- a/Pages/Index.razor
+++ b/Pages/Index.razor
@@ -1,8 +1,6 @@
@page "/"
-@using KWWebInvApp.Data
-@inject UserServices userServices
-@inject NavigationManager navigationManager
+@attribute [Authorize]
Index
diff --git a/Pages/Items/ItemDetails.razor b/Pages/Items/ItemDetails.razor
index f5c265c..5b41d40 100644
--- a/Pages/Items/ItemDetails.razor
+++ b/Pages/Items/ItemDetails.razor
@@ -1,5 +1,7 @@
@page "/items/itemdetails"
+@attribute [Authorize]
+
Item Details
@code {
diff --git a/Pages/Items/ItemSearch.razor b/Pages/Items/ItemSearch.razor
index d09c097..6f9a678 100644
--- a/Pages/Items/ItemSearch.razor
+++ b/Pages/Items/ItemSearch.razor
@@ -1,5 +1,7 @@
@page "/items/tracesearch"
+@attribute [Authorize]
+
ItemSearch
@code {
diff --git a/Pages/Items/TraceHistory.razor b/Pages/Items/TraceHistory.razor
index 9ce539b..e7b3b0c 100644
--- a/Pages/Items/TraceHistory.razor
+++ b/Pages/Items/TraceHistory.razor
@@ -1,5 +1,7 @@
@page "/items/tracehistory"
+@attribute [Authorize]
+
TraceHistory
@code {
diff --git a/Pages/UserLogin.razor b/Pages/UserLogin.razor
new file mode 100644
index 0000000..d39d1f1
--- /dev/null
+++ b/Pages/UserLogin.razor
@@ -0,0 +1,85 @@
+@page "/userlogin"
+@using KWWebInvApp.Data;
+@using KWWebInvApp.Services;
+@using Microsoft.AspNetCore.WebUtilities;
+
+@inject IAuthenticationService AuthenticationStateService
+@inject AuthenticationStateProvider AuthenticationStateProvider
+@inject NavigationManager NavigationManager
+
+User Login
+Enter your credential for verification
+
+
+
+
+
+
+ Login
+ Welcome to Merchandise and SAC System
+ @if (error != null)
+ {
+ @error
+ }
+
+
+
+
+ @submitButtonText
+ Reset
+
+
+
+
+
+
+
+@code {
+ bool submitButtonDisabled = false;
+ string? error, submitButtonText = "Login";
+ LoginData loginData = new();
+
+ protected override async Task OnInitializedAsync()
+ {
+
+ }
+
+ async Task SubmitLogin()
+ {
+ error = null;
+
+ waitingButton(true);
+ var webAuthenticationStateProvider = (WebAuthenticationStateProvider)AuthenticationStateProvider;
+ var loginSuccess = await webAuthenticationStateProvider.LoginAsync(loginData);
+
+ if (loginSuccess)
+ {
+ var uri = NavigationManager.ToAbsoluteUri(NavigationManager.Uri);
+ if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("returnUrl", out var returnURL))
+ NavigationManager.NavigateTo($"/{returnURL}");
+ else
+ NavigationManager.NavigateTo("/");
+ }
+ else
+ error = "Invalid username or password. Please try again.";
+
+ waitingButton(false);
+ }
+
+ void waitingButton(bool waiting = false)
+ {
+ if(waiting)
+ {
+ submitButtonDisabled = true;
+ submitButtonText = "Please Wait...";
+ }
+ else
+ {
+ submitButtonDisabled = false;
+ submitButtonText = "Login";
+ }
+ }
+}
diff --git a/Program.cs b/Program.cs
index 076c785..96f38f7 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,5 +1,8 @@
using KWWebInvApp.Data;
+using KWWebInvApp.Services;
using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Authorization;
+using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Hosting.StaticWebAssets;
using MudBlazor.Services;
@@ -8,13 +11,21 @@ var builder = WebApplication.CreateBuilder(args);
StaticWebAssetsLoader.UseStaticWebAssets(builder.Environment, builder.Configuration);
+builder.Services.AddSession(options =>
+{
+ options.IdleTimeout = TimeSpan.FromDays(1); // Set the session timeout as needed
+});
+
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton();
-builder.Services.AddSingleton();
builder.Services.AddMudServices();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
+
var app = builder.Build();
// Configure the HTTP request pipeline.
@@ -25,12 +36,15 @@ if (!app.Environment.IsDevelopment())
app.UseHsts();
}
+
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
+app.UseSession();
+
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
diff --git a/Services/AuthenticationService.cs b/Services/AuthenticationService.cs
new file mode 100644
index 0000000..2e5d717
--- /dev/null
+++ b/Services/AuthenticationService.cs
@@ -0,0 +1,47 @@
+using KWWebInvApp.Data;
+using UserInfoServices;
+
+namespace KWWebInvApp.Services
+{
+ public class AuthenticationService : IAuthenticationService
+ {
+ private UserInfoServices.userinfo? CurrentUser;
+
+ public async Task GetAuthenticatedUserAsync()
+ {
+ return CurrentUser;
+ }
+
+ public async Task SetAuthenticatedUserAsync(UserInfoServices.userinfo currentUser)
+ {
+ CurrentUser = currentUser;
+ }
+
+ public async Task LoginAsync(LoginData loginData)
+ {
+ if (!string.IsNullOrWhiteSpace(loginData.username) && !string.IsNullOrWhiteSpace(loginData.password))
+ {
+ UserInfoServices.UserInfoServiceClient userInfoServiceClient = new();
+ UserInfoServices.userinfo userAttemptingToLogin = new UserInfoServices.userinfo()
+ {
+ username = loginData.username,
+ pass = await userInfoServiceClient.md5EncodingAsync(loginData.password)
+ };
+
+ CurrentUser = await userInfoServiceClient.AuthenticateUserAsync(userAttemptingToLogin);
+
+ if (CurrentUser == null)
+ return false;
+ else
+ return true;
+ }
+
+ return false;
+ }
+
+ public async Task LogoutAsync()
+ {
+ CurrentUser = null;
+ }
+ }
+}
diff --git a/Services/IAuthenticationService.cs b/Services/IAuthenticationService.cs
new file mode 100644
index 0000000..1487b4f
--- /dev/null
+++ b/Services/IAuthenticationService.cs
@@ -0,0 +1,12 @@
+using KWWebInvApp.Data;
+
+namespace KWWebInvApp.Services
+{
+ public interface IAuthenticationService
+ {
+ Task GetAuthenticatedUserAsync();
+ Task SetAuthenticatedUserAsync(UserInfoServices.userinfo userInfo);
+ Task LoginAsync(LoginData loginData);
+ Task LogoutAsync();
+ }
+}
diff --git a/Services/WebAuthenticationStateProvider.cs b/Services/WebAuthenticationStateProvider.cs
new file mode 100644
index 0000000..3462446
--- /dev/null
+++ b/Services/WebAuthenticationStateProvider.cs
@@ -0,0 +1,145 @@
+using KWWebInvApp.Data;
+using Microsoft.AspNetCore.Components.Authorization;
+using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
+using System.Security.Claims;
+
+namespace KWWebInvApp.Services
+{
+ public class WebAuthenticationStateProvider : AuthenticationStateProvider
+ {
+ private readonly IAuthenticationService _authService;
+ private readonly ProtectedSessionStorage _sessionStorage;
+
+ public WebAuthenticationStateProvider(IAuthenticationService authService, ProtectedSessionStorage sessionStorage)
+ {
+ _authService = authService;
+ _sessionStorage = sessionStorage;
+ }
+
+ /*
+
+ public override async Task GetAuthenticationStateAsync()
+ {
+ var user = await _authService.GetAuthenticatedUserAsync();
+
+ if (user == null)
+ return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
+
+ var claims = new List
+ {
+ new Claim(ClaimTypes.Name, user.username),
+ new Claim(ClaimTypes.Role, user.userlvl.ToString())
+ // Add any other claims based on your application's requirements
+ };
+
+ var identity = new ClaimsIdentity(claims, "CustomAuth");
+ var principal = new ClaimsPrincipal(identity);
+
+ return new AuthenticationState(principal);
+ }
+
+
+ public override async Task GetAuthenticationStateAsync()
+ {
+ var principal = new ClaimsPrincipal(new ClaimsIdentity());
+ UserInfoServices.userinfo? user = null;
+
+ try
+ {
+ var userSessionResult = await _sessionStorage.GetAsync("UserInfoSession");
+ user = (userSessionResult.Success) ? userSessionResult.Value : null;
+
+ if (user == null)
+ return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
+
+
+ var claims = new List
+ {
+ new Claim(ClaimTypes.Name, user.username),
+ new Claim(ClaimTypes.Role, user.userlvl.ToString())
+ // Add any other claims based on your application's requirements
+ };
+
+ var identity = new ClaimsIdentity(claims, "KWWebInvAppAuth");
+ principal = new ClaimsPrincipal(identity);
+
+ }
+ catch { return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); }
+
+ var authState = new AuthenticationState(principal);
+
+ return authState;
+ }
+
+ */
+
+ public override async Task GetAuthenticationStateAsync()
+ {
+ var principal = new ClaimsPrincipal(new ClaimsIdentity());
+ UserInfoServices.userinfo? user = null;
+
+ try
+ {
+ user = await _authService.GetAuthenticatedUserAsync();
+
+ if (user == null)
+ {
+ var userSessionResult = await _sessionStorage.GetAsync("UserInfoSession");
+ user = (userSessionResult.Success) ? userSessionResult.Value : null;
+
+ if (user == null)
+ return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
+ else
+ await _authService.SetAuthenticatedUserAsync(user);
+ }
+
+ var claims = new List
+ {
+ new Claim(ClaimTypes.Name, user.username),
+ new Claim(ClaimTypes.Role, user.userlvl.ToString())
+ // Add any other claims based on your application's requirements
+ };
+
+ var identity = new ClaimsIdentity(claims, "KWWebInvAppAuth");
+ principal = new ClaimsPrincipal(identity);
+
+ }
+ catch { return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())); }
+
+ return new AuthenticationState(principal);
+ }
+
+
+
+ public async Task LoginAsync(LoginData loginData)
+ {
+ bool loginSuccess = await _authService.LoginAsync(loginData);
+
+ if(loginSuccess)
+ {
+ UserInfoServices.userinfo user = await _authService.GetAuthenticatedUserAsync();
+
+ // Supply sessionStorage with user data first before using SetAuthenticationState.
+ // authState will rely on the value of UserInfoSession stored here
+ await _sessionStorage.SetAsync("UserInfoSession", user);
+
+ AuthenticationState authState = await GetAuthenticationStateAsync();
+ SetAuthenticationState(authState);
+ }
+
+ return loginSuccess;
+ }
+
+ public async Task LogoutAsync()
+ {
+ await _authService.LogoutAsync();
+ await _sessionStorage.DeleteAsync("UserInfoSession");
+ SetAuthenticationState(new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity())));
+ }
+
+ public void SetAuthenticationState(AuthenticationState authState)
+ {
+ NotifyAuthenticationStateChanged(Task.FromResult(authState));
+ }
+ }
+}
diff --git a/Shared/Login.razor b/Shared/Login.razor
deleted file mode 100644
index 97b810b..0000000
--- a/Shared/Login.razor
+++ /dev/null
@@ -1,81 +0,0 @@
-@using KWWebInvApp.Data
-@inject UserServices userService
-@inject IDialogService DialogService
-@inject NavigationManager navigationManager
-
-
-
-
-
-
- Login
- Welcome to Merchandise and SAC System
- @if (error != null)
- {
- @error
- }
-
-
-
-
- @submitButtonText
- Reset
-
-
-
-
-
-
-
-
-@code {
-
- bool submitButtonDisabled = false;
- string? pass, error, submitButtonText = "Login";
- UserInfoServices.userinfo userAttemtingToLogin = new();
-
- //protected override async Task OnInitializedAsync()
- //{
-
- //}
-
- async Task SubmitLogin()
- {
- error = null;
-
- if (String.IsNullOrEmpty(userAttemtingToLogin.username) || String.IsNullOrEmpty(pass))
- {
- error = "Username and Password is required";
- return;
- }
-
- UserInfoServices.UserInfoServiceClient userInfoServiceClient = new();
-
- waitingButton(true);
- userAttemtingToLogin.pass = await userInfoServiceClient.md5EncodingAsync(pass);
- userService.CurrentUser = await userInfoServiceClient.AuthenticateUserAsync(userAttemtingToLogin);
- waitingButton();
-
- if (userService.CurrentUser == null)
- error = "Invalid Username or Password";
- else
- navigationManager.NavigateTo("/");
- }
-
- void waitingButton(bool waiting = false)
- {
- if(waiting)
- {
- submitButtonDisabled = true;
- submitButtonText = "Please Wait...";
- }
- else
- {
- submitButtonDisabled = false;
- submitButtonText = "Login";
- }
- }
-}
diff --git a/Shared/MainLayout.razor b/Shared/MainLayout.razor
index 47fa0f1..44b25c5 100644
--- a/Shared/MainLayout.razor
+++ b/Shared/MainLayout.razor
@@ -1,6 +1,10 @@
@inherits LayoutComponentBase
+
@using KWWebInvApp.Data
-@inject UserServices userServices
+@using KWWebInvApp.Services;
+
+@inject IAuthenticationService AuthenticationStateService
+@inject AuthenticationStateProvider AuthenticationStateProvider
@inject NavigationManager navigationManager
@@ -8,52 +12,58 @@
-
- @if (userServices.IsAuthenticated())
- {
-
-
-
-
-
- }
-
-
- @if (userServices.IsAuthenticated())
- {
-
-
- KW Web App
-
-
-
-
-
- @Body
-
-
- }
- else
- {
-
-
-
-
-
- }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ KW Web Inventory
+
+
+
+
+
+
+
+
+ @Body
+
+
@code {
bool _drawerOpen = true;
+ private UserInfoServices.userinfo? user;
+
+ protected override async void OnAfterRender(bool firstRender)
+ {
+ base.OnAfterRender(firstRender);
+
+ user = await AuthenticationStateService.GetAuthenticatedUserAsync();
+ }
void DrawerToggle()
{
_drawerOpen = !_drawerOpen;
}
- void Logout()
+ async void Logout()
{
- userServices.CurrentUser = null;
+ var webAuthenticationStateProvider = (WebAuthenticationStateProvider)AuthenticationStateProvider;
+ await webAuthenticationStateProvider.LogoutAsync();
navigationManager.NavigateTo("/");
}
}
\ No newline at end of file
diff --git a/Shared/RedirectToLogin.razor b/Shared/RedirectToLogin.razor
new file mode 100644
index 0000000..4362608
--- /dev/null
+++ b/Shared/RedirectToLogin.razor
@@ -0,0 +1,34 @@
+@using KWWebInvApp.Data
+@using KWWebInvApp.Services;
+
+@inject NavigationManager navigationManager
+@inject AuthenticationStateProvider AuthenticationStateProvider
+
+@code {
+ protected override async Task OnInitializedAsync()
+ {
+ //var returnUrl = Navigation.ToBaseRelativePath(Navigation.Uri);
+
+ //if (string.IsNullOrWhiteSpace(returnUrl))
+ // Navigation.NavigateTo("/userlogin", true);
+ //else
+ //{
+ // if (returnUrl == "userlogin")
+ // Navigation.NavigateTo("/userlogin", true);
+ // else
+ // Navigation.NavigateTo($"/userlogin?returnUrl={returnUrl}", true);
+ //}
+ }
+
+ protected override void OnAfterRender(bool firstRender)
+ {
+ base.OnAfterRender(firstRender);
+
+ var returnUrl = navigationManager.ToBaseRelativePath(navigationManager.Uri);
+
+ if (string.IsNullOrWhiteSpace(returnUrl))
+ navigationManager.NavigateTo("/userlogin", true);
+ else
+ navigationManager.NavigateTo($"/userlogin?returnUrl={returnUrl}", true);
+ }
+}