@page "/login" @rendermode InteractiveServer @attribute [AllowAnonymous] @inject IJSRuntime JS @inject NavigationManager Nav @inject AuthenticationStateProvider AuthStateProvider Sign In — Chrono CCG

Chrono CCG

@if (_error is not null) {
@_error
} @if (_enrolled) { } else { }
@code { private bool _enrolled; private bool _busy; private string? _error; protected override async Task OnInitializedAsync() { var authState = await AuthStateProvider.GetAuthenticationStateAsync(); if (authState.User.Identity?.IsAuthenticated == true) { Nav.NavigateTo("/", replace: true); return; } try { using var http = new HttpClient { BaseAddress = new Uri(Nav.BaseUri) }; var status = await http.GetFromJsonAsync("/api/auth/status"); _enrolled = status?.Enrolled ?? false; } catch { _enrolled = false; } } private async Task SignIn() { _busy = true; _error = null; try { await JS.InvokeVoidAsync("passkeyLogin"); Nav.NavigateTo("/", true); } catch (Exception ex) { _error = ex.Message; } finally { _busy = false; } } private async Task Enroll() { _busy = true; _error = null; try { await JS.InvokeVoidAsync("passkeyEnroll"); Nav.NavigateTo("/", true); } catch (Exception ex) { _error = ex.Message; } finally { _busy = false; } } private record StatusResponse(bool Enrolled, bool Authenticated); }