using Microsoft.AspNetCore.Identity;
using Nuuru.Server.Models;
namespace Nuuru.Server.Auth;
///
/// Password hasher that supports migrating from Shimmie's bcrypt hashes.
/// On successful verification of a Shimmie hash, returns SuccessRehashNeeded
/// to trigger automatic upgrade to Identity's default algorithm.
///
public class ShimmiePasswordHasher : IPasswordHasher
{
private readonly PasswordHasher _defaultHasher = new();
public string HashPassword(ApplicationUser user, string password)
{
// Always hash new passwords with Identity's default algorithm
return _defaultHasher.HashPassword(user, password);
}
public PasswordVerificationResult VerifyHashedPassword(
ApplicationUser user, string hashedPassword, string providedPassword)
{
if (string.IsNullOrEmpty(hashedPassword))
return PasswordVerificationResult.Failed;
// Check if it's a Shimmie/PHP bcrypt hash ($2y$, $2a$, $2b$)
if (hashedPassword.StartsWith("$2"))
{
try
{
// Normalize $2y$ to $2a$ for BCrypt.Net compatibility
var normalizedHash = hashedPassword;
if (hashedPassword.StartsWith("$2y$"))
{
normalizedHash = "$2a$" + hashedPassword.Substring(4);
}
if (BCrypt.Net.BCrypt.Verify(providedPassword, normalizedHash))
{
// Password matches - trigger rehash with new algorithm
return PasswordVerificationResult.SuccessRehashNeeded;
}
return PasswordVerificationResult.Failed;
}
catch
{
// If BCrypt verification fails, fall through to default
}
}
// Use default Identity verification for non-Shimmie hashes
return _defaultHasher.VerifyHashedPassword(user, hashedPassword, providedPassword);
}
}