2023-03-03 13:24:27 +01:00
|
|
|
#nullable enable
|
2024-09-12 05:31:57 +02:00
|
|
|
using System;
|
2023-03-03 13:24:27 +01:00
|
|
|
using System.Threading.Tasks;
|
2024-09-12 05:31:57 +02:00
|
|
|
using BTCPayServer.Data;
|
2024-02-28 12:43:18 +01:00
|
|
|
using BTCPayServer.Security;
|
2023-03-03 13:24:27 +01:00
|
|
|
using Microsoft.AspNetCore.Identity;
|
|
|
|
|
|
|
|
namespace BTCPayServer
|
|
|
|
{
|
|
|
|
public static class UserManagerExtensions
|
|
|
|
{
|
2024-02-28 12:43:18 +01:00
|
|
|
private const string InvitationPurpose = "invitation";
|
|
|
|
|
|
|
|
public static async Task<TUser?> FindByIdOrEmail<TUser>(this UserManager<TUser> userManager, string? idOrEmail) where TUser : class
|
2023-03-03 13:24:27 +01:00
|
|
|
{
|
|
|
|
if (string.IsNullOrEmpty(idOrEmail))
|
|
|
|
return null;
|
|
|
|
if (idOrEmail.Contains('@'))
|
|
|
|
return await userManager.FindByEmailAsync(idOrEmail);
|
2024-02-28 12:43:18 +01:00
|
|
|
|
|
|
|
return await userManager.FindByIdAsync(idOrEmail);
|
|
|
|
}
|
|
|
|
|
2024-09-12 05:31:57 +02:00
|
|
|
public static async Task<string?> GenerateInvitationTokenAsync<TUser>(this UserManager<ApplicationUser> userManager, string userId) where TUser : class
|
2024-02-28 12:43:18 +01:00
|
|
|
{
|
2024-09-12 05:31:57 +02:00
|
|
|
var token = Guid.NewGuid().ToString("n")[..12];
|
|
|
|
return await userManager.SetInvitationTokenAsync<TUser>(userId, token) ? token : null;
|
2024-02-28 12:43:18 +01:00
|
|
|
}
|
|
|
|
|
2024-09-12 05:31:57 +02:00
|
|
|
public static async Task<bool> UnsetInvitationTokenAsync<TUser>(this UserManager<ApplicationUser> userManager, string userId) where TUser : class
|
|
|
|
{
|
|
|
|
return await userManager.SetInvitationTokenAsync<TUser>(userId, null);
|
|
|
|
}
|
|
|
|
|
2024-10-03 14:35:01 +02:00
|
|
|
public static bool HasInvitationToken<TUser>(this UserManager<ApplicationUser> userManager, ApplicationUser user, string? token = null) where TUser : class
|
|
|
|
{
|
|
|
|
var blob = user.GetBlob() ?? new UserBlob();
|
|
|
|
return token == null ? !string.IsNullOrEmpty(blob.InvitationToken) : blob.InvitationToken == token;
|
|
|
|
}
|
|
|
|
|
2024-09-12 05:31:57 +02:00
|
|
|
private static async Task<bool> SetInvitationTokenAsync<TUser>(this UserManager<ApplicationUser> userManager, string userId, string? token) where TUser : class
|
|
|
|
{
|
|
|
|
var user = await userManager.FindByIdAsync(userId);
|
|
|
|
if (user == null) return false;
|
|
|
|
var blob = user.GetBlob() ?? new UserBlob();
|
|
|
|
blob.InvitationToken = token;
|
|
|
|
user.SetBlob(blob);
|
|
|
|
await userManager.UpdateAsync(user);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async Task<ApplicationUser?> FindByInvitationTokenAsync<TUser>(this UserManager<ApplicationUser> userManager, string userId, string token) where TUser : class
|
2024-02-28 12:43:18 +01:00
|
|
|
{
|
|
|
|
var user = await userManager.FindByIdAsync(userId);
|
2024-09-12 05:31:57 +02:00
|
|
|
var isValid = user is not null && (
|
|
|
|
user.GetBlob()?.InvitationToken == token ||
|
|
|
|
// backwards-compatibility with old tokens
|
|
|
|
await userManager.VerifyUserTokenAsync(user, InvitationTokenProviderOptions.ProviderName, InvitationPurpose, token));
|
2024-02-28 12:43:18 +01:00
|
|
|
return isValid ? user : null;
|
2023-03-03 13:24:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|