Implement responsive profile and account data controls
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using QuestionsApi.Models;
|
||||
using QuestionsApi.Services;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace QuestionsApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/profile")]
|
||||
public sealed class ProfileController(UserProfileStore profiles, IConfiguration configuration) : ControllerBase
|
||||
{
|
||||
[HttpGet("me/preferences")]
|
||||
[Authorize(Roles = "USER,SUPER")]
|
||||
public async Task<IActionResult> GetPreferences()
|
||||
{
|
||||
var profile = await profiles.GetAsync(UserId());
|
||||
return Ok(profile ?? new UserStudyProfile { UserId = UserId() });
|
||||
}
|
||||
|
||||
[HttpPut("me/preferences")]
|
||||
[Authorize(Roles = "USER,SUPER")]
|
||||
public async Task<IActionResult> UpdatePreferences(UpdateUserStudyProfileRequest request)
|
||||
{
|
||||
if (UserStudyProfileValidator.Validate(request) is { } error) return BadRequest(error);
|
||||
return Ok(await profiles.UpsertAsync(UserId(), request));
|
||||
}
|
||||
|
||||
[HttpGet("me/export")]
|
||||
[Authorize(Roles = "USER,SUPER")]
|
||||
public async Task<IActionResult> Export() => Ok(new
|
||||
{
|
||||
schemaVersion = 1,
|
||||
exportedUtc = DateTime.UtcNow,
|
||||
userId = UserId(),
|
||||
records = await profiles.ExportAsync(UserId())
|
||||
});
|
||||
|
||||
[HttpDelete("internal/users/{userId}")]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Purge(string userId)
|
||||
{
|
||||
var expected = configuration["InternalPurge:Secret"];
|
||||
var supplied = Request.Headers["X-MedMind-Internal-Key"].FirstOrDefault();
|
||||
if (string.IsNullOrWhiteSpace(expected) || !CryptographicOperations.FixedTimeEquals(
|
||||
System.Text.Encoding.UTF8.GetBytes(expected),
|
||||
System.Text.Encoding.UTF8.GetBytes(supplied ?? "")))
|
||||
return Unauthorized();
|
||||
await profiles.PurgeAsync(userId);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
private string UserId() => User.FindFirstValue(ClaimTypes.NameIdentifier)
|
||||
?? User.FindFirstValue(ClaimTypes.Name)
|
||||
?? User.Identity?.Name
|
||||
?? throw new UnauthorizedAccessException();
|
||||
}
|
||||
Reference in New Issue
Block a user