using MemberCenter.Api.Contracts; using MemberCenter.Api.Extensions; using MemberCenter.Application.Abstractions; using MemberCenter.Application.Models.Profile; using MemberCenter.Infrastructure.Identity; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; namespace MemberCenter.Api.Controllers; [ApiController] [Route("user")] public class UserController : ControllerBase { private readonly IProfileService _profileService; private readonly INewsletterService _newsletterService; private readonly UserManager _userManager; public UserController( IProfileService profileService, INewsletterService newsletterService, UserManager userManager) { _profileService = profileService; _newsletterService = newsletterService; _userManager = userManager; } [Authorize(Policy = "ProfileBasicRead")] [HttpGet("profile")] public async Task Profile() { var user = await _userManager.GetUserAsync(User); if (user is null) { return Unauthorized(); } var profile = await _profileService.GetProfileAsync(user.Id); return Ok(new { id = user.Id, email = user.Email, email_verified = user.EmailConfirmed, created_at = user.CreatedAt, profile }); } [Authorize(Policy = "ProfileBasicWrite")] [HttpPost("profile")] public async Task SaveProfile([FromBody] SaveProfileRequest request) { var user = await _userManager.GetUserAsync(User); if (user is null) { return Unauthorized(); } try { var profile = await _profileService.SaveProfileAsync(user.Id, new SaveUserProfileRequest( request.LastName, request.FirstName, request.NickName, request.MobilePhone, request.LandlinePhone, request.DateOfBirth, request.Gender, request.CompanyName, request.Department, request.JobTitle, request.CompanyPhone, request.TaxId, request.InvoiceTitle, request.Remark)); return Ok(profile); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } [Authorize(Policy = "ProfileAddressesRead")] [HttpGet("addresses")] public async Task Addresses() { var user = await _userManager.GetUserAsync(User); if (user is null) { return Unauthorized(); } return Ok(await _profileService.ListAddressesAsync(user.Id)); } [Authorize(Policy = "ProfileAddressesWrite")] [HttpPost("addresses")] public async Task SaveAddress([FromBody] SaveAddressRequest request) { var user = await _userManager.GetUserAsync(User); if (user is null) { return Unauthorized(); } try { var address = await _profileService.SaveAddressAsync(user.Id, new SaveUserAddressRequest( request.Id, request.Label, request.RecipientName, request.RecipientPhone, request.CountryCode, request.PostalCode, request.StateRegion, request.City, request.District, request.AddressLine1, request.AddressLine2, request.CompanyName, request.Usage, request.IsDefault, request.AddressMetaJson)); return Ok(address); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } [Authorize(Policy = "ProfileAddressesWrite")] [HttpDelete("addresses/{id:guid}")] public async Task DeleteAddress(Guid id) { var user = await _userManager.GetUserAsync(User); if (user is null) { return Unauthorized(); } try { await _profileService.DeleteAddressAsync(user.Id, id); return NoContent(); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } [Authorize(Policy = "ProfileSubscriptionsRead")] [HttpGet("subscriptions")] public async Task Subscriptions() { var user = await _userManager.GetUserAsync(User); if (user is null) { return Unauthorized(); } return Ok(await _newsletterService.ListSubscriptionsForUserAsync(user.Id)); } [Authorize(Policy = "ProfileSubscriptionsWrite")] [HttpPost("subscriptions/{id:guid}/unsubscribe")] public async Task Unsubscribe(Guid id) { var user = await _userManager.GetUserAsync(User); if (user is null) { return Unauthorized(); } var subscription = await _newsletterService.UnsubscribeForUserAsync(user.Id, id); return subscription is null ? NotFound() : Ok(subscription); } [Authorize(Policy = "ProfileBasicRead")] [HttpGet("profile/by-email")] public async Task ProfileByEmail([FromQuery] string email) { var user = await _userManager.FindByEmailAsync(email); if (user is null) { return NotFound(); } var profile = await _profileService.GetProfileAsync(user.Id); return Ok(profile); } [Authorize(Policy = "ProfileBasicWrite")] [HttpPost("profile/by-email")] public async Task SaveProfileByEmail([FromQuery] string email, [FromBody] SaveProfileRequest request) { var user = await _userManager.FindByEmailAsync(email); if (user is null) { return NotFound(); } try { var profile = await _profileService.SaveProfileAsync(user.Id, new SaveUserProfileRequest( request.LastName, request.FirstName, request.NickName, request.MobilePhone, request.LandlinePhone, request.DateOfBirth, request.Gender, request.CompanyName, request.Department, request.JobTitle, request.CompanyPhone, request.TaxId, request.InvoiceTitle, request.Remark)); return Ok(profile); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } [Authorize(Policy = "ProfileAddressesRead")] [HttpGet("addresses/by-email")] public async Task AddressesByEmail([FromQuery] string email) { var user = await _userManager.FindByEmailAsync(email); if (user is null) { return NotFound(); } return Ok(await _profileService.ListAddressesAsync(user.Id)); } [Authorize(Policy = "ProfileAddressesWrite")] [HttpPost("addresses/by-email")] public async Task SaveAddressByEmail([FromQuery] string email, [FromBody] SaveAddressRequest request) { var user = await _userManager.FindByEmailAsync(email); if (user is null) { return NotFound(); } try { var address = await _profileService.SaveAddressAsync(user.Id, new SaveUserAddressRequest( request.Id, request.Label, request.RecipientName, request.RecipientPhone, request.CountryCode, request.PostalCode, request.StateRegion, request.City, request.District, request.AddressLine1, request.AddressLine2, request.CompanyName, request.Usage, request.IsDefault, request.AddressMetaJson)); return Ok(address); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } [Authorize(Policy = "ProfileAddressesWrite")] [HttpDelete("addresses/by-email/{id:guid}")] public async Task DeleteAddressByEmail(Guid id, [FromQuery] string email) { var user = await _userManager.FindByEmailAsync(email); if (user is null) { return NotFound(); } try { await _profileService.DeleteAddressAsync(user.Id, id); return NoContent(); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } [Authorize(Policy = "ProfileSubscriptionsRead")] [HttpGet("subscriptions/by-email")] public async Task SubscriptionsByEmail([FromQuery] string email) { return Ok(await _newsletterService.ListSubscriptionsByEmailAsync(email)); } [Authorize(Policy = "ProfileSubscriptionsWrite")] [HttpPost("subscriptions/by-email/{id:guid}/unsubscribe")] public async Task UnsubscribeByEmail(Guid id, [FromQuery] string email) { var subscription = await _newsletterService.UnsubscribeByEmailAsync(email, id); return subscription is null ? NotFound() : Ok(subscription); } }