using DysonNetwork.Sphere.Account.Proto; using Grpc.Core; using Google.Protobuf.WellKnownTypes; using Microsoft.EntityFrameworkCore; using DysonNetwork.Sphere.Auth; namespace DysonNetwork.Sphere.Account; public class AccountGrpcService : DysonNetwork.Sphere.Account.Proto.AccountService.AccountServiceBase { private readonly AppDatabase _db; private readonly AuthService _auth; public AccountGrpcService(AppDatabase db, AuthService auth) { _db = db; _auth = auth; } public override async Task GetAccount(Empty request, ServerCallContext context) { var account = await GetAccountFromContext(context); return ToAccountResponse(account); } public override async Task UpdateAccount(UpdateAccountRequest request, ServerCallContext context) { var account = await GetAccountFromContext(context); if (request.Email != null) { var emailContact = await _db.AccountContacts.FirstOrDefaultAsync(c => c.AccountId == account.Id && c.Type == AccountContactType.Email); if (emailContact != null) { emailContact.Content = request.Email; } else { account.Contacts.Add(new AccountContact { Type = AccountContactType.Email, Content = request.Email }); } } if (request.DisplayName != null) { account.Nick = request.DisplayName; } await _db.SaveChangesAsync(); return ToAccountResponse(account); } private async Task GetAccountFromContext(ServerCallContext context) { var authorizationHeader = context.RequestHeaders.FirstOrDefault(h => h.Key == "authorization"); if (authorizationHeader == null) { throw new RpcException(new Grpc.Core.Status(StatusCode.Unauthenticated, "Missing authorization header.")); } var token = authorizationHeader.Value.Replace("Bearer ", ""); if (!_auth.ValidateToken(token, out var sessionId)) { throw new RpcException(new Grpc.Core.Status(StatusCode.Unauthenticated, "Invalid token.")); } var session = await _db.AuthSessions.Include(s => s.Account).ThenInclude(a => a.Contacts).FirstOrDefaultAsync(s => s.Id == sessionId); if (session == null) { throw new RpcException(new Grpc.Core.Status(StatusCode.Unauthenticated, "Session not found.")); } return session.Account; } private AccountResponse ToAccountResponse(DysonNetwork.Sphere.Account.Account account) { var emailContact = account.Contacts.FirstOrDefault(c => c.Type == AccountContactType.Email); return new AccountResponse { Id = account.Id.ToString(), Username = account.Name, Email = emailContact?.Content ?? "", DisplayName = account.Nick }; } }