fix: fix wrong password messaging

This commit is contained in:
waterplea
2024-07-12 11:14:45 +05:00
parent d235ebaac9
commit 0f5cec0a60
9 changed files with 170 additions and 115 deletions

View File

@@ -6,6 +6,10 @@ import {
LoadingService,
StartOSDiskInfo,
} from '@start9labs/shared'
import {
PasswordPromptComponent,
PromptOptions,
} from 'src/app/modals/password-prompt.component'
import {
BackupInfo,
CifsBackupTarget,
@@ -14,7 +18,6 @@ import {
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { MappedBackupTarget } from 'src/app/types/mapped-backup-target'
import { AppRecoverSelectPage } from '../app-recover-select/app-recover-select.page'
import { PasswordPromptModal } from './password-prompt.modal'
@Component({
selector: 'backup-server-select',
@@ -38,24 +41,35 @@ export class BackupServerSelectModal {
async presentModalPassword(
serverId: string,
server: StartOSDiskInfo,
{ passwordHash }: StartOSDiskInfo,
): Promise<void> {
const options: PromptOptions = {
title: 'Password Required',
message:
'Enter the password that was used to encrypt this backup. On the next screen, you will select the individual services you want to restore.',
label: 'Decrypt Backup',
placeholder: 'Enter password',
buttonText: 'Next',
}
const modal = await this.modalCtrl.create({
component: PasswordPromptModal,
component: PasswordPromptComponent,
componentProps: { options },
canDismiss: async password => {
if (password === null) {
return true
}
try {
argon2.verify(passwordHash!, password)
await this.restoreFromBackup(serverId, password)
return true
} catch (e: any) {
this.errorService.handleError(e)
return false
}
},
})
modal.present()
const { data, role } = await modal.onWillDismiss()
if (role === 'confirm') {
try {
// @TODO Alex if invalid password, we should tell the user "Invalid password" and halt execution of this function. The modal should remain so the user can try again. Correct password is asdfasdf
argon2.verify(server.passwordHash!, data)
await this.restoreFromBackup(serverId, data)
} catch (e: any) {
this.errorService.handleError(e)
}
}
}
private async restoreFromBackup(

View File

@@ -1,14 +1,29 @@
import { Component } from '@angular/core'
import {
AfterViewInit,
Component,
ElementRef,
Input,
ViewChild,
} from '@angular/core'
import { FormsModule } from '@angular/forms'
import { IonicModule, ModalController } from '@ionic/angular'
import { TuiTextfieldComponent } from '@taiga-ui/core'
import { TuiInputPasswordModule } from '@taiga-ui/kit'
export interface PromptOptions {
title: string
message: string
label: string
placeholder: string
buttonText: string
}
@Component({
standalone: true,
template: `
<ion-header>
<ion-toolbar>
<ion-title>Decrypt Backup</ion-title>
<ion-title>{{ options.title }}</ion-title>
<ion-buttons slot="end">
<ion-button (click)="cancel()">
<ion-icon slot="icon-only" name="close"></ion-icon>
@@ -18,13 +33,11 @@ import { TuiInputPasswordModule } from '@taiga-ui/kit'
</ion-header>
<ion-content class="ion-padding">
<p>{{ options.message }}</p>
<p>
Enter the password that was used to encrypt this backup. On the next
screen, you will select the individual services you want to restore.
</p>
<p>
<tui-input-password [(ngModel)]="password">
Enter password
<tui-input-password [(ngModel)]="password" (keydown.enter)="confirm()">
{{ options.label }}
<input tuiTextfield [placeholder]="options.placeholder" />
</tui-input-password>
</p>
</ion-content>
@@ -47,18 +60,30 @@ import { TuiInputPasswordModule } from '@taiga-ui/kit'
[disabled]="!password"
(click)="confirm()"
>
Next
{{ options.buttonText }}
</ion-button>
</ion-toolbar>
</ion-footer>
`,
imports: [IonicModule, FormsModule, TuiInputPasswordModule],
})
export class PasswordPromptModal {
export class PasswordPromptComponent implements AfterViewInit {
@ViewChild(TuiTextfieldComponent, { read: ElementRef })
input?: ElementRef<HTMLInputElement>
@Input()
options!: PromptOptions
password = ''
constructor(private modalCtrl: ModalController) {}
ngAfterViewInit() {
setTimeout(() => {
this.input?.nativeElement.focus({ preventScroll: true })
}, 300)
}
cancel() {
return this.modalCtrl.dismiss(null, 'cancel')
}