Skip to content

Commit 9ae5db3

Browse files
committed
identity: simplify user sign up
1 parent d5790d8 commit 9ae5db3

File tree

13 files changed

+222
-209
lines changed

13 files changed

+222
-209
lines changed

Notesnook.API/Controllers/UsersController.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ You should have received a copy of the Affero GNU General Public License
3333
using Streetwriters.Common.Accessors;
3434
using Streetwriters.Common.Extensions;
3535
using Streetwriters.Common.Messages;
36+
using Streetwriters.Common.Models;
3637

3738
namespace Notesnook.API.Controllers
3839
{
@@ -43,12 +44,11 @@ public class UsersController(IUserService UserService, WampServiceAccessor servi
4344
{
4445
[HttpPost]
4546
[AllowAnonymous]
46-
public async Task<IActionResult> Signup()
47+
public async Task<IActionResult> Signup([FromForm] SignupForm form)
4748
{
4849
try
4950
{
50-
await UserService.CreateUserAsync();
51-
return Ok();
51+
return Ok(await UserService.CreateUserAsync(form));
5252
}
5353
catch (Exception ex)
5454
{

Notesnook.API/Interfaces/IUserService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@ You should have received a copy of the Affero GNU General Public License
2020
using System.Threading.Tasks;
2121
using Notesnook.API.Models;
2222
using Notesnook.API.Models.Responses;
23+
using Streetwriters.Common.Models;
2324

2425
namespace Notesnook.API.Interfaces
2526
{
2627
public interface IUserService
2728
{
28-
Task CreateUserAsync();
29+
Task<SignupResponse> CreateUserAsync(SignupForm form);
2930
Task DeleteUserAsync(string userId);
3031
Task DeleteUserAsync(string userId, string? jti, string password);
3132
Task<bool> ResetUserAsync(string userId, bool removeAttachments);

Notesnook.API/Models/Responses/SignupResponse.cs

Lines changed: 0 additions & 14 deletions
This file was deleted.

Notesnook.API/Services/UserService.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,16 @@ public class UserService(IHttpContextAccessor accessor,
5151
private IS3Service S3Service { get; set; } = s3Service;
5252
private readonly IUnitOfWork unit = unitOfWork;
5353

54-
public async Task CreateUserAsync()
54+
public async Task<SignupResponse> CreateUserAsync(SignupForm form)
5555
{
56-
SignupResponse response = await httpClient.ForwardAsync<SignupResponse>(this.HttpContextAccessor, $"{Servers.IdentityServer}/signup", HttpMethod.Post);
57-
if (!response.Success || (response.Errors != null && response.Errors.Length > 0) || response.UserId == null)
56+
SignupResponse response = await serviceAccessor.UserAccountService.CreateUserAsync(form.ClientId, form.Email, form.Password, HttpContextAccessor.HttpContext?.Request.Headers["User-Agent"].ToString());
57+
58+
if ((response.Errors != null && response.Errors.Length > 0) || response.UserId == null)
5859
{
5960
logger.LogError("Failed to sign up user: {Response}", JsonSerializer.Serialize(response));
6061
if (response.Errors != null && response.Errors.Length > 0)
6162
throw new Exception(string.Join(" ", response.Errors));
62-
else throw new Exception("Could not create a new account. Error code: " + response.StatusCode);
63+
else throw new Exception("Could not create a new account.");
6364
}
6465

6566
await Repositories.UsersSettings.InsertAsync(new UserSettings
@@ -84,7 +85,7 @@ await Repositories.UsersSettings.InsertAsync(new UserSettings
8485
});
8586
}
8687

87-
logger.LogInformation("New user created: {Response}", JsonSerializer.Serialize(response));
88+
return response;
8889
}
8990

9091
public async Task<UserResponse> GetUserAsync(string userId)

Streetwriters.Common/Interfaces/IUserAccountService.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ public interface IUserAccountService
1616
Task<bool> ResetPasswordAsync(string userId, string newPassword);
1717
[WampProcedure("co.streetwriters.identity.users.clear_sessions")]
1818
Task<bool> ClearSessionsAsync(string userId, string clientId, bool all, string jti, string? refreshToken);
19+
[WampProcedure("co.streetwriters.identity.users.create_user")]
20+
Task<SignupResponse> CreateUserAsync(string clientId, string email, string password, string? userAgent = null);
1921
}
2022
}

Streetwriters.Identity/Models/SignupForm.cs renamed to Streetwriters.Common/Models/SignupForm.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ You should have received a copy of the Affero GNU General Public License
2121
using System.Runtime.Serialization;
2222
using Microsoft.AspNetCore.Mvc;
2323

24-
namespace Streetwriters.Identity.Models
24+
namespace Streetwriters.Common.Models
2525
{
2626
public class SignupForm
2727
{
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Text.Json.Serialization;
4+
using Streetwriters.Common.Models;
5+
6+
namespace Streetwriters.Common.Models
7+
{
8+
public class SignupResponse
9+
{
10+
[JsonPropertyName("access_token")]
11+
public string AccessToken { get; set; }
12+
[JsonPropertyName("expires_in")]
13+
public int AccessTokenLifetime { get; set; }
14+
[JsonPropertyName("refresh_token")]
15+
public string RefreshToken { get; set; }
16+
[JsonPropertyName("scope")]
17+
public string Scope { get; set; }
18+
[JsonPropertyName("user_id")]
19+
public string UserId { get; set; }
20+
public string[]? Errors { get; set; }
21+
22+
public static SignupResponse Error(IEnumerable<string> errors)
23+
{
24+
return new SignupResponse
25+
{
26+
Errors = [.. errors]
27+
};
28+
}
29+
}
30+
}

Streetwriters.Identity/Controllers/AccountController.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ You should have received a copy of the Affero GNU General Public License
3838
using Streetwriters.Common.Messages;
3939
using Streetwriters.Common.Models;
4040
using Streetwriters.Identity.Enums;
41+
using Streetwriters.Identity.Extensions;
4142
using Streetwriters.Identity.Interfaces;
4243
using Streetwriters.Identity.Models;
4344
using Streetwriters.Identity.Services;
@@ -125,7 +126,7 @@ public async Task<IActionResult> SendVerificationEmail([FromForm] string newEmai
125126
{
126127
ArgumentNullException.ThrowIfNull(user.Email);
127128
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
128-
var callbackUrl = Url.TokenLink(user.Id.ToString(), code, client.Id, TokenType.CONFRIM_EMAIL);
129+
var callbackUrl = UrlExtensions.TokenLink(user.Id.ToString(), code, client.Id, TokenType.CONFRIM_EMAIL);
129130
await EmailSender.SendConfirmationEmailAsync(user.Email, callbackUrl, client);
130131
}
131132
else
@@ -158,7 +159,7 @@ public async Task<IActionResult> ResetUserPassword([FromForm] ResetPasswordForm
158159
if (!await UserService.IsUserValidAsync(UserManager, user, form.ClientId)) return Ok();
159160

160161
var code = await UserManager.GenerateUserTokenAsync(user, TokenOptions.DefaultProvider, "ResetPassword");
161-
var callbackUrl = Url.TokenLink(user.Id.ToString(), code, client.Id, TokenType.RESET_PASSWORD);
162+
var callbackUrl = UrlExtensions.TokenLink(user.Id.ToString(), code, client.Id, TokenType.RESET_PASSWORD);
162163
#if (DEBUG || STAGING)
163164
return Ok(callbackUrl);
164165
#else

Streetwriters.Identity/Controllers/SignupController.cs

Lines changed: 0 additions & 156 deletions
This file was deleted.

Streetwriters.Identity/Extensions/UrlExtensions.cs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,24 @@ You should have received a copy of the Affero GNU General Public License
2525
using Streetwriters.Identity.Controllers;
2626
using Streetwriters.Identity.Enums;
2727

28-
namespace Microsoft.AspNetCore.Mvc
28+
namespace Streetwriters.Identity.Extensions
2929
{
30-
public static class UrlHelperExtensions
30+
public static class UrlExtensions
3131
{
32-
public static string? TokenLink(this IUrlHelper urlHelper, string userId, string code, string clientId, TokenType type)
32+
public static string? TokenLink(string userId, string code, string clientId, TokenType type)
3333
{
34-
35-
return urlHelper.ActionLink(
34+
var url = new UriBuilder();
3635
#if (DEBUG || STAGING)
37-
host: $"{Servers.IdentityServer.Hostname}:{Servers.IdentityServer.Port}",
38-
protocol: "http",
36+
url.Host = $"{Servers.IdentityServer.Hostname}";
37+
url.Port = Servers.IdentityServer.Port;
38+
url.Scheme = "http";
3939
#else
40-
host: Servers.IdentityServer.PublicURL.Host,
41-
protocol: Servers.IdentityServer.PublicURL.Scheme,
40+
url.Host = Servers.IdentityServer.PublicURL.Host;
41+
url.Scheme = Servers.IdentityServer.PublicURL.Scheme;
4242
#endif
43-
action: nameof(AccountController.ConfirmToken),
44-
controller: "Account",
45-
values: new { userId, code, clientId, type });
46-
43+
url.Path = "account/confirm";
44+
url.Query = $"userId={Uri.EscapeDataString(userId)}&code={Uri.EscapeDataString(code)}&clientId={Uri.EscapeDataString(clientId)}&type={Uri.EscapeDataString(type.ToString())}";
45+
return url.ToString();
4746
}
4847
}
4948
}

0 commit comments

Comments
 (0)