Settings: change the login's password, or delete the login
A Login section in Settings changes the root's password (the current one given) and deletes the whole login, every persona with it, after its password and an explicit "I understand"; the client then signs out. Both use PrivaPub's existing /clientapi/user routes. The e2e signs up a login of its own, changes its password and deletes it, checking each against PrivaPub's login. Signing in now waits for either the feed or an enabled persona chooser, so a login with one persona (which goes on by itself) and a new persona's empty feed both sign in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
0bbab720a5
commit
228708c328
11 files changed
+258
-6
No files matched your search
@@ -0,0 +1,76 @@
|
||||
@inherits LocalizableComponentBase
|
||||
|
||||
@* The login itself (the root, /clientapi/user): its password changed, or the whole of it deleted, every persona with
|
||||
it. Deleting it deletes everything public its personas had, and PrivaPub tells the servers that hold it. *@
|
||||
<div class="flex flex-col gap-4 w-full" data-account>
|
||||
<EditForm Model="password" OnValidSubmit="ChangePassword" class="flex flex-col gap-2 p-3 rounded-xl neo-inset neo-2xs" data-account-password>
|
||||
<DataAnnotationsValidator />
|
||||
<b class="text-sm">@Localizer["Change the password"]</b>
|
||||
<DInput TValue="string" type="password" @bind-Value="password.OldPassword" Immediate="true" autocomplete="current-password"
|
||||
placeholder="@Localizer["Current password"]" data-account-current />
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<DInput TValue="string" type="password" class="flex-1 min-w-40" @bind-Value="password.NewPassword" Immediate="true" autocomplete="new-password"
|
||||
placeholder="@Localizer["New password"]" data-account-new />
|
||||
<DInput TValue="string" type="password" class="flex-1 min-w-40" @bind-Value="password.RepeatedPassword" Immediate="true" autocomplete="new-password"
|
||||
placeholder="@Localizer["Repeat the new password"]" data-account-repeat />
|
||||
</div>
|
||||
<ErrorViewer />
|
||||
<DButton Type="submit" Size="DSize.Sm" Color="DColor.Primary" class="self-end" Disabled="@(IsDefaultDisabled || isSaving)" data-account-password-save>
|
||||
<i class="ion-md-key"></i><span>@Localizer["Change the password"]</span>
|
||||
</DButton>
|
||||
</EditForm>
|
||||
|
||||
<EditForm Model="removal" OnValidSubmit="Delete" class="flex flex-col gap-2 p-3 rounded-xl neo-inset neo-2xs" data-account-delete>
|
||||
<DataAnnotationsValidator />
|
||||
<b class="text-sm text-error">@Localizer["Delete this login"]</b>
|
||||
<p class="text-sm">@Localizer["Every persona of this login goes with it, and everything public they had, here and on the servers that hold it. It cannot be undone."]</p>
|
||||
<DInput TValue="string" type="password" @bind-Value="removal.Password" Immediate="true" autocomplete="current-password"
|
||||
placeholder="@Localizer["Current password"]" data-account-delete-password />
|
||||
<DCheckbox @bind-Value="understood" Size="DSize.Sm" LabelText="@Localizer["I understand: delete this login and every persona of it"]" data-account-delete-understood />
|
||||
<ErrorViewer />
|
||||
<DButton Type="submit" Size="DSize.Sm" Color="DColor.Error" class="self-end" Disabled="@(IsDefaultDisabled || isSaving || !understood)" data-account-delete-confirm>
|
||||
<i class="ion-md-trash"></i><span>@Localizer["Delete it for good"]</span>
|
||||
</DButton>
|
||||
</EditForm>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Inject] AuthService AuthService { get; set; }
|
||||
|
||||
UserPasswordForm password = new();
|
||||
RemoveSelfForm removal = new();
|
||||
bool understood;
|
||||
bool isSaving;
|
||||
|
||||
protected override void OnInitialized() => IsLoading = false;
|
||||
|
||||
async Task ChangePassword()
|
||||
{
|
||||
isSaving = true;
|
||||
var result = await AuthService.ChangePassword(password);
|
||||
isSaving = false;
|
||||
if (result.IsInvalid)
|
||||
{
|
||||
Toast.AddResponseError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
password = new();
|
||||
Toast.AddResponseSuccess(Localizer["Password changed."]);
|
||||
}
|
||||
|
||||
async Task Delete()
|
||||
{
|
||||
isSaving = true;
|
||||
var result = await AuthService.DeleteAccount(removal);
|
||||
isSaving = false;
|
||||
if (result.IsInvalid)
|
||||
{
|
||||
Toast.AddResponseError(result);
|
||||
return;
|
||||
}
|
||||
|
||||
await CascadingState.SignOut();
|
||||
Navigation.NavigateTo("login");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user