From 1776188a4c7265a076cfe6f5634b6f7f50daac9a Mon Sep 17 00:00:00 2001 From: Dennis Mullen Date: Mon, 8 Jul 2019 10:22:09 -0400 Subject: [PATCH 1/3] NAS-102362 warnings about keys --- src/app/helptext/storage/volumes/volume-key.ts | 6 +++++- .../volumeaddkey-form/volumeaddkey-form.component.ts | 5 +++++ .../volumecreatekey-form/volumecreatekey-form.component.ts | 4 ++++ .../volumes/volumerekey-form/volumerekey-form.component.ts | 4 ++++ src/assets/styles/themes/ix-blue.scss | 4 ++++ 5 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/app/helptext/storage/volumes/volume-key.ts b/src/app/helptext/storage/volumes/volume-key.ts index b43aceb157f..34497fb6868 100644 --- a/src/app/helptext/storage/volumes/volume-key.ts +++ b/src/app/helptext/storage/volumes/volume-key.ts @@ -4,7 +4,8 @@ import { T } from '../../../translate-marker'; export default { // Add key form add_key_name_validation: [Validators.required], - +add_key_instructions: T('You are about to add a recovery key for this volume.\ + This will invalidate any previous recovery key.'), add_key_password_placeholder: T('Root password'), add_key_password_tooltip: T('Enter the root password to authorize this operation.'), add_key_password_validation: [Validators.required], @@ -14,6 +15,8 @@ changekey_adminpw_placeholder: T('Root Password'), changekey_adminpw_tooltip: T('Enter the root password.'), changekey_adminpw_validation: [Validators.required], +changekey_instructions: T('Remember to add a new recovery key as this action\ + invalidates the previous recovery key.'), changekey_passphrase_placeholder: T('Passphrase'), changekey_passphrase_tooltip: T('Enter the GELI passphrase.'), changekey_passphrase_validation: [Validators.required], @@ -35,6 +38,7 @@ createkey_passphrase2_tooltip: T('Confirm the GELI passphrase.'), createkey_passphrase2_validation: [Validators.required], // Rekey form +rekey_instructions: T('You are about to re-key the encryption.'), rekey_password_label: T('Passphrase'), rekey_password_placeholder: T('Root password'), rekey_password_tooltip: T('Enter the root password to authorize this operation.'), diff --git a/src/app/pages/storage/volumes/volumeaddkey-form/volumeaddkey-form.component.ts b/src/app/pages/storage/volumes/volumeaddkey-form/volumeaddkey-form.component.ts index a9bb20d5eb4..51e7b069536 100644 --- a/src/app/pages/storage/volumes/volumeaddkey-form/volumeaddkey-form.component.ts +++ b/src/app/pages/storage/volumes/volumeaddkey-form/volumeaddkey-form.component.ts @@ -36,6 +36,11 @@ export class VolumeAddkeyFormComponent implements Formconfiguration { }; fieldConfig: FieldConfig[] = [ + { + type: 'paragraph', + name: 'addkey-instructions', + paraText: helptext.add_key_instructions, + }, { type : 'input', name : 'name', diff --git a/src/app/pages/storage/volumes/volumecreatekey-form/volumecreatekey-form.component.ts b/src/app/pages/storage/volumes/volumecreatekey-form/volumecreatekey-form.component.ts index 6c5fe9edeec..11021022ee7 100644 --- a/src/app/pages/storage/volumes/volumecreatekey-form/volumecreatekey-form.component.ts +++ b/src/app/pages/storage/volumes/volumecreatekey-form/volumecreatekey-form.component.ts @@ -40,6 +40,10 @@ export class VolumeCreatekeyFormComponent implements Formconfiguration { type : 'input', name : 'name', isHidden: true + },{ + type: 'paragraph', + name: 'createkey-instructions', + paraText: helptext.changekey_instructions },{ type : 'input', inputType: 'password', diff --git a/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts b/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts index c19c348ac20..035bce59951 100644 --- a/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts +++ b/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts @@ -39,6 +39,10 @@ export class VolumeRekeyFormComponent implements Formconfiguration { type : 'input', name : 'name', isHidden: true + },{ + type: 'paragraph', + name: 'rekey-instructions', + paraText: helptext.rekey_instructions },{ type : 'input', inputType: 'password', diff --git a/src/assets/styles/themes/ix-blue.scss b/src/assets/styles/themes/ix-blue.scss index 8e0794b9e04..aa07e68c346 100644 --- a/src/assets/styles/themes/ix-blue.scss +++ b/src/assets/styles/themes/ix-blue.scss @@ -1303,4 +1303,8 @@ $primary-dark: darken( map-get($md-primary, 500), 8% ); //overflow: hidden; // This clips tooltips } + #addkey-instructions p, #createkey-instructions p { + color: var(--red); + } + } // end of ix theme From c27790248ae553d1971b25bb1ebd4d96fa9da531 Mon Sep 17 00:00:00 2001 From: Dennis Mullen Date: Mon, 8 Jul 2019 16:11:16 -0400 Subject: [PATCH 2/3] NAS-102362 add key download dialogs --- .../helptext/storage/volumes/volume-key.ts | 13 ++++++---- .../volumeaddkey-form.component.ts | 15 ++++++++---- .../volumechangekey-form.component.ts | 23 ++++++++++++++---- .../volumecreatekey-form.component.ts | 20 +++++++++++----- .../volumerekey-form.component.ts | 24 +++++++++++++------ src/assets/styles/themes/ix-blue.scss | 4 ---- 6 files changed, 67 insertions(+), 32 deletions(-) diff --git a/src/app/helptext/storage/volumes/volume-key.ts b/src/app/helptext/storage/volumes/volume-key.ts index 34497fb6868..42ff789f31a 100644 --- a/src/app/helptext/storage/volumes/volume-key.ts +++ b/src/app/helptext/storage/volumes/volume-key.ts @@ -4,8 +4,8 @@ import { T } from '../../../translate-marker'; export default { // Add key form add_key_name_validation: [Validators.required], -add_key_instructions: T('You are about to add a recovery key for this volume.\ - This will invalidate any previous recovery key.'), +add_key_instructions: T('Adding a recovery key invalidates any previous recovery key.\ + A dialog will open to save a backup of the new recovery key.'), add_key_password_placeholder: T('Root password'), add_key_password_tooltip: T('Enter the root password to authorize this operation.'), add_key_password_validation: [Validators.required], @@ -15,12 +15,14 @@ changekey_adminpw_placeholder: T('Root Password'), changekey_adminpw_tooltip: T('Enter the root password.'), changekey_adminpw_validation: [Validators.required], -changekey_instructions: T('Remember to add a new recovery key as this action\ - invalidates the previous recovery key.'), +changekey_instructions: T('Creating a passphrase requires the creation of a new\ + recovery key. A dialog will open to save a backup of the new recovery key.'), changekey_passphrase_placeholder: T('Passphrase'), changekey_passphrase_tooltip: T('Enter the GELI passphrase.'), changekey_passphrase_validation: [Validators.required], +changekey_instructions2: T('Changing the passphrase requires the creation of a new\ + recovery key. A dialog will open to save a backup of the new recovery key.'), changekey_passphrase2_placeholder: T('Verify passphrase'), changekey_passphrase2_tooltip: T('Confirm the GELI passphrase.'), changekey_passphrase2_validation: [Validators.required], @@ -38,7 +40,8 @@ createkey_passphrase2_tooltip: T('Confirm the GELI passphrase.'), createkey_passphrase2_validation: [Validators.required], // Rekey form -rekey_instructions: T('You are about to re-key the encryption.'), +rekey_instructions: T('Generate a new GELI key, replacing the old one on the disks in the pool.\ + Passphrases will be removed by this operation.
A dialog will open to save a backup of the new recovery key.'), rekey_password_label: T('Passphrase'), rekey_password_placeholder: T('Root password'), rekey_password_tooltip: T('Enter the root password to authorize this operation.'), diff --git a/src/app/pages/storage/volumes/volumeaddkey-form/volumeaddkey-form.component.ts b/src/app/pages/storage/volumes/volumeaddkey-form/volumeaddkey-form.component.ts index 51e7b069536..65aa0b0fdc4 100644 --- a/src/app/pages/storage/volumes/volumeaddkey-form/volumeaddkey-form.component.ts +++ b/src/app/pages/storage/volumes/volumeaddkey-form/volumeaddkey-form.component.ts @@ -5,7 +5,6 @@ import { } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { MatSnackBar } from '@angular/material'; import * as _ from 'lodash'; import { RestService, WebSocketService, StorageService } from '../../../../services/'; @@ -13,9 +12,11 @@ import { FieldConfig } from '../../../common/entity/entity-form/models/field-config.interface'; import { DialogService } from 'app/services/dialog.service'; +import { MatSnackBar, MatDialog } from '@angular/material'; import { Formconfiguration } from 'app/pages/common/entity/entity-form/entity-form.component'; import { AppLoaderService } from '../../../../services/app-loader/app-loader.service'; import { T } from '../../../../translate-marker'; +import { DownloadKeyModalDialog } from '../../../../components/common/dialog/downloadkey/downloadkey-dialog.component'; import helptext from '../../../../helptext/storage/volumes/volume-key'; @Component({ @@ -73,7 +74,8 @@ export class VolumeAddkeyFormComponent implements Formconfiguration { protected dialogService: DialogService, protected loader: AppLoaderService, protected storage: StorageService, - protected snackBar: MatSnackBar + protected snackBar: MatSnackBar, + protected mdDialog: MatDialog ) { } @@ -95,9 +97,12 @@ export class VolumeAddkeyFormComponent implements Formconfiguration { this.rest.post(this.resource_name + "/" + this.pk + "/recoverykey/", {}).subscribe((restPostResp) => { this.loader.close(); this.snackBar.open(T("Recovery key added to pool ") + value.name, 'close', { duration: 5000 }); - this.storage.downloadFile('geli_recovery.key', restPostResp.data.content, 'application/octet-stream'); - this.router.navigate(new Array('/').concat( - this.route_success)); + let dialogRef = this.mdDialog.open(DownloadKeyModalDialog, {disableClose:true}); + dialogRef.componentInstance.volumeId = this.pk; + dialogRef.afterClosed().subscribe(result => { + this.router.navigate(new Array('/').concat( + this.route_success)); + }) }, (res) => { this.loader.close(); this.dialogService.errorReport(T("Error adding recovery key to pool."), res.error.error_message, res.error.traceback); diff --git a/src/app/pages/storage/volumes/volumechangekey-form/volumechangekey-form.component.ts b/src/app/pages/storage/volumes/volumechangekey-form/volumechangekey-form.component.ts index 99566521255..0a0ed59e784 100644 --- a/src/app/pages/storage/volumes/volumechangekey-form/volumechangekey-form.component.ts +++ b/src/app/pages/storage/volumes/volumechangekey-form/volumechangekey-form.component.ts @@ -12,8 +12,10 @@ import { FieldConfig } from '../../../common/entity/entity-form/models/field-config.interface'; import { DialogService } from 'app/services/dialog.service'; +import { MatSnackBar, MatDialog } from '@angular/material'; import { Formconfiguration } from 'app/pages/common/entity/entity-form/entity-form.component'; import { AppLoaderService } from '../../../../services/app-loader/app-loader.service'; +import { DownloadKeyModalDialog } from '../../../../components/common/dialog/downloadkey/downloadkey-dialog.component'; import { T } from '../../../../translate-marker'; import helptext from '../../../../helptext/storage/volumes/volume-key'; @@ -40,6 +42,10 @@ export class VolumeChangekeyFormComponent implements Formconfiguration { type : 'input', name : 'name', isHidden: true + },{ + type: 'paragraph', + name: 'changekey-instructions', + paraText: helptext.changekey_instructions2 },{ type : 'input', inputType: 'password', @@ -89,7 +95,9 @@ export class VolumeChangekeyFormComponent implements Formconfiguration { protected _injector: Injector, protected _appRef: ApplicationRef, protected dialogService: DialogService, - protected loader: AppLoaderService + protected loader: AppLoaderService, + public mdDialog: MatDialog, + public snackBar: MatSnackBar ) { } @@ -132,10 +140,15 @@ export class VolumeChangekeyFormComponent implements Formconfiguration { this.loader.open(); this.ws.call('pool.passphrase', params).subscribe(() => { this.loader.close(); - this.dialogService.Info(T("Change Pool Passphrase"), T("Passphrase " + success_msg + " pool ") + value.name) - .subscribe(() => { - this.router.navigate(new Array('/').concat(this.route_success)); - }) + this.snackBar.open(T('Passphrase changed for pool ' + value.name), T("Close"), { + duration: 5000, + }); + let dialogRef = this.mdDialog.open(DownloadKeyModalDialog, {disableClose:true}); + dialogRef.componentInstance.volumeId = this.pk; + dialogRef.afterClosed().subscribe(result => { + this.router.navigate(new Array('/').concat( + this.route_success)); + }); },(err) => { this.loader.close(); this.dialogService.errorReport(T("Error changing passphrase for pool ") + value.name, err.reason, err.trace.formatted); diff --git a/src/app/pages/storage/volumes/volumecreatekey-form/volumecreatekey-form.component.ts b/src/app/pages/storage/volumes/volumecreatekey-form/volumecreatekey-form.component.ts index 11021022ee7..537ae46a54f 100644 --- a/src/app/pages/storage/volumes/volumecreatekey-form/volumecreatekey-form.component.ts +++ b/src/app/pages/storage/volumes/volumecreatekey-form/volumecreatekey-form.component.ts @@ -12,9 +12,11 @@ import { FieldConfig } from '../../../common/entity/entity-form/models/field-config.interface'; import { DialogService } from 'app/services/dialog.service'; +import { MatSnackBar, MatDialog } from '@angular/material'; import { Formconfiguration } from 'app/pages/common/entity/entity-form/entity-form.component'; import { AppLoaderService } from '../../../../services/app-loader/app-loader.service'; import { T } from '../../../../translate-marker'; +import { DownloadKeyModalDialog } from '../../../../components/common/dialog/downloadkey/downloadkey-dialog.component'; import helptext from '../../../../helptext/storage/volumes/volume-key'; @Component({ @@ -77,7 +79,9 @@ export class VolumeCreatekeyFormComponent implements Formconfiguration { protected _injector: Injector, protected _appRef: ApplicationRef, protected dialogService: DialogService, - protected loader: AppLoaderService + protected loader: AppLoaderService, + private snackBar: MatSnackBar, + private mdDialog: MatDialog ) { } @@ -94,13 +98,17 @@ export class VolumeCreatekeyFormComponent implements Formconfiguration { customSubmit(value) { this.loader.open(); - return this.rest.post(this.resource_name + "/" + this.pk + "/keypassphrase/", { body: JSON.stringify({passphrase: value.passphrase, passphrase2: value.passphrase2}) }).subscribe((restPostResp) => { this.loader.close(); - this.dialogService.Info(T("Create Pool Passphrase"), T("Passphrase created for pool ") + value.name); - - this.router.navigate(new Array('/').concat( - this.route_success)); + this.snackBar.open(T('Passphrase created for pool ') + value.name, T("Close"), { + duration: 5000, + }); + let dialogRef = this.mdDialog.open(DownloadKeyModalDialog, {disableClose:true}); + dialogRef.componentInstance.volumeId = this.pk; + dialogRef.afterClosed().subscribe(result => { + this.router.navigate(new Array('/').concat( + this.route_success)); + }); }, (res) => { this.loader.close(); this.dialogService.errorReport(T("Error creating passphrase for pool ") + value.name, res.error.message, res.error.traceback); diff --git a/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts b/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts index 035bce59951..6b365b760ea 100644 --- a/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts +++ b/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts @@ -12,8 +12,10 @@ import { FieldConfig } from '../../../common/entity/entity-form/models/field-config.interface'; import { DialogService } from 'app/services/dialog.service'; +import { MatSnackBar, MatDialog } from '@angular/material'; import { Formconfiguration } from 'app/pages/common/entity/entity-form/entity-form.component'; import { AppLoaderService } from '../../../../services/app-loader/app-loader.service'; +import { DownloadKeyModalDialog } from '../../../../components/common/dialog/downloadkey/downloadkey-dialog.component'; import { T } from '../../../../translate-marker'; import helptext from '../../../../helptext/storage/volumes/volume-key'; @@ -68,7 +70,9 @@ export class VolumeRekeyFormComponent implements Formconfiguration { protected _injector: Injector, protected _appRef: ApplicationRef, protected dialogService: DialogService, - protected loader: AppLoaderService + protected loader: AppLoaderService, + protected snackBar: MatSnackBar, + protected mdDialog: MatDialog ) { } @@ -86,12 +90,18 @@ export class VolumeRekeyFormComponent implements Formconfiguration { customSubmit(value) { this.loader.open(); - return this.rest.post(this.resource_name + "/" + this.pk + "/rekey/", { body: JSON.stringify({passphrase: value.passphrase}) }).subscribe((restPostResp) => { - this.loader.close(); - this.dialogService.Info(T("Re-keyed Pool"), T("Successfully re-keyed pool ") + value.name); - - this.router.navigate(new Array('/').concat( - this.route_success)); + return this.rest.post(this.resource_name + "/" + this.pk + "/rekey/", + { body: JSON.stringify({passphrase: value.passphrase}) }).subscribe((restPostResp) => { + this.loader.close(); + this.snackBar.open(T('Successfully re-keyed pool ' + value.name), T("Close"), { + duration: 5000, + }); + let dialogRef = this.mdDialog.open(DownloadKeyModalDialog, {disableClose:true}); + dialogRef.componentInstance.volumeId = this.pk; + dialogRef.afterClosed().subscribe(result => { + this.router.navigate(new Array('/').concat( + this.route_success)); + }); }, (res) => { this.loader.close(); this.dialogService.errorReport(T("Error re-keying pool"), res.error, res.trace.formatted); diff --git a/src/assets/styles/themes/ix-blue.scss b/src/assets/styles/themes/ix-blue.scss index aa07e68c346..8e0794b9e04 100644 --- a/src/assets/styles/themes/ix-blue.scss +++ b/src/assets/styles/themes/ix-blue.scss @@ -1303,8 +1303,4 @@ $primary-dark: darken( map-get($md-primary, 500), 8% ); //overflow: hidden; // This clips tooltips } - #addkey-instructions p, #createkey-instructions p { - color: var(--red); - } - } // end of ix theme From a38ec210b23a16c01d3f1c3640dd1b438668ceb8 Mon Sep 17 00:00:00 2001 From: Dennis Mullen Date: Wed, 10 Jul 2019 08:30:35 -0400 Subject: [PATCH 3/3] NAS-102362 typo fix --- .../volumes/volumerekey-form/volumerekey-form.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts b/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts index 6b365b760ea..23a3eb0d250 100644 --- a/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts +++ b/src/app/pages/storage/volumes/volumerekey-form/volumerekey-form.component.ts @@ -93,7 +93,7 @@ export class VolumeRekeyFormComponent implements Formconfiguration { return this.rest.post(this.resource_name + "/" + this.pk + "/rekey/", { body: JSON.stringify({passphrase: value.passphrase}) }).subscribe((restPostResp) => { this.loader.close(); - this.snackBar.open(T('Successfully re-keyed pool ' + value.name), T("Close"), { + this.snackBar.open(T('Successfully re-keyed pool ') + value.name, T("Close"), { duration: 5000, }); let dialogRef = this.mdDialog.open(DownloadKeyModalDialog, {disableClose:true});