Files
MoShiro/backend/src/MoShiro.Backend.Application/Ports/IAuthStore.cs
T

54 lines
2.4 KiB
C#

namespace MoShiro.Backend.Application;
public sealed record UserRecord(string Id, string Username, byte[] PasswordHash, byte[] PasswordSalt, int Iterations, long CreatedAtMs);
public sealed record SessionRecord(byte[] IdSha256, string UserId, byte[] CsrfToken, long CreatedAtMs, long ExpiresAtMs, string AuthMethod = AuthMethods.Password);
public sealed record ApiTokenRecord(string Id, string Name, IReadOnlyList<string> Capabilities, byte[] TokenSha256, long CreatedAtMs, long? LastUsedAtMs, long? ExpiresAtMs, long? RevokedAtMs);
public interface IAuthStore
{
ValueTask<int> CountUsersAsync(CancellationToken ct);
ValueTask<UserRecord?> GetUserByNameAsync(string username, CancellationToken ct);
ValueTask<UserRecord?> GetUserAsync(string id, CancellationToken ct);
ValueTask<IReadOnlyList<UserRecord>> ListUsersAsync(CancellationToken ct);
/// <summary>用户名已存在时返回 false。</summary>
ValueTask<bool> CreateUserAsync(UserRecord user, CancellationToken ct);
ValueTask UpdatePasswordAsync(string userId, byte[] hash, byte[] salt, int iterations, CancellationToken ct);
ValueTask CreateSessionAsync(SessionRecord session, CancellationToken ct);
ValueTask<SessionRecord?> GetSessionAsync(byte[] idSha256, CancellationToken ct);
ValueTask DeleteSessionAsync(byte[] idSha256, CancellationToken ct);
ValueTask DeleteExpiredSessionsAsync(long nowMs, CancellationToken ct);
ValueTask CreateApiTokenAsync(ApiTokenRecord token, CancellationToken ct);
/// <summary>凭证 id 已经存在时返回 false。</summary>
ValueTask<bool> AddPasskeyAsync(PasskeyRecord passkey, CancellationToken ct);
ValueTask<PasskeyRecord?> FindPasskeyAsync(string credentialId, CancellationToken ct);
ValueTask<IReadOnlyList<PasskeyRecord>> ListPasskeysAsync(string userId, CancellationToken ct);
/// <summary>只能删自己的。</summary>
ValueTask<bool> DeletePasskeyAsync(string userId, string credentialId, CancellationToken ct);
ValueTask TouchPasskeyAsync(string credentialId, long signCount, long nowMs, CancellationToken ct);
ValueTask<ApiTokenRecord?> FindApiTokenAsync(byte[] tokenSha256, CancellationToken ct);
ValueTask<IReadOnlyList<ApiTokenRecord>> ListApiTokensAsync(CancellationToken ct);
ValueTask<bool> RevokeApiTokenAsync(string id, long nowMs, CancellationToken ct);
ValueTask TouchApiTokenAsync(string id, long nowMs, CancellationToken ct);
}