Files
Relay/RelayCore/Services/APIAuthService.cs

99 lines
3.9 KiB
C#

using Newtonsoft.Json;
using RelayCore.Endpoints;
using RelayCore.Enums;
using RelayCore.Models;
using SurrealDb.Net;
using SurrealDb.Net.Models;
namespace RelayCore.Services;
public class APIAuthService(SurrealDbClient _db)
{
public async Task<List<Users>> GetUsersAsync()
{
var users = await _db.Select<Users>("auth_users");
return users.Where(x => x.Username is not null).OrderByDescending(x=>x.CreatedAt).ToList();
}
public async Task<string?> UserSigninAsync(AuthSignin request, string ip, string userAgent)
{
var hasher = new PasswordHasher();
var users = await _db.Select<Users>("auth_users");
var user = users.FirstOrDefault(x => (x.Username.ToLower() == request.UserName.ToLower() ||
x.Email.ToLower() == request.UserName.ToLower()) &&
hasher.VerifyPassword(x.Id + request.Password, x.Password));
if (user == null)
return null;
var tokens = await _db.Select<Sessions>("auth_sessions");
var token = tokens.Where(x => x.UserId == user.Id && x.IpAddress == ip && x.UserAgent == userAgent && !x.Revoked)
.OrderByDescending(x => x.ExpiresAt).FirstOrDefault();
if (token != null)
if (token.ExpiresAt > DateTime.UtcNow)
return token.TokenHash;
//TODO: Generate TOKEN
var newToken = hasher.HashPassword($"{request.UserName}{userAgent}");
//TODO: Store TOKEN and Username for verification
var sessionId = await _db.Create("auth_sessions", new Sessions
{
UserId = user.Id,
TokenHash = newToken,
IssuedAt = DateTime.UtcNow,
ExpiresAt = DateTime.UtcNow.AddDays(30),
DeviceName = "",
Revoked = false,
IpAddress = ip,
UserAgent = userAgent
});
//TODO: Add invalidation to TOKENs
return newToken;
}
public async Task<string?> UserRegisterAsync(AuthRegister request, string ip, string userAgent)
{
var hasher = new PasswordHasher();
var users = await _db.Select<Users>("auth_users");
var user = users.FirstOrDefault(x => x.Username.ToLower() == request.Username.ToLower() || x.Email.ToLower() == request.Email.ToLower());
if (user == null)
{
var now = DateTime.Now;
var created = await _db.Create("auth_users", new Users
{
Username = request.Username,
Email = request.Email,
CreatedAt = now,
UpdatedAt = now,
LastLogin = now,
TwoFactorEnabled = false,
EmailVerified = false,
AccountStatus = (int)AccountStatuses.Active,
OnlineStatus = (int)OnlineStatuses.Online,
});
var passwordHash = hasher.HashPassword(created.Id + request.Password);
await _db.Merge<PasswordHash, Users>(new PasswordHash
{
Id = created.Id,
Password = passwordHash
});
return await UserSigninAsync(new AuthSignin{UserName=request.Username, Password = request.Password}, ip, userAgent);
}
return null;
}
public async Task<bool> ServerVerifyUser(AuthUserVerify request)
{
var users = await _db.Select<Users>("auth_users");
var user = users.FirstOrDefault(x => x.Username == request.Username);
if (user == null)
return false;
var sessions = await _db.Select<Sessions>("auth_sessions");
var session = sessions.FirstOrDefault(x => x.TokenHash == request.Token && x.UserId == user.Id);
if (session == null)
return false;
return true;
}
}