Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Commit

Permalink
feat(auth): add register
Browse files Browse the repository at this point in the history
  • Loading branch information
foxminchan committed May 12, 2024
1 parent b44f2ce commit 2e788a3
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

<button class="btn btn-primary" name="Input.Button" value="login">Login</button>
<button class="btn btn-secondary" name="Input.Button" value="cancel">Cancel</button>
<button class="btn btn-secondary" name="Input.Button" value="register">Register</button>
</form>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ public async Task<IActionResult> OnPost()
// check if we are in the context of an authorization request
var context = await interaction.GetAuthorizationContextAsync(Input.ReturnUrl);

if (Input.Button == "register")
return RedirectToPage("/Account/Register/Index", new { returnUrl = Input.ReturnUrl });

// the user clicked the "cancel" button
if (Input.Button != "login")
{
Expand Down Expand Up @@ -136,7 +139,7 @@ private async Task BuildModelAsync(string? returnUrl)

Input.Username = context.LoginHint;

if (!local) View.ExternalProviders = new[] { new ViewModel.ExternalProvider(context.IdP) };
if (!local) View.ExternalProviders = [new(context.IdP)];

return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public sealed class ViewModel
public bool AllowRememberLogin { get; set; } = true;
public bool EnableLocalLogin { get; set; } = true;

public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = Enumerable.Empty<ExternalProvider>();
public IEnumerable<ExternalProvider> ExternalProviders { get; set; } = [];

public IEnumerable<ExternalProvider> VisibleExternalProviders =>
ExternalProviders.Where(x => !string.IsNullOrWhiteSpace(x.DisplayName));
Expand Down
49 changes: 49 additions & 0 deletions src/RookieShop.IdentityService/Pages/Account/Register/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@page
@model RookieShop.IdentityService.Pages.Account.Register.Index

<div class="register-page">
<div class="lead">
<h1>Create a new account</h1>
</div>

<partial name="_ValidationSummary"/>

<form asp-page="/Account/Register/Index">
<input type="hidden" asp-for="Input.ReturnUrl"/>
<div class="form-group">
<label asp-for="Input.Username" class="col-md-2 control-label">Username</label>
<div class="col-md-10">
<input asp-for="Input.Username" placeholder="example@gmail.com" class="form-control" autofocus/>
<span asp-validation-for="Input.Username" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Input.PhoneNumber" class="col-md-2 control-label">Confirm Password</label>
<div class="col-md-10">
<input asp-for="Input.PhoneNumber" placeholder="0123456789" class="form-control"/>
<span asp-validation-for="Input.PhoneNumber" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Input.Password" class="col-md-2 control-label">Password</label>
<div class="col-md-10">
<input asp-for="Input.Password" class="form-control"/>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Input.ConfirmPassword" class="col-md-2 control-label">Confirm Password</label>
<div class="col-md-10">
<input asp-for="Input.ConfirmPassword" class="form-control"/>
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button class="btn btn-primary" name="Input.Button" value="register">Register</button>
<button class="btn btn-secondary" name="Input.Button" value="cancel">Cancel</button>
</div>
</div>
</form>

</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using RookieShop.IdentityService.Models;

namespace RookieShop.IdentityService.Pages.Account.Register;

[SecurityHeaders]
[AllowAnonymous]
public sealed class Index(UserManager<ApplicationUser> userManager) : PageModel
{
[BindProperty] public InputModel Input { get; set; } = default!;

public async Task<IActionResult> OnGet(string? returnUrl)
{
Input = new()
{
ReturnUrl = returnUrl
};

return Page();
}

public async Task<IActionResult> OnPost()
{
if (Input.Button != "register")
return RedirectToPage("/Account/Login/Index", new { returnUrl = Input.ReturnUrl });

if (!ModelState.IsValid)
return Page();

if (Input.Username is null || Input.Password is null || Input.PhoneNumber is null)
return Page();

var user = await userManager.FindByNameAsync(Input.Username);

if (user is not null)
{
ModelState.AddModelError("Username", "Username is already taken");
return Page();
}

user = new()
{
UserName = Input.Username,
PhoneNumber = Input.PhoneNumber
};

var result = await userManager.CreateAsync(user, Input.Password);

if (!result.Succeeded)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}

return Page();
}

await userManager.AddToRoleAsync(user, "user");

return RedirectToPage("/Account/Login/Index", new { returnUrl = Input.ReturnUrl });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.ComponentModel.DataAnnotations;

namespace RookieShop.IdentityService.Pages.Account.Register;

public sealed class InputModel
{
[Required]
[EmailAddress]
[MaxLength(50)]
public string? Username { get; set; }

[Required]
[RegularExpression(@"^\d{8,16}$", ErrorMessage = "Phone number must be 8-16 digits.")]
public string? PhoneNumber { get; set; }

[Required]
[RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,15}$",
ErrorMessage =
"Password must be 8-15 characters and contain at least one uppercase letter, one lowercase letter, and one digit.")]
public string? Password { get; set; }

[Required]
[Compare(nameof(Password))]
public string? ConfirmPassword { get; set; }

public string? ReturnUrl { get; set; }

public string? Button { get; set; }
}

0 comments on commit 2e788a3

Please sign in to comment.