using MailApi.Models; using MailApi.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; namespace MailApi.Controllers; [ApiController] [Route("api/[controller]")] public class MailController : ControllerBase { private readonly MailStore _mail; public MailController(MailStore mail) { _mail = mail; } [HttpGet("characters/{characterId}")] [Authorize(Roles = "USER,SUPER")] public async Task GetMailbox(string characterId) { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); if (string.IsNullOrWhiteSpace(userId)) return Unauthorized(); var access = await _mail.ResolveCharacterAsync(characterId, userId, User.IsInRole("SUPER")); if (!access.Exists) return NotFound(); if (!access.IsAuthorized) return Forbid(); var inbox = await _mail.GetInboxAsync(characterId); var sent = await _mail.GetSentAsync(characterId); return Ok(new MailboxResponse { CharacterId = characterId, Inbox = inbox.Select(MailMessageResponse.FromModel).ToList(), Sent = sent.Select(MailMessageResponse.FromModel).ToList() }); } [HttpPost("characters/{characterId}/send")] [Authorize(Roles = "USER,SUPER")] public async Task Send(string characterId, [FromBody] SendMailRequest req) { if (string.IsNullOrWhiteSpace(req.RecipientCharacterName)) return BadRequest("recipientCharacterName required"); if (string.IsNullOrWhiteSpace(req.Subject)) return BadRequest("subject required"); if (string.IsNullOrWhiteSpace(req.Body)) return BadRequest("body required"); var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); if (string.IsNullOrWhiteSpace(userId)) return Unauthorized(); var access = await _mail.ResolveCharacterAsync(characterId, userId, User.IsInRole("SUPER")); if (!access.Exists) return NotFound(); if (!access.IsAuthorized) return Forbid(); var result = await _mail.SendAsync(characterId, req.RecipientCharacterName, req.Subject, req.Body); return result.Status switch { MailStore.SendMailStatus.SenderNotFound => NotFound("Sender character not found"), MailStore.SendMailStatus.RecipientNotFound => NotFound("Recipient character not found"), MailStore.SendMailStatus.RecipientAmbiguous => Conflict("Recipient character name is ambiguous"), MailStore.SendMailStatus.Invalid => BadRequest("Invalid recipient"), _ => Ok(MailMessageResponse.FromModel(result.Message!)) }; } [HttpPost("characters/{characterId}/messages/{messageId}/read")] [Authorize(Roles = "USER,SUPER")] public async Task MarkRead(string characterId, string messageId) { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); if (string.IsNullOrWhiteSpace(userId)) return Unauthorized(); var access = await _mail.ResolveCharacterAsync(characterId, userId, User.IsInRole("SUPER")); if (!access.Exists) return NotFound(); if (!access.IsAuthorized) return Forbid(); var message = await _mail.MarkReadAsync(characterId, messageId); return message is null ? NotFound() : Ok(MailMessageResponse.FromModel(message)); } }