api: move to atomic password reset

This commit is contained in:
Abdullah Atta
2026-02-13 11:13:19 +05:00
committed by Abdullah Atta
parent b9385ae112
commit 9424afed68
11 changed files with 203 additions and 83 deletions

View File

@@ -18,7 +18,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Net.Http;
using System.Security.Claims;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.Timeouts;
@@ -28,13 +30,16 @@ using Notesnook.API.Interfaces;
using Notesnook.API.Models;
using Notesnook.API.Models.Responses;
using Streetwriters.Common;
using Streetwriters.Common.Accessors;
using Streetwriters.Common.Extensions;
using Streetwriters.Common.Messages;
namespace Notesnook.API.Controllers
{
[ApiController]
[Authorize]
[Route("users")]
public class UsersController(IUserService UserService, ILogger<UsersController> logger) : ControllerBase
public class UsersController(IUserService UserService, WampServiceAccessor serviceAccessor, ILogger<UsersController> logger) : ControllerBase
{
[HttpPost]
[AllowAnonymous]
@@ -85,6 +90,43 @@ namespace Notesnook.API.Controllers
}
}
[HttpPatch("password/{type}")]
public async Task<IActionResult> ChangePassword([FromRoute] string type, [FromBody] ChangePasswordForm form)
{
var userId = User.GetUserId();
var clientId = User.FindFirstValue("client_id");
var jti = User.FindFirstValue("jti");
var isPasswordReset = type == "reset";
try
{
var result = isPasswordReset ? await serviceAccessor.UserAccountService.ResetPasswordAsync(userId, form.NewPassword) : await serviceAccessor.UserAccountService.ChangePasswordAsync(userId, form.OldPassword, form.NewPassword);
if (!result)
return BadRequest("Failed to change password.");
await UserService.SetUserKeysAsync(userId, form.UserKeys);
await serviceAccessor.UserAccountService.ClearSessionsAsync(userId, clientId, all: false, jti, null);
await WampServers.MessengerServer.PublishMessageAsync(MessengerServerTopics.SendSSETopic, new SendSSEMessage
{
UserId = userId,
OriginTokenId = User.FindFirstValue("jti"),
Message = new Message
{
Type = "logout",
Data = JsonSerializer.Serialize(new { reason = "Password changed." })
}
});
return Ok();
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to change password");
return BadRequest(new { error = ex.Message });
}
}
[HttpPost("reset")]
public async Task<IActionResult> Reset([FromForm] bool removeAttachments)
{