mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-04-06 02:19:05 +00:00
Begin work on user confirmation workflow
This commit is contained in:
21
src/Core/Service/Service.Auth/IConfirmationService.cs
Normal file
21
src/Core/Service/Service.Auth/IConfirmationService.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Runtime.InteropServices.JavaScript;
|
||||
using Infrastructure.Repository.Auth;
|
||||
|
||||
namespace Service.Auth;
|
||||
|
||||
public record ConfirmationServiceReturn(DateTime confirmedAt, Guid userId);
|
||||
|
||||
public interface IConfirmationService
|
||||
{
|
||||
Task<ConfirmationServiceReturn> ConfirmUserAsync(string confirmationToken);
|
||||
}
|
||||
|
||||
|
||||
public class ConfirmationService(IAuthRepository authRepository) : IConfirmationService
|
||||
{
|
||||
|
||||
public async Task<ConfirmationServiceReturn> ConfirmUserAsync(string confirmationToken)
|
||||
{
|
||||
return new ConfirmationServiceReturn(DateTime.Now, Guid.NewGuid());
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,11 @@ using Domain.Entities;
|
||||
|
||||
namespace Service.Auth;
|
||||
|
||||
public record LoginServiceReturn(
|
||||
UserAccount UserAccount,
|
||||
string RefreshToken,
|
||||
string AccessToken
|
||||
);
|
||||
public interface ILoginService
|
||||
{
|
||||
Task<LoginServiceReturn> LoginAsync(string username, string password);
|
||||
|
||||
@@ -36,4 +36,4 @@ public interface IRegisterService
|
||||
UserAccount userAccount,
|
||||
string password
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,28 +7,73 @@ public interface ITokenService
|
||||
{
|
||||
public string GenerateAccessToken(UserAccount user);
|
||||
public string GenerateRefreshToken(UserAccount user);
|
||||
public string GenerateConfirmationToken(UserAccount user);
|
||||
}
|
||||
|
||||
public static class TokenServiceExpirationHours
|
||||
{
|
||||
public const double AccessTokenHours = 1;
|
||||
public const double RefreshTokenHours = 504; // 21 days
|
||||
public const double ConfirmationTokenHours = 0.5; // 30 minutes
|
||||
}
|
||||
|
||||
public class TokenService(ITokenInfrastructure tokenInfrastructure)
|
||||
: ITokenService
|
||||
{
|
||||
private readonly string _accessTokenSecret =
|
||||
Environment.GetEnvironmentVariable("ACCESS_TOKEN_SECRET")
|
||||
?? throw new InvalidOperationException(
|
||||
"ACCESS_TOKEN_SECRET environment variable is not set"
|
||||
);
|
||||
|
||||
private readonly string _refreshTokenSecret =
|
||||
Environment.GetEnvironmentVariable("REFRESH_TOKEN_SECRET")
|
||||
?? throw new InvalidOperationException(
|
||||
"REFRESH_TOKEN_SECRET environment variable is not set"
|
||||
);
|
||||
|
||||
private readonly string _confirmationTokenSecret =
|
||||
Environment.GetEnvironmentVariable("CONFIRMATION_TOKEN_SECRET")
|
||||
?? throw new InvalidOperationException(
|
||||
"CONFIRMATION_TOKEN_SECRET environment variable is not set"
|
||||
);
|
||||
|
||||
public string GenerateAccessToken(UserAccount userAccount)
|
||||
{
|
||||
var jwtExpiresAt = DateTime.UtcNow.AddHours(1);
|
||||
var jwtExpiresAt = DateTime.UtcNow.AddHours(
|
||||
TokenServiceExpirationHours.AccessTokenHours
|
||||
);
|
||||
return tokenInfrastructure.GenerateJwt(
|
||||
userAccount.UserAccountId,
|
||||
userAccount.Username,
|
||||
jwtExpiresAt
|
||||
jwtExpiresAt,
|
||||
_accessTokenSecret
|
||||
);
|
||||
}
|
||||
|
||||
public string GenerateRefreshToken(UserAccount userAccount)
|
||||
{
|
||||
var jwtExpiresAt = DateTime.UtcNow.AddDays(21);
|
||||
var jwtExpiresAt = DateTime.UtcNow.AddHours(
|
||||
TokenServiceExpirationHours.RefreshTokenHours
|
||||
);
|
||||
return tokenInfrastructure.GenerateJwt(
|
||||
userAccount.UserAccountId,
|
||||
userAccount.Username,
|
||||
jwtExpiresAt
|
||||
jwtExpiresAt,
|
||||
_refreshTokenSecret
|
||||
);
|
||||
}
|
||||
|
||||
public string GenerateConfirmationToken(UserAccount userAccount)
|
||||
{
|
||||
var jwtExpiresAt = DateTime.UtcNow.AddHours(
|
||||
TokenServiceExpirationHours.ConfirmationTokenHours
|
||||
);
|
||||
return tokenInfrastructure.GenerateJwt(
|
||||
userAccount.UserAccountId,
|
||||
userAccount.Username,
|
||||
jwtExpiresAt,
|
||||
_confirmationTokenSecret
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,6 @@ using Infrastructure.Repository.Auth;
|
||||
|
||||
namespace Service.Auth;
|
||||
|
||||
public record LoginServiceReturn(
|
||||
UserAccount UserAccount,
|
||||
string RefreshToken,
|
||||
string AccessToken
|
||||
);
|
||||
|
||||
public class LoginService(
|
||||
IAuthRepository authRepo,
|
||||
|
||||
@@ -53,6 +53,7 @@ public class RegisterService(
|
||||
|
||||
var accessToken = tokenService.GenerateAccessToken(createdUser);
|
||||
var refreshToken = tokenService.GenerateRefreshToken(createdUser);
|
||||
var confirmationToken = tokenService.GenerateConfirmationToken(createdUser);
|
||||
|
||||
if (
|
||||
string.IsNullOrEmpty(accessToken)
|
||||
@@ -67,14 +68,15 @@ public class RegisterService(
|
||||
{
|
||||
// send confirmation email
|
||||
await emailService.SendRegistrationEmailAsync(
|
||||
createdUser,
|
||||
"some-confirmation-token"
|
||||
createdUser, confirmationToken
|
||||
);
|
||||
|
||||
emailSent = true;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Console.Error.WriteLineAsync(ex.Message);
|
||||
Console.WriteLine("Could not send email.");
|
||||
// ignored
|
||||
}
|
||||
|
||||
@@ -85,4 +87,4 @@ public class RegisterService(
|
||||
emailSent
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user