Skip to content

Commit

Permalink
Added new testing ability for manually generated tokens and magic lin…
Browse files Browse the repository at this point in the history
…ks. Showing claims on hello world to show which claims the user has.
  • Loading branch information
jrmccannon committed Jun 18, 2024
1 parent 1a150f2 commit 53d8f5e
Show file tree
Hide file tree
Showing 9 changed files with 437 additions and 374 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@

@if (canLogin)
{
<script src="~/js/site.js"></script>
<script type="module">
import {Client} from "/js/site.js";
async function login() {
const alias = document.getElementById("email").value;
const p = new Client(
const p = new Passwordless.Client(
{
apiKey: "@PasswordlessOptions.Value.ApiKey",
apiUrl: "@PasswordlessOptions.Value.ApiUrl"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
Expand All @@ -10,6 +12,11 @@ public class Logout(SignInManager<IdentityUser> userSignInManager, ILogger<Logou
{
public async Task<IActionResult> OnGet()
{
var userManager = userSignInManager.UserManager;

var user = await userManager.GetUserAsync(User);
if (user is not null) await userManager.RemoveClaimsAsync(user, await userManager.GetClaimsAsync(user));

await userSignInManager.SignOutAsync();
logger.LogInformation("User has signed out.");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@model Passwordless.AspNetIdentity.Example.Pages.Account.Recovery

<style lang="css">
.block-element {
display: block;
}
</style>

@{
ViewData["Title"] = "Account Recovery";
}
Expand All @@ -17,7 +23,10 @@ and a "magic link" will be used to authenticate the intended user.
<label asp-for="Form.Email">Email: </label>
<input asp-for="Form.Email" type="email" id="email" placeholder="janedoe@example.org"/>
<span class="text-danger" asp-validation-for="Form.Email"></span>
<button type="submit" class="btn-primary">Send</button>
<p>Recovery Method:</p>
<label class="block-element"><input type="radio" asp-for="Form.RecoveryMethod" value="@Recovery.GeneratedSignIn"/>Generated Sign In Token</label>
<label class="block-element"><input type="radio" asp-for="Form.RecoveryMethod" value="@Recovery.MagicLink"/>Magic Link</label>
<button type="submit" class="btn-primary block-element">Send</button>
</form>

@if (!string.IsNullOrWhiteSpace(Model.RecoveryMessage))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel.DataAnnotations;
using System.Net.Mail;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
Expand All @@ -23,6 +21,9 @@ public class Recovery : PageModel
private readonly IUrlHelperFactory _urlHelperFactory;
private readonly IActionContextAccessor _actionContextAccessor;

public const string MagicLink = "magic_link";
public const string GeneratedSignIn = "generated_signin";

public RecoveryForm Form { get; } = new();

public string RecoveryMessage { get; set; } = string.Empty;
Expand Down Expand Up @@ -61,18 +62,41 @@ public async Task<IActionResult> OnPostAsync(RecoveryForm form, CancellationToke
throw new InvalidOperationException("ActionContext is null");
}

var token = await _passwordlessClient.GenerateAuthenticationTokenAsync(new AuthenticationOptions(user.Id), cancellationToken);
var urlBuilder = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
var url = urlBuilder.PageLink("/Account/Magic") ?? urlBuilder.Content("~/");

var uriBuilder = new UriBuilder(url);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query["token"] = "";
query["token"] = string.Empty;
uriBuilder.Query = query.ToString();
var successMessage = string.Empty;

if (string.Equals(form.RecoveryMethod, MagicLink, StringComparison.OrdinalIgnoreCase))
{
await _passwordlessClient.SendMagicLinkAsync(new SendMagicLinkRequest(form.Email!, uriBuilder.Uri + "$TOKEN", user.Id, null), cancellationToken);

successMessage = "Check your API magic link destination (mail.md if running local, email if using cloud.";
}
else if (string.Equals(form.RecoveryMethod, GeneratedSignIn, StringComparison.OrdinalIgnoreCase))
{
var token = await _passwordlessClient.GenerateAuthenticationTokenAsync(new AuthenticationOptions(user.Id), cancellationToken);
query["token"] = token.Token;
uriBuilder.Query = query.ToString();

await _passwordlessClient.SendMagicLinkAsync(new SendMagicLinkRequest(form.Email!, uriBuilder.Uri + "$TOKEN", user.Id, null), cancellationToken);
var message = $"""
New message:

return RedirectToPage("Recovery", "SuccessfulRecovery", new { message = "message" });
This was generated with manually generated authentication token.
<a href="{uriBuilder}">Link<a>
{Environment.NewLine}
""";

await System.IO.File.AppendAllTextAsync("mail.md", message, cancellationToken);

successMessage = message;
}

return RedirectToPage("Recovery", "SuccessfulRecovery", new { message = successMessage });
}
}

Expand All @@ -81,4 +105,7 @@ public class RecoveryForm
[EmailAddress]
[Required]
public string? Email { get; set; }

[Required]
public string RecoveryMethod { get; set; } = string.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
<div>
<h3>Current Claims:</h3>
<ul>
@foreach (var claim in User.Claims)
@foreach (var claim in Model.Claims)
{
<li>@claim.Type : @claim.Value</li>
<li>@claim.ClaimName : @claim.ClaimValue</li>
}
</ul>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
using System.Security.Claims;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace Passwordless.AspNetIdentity.Example.Pages.Authorized;

public class HelloWorldModel(ILogger<HelloWorldModel> logger) : PageModel
public class HelloWorldModel(ILogger<HelloWorldModel> logger, UserManager<IdentityUser> userManager) : PageModel
{
public void OnGet()
public async Task OnGetAsync()
{
var identity = HttpContext.User.Identity!;
var email = User.FindFirstValue(ClaimTypes.Email)!;
AuthenticatedUser = new AuthenticatedUserModel(identity.Name!, email);
Claims = (await userManager.GetClaimsAsync((await userManager.GetUserAsync(User))!))
.Select(ClaimRecord.GetInstance)
.Concat(User.Claims.Select(ClaimRecord.GetInstance));
}

public void OnPost(string? nickname)
Expand All @@ -26,6 +34,13 @@ public void OnPost(string? nickname)
public string? Nickname { get; set; }

public bool CanAddPassKeys { get; set; }

public IEnumerable<ClaimRecord> Claims { get; set; } = ArraySegment<ClaimRecord>.Empty;
}

public record AuthenticatedUserModel(string Username, string Email);
public record AuthenticatedUserModel(string Username, string Email);

public record ClaimRecord(string ClaimName, string ClaimValue)
{
public static ClaimRecord GetInstance(Claim claim) => new(claim.Type, claim.Value);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
@{
ViewData["Title"] = "Step Up";
}

<script src="~/js/site.js"></script>
<script type="module">
import {Client} from "/js/site.js";
async function stepup() {
const p = new Client(
const p = new Passwordless.Client(
{
apiKey: "@PasswordlessOptions.Value.ApiKey",
apiUrl: "@PasswordlessOptions.Value.ApiUrl"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" type="module" asp-append-version="true"></script>

@await RenderSectionAsync("Scripts", required: false)
</body>
Expand Down
Loading

0 comments on commit 53d8f5e

Please sign in to comment.