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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Shifty.App/Authentication/Authentication.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@page "/Auth"
@using Microsoft.AspNetCore.Authorization
@attribute [AllowAnonymous]
@using Shifty.App.Services
@inject NavigationManager NavManager
@inject IAuthenticationService _authenticationService

@code {
[CascadingParameter] public Task<AuthenticationState> AuthTask { get; set; }

[SupplyParameterFromQuery(Name = "token")]
public string Token { get; set; }

[AllowAnonymous]
protected override async Task OnInitializedAsync()
{
if (!string.IsNullOrWhiteSpace(Token))
{
await _authenticationService.Authenticate(Token);
}

NavManager.NavigateTo("/");
}

}
13 changes: 11 additions & 2 deletions Shifty.App/Components/RedirectToLogin.razor
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
@using Shifty.App.Services
@inject NavigationManager Navigation
@inject IAuthenticationService _authenticationService

@code {
protected override void OnInitialized()
protected override async Task OnInitializedAsync()
{
Navigation.NavigateTo("/login", false);
if (await _authenticationService.Refresh())
{
Navigation.NavigateTo("/", false);
}
else
{
Navigation.NavigateTo("/login", false);
}
}
}
10 changes: 1 addition & 9 deletions Shifty.App/Pages/Login.razor
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@
For="() => _loginForm.Email"
Immediate="true"
DebounceInterval="500"/>
<MudTextField T="string" Label="Password"
@bind-Value="_loginForm.Password"
InputType="InputType.Password"
For="() => _loginForm.Password"
Immediate="true"/>
}
</MudCardContent>
<MudCardActions>
Expand All @@ -60,16 +55,13 @@
[Required]
[EmailAddress]
public string Email { get; set; }

[Required]
public string Password { get; set; }
}

async Task LoginUser()
{
_successfulLogin = true;
_loggingIn = true;
_successfulLogin = await _authenticationService.LoginUser(_loginForm.Email, _loginForm.Password);
_successfulLogin = await _authenticationService.LoginUser(_loginForm.Email);
_loggingIn = false;
if (_successfulLogin)
{
Expand Down
17 changes: 10 additions & 7 deletions Shifty.App/Repositories/AccountRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@ public AccountRepository(AnalogCoreV1 v1client, AnalogCoreV2 v2client)
_v2client = v2client;
}

public async Task<Either<Error, TokenDto>> LoginAsync(string username, string password)
public async Task<Either<Error, Task>> LoginAsync(string username)
{
var dto = new LoginDto()
{
Email= username,
Password = password,
Version = "2.1.0"
var dto = new UserLoginRequest(){
Email = username
};
return await TryAsync(_v1client.ApiV1AccountLoginAsync(loginDto: dto)).ToEither();

return await TryAsync(_v2client.ApiV2AccountLoginAsync(dto)).ToEither();
}

public async Task<Try<UserSearchResponse>> SearchUserAsync(string query, int page, int pageSize)
Expand All @@ -40,5 +38,10 @@ public async Task<Try<Task>> UpdateUserGroupAsync(int userId, UserGroup group)
{
return await TryAsync(_v2client.ApiV2AccountUserGroupAsync(userId, new(){UserGroup = group}));
}

public async Task<Either<Error, UserLoginResponse>> AuthenticateAsync(string token)
{
return await TryAsync(_v2client.ApiV2AccountAuthAsync(new(){Token = token})).ToEither();
}
}
}
4 changes: 3 additions & 1 deletion Shifty.App/Repositories/IAccountRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ namespace Shifty.App.Repositories
{
public interface IAccountRepository
{
public Task<Either<Error, TokenDto>> LoginAsync(string username, string password);
public Task<Either<Error, Task>> LoginAsync(string username);
public Task<Try<UserSearchResponse>> SearchUserAsync(string query, int page, int pageSize);
public Task<Try<Task>> UpdateUserGroupAsync(int userId, UserGroup group);
public Task<Either<Error, UserLoginResponse>> AuthenticateAsync(string token);

}
}
65 changes: 39 additions & 26 deletions Shifty.App/Services/AuthenticationService.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System.Threading.Tasks;
using System;
using System.Security.Cryptography;
using System.Text;
using Blazored.LocalStorage;
using LanguageExt.UnsafeValueAccess;
using Shifty.App.Authentication;
using Shifty.App.Repositories;
using Microsoft.AspNetCore.Authorization;

namespace Shifty.App.Services
{
Expand All @@ -21,37 +18,53 @@ public AuthenticationService(IAccountRepository accountRepository, CustomAuthSta
_authStateProvider = stateProvider;
_localStorage = storageService;
}

private static string EncodePasscode(string passcode)
{
byte[] bytes = Encoding.UTF8.GetBytes(passcode);
using (SHA256 sha256 = SHA256.Create())
{
byte[] passcodeHash = sha256.ComputeHash(bytes);
return Convert.ToBase64String(passcodeHash);
}
}

public async Task<bool> LoginUser(string username, string password)
public async Task<bool> LoginUser(string username)
{
var encodedPassword = EncodePasscode(password);
var either = await _accountRepository.LoginAsync(username, encodedPassword);
var either = await _accountRepository.LoginAsync(username);

if (either.IsLeft)
{
System.Console.WriteLine(either.Right(w => w.ToString()).Left(e => e.Message));
return false;
}

var jwtString = either.ValueUnsafe().Token;
await _localStorage.SetItemAsync("token", jwtString);
return _authStateProvider.UpdateAuthState(jwtString);
return either.Match(
Left: error =>
{
return false;
},
Right: _ => true
);
}

public async Task Logout()
{
await _localStorage.RemoveItemAsync("token");
await _localStorage.RemoveItemAsync("refreshToken");
_authStateProvider.UpdateAuthState("");
}

[AllowAnonymous]
public async Task<bool> Refresh()
{
var refreshToken = await _localStorage.GetItemAsync<string>("refreshToken");
return await Authenticate(refreshToken);
}

[AllowAnonymous]
public async Task<bool> Authenticate(string token)
{
var either = await _accountRepository.AuthenticateAsync(token);

return await either.Match(
Left: e =>
{
return Task.FromResult(false);
},
Right: async response =>
{
var jwtString = response.Jwt;
await _localStorage.SetItemAsync("refreshToken", response.RefreshToken);
await _localStorage.SetItemAsync("token", jwtString);
_authStateProvider.UpdateAuthState(jwtString);

return true;
});
}
}
}
4 changes: 3 additions & 1 deletion Shifty.App/Services/IAuthenticationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ namespace Shifty.App.Services
{
public interface IAuthenticationService
{
Task<bool> LoginUser(string username, string password);
Task<bool> LoginUser(string username);
Task Logout();
Task<bool> Authenticate(string token);
Task<bool> Refresh();
}
}
Loading
Loading