@using Microsoft.AspNetCore.WebUtilities @inject NavigationManager Navigation @if (IsAuthenticated) { @AuthenticatedView } else if (IsCodeRequest) { @PostAuthView } else { if (IsAuthStateChecking) { if (Loader != null) { @Loader } } else { @PreAuthView } } @code { [Parameter] public RenderFragment PreAuthView { get; set; } [Parameter] public RenderFragment PostAuthView { get; set; } [Parameter] public RenderFragment AuthenticatedView { get; set; } [Parameter] public RenderFragment? Loader { get; set; } [Parameter] public Func> GetAuthState { get; set; } [Parameter] public Func> GetLoginUrl { get; set; } [Parameter] public Func> HandleCode { get; set; } private bool IsAuthStateChecking = true; private bool IsCodeRequest = false; private bool IsAuthenticated = false; private string Code; protected override async Task OnAfterRenderAsync(bool firstRender) { if (!firstRender) return; await Load(); } private async Task Load() { IsAuthenticated = false; IsAuthStateChecking = true; IsCodeRequest = HandleQueryCode(); await InvokeAsync(StateHasChanged); if (IsCodeRequest) { var codeCorrect = await HandleCode.Invoke(Code); if (codeCorrect) { IsAuthenticated = true; await InvokeAsync(StateHasChanged); return; } } IsAuthenticated = await GetAuthState.Invoke(); IsAuthStateChecking = false; await InvokeAsync(StateHasChanged); var url = await GetLoginUrl.Invoke(); Navigation.NavigateTo(url, true); } public async Task Reload() => await Load(); private bool HandleQueryCode() { var uri = new Uri(Navigation.Uri); var query = QueryHelpers.ParseQuery(uri.Query); if (!query.TryGetValue("code", out var codeValues)) return false; if (codeValues.Count == 0) return false; var code = codeValues.First(); if (string.IsNullOrEmpty(code)) return false; Code = code; return true; } }