Skip to content

Commit cec5844

Browse files
committed
Start work on this
1 parent c0f6c36 commit cec5844

4 files changed

Lines changed: 57 additions & 1 deletion

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System.Net.Mime;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Asp.Versioning;
4+
using OpenShock.API.Models.Requests;
5+
using OpenShock.Common.Problems;
6+
7+
namespace OpenShock.API.Controller.Account;
8+
9+
public sealed partial class AccountController
10+
{
11+
/// <summary>
12+
/// Verify account email
13+
/// </summary>
14+
/// <response code="200"></response>
15+
[HttpPost("verify/email")]
16+
[ProducesResponseType(StatusCodes.Status200OK)]
17+
[ProducesResponseType<OpenShockProblem>(StatusCodes.Status403Forbidden, MediaTypeNames.Application.Json)]
18+
[MapToApiVersion("2")]
19+
public async Task<IActionResult> EmailVerify([FromBody] AccountVerifyEmailRequest body, CancellationToken cancellationToken)
20+
{
21+
bool ok = await _accountService.TryVerifyEmailAsync(body.Secret, cancellationToken);
22+
23+
return Ok();
24+
}
25+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace OpenShock.API.Models.Requests;
2+
3+
public sealed class AccountVerifyEmailRequest
4+
{
5+
public required string Secret { get; set; }
6+
}

API/Services/Account/AccountService.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public async Task<OneOf<Success<User>, AccountWithEmailOrUsernameExists>> Create
118118
await _db.SaveChangesAsync();
119119

120120
await _emailService.VerifyEmail(new Contact(email, username),
121-
new Uri(_frontendConfig.BaseUrl, $"/#/account/activate/{user.Id}/{secret}"));
121+
new Uri(_frontendConfig.BaseUrl, $"/account/activate/{user.Id}/{secret}"));
122122
return new Success<User>(user);
123123
}
124124

@@ -404,6 +404,23 @@ public async Task<OneOf<Success, AccountDeactivated, NotFound>> ChangePasswordAs
404404
return new Success();
405405
}
406406

407+
public async Task<bool> TryVerifyEmailAsync(string secret, CancellationToken cancellationToken = default)
408+
{
409+
var hash = HashingUtils.HashToken(secret);
410+
411+
var user = await _db.Users
412+
.Include(u => u.UserActivationRequest)
413+
.FirstOrDefaultAsync(x => x.UserActivationRequest != null && x.UserActivationRequest.SecretHash == hash, cancellationToken);
414+
if (user?.UserActivationRequest is null) return false;
415+
416+
user.ActivatedAt = DateTime.UtcNow;
417+
418+
_db.UserActivationRequests.Remove(user.UserActivationRequest);
419+
420+
await _db.SaveChangesAsync(cancellationToken);
421+
422+
return true;
423+
}
407424

408425
private async Task<bool> CheckPassword(string password, User user)
409426
{

API/Services/Account/IAccountService.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ public interface IAccountService
9494
/// <param name="newPassword"></param>
9595
/// <returns></returns>
9696
public Task<OneOf<Success, AccountDeactivated, NotFound>> ChangePasswordAsync(Guid userId, string newPassword);
97+
98+
/// <summary>
99+
///
100+
/// </summary>
101+
/// <param name="secret"></param>
102+
/// <param name="cancellationToken"></param>
103+
/// <returns></returns>
104+
Task<bool> TryVerifyEmailAsync(string secret, CancellationToken cancellationToken = default);
97105
}
98106

99107
public readonly record struct AccountDeactivated;

0 commit comments

Comments
 (0)