Adds supports for RefreshTokens

This commit is contained in:
2025-04-17 04:33:28 -04:00
parent c19e2eb493
commit 16ae68a02e
28 changed files with 620 additions and 76 deletions

View File

@@ -1,11 +1,14 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Hutopy.Web.Common.Security;
using Hutopy.Web.Features.Users.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using IdentityUser = Hutopy.Web.Features.Users.Data.IdentityUser;
namespace Hutopy.Web.Features.Users.Handlers;
[PublicAPI]
public class FacebookUserInfo
{
[JsonPropertyName("id")] public required string Id { get; init; }
@@ -14,11 +17,13 @@ public class FacebookUserInfo
[JsonPropertyName("picture")] public required FacebookPictureData Picture { get; init; }
}
[PublicAPI]
public class FacebookPictureData
{
[JsonPropertyName("data")] public required FacebookPicture Picture { get; init; }
}
[PublicAPI]
public class FacebookPicture
{
[JsonPropertyName("url")] public required string Url { get; init; }
@@ -80,10 +85,10 @@ public class LoginWithFacebookHandler(
// Check if user exists or create a new one
var user = await userManager.FindByEmailAsync(userInfo.Email!);
if (user is null)
{
var generatedPassword = PasswordGenerator.GeneratePassword();
var generatedPassword = PasswordGenerator.Next();
var generatedUser = new IdentityUser
{
UserName = userInfo.Email ?? $"fb_{userInfo.Id}",
@@ -94,11 +99,11 @@ public class LoginWithFacebookHandler(
PortraitUrl = userInfo.Picture.Picture.Url,
FacebookId = userInfo.Id, // Storing Facebook ID
};
var result = await userManager.CreateAsync(
generatedUser,
generatedPassword);
if (!result.Succeeded)
{
await SendStringAsync(
@@ -113,20 +118,28 @@ public class LoginWithFacebookHandler(
await signInManager.SignInAsync(user, isPersistent: false);
// Generate refresh token
var refreshToken = RefreshTokenGenerator.Next();
// Store refresh token in user's properties
user.RefreshToken = refreshToken;
user.RefreshTokenExpiryTime = DateTime.UtcNow.Add(jwtOptions.Value.RefreshTokenLifetime);
await userManager.UpdateAsync(user);
var accessToken = JwtTokenHelper.GenerateJwtToken(
expiresIn: jwtOptions.Value.Lifetime,
issuer: jwtOptions.Value.Issuer,
audience: jwtOptions.Value.Audience,
key: jwtOptions.Value.Key,
userId: user.Id.ToString(),
email: user.Email,
email: user.Email ?? string.Empty,
alias: user.Alias,
firstname: user.Firstname,
lastname: user.Lastname,
firstname: user.Firstname ?? string.Empty,
lastname: user.Lastname ?? string.Empty,
portraitUrl: user.PortraitUrl);
await SendOkAsync(
new LoginWithFacebookResponse(accessToken, string.Empty),
new LoginWithFacebookResponse(accessToken, refreshToken),
cancellation: ct);
}
}