Add provider-neutral Google authentication

This commit is contained in:
hz
2026-07-20 21:42:56 -05:00
parent 48e19f138e
commit 72fd1e3e0f
20 changed files with 1084 additions and 36 deletions
+20 -2
View File
@@ -20,6 +20,9 @@ public sealed class AuthController(
UserProfileStore profiles,
PasswordResetStore passwordResets,
SteamAuthTransactionStore steamTransactions,
ExternalIdentityStore externalIdentities,
ExternalAuthTransactionStore externalTransactions,
IEnumerable<IExternalAuthProvider> externalProviders,
PasswordResetCodeService resetCodes,
IPasswordResetEmailSender resetEmail,
IConfiguration configuration,
@@ -109,7 +112,7 @@ public sealed class AuthController(
[HttpGet("me")]
[Authorize(Roles = "USER,SUPER")]
public async Task<IActionResult> Me() =>
await CurrentUserAsync() is { } user ? Ok(ProfileResponse(user)) : Unauthorized();
await CurrentUserAsync() is { } user ? Ok(await ProfileResponseAsync(user)) : Unauthorized();
[HttpPost("legal/accept")]
[Authorize(Roles = "USER,SUPER")]
@@ -152,7 +155,7 @@ public sealed class AuthController(
{
return Conflict("Email address is already in use.");
}
return Ok(ProfileResponse(user));
return Ok(await ProfileResponseAsync(user));
}
[HttpPost("me/change-password")]
@@ -186,6 +189,7 @@ public sealed class AuthController(
await profiles.PurgeAsync(user.Id);
await passwordResets.DeleteForUserAsync(user.Id);
await steamTransactions.DeleteForUserAsync(user.Id);
await externalTransactions.DeleteForUserAsync(user.Id);
await RevokeCurrentTokenAsync();
await users.DeleteAsync(user.Id);
return NoContent();
@@ -302,6 +306,20 @@ public sealed class AuthController(
legal = legal.Status(user)
};
private async Task<object> ProfileResponseAsync(AuthUser user) => new
{
userId = user.Id,
user.Username,
user.DisplayName,
user.Email,
user.Role,
createdUtc = user.CreatedUtc ?? CreationDate(user),
connectedProviders = await externalIdentities.ProvidersForUserAsync(user.Id),
availableProviders = externalProviders.Where(provider => provider.IsConfigured)
.Select(provider => provider.Id).OrderBy(provider => provider),
legal = legal.Status(user)
};
private object SessionResponse(AuthUser user, string accessToken, DateTime expiresUtc,
string? jti = null, string? refreshToken = null) => new
{