using Flawless.Communication.Request; using Flawless.Communication.Response; using Flawless.Communication.Shared; using Flawless.Server.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace Flawless.Server.Controllers; [ApiController, Authorize, Route("api/user")] public class UserController( UserManager userManager ) : ControllerBase { [HttpPost("update/info")] public async Task UpdateUserInfoAsync(UserInfoModifyResponse r) { bool update = false; bool renew = false; // Modify content var u = (await userManager.GetUserAsync(HttpContext.User))!; if (r.NickName != null) { update = true; u.NickName = r.NickName; } if (r.Bio != null) { update = true; u.Bio = r.Bio; } if (r.Gender != null) { update = true; u.Gender = r.Gender ?? UserSex.Unset; } if (r.PublicEmail != null) { update = true; u.PublicEmail = r.PublicEmail ?? false; } if (renew) u.RenewSecurityStamp(); if (update || renew) await userManager.UpdateAsync(u); return Ok(); } [HttpPost("update/email")] public async Task UpdateEmailAsync(UserContactModifyResponse r) { if (string.IsNullOrWhiteSpace(r.Email)) return BadRequest(new FailedResponse("No valid email address provided!")); var u = (await userManager.GetUserAsync(HttpContext.User))!; var result = await userManager.SetEmailAsync(u, r.Email); if (!result.Succeeded) return BadRequest(new FailedResponse(result.Errors)); return Ok(); } [HttpPost("update/phone")] public async Task UpdatePhoneAsync(UserContactModifyResponse r) { if (string.IsNullOrWhiteSpace(r.Phone)) return BadRequest(new FailedResponse("No valid phone number provided!")); var u = (await userManager.GetUserAsync(HttpContext.User))!; var result = await userManager.SetPhoneNumberAsync(u, r.Phone); if (!result.Succeeded) return BadRequest(new FailedResponse(result.Errors)); return Ok(); } [HttpGet("get/info")] public async Task> GetUserInfoAsync(LocateUserRequest r) { var self = (await userManager.GetUserAsync(HttpContext.User))!; if (r.UserId != null) { var u = await userManager.FindByIdAsync(r.UserId); if (u == null) return BadRequest(new FailedResponse("User is not existed!")); return Ok(GetUserInfoInternal(u, self)); } if (r.Username != null) { var u = await userManager.FindByNameAsync(r.Username); if (u == null) return BadRequest(new FailedResponse("User is not existed!")); return Ok(GetUserInfoInternal(u, self)); } // Return self as default return Ok(GetUserInfoInternal(self, self)); } [HttpGet("query/info")] public async Task>> GetUserInfoAsync(QueryPagesRequest r) { var queryNamePrefix = r.Parameter?.Username ?? String.Empty; var queryId = r.Parameter == null ? Guid.Empty : Guid.Parse(r.Parameter.UserId!); var payload = await userManager.Users .Where(u => u.UserName!.StartsWith(queryNamePrefix) || u.Id == queryId) .Skip(r.Offset) .Take(r.Length) .Select(u => GetUserInfoInternal(u, null)) .ToArrayAsync(); // Return self as default return Ok(new PagedResponse { Offset = r.Offset, Length = r.Length, Data = payload }); } [HttpGet("delete")] public async Task DeleteUserAsync() { var self = (await userManager.GetUserAsync(HttpContext.User))!; await userManager.DeleteAsync(self); return Ok(); } private UserInfoResponse GetUserInfoInternal(AppUser queryUser, AppUser? currentUser) { var authorized = queryUser.Id == currentUser?.Id; return new UserInfoResponse { Username = queryUser.UserName, CreatedAt = queryUser.CreatedOn, Bio = queryUser.Bio, Gender = queryUser.Gender, NickName = queryUser.NickName, Email = queryUser.PublicEmail || authorized ? queryUser.Email : null, }; } }