@page "/settings/account" @using Iceshrimp.Frontend.Core.Services @using Iceshrimp.Frontend.Localization @using Microsoft.AspNetCore.Authorization @using Microsoft.Extensions.Localization @using Microsoft.AspNetCore.Components.Sections @using Iceshrimp.Assets.PhosphorIcons @using Iceshrimp.Frontend.Core.Miscellaneous @using Iceshrimp.Shared.Schemas.Web @using Iceshrimp.Frontend.Components @attribute [Authorize] @layout SettingsLayout @inject ApiService Api; @inject ILogger Logger; @inject IStringLocalizer Loc; @inject IJSRuntime Js; @Loc["Account"] @if (State is State.Loaded) {

@Loc["Settings"]

@Loc["Save changes"] @Loc["Saved"] @Loc["Loading"] @Loc["Error"]

@Loc["Two-Factor Authentication"]

@if (SettingsForm.TwoFactorEnrolled == false) { } @if (SettingsForm.TwoFactorEnrolled) { } @if (TwoFactorResponse is not null) {

@Loc["Two-Factor Authentication"]

@Loc["Two-Factor secret"]
@TwoFactorResponse.Secret
@Loc["Two-Factor URL"]
@TwoFactorResponse.Url
@Loc["Processing"] @Loc["Failed to enroll"] @Loc["Two-Factor Authentication enabled!"] @Loc["Confirm 2FA Code"]
}

@Loc["Two-Factor Authentication"]

@Loc["Processing"] @Loc["Failed to disable Two-Factor Authentication"] @Loc["Two-Factor Authentication disabled!"] @Loc["Disable Two-Factor Authentication"]
} @code { private UserSettingsResponse SettingsForm { get; set; } = null!; private State State { get; set; } = State.Loading; private StateButton SaveButton { get; set; } = null!; private StateButton DisableButton { get; set; } = null!; private StateButton TwoFactorButton { get; set; } = null!; private ElementReference EnrollDialog { get; set; } private ElementReference DisableDialog { get; set; } private TwoFactorEnrollmentResponse? TwoFactorResponse { get; set; } private string? OtpEnable { get; set; } private string? OtpDisable { get; set; } private readonly Lazy> _moduleTask; public Account() { _moduleTask = new Lazy>(() => Js.InvokeAsync( "import", "./Pages/Settings/Account.razor.js") .AsTask()); } protected override async Task OnInitializedAsync() { SettingsForm = await Api.Settings.GetSettingsAsync(); State = State.Loaded; } private async Task Submit() { try { var res = await Api.Settings.UpdateSettingsAsync(SettingsForm); SaveButton.State = StateButton.StateEnum.Loading; StateHasChanged(); SaveButton.State = res ? StateButton.StateEnum.Success : StateButton.StateEnum.Failed; } catch (ApiException) { SaveButton.State = StateButton.StateEnum.Failed; } } private async Task Enroll2FA() { var module = await _moduleTask.Value; TwoFactorResponse = await Api.Settings.EnrollTwoFactorAsync(); await module.InvokeVoidAsync("openDialog", EnrollDialog); } private async Task Disable2FAMenu() { var module = await _moduleTask.Value; await module.InvokeVoidAsync("openDialog", DisableDialog); } private async Task Disable2FA() { var module = await _moduleTask.Value; if (OtpDisable is null) { return; } try { DisableButton.State = StateButton.StateEnum.Loading; StateHasChanged(); await Api.Settings.DisableTwoFactorAsync(new TwoFactorRequest { Code = OtpDisable }); DisableButton.State = StateButton.StateEnum.Success; StateHasChanged(); await Task.Delay(1000); SettingsForm = await Api.Settings.GetSettingsAsync(); await module.InvokeVoidAsync("closeDialog", DisableDialog); } catch (ApiException e) { Logger.LogError(e, "2FA enrollment failed"); DisableButton.State = StateButton.StateEnum.Failed; } } private async Task Confirm2FA() { var module = await _moduleTask.Value; if (OtpEnable is null) { return; } try { TwoFactorButton.State = StateButton.StateEnum.Loading; StateHasChanged(); await Api.Settings.ConfirmTwoFactorAsync(new TwoFactorRequest { Code = OtpEnable }); TwoFactorButton.State = StateButton.StateEnum.Success; StateHasChanged(); await Task.Delay(1000); SettingsForm = await Api.Settings.GetSettingsAsync(); await module.InvokeVoidAsync("closeDialog", EnrollDialog); } catch (ApiException e) { Logger.LogError(e, "2FA enrollment failed"); TwoFactorButton.State = StateButton.StateEnum.Failed; } } private async Task CloseDialog(ElementReference dialog) { var module = await _moduleTask.Value; await module.InvokeVoidAsync("closeDialog", dialog); } }