mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 12:11:56 +00:00
fix: fix wrong password messaging
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
Reference in New Issue
Block a user