mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 10:21:52 +00:00
fix: fix wrong password messaging
This commit is contained in:
94
web/package-lock.json
generated
94
web/package-lock.json
generated
@@ -28,12 +28,12 @@
|
||||
"@start9labs/argon2": "^0.2.2",
|
||||
"@start9labs/emver": "^0.1.5",
|
||||
"@start9labs/start-sdk": "file:../sdk/dist",
|
||||
"@taiga-ui/addon-charts": "3.84.0",
|
||||
"@taiga-ui/cdk": "3.84.0",
|
||||
"@taiga-ui/core": "3.84.0",
|
||||
"@taiga-ui/experimental": "3.84.0",
|
||||
"@taiga-ui/icons": "3.84.0",
|
||||
"@taiga-ui/kit": "3.84.0",
|
||||
"@taiga-ui/addon-charts": "3.86.0",
|
||||
"@taiga-ui/cdk": "3.86.0",
|
||||
"@taiga-ui/core": "3.86.0",
|
||||
"@taiga-ui/experimental": "3.86.0",
|
||||
"@taiga-ui/icons": "3.86.0",
|
||||
"@taiga-ui/kit": "3.86.0",
|
||||
"@tinkoff/ng-dompurify": "4.0.0",
|
||||
"@tinkoff/ng-event-plugins": "3.2.0",
|
||||
"angular-svg-round-progressbar": "^9.0.0",
|
||||
@@ -4128,9 +4128,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/addon-charts": {
|
||||
"version": "3.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.84.0.tgz",
|
||||
"integrity": "sha512-XR7UFywnrv4NRLHOCbba63gXDYYDL4Rt0MbjnF54p5U2EXnbt2of7VbjlB6cPx40XkQqfqa3CNayYxWZP82Ijg==",
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-3.86.0.tgz",
|
||||
"integrity": "sha512-Du/85qqaj8hpFSI6hPuFeIhtE93Z6WSkYZLt0gvnsaCb2qSAg8D4oHSogrtF1rsWGGoM+fvXjD7UEUw9GzFIPg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
@@ -4138,15 +4138,15 @@
|
||||
"@angular/common": ">=12.0.0",
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@taiga-ui/cdk": "^3.84.0",
|
||||
"@taiga-ui/core": "^3.84.0",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/core": "^3.86.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/addon-commerce": {
|
||||
"version": "3.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.84.0.tgz",
|
||||
"integrity": "sha512-1zqLwnZLAYYcHvjH89d7JmtV2+QeZ2YnSJ3YWEMNLjGPzpev4RvQXtDfglIyu0LCyTxqpXmuzes9v/cgq2P5TQ==",
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-3.86.0.tgz",
|
||||
"integrity": "sha512-8QSB490ckI4jnU+1sQ3x8os2GVE162hbvzPVYIZ0TruoeXl076dAz6PT2WRaFwjcaCAIGsuaQgQ4Cv02NjkiYQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
@@ -4159,18 +4159,18 @@
|
||||
"@maskito/core": "^1.9.0",
|
||||
"@maskito/kit": "^1.9.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@taiga-ui/cdk": "^3.84.0",
|
||||
"@taiga-ui/core": "^3.84.0",
|
||||
"@taiga-ui/i18n": "^3.84.0",
|
||||
"@taiga-ui/kit": "^3.84.0",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/core": "^3.86.0",
|
||||
"@taiga-ui/i18n": "^3.86.0",
|
||||
"@taiga-ui/kit": "^3.86.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/cdk": {
|
||||
"version": "3.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.84.0.tgz",
|
||||
"integrity": "sha512-0umw/CUmYNEYOCUNQVTQS53zXzxZsH/6+lj1mFVzocvfJFJWAUT6ltCH9QvxYmxSDDGWwNGg16AaVo2K+aGL0w==",
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-3.86.0.tgz",
|
||||
"integrity": "sha512-aVbnW01Oh0Er1sHKVGHP8W05mOSKxjSzFE3Qx4iF4T6KW7Rlz9HZoNx5ADMg0TATYChtWh9Kwjo8I4LSVj2ZUw==",
|
||||
"dependencies": {
|
||||
"@ng-web-apis/common": "3.0.6",
|
||||
"@ng-web-apis/mutation-observer": "3.1.0",
|
||||
@@ -4221,11 +4221,11 @@
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/@taiga-ui/core": {
|
||||
"version": "3.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.84.0.tgz",
|
||||
"integrity": "sha512-FZy77z0E4qjYcszVcp+qPFkPwJPl8qXZb7t2P+juUtJvSmSn2foQHHdyhbIYN808H26tqCdgkTMG1BWQxVuDSg==",
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-3.86.0.tgz",
|
||||
"integrity": "sha512-diQKOnPtDDfxPOMk6wLRq8nyDVfNSPSNy+1TeyqzUgOvJ6XAjfaBXGsL3iuR7AN8+sz/b3rJmBce+vdw6FjMLQ==",
|
||||
"dependencies": {
|
||||
"@taiga-ui/i18n": "^3.84.0",
|
||||
"@taiga-ui/i18n": "^3.86.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
@@ -4237,35 +4237,35 @@
|
||||
"@angular/router": ">=12.0.0",
|
||||
"@ng-web-apis/common": "^3.0.6",
|
||||
"@ng-web-apis/mutation-observer": "^3.1.0",
|
||||
"@taiga-ui/cdk": "^3.84.0",
|
||||
"@taiga-ui/i18n": "^3.84.0",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/i18n": "^3.86.0",
|
||||
"@tinkoff/ng-event-plugins": "^3.2.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/experimental": {
|
||||
"version": "3.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.84.0.tgz",
|
||||
"integrity": "sha512-q0hNVy+EmywCG8hpZlg/+haKIFhnmxicQiSeV/D1P7CHO10safjGo0ptT6e1hYMFa5/cJZOM4OwDPen2xs17Wg==",
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/experimental/-/experimental-3.86.0.tgz",
|
||||
"integrity": "sha512-ACjoRVeX5MgsNJsiu2ukliXLD2mfEWm8Vtmk78vqcnkyPUmy1ZWK4sG3p5ybFN8AdIMHkblVq0l+x2qAwr/+LQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=12.0.0",
|
||||
"@angular/core": ">=12.0.0",
|
||||
"@taiga-ui/addon-commerce": "^3.84.0",
|
||||
"@taiga-ui/cdk": "^3.84.0",
|
||||
"@taiga-ui/core": "^3.84.0",
|
||||
"@taiga-ui/kit": "^3.84.0",
|
||||
"@taiga-ui/addon-commerce": "^3.86.0",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/core": "^3.86.0",
|
||||
"@taiga-ui/kit": "^3.86.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/i18n": {
|
||||
"version": "3.85.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.85.0.tgz",
|
||||
"integrity": "sha512-CGoxfq9WY+psX5ZOfWmuQZ6OA/0CAPYJTlbHkw5sRKAyhEQ3NM/Wbx3xcwrcYRRJDnt9yOlfibz+3a+WDF2bFA==",
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-3.86.0.tgz",
|
||||
"integrity": "sha512-8zkNhMo/QtxZ2Zp6EP/nxo4SOLwaIrX+P3X/Wt+1cjFNZUYWWfdvfHLLdNviKFPVl4RAOxvkhDfza/wkrwv+iQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
@@ -4276,20 +4276,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/icons": {
|
||||
"version": "3.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.84.0.tgz",
|
||||
"integrity": "sha512-KiH7BJRZ6wbkOHlJAS0XHq2gYnQTpRgdEogKW+GoD0da/4trCdM66vhDk2j0DwDFdBGq5U0inHJCjnskBI1nSQ==",
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-3.86.0.tgz",
|
||||
"integrity": "sha512-jVBEbvE/r9JG+knmXMTn/l/js3JjYi8nSGbrLCryJZZoS2izRnQARN2txABieUJm8H463CoF0rcdXlHKRuA4Ew==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@taiga-ui/cdk": "^3.84.0"
|
||||
"@taiga-ui/cdk": "^3.86.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/kit": {
|
||||
"version": "3.84.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.84.0.tgz",
|
||||
"integrity": "sha512-lSUPDco5FeBYK3ESnXeEPLCdMCmNXwcdHNK/we+0ZoH4VPx/OGg2hpEP0Fej7jfGHwXFTzDbufQD0hT6WlfTAw==",
|
||||
"version": "3.86.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-3.86.0.tgz",
|
||||
"integrity": "sha512-naAy4pyhCaQ9+vWxqSMjbV+9KwnMxT5ybrw+MAJgMn2evzRq0FjqzyFZFog7oiRbRvgVdoWPQfBNKaaLhJcpsw==",
|
||||
"dependencies": {
|
||||
"@maskito/angular": "1.9.0",
|
||||
"@maskito/core": "1.9.0",
|
||||
@@ -4306,9 +4306,9 @@
|
||||
"@ng-web-apis/common": "3.0.6",
|
||||
"@ng-web-apis/mutation-observer": "^3.1.0",
|
||||
"@ng-web-apis/resize-observer": "^3.0.6",
|
||||
"@taiga-ui/cdk": "^3.84.0",
|
||||
"@taiga-ui/core": "^3.84.0",
|
||||
"@taiga-ui/i18n": "^3.84.0",
|
||||
"@taiga-ui/cdk": "^3.86.0",
|
||||
"@taiga-ui/core": "^3.86.0",
|
||||
"@taiga-ui/i18n": "^3.86.0",
|
||||
"@tinkoff/ng-polymorpheus": "^4.3.0",
|
||||
"rxjs": ">=6.0.0"
|
||||
}
|
||||
|
||||
@@ -51,12 +51,12 @@
|
||||
"@start9labs/argon2": "^0.2.2",
|
||||
"@start9labs/emver": "^0.1.5",
|
||||
"@start9labs/start-sdk": "file:../sdk/dist",
|
||||
"@taiga-ui/addon-charts": "3.84.0",
|
||||
"@taiga-ui/cdk": "3.84.0",
|
||||
"@taiga-ui/core": "3.84.0",
|
||||
"@taiga-ui/experimental": "3.84.0",
|
||||
"@taiga-ui/icons": "3.84.0",
|
||||
"@taiga-ui/kit": "3.84.0",
|
||||
"@taiga-ui/addon-charts": "3.86.0",
|
||||
"@taiga-ui/cdk": "3.86.0",
|
||||
"@taiga-ui/core": "3.86.0",
|
||||
"@taiga-ui/experimental": "3.86.0",
|
||||
"@taiga-ui/icons": "3.86.0",
|
||||
"@taiga-ui/kit": "3.86.0",
|
||||
"@tinkoff/ng-dompurify": "4.0.0",
|
||||
"@tinkoff/ng-event-plugins": "3.2.0",
|
||||
"angular-svg-round-progressbar": "^9.0.0",
|
||||
|
||||
@@ -15,7 +15,6 @@ export class ErrorService extends ErrorHandler {
|
||||
this.alerts
|
||||
.open(getErrorMessage(error, link), {
|
||||
label: 'Error',
|
||||
autoClose: false,
|
||||
status: TuiNotification.Error,
|
||||
})
|
||||
.subscribe()
|
||||
|
||||
@@ -32,7 +32,7 @@ export class BadgeMenuComponent {
|
||||
constructor(
|
||||
private readonly splitPane: SplitPaneTracker,
|
||||
private readonly patch: PatchDB<DataModel>,
|
||||
private readonly dialog: TuiDialogService,
|
||||
private readonly dialogs: TuiDialogService,
|
||||
private readonly clientStorageService: ClientStorageService,
|
||||
) {}
|
||||
|
||||
@@ -44,6 +44,6 @@ export class BadgeMenuComponent {
|
||||
}
|
||||
|
||||
onWidgets() {
|
||||
this.dialog.open(WIDGETS_COMPONENT, { label: 'Widgets' }).subscribe()
|
||||
this.dialogs.open(WIDGETS_COMPONENT, { label: 'Widgets' }).subscribe()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ModalController, NavController } from '@ionic/angular'
|
||||
import { LoadingService } from '@start9labs/shared'
|
||||
import { TuiDialogService } from '@taiga-ui/core'
|
||||
import { PROMPT, PromptOptions } from 'src/app/modals/prompt.component'
|
||||
import { ErrorService, LoadingService } from '@start9labs/shared'
|
||||
import {
|
||||
PasswordPromptComponent,
|
||||
PromptOptions,
|
||||
} from 'src/app/modals/password-prompt.component'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { skip, take, takeUntil } from 'rxjs/operators'
|
||||
import { skip, takeUntil } from 'rxjs/operators'
|
||||
import { MappedBackupTarget } from 'src/app/types/mapped-backup-target'
|
||||
import * as argon2 from '@start9labs/argon2'
|
||||
import { TuiDestroyService } from '@taiga-ui/cdk'
|
||||
@@ -22,7 +24,6 @@ import { BackupService } from 'src/app/components/backup-drives/backup.service'
|
||||
@Component({
|
||||
selector: 'server-backup',
|
||||
templateUrl: './server-backup.page.html',
|
||||
styleUrls: ['./server-backup.page.scss'],
|
||||
providers: [TuiDestroyService],
|
||||
})
|
||||
export class ServerBackupPage {
|
||||
@@ -31,8 +32,8 @@ export class ServerBackupPage {
|
||||
readonly backingUp$ = this.eosService.backingUp$
|
||||
|
||||
constructor(
|
||||
private readonly errorService: ErrorService,
|
||||
private readonly loader: LoadingService,
|
||||
private readonly dialogs: TuiDialogService,
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly embassyApi: ApiService,
|
||||
private readonly navCtrl: NavController,
|
||||
@@ -74,29 +75,35 @@ export class ServerBackupPage {
|
||||
target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>,
|
||||
): Promise<void> {
|
||||
const options: PromptOptions = {
|
||||
title: 'Master Password Needed',
|
||||
message: 'Enter your master password to encrypt this backup.',
|
||||
label: 'Master Password',
|
||||
placeholder: 'Enter master password',
|
||||
useMask: true,
|
||||
buttonText: 'Create Backup',
|
||||
}
|
||||
|
||||
this.dialogs
|
||||
.open<string>(PROMPT, {
|
||||
label: 'Master Password Needed',
|
||||
data: options,
|
||||
})
|
||||
.pipe(take(1))
|
||||
.subscribe(async (password: string) => {
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: PasswordPromptComponent,
|
||||
componentProps: { options },
|
||||
canDismiss: async password => {
|
||||
if (password === null) {
|
||||
return true
|
||||
}
|
||||
|
||||
const { passwordHash, id } = await getServerInfo(this.patch)
|
||||
|
||||
// @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
|
||||
// confirm password matches current master password
|
||||
argon2.verify(passwordHash, password)
|
||||
try {
|
||||
argon2.verify(passwordHash, password)
|
||||
} catch (e: any) {
|
||||
this.errorService.handleError(e)
|
||||
return false
|
||||
}
|
||||
|
||||
// first time backup
|
||||
if (!this.backupService.hasThisBackup(target.entry, id)) {
|
||||
await this.createBackup(target, password)
|
||||
this.createBackup(target, password)
|
||||
return true
|
||||
// existing backup
|
||||
} else {
|
||||
try {
|
||||
@@ -106,39 +113,49 @@ export class ServerBackupPage {
|
||||
() => this.presentModalOldPassword(target, password),
|
||||
250,
|
||||
)
|
||||
return
|
||||
return true
|
||||
}
|
||||
await this.createBackup(target, password)
|
||||
return true
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
modal.present()
|
||||
}
|
||||
|
||||
private async presentModalOldPassword(
|
||||
target: MappedBackupTarget<CifsBackupTarget | DiskBackupTarget>,
|
||||
password: string,
|
||||
): Promise<void> {
|
||||
const { id } = await getServerInfo(this.patch)
|
||||
const options: PromptOptions = {
|
||||
title: 'Original Password Needed',
|
||||
message:
|
||||
'This backup was created with a different password. Enter the ORIGINAL password that was used to encrypt this backup.',
|
||||
label: 'Original Password',
|
||||
placeholder: 'Enter original password',
|
||||
useMask: true,
|
||||
buttonText: 'Create Backup',
|
||||
}
|
||||
|
||||
const { id } = await getServerInfo(this.patch)
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: PasswordPromptComponent,
|
||||
componentProps: { options },
|
||||
canDismiss: async oldPassword => {
|
||||
if (oldPassword === null) {
|
||||
return true
|
||||
}
|
||||
|
||||
this.dialogs
|
||||
.open<string>(PROMPT, {
|
||||
label: 'Original Password Needed',
|
||||
data: options,
|
||||
})
|
||||
.pipe(take(1))
|
||||
.subscribe(async (oldPassword: string) => {
|
||||
// @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(target.entry.startOs[id].passwordHash!, oldPassword)
|
||||
await this.createBackup(target, password, oldPassword)
|
||||
})
|
||||
try {
|
||||
argon2.verify(target.entry.startOs[id].passwordHash!, oldPassword)
|
||||
await this.createBackup(target, password, oldPassword)
|
||||
return true
|
||||
} catch (e: any) {
|
||||
this.errorService.handleError(e)
|
||||
return false
|
||||
}
|
||||
},
|
||||
})
|
||||
modal.present()
|
||||
}
|
||||
|
||||
private async createBackup(
|
||||
|
||||
@@ -56,7 +56,7 @@ export class WidgetsPage {
|
||||
@Optional()
|
||||
@Inject(POLYMORPHEUS_CONTEXT)
|
||||
readonly context: TuiDialogContext | null,
|
||||
private readonly dialog: TuiDialogService,
|
||||
private readonly dialogs: TuiDialogService,
|
||||
private readonly patch: PatchDB<DataModel>,
|
||||
private readonly cdr: ChangeDetectorRef,
|
||||
private readonly api: ApiService,
|
||||
@@ -83,7 +83,7 @@ export class WidgetsPage {
|
||||
}
|
||||
|
||||
add() {
|
||||
this.dialog.open(ADD_WIDGET, { label: 'Add widget' }).subscribe(widget => {
|
||||
this.dialogs.open(ADD_WIDGET, { label: 'Add widget' }).subscribe(widget => {
|
||||
this.addWidget(widget!)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user