90 lines
3.4 KiB
C#
90 lines
3.4 KiB
C#
using System.Text.Json;
|
|
using khmereid_backend.Dtos;
|
|
using khmereid_backend.Integrations;
|
|
|
|
namespace khmereid_backend.Services;
|
|
|
|
public class AuthService(
|
|
IAuthnApi authnApi,
|
|
ILogger<AuthService> logger,
|
|
UserService userService)
|
|
{
|
|
private readonly UserService _userService = userService;
|
|
private readonly ILogger<AuthService> _logger = logger;
|
|
private readonly IAuthnApi _authnApi = authnApi;
|
|
|
|
public async Task<ApiResponse<object>> StartRegistrationAsync(string phone)
|
|
{
|
|
if (await _userService.IsUserExistsAsync(phone))
|
|
{
|
|
_logger.LogWarning("User {Phone} already exists", phone);
|
|
return ApiResponse<object>.Fail("User already exists.");
|
|
}
|
|
|
|
_logger.LogInformation("Starting OTP registration for phone {Phone}", phone);
|
|
var result = await _authnApi.CreateOtpRegistrationFlowAsync(phone);
|
|
|
|
return ApiResponse<object>.Ok(result, "OTP sent if the phone number is valid.");
|
|
}
|
|
|
|
public async Task<ApiResponse<SignupResultDto>> CompleteRegistrationAsync(string flowId, string phone, string otp)
|
|
{
|
|
var data = await _authnApi.CompleteOtpRegistrationFlowAsync(otp, phone, flowId);
|
|
|
|
if (data.Error != null)
|
|
return ApiResponse<SignupResultDto>.Fail(data.Message ?? "Registration failed.", null, data.Code);
|
|
|
|
var user = await _userService.CreateUserAsync(phone, (Guid)data.IdentityId!);
|
|
return ApiResponse<SignupResultDto>.Ok(data, "Registration completed successfully.");
|
|
}
|
|
|
|
public async Task<ApiResponse<FlowDto>> StartLoginAsync(string phone)
|
|
{
|
|
_logger.LogInformation("Starting OTP login for phone {Phone}", phone);
|
|
var data = await _authnApi.CreateOtpLoginFlowAsync(phone);
|
|
|
|
if (data.Error != null)
|
|
return ApiResponse<FlowDto>.Fail(data.Message ?? "Request failed.", null, data.Code);
|
|
return ApiResponse<FlowDto>.Ok(data, "Request completed successfully.");
|
|
}
|
|
|
|
public async Task<ApiResponse<LoginResultDto>> CompleteLoginAsync(string flowId, string phone, string otp)
|
|
{
|
|
_logger.LogInformation("Completing OTP login for phone {Phone}, Flow: {FlowId}", phone, flowId);
|
|
|
|
var data = await _authnApi.CompleteOtpLoginFlowAsync(flowId, phone, otp);
|
|
|
|
if (data.Error != null)
|
|
return ApiResponse<LoginResultDto>.Fail(data.Message ?? "Login failed.", null, data.Code);
|
|
return ApiResponse<LoginResultDto>.Ok(data, "Login completed successfully.");
|
|
}
|
|
|
|
public async Task<ApiResponse<string>> LogoutAsync(string sessionToken)
|
|
{
|
|
_logger.LogInformation("Logging out session token {Token}", sessionToken);
|
|
await _authnApi.Logout(sessionToken);
|
|
return ApiResponse<string>.Ok("Logout completed successfully.");
|
|
}
|
|
|
|
public async Task<ApiResponse<SessionDto>> GetMeAsync(string sessionToken)
|
|
{
|
|
try
|
|
{
|
|
_logger.LogInformation("Fetching current session for token {Token}", sessionToken);
|
|
var response = await _authnApi.GetMeAsync(sessionToken);
|
|
|
|
if (response.Error != null)
|
|
return ApiResponse<SessionDto>.Fail(response.Message ?? "Failed.");
|
|
return ApiResponse<SessionDto>.Ok(response, "Session returned.");
|
|
}
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
throw;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to fetch session from Kratos");
|
|
throw;
|
|
}
|
|
}
|
|
} |