export vault

This commit is contained in:
Kyle Spearrin 2018-08-01 23:21:32 -04:00
parent 696bc780ba
commit b032bc2f33
10 changed files with 117 additions and 4 deletions

2
jslib

@ -1 +1 @@
Subproject commit 76c89f01ef993e572d8c2cbb057cf11f1ea21742
Subproject commit 6f64c5cb5a90354d1a76b5270378030dc99d325b

View File

@ -43,6 +43,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe';
import { AddEditComponent } from './vault/add-edit.component';
import { AttachmentsComponent } from './vault/attachments.component';
import { CiphersComponent } from './vault/ciphers.component';
import { ExportComponent } from './vault/export.component';
import { FolderAddEditComponent } from './vault/folder-add-edit.component';
import { GroupingsComponent } from './vault/groupings.component';
import { PasswordGeneratorHistoryComponent } from './vault/password-generator-history.component';
@ -75,6 +76,7 @@ import { ViewComponent } from './vault/view.component';
BoxRowDirective,
CiphersComponent,
EnvironmentComponent,
ExportComponent,
FallbackSrcDirective,
FolderAddEditComponent,
GroupingsComponent,
@ -102,6 +104,7 @@ import { ViewComponent } from './vault/view.component';
entryComponents: [
AttachmentsComponent,
EnvironmentComponent,
ExportComponent,
FolderAddEditComponent,
ModalComponent,
PasswordGeneratorComponent,

View File

@ -0,0 +1,40 @@
<div class="modal fade">
<div class="modal-dialog">
<form class="modal-content" #form (ngSubmit)="submit()">
<div class="modal-body">
<div class="box">
<div class="box-header">
{{'exportVault' | i18n}}
</div>
<div class="box-content">
<div class="box-content-row box-content-row-flex" appBoxRow>
<div class="row-main">
<label for="masterPassword">{{'masterPass' | i18n}}</label>
<input id="masterPassword" type="{{showPassword ? 'text' : 'password'}}"
name="MasterPassword" class="monospaced" [(ngModel)]="masterPassword" required
appAutofocus>
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appBlurClick
title="{{'toggleVisibility' | i18n}}" (click)="togglePassword()">
<i class="fa fa-lg"
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
</a>
</div>
</div>
</div>
<div class="box-footer">
<p>{{'exportMasterPassword' | i18n}}</p>
<strong>{{'warning' | i18n}}</strong>: {{'exportWarning' | i18n}}
</div>
</div>
</div>
<div class="modal-footer">
<button appBlurClick type="submit" class="primary" title="{{'submit' | i18n}}">
<i class="fa fa-download fa-lg fa-fw"></i>
</button>
<button type="button" data-dismiss="modal">{{'cancel' | i18n}}</button>
</div>
</form>
</div>
</div>

View File

@ -0,0 +1,26 @@
import { ToasterService } from 'angular2-toaster';
import { Angulartics2 } from 'angulartics2';
import { Component } from '@angular/core';
import { CryptoService } from 'jslib/abstractions/crypto.service';
import { ExportService } from 'jslib/abstractions/export.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { UserService } from 'jslib/abstractions/user.service';
import { ExportComponent as BaseExportComponent } from 'jslib/angular/components/export.component';
@Component({
selector: 'app-export',
templateUrl: 'export.component.html',
})
export class ExportComponent extends BaseExportComponent {
constructor(analytics: Angulartics2, toasterService: ToasterService,
cryptoService: CryptoService, userService: UserService,
i18nService: I18nService, platformUtilsService: PlatformUtilsService,
exportService: ExportService) {
super(analytics, toasterService, cryptoService, userService, i18nService, platformUtilsService,
exportService, window);
}
}

View File

@ -20,7 +20,7 @@
<i class="fa fa-save fa-lg fa-fw" [hidden]="form.loading"></i>
<i class="fa fa-spinner fa-spin fa-lg fa-fw" [hidden]="!form.loading"></i>
</button>
<button type="button" data-dismiss="modal">{{'close' | i18n}}</button>
<button type="button" data-dismiss="modal">{{'cancel' | i18n}}</button>
<div class="right">
<button #deleteBtn appBlurClick type="button" (click)="delete()" class="danger"
title="{{'delete' | i18n}}" *ngIf="editMode" [disabled]="deleteBtn.loading"

View File

@ -78,7 +78,7 @@
title="{{'select' | i18n}}">
<i class="fa fa-lg fa-fw fa-check"></i>
</button>
<button type="button" data-dismiss="modal">{{'close' | i18n}}</button>
<button type="button" data-dismiss="modal">{{(showSelect ? 'cancel' : 'close') | i18n}}</button>
</div>
</div>
</div>

View File

@ -43,4 +43,5 @@
<ng-template #attachments></ng-template>
<ng-template #folderAddEdit></ng-template>
<ng-template #passwordHistory></ng-template>
<ng-template #exportVault></ng-template>
</div>

View File

@ -26,6 +26,7 @@ import { ModalComponent } from 'jslib/angular/components/modal.component';
import { AddEditComponent } from './add-edit.component';
import { AttachmentsComponent } from './attachments.component';
import { CiphersComponent } from './ciphers.component';
import { ExportComponent } from './export.component';
import { FolderAddEditComponent } from './folder-add-edit.component';
import { GroupingsComponent } from './groupings.component';
import { PasswordGeneratorComponent } from './password-generator.component';
@ -56,6 +57,7 @@ export class VaultComponent implements OnInit, OnDestroy {
@ViewChild('attachments', { read: ViewContainerRef }) attachmentsModalRef: ViewContainerRef;
@ViewChild('folderAddEdit', { read: ViewContainerRef }) folderAddEditModalRef: ViewContainerRef;
@ViewChild('passwordHistory', { read: ViewContainerRef }) passwordHistoryModalRef: ViewContainerRef;
@ViewChild('exportVault', { read: ViewContainerRef }) exportVaultModalRef: ViewContainerRef;
action: string;
cipherId: string = null;
@ -102,6 +104,9 @@ export class VaultComponent implements OnInit, OnDestroy {
case 'openPasswordGenerator':
await this.openPasswordGenerator(false);
break;
case 'exportVault':
await this.openExportVault();
break;
case 'syncVault':
try {
await this.syncService.fullSync(true);
@ -434,6 +439,24 @@ export class VaultComponent implements OnInit, OnDestroy {
});
}
async openExportVault() {
if (this.modal != null) {
this.modal.close();
}
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
this.modal = this.exportVaultModalRef.createComponent(factory).instance;
const childComponent = this.modal.show<ExportComponent>(ExportComponent, this.exportVaultModalRef);
childComponent.onSaved.subscribe(() => {
this.modal.close();
});
this.modal.onClosed.subscribe(() => {
this.modal = null;
});
}
async addFolder() {
if (this.modal != null) {
this.modal.close();

View File

@ -1075,5 +1075,18 @@
"datePasswordUpdated": {
"message": "Password Updated",
"description": "ex. Date this password was updated"
},
"exportVault": {
"message": "Export Vault"
},
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
},
"exportWarning": {
"message": "This export contains your unencrypted data in .csv format. You should not store or send it over unsecure channels (such as email). Delete it immediately after your are done using it."
},
"exportMasterPassword": {
"message": "Enter your master password to export your vault data."
}
}

View File

@ -25,6 +25,7 @@ export class MenuMain extends BaseMenu {
addNewItem: MenuItem;
addNewFolder: MenuItem;
syncVault: MenuItem;
exportVault: MenuItem;
settings: MenuItem;
lockNow: MenuItem;
logOut: MenuItem;
@ -51,6 +52,7 @@ export class MenuMain extends BaseMenu {
this.addNewItem = this.menu.getMenuItemById('addNewItem');
this.addNewFolder = this.menu.getMenuItemById('addNewFolder');
this.syncVault = this.menu.getMenuItemById('syncVault');
this.exportVault = this.menu.getMenuItemById('exportVault');
this.settings = this.menu.getMenuItemById('settings');
this.lockNow = this.menu.getMenuItemById('lockNow');
this.logOut = this.menu.getMenuItemById('logOut');
@ -64,7 +66,7 @@ export class MenuMain extends BaseMenu {
this.unlockedRequiredMenuItems = [
this.addNewLogin, this.addNewItem, this.addNewFolder,
this.syncVault, this.settings, this.lockNow, this.twoStepLogin, this.changeEmail,
this.syncVault, this.exportVault, this.settings, this.lockNow, this.twoStepLogin, this.changeEmail,
this.changeMasterPass, this.premiumMembership, this.passwordGenerator, this.passwordHistory,
this.searchVault];
this.updateApplicationMenuState(false, true);
@ -210,6 +212,11 @@ export class MenuMain extends BaseMenu {
id: 'syncVault',
click: () => this.main.messagingService.send('syncVault'),
},
{
label: this.main.i18nService.t('exportVault'),
id: 'exportVault',
click: () => this.main.messagingService.send('exportVault'),
},
],
},
this.editMenuItemOptions,