1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 16:53:34 +00:00
Files
browser/src/app/tools/import.component.ts

188 lines
6.5 KiB
TypeScript

import {
Component,
OnInit,
} from '@angular/core';
import { Router } from '@angular/router';
import { ToasterService } from 'angular2-toaster';
import { I18nService } from 'jslib-common/abstractions/i18n.service';
import { ImportOption, ImportService } from 'jslib-common/abstractions/import.service';
import { LogService } from 'jslib-common/abstractions/log.service';
import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.service';
import { PolicyService } from 'jslib-common/abstractions/policy.service';
import { PolicyType } from 'jslib-common/enums/policyType';
import Swal, { SweetAlertIcon } from 'sweetalert2';
@Component({
selector: 'app-import',
templateUrl: 'import.component.html',
})
export class ImportComponent implements OnInit {
featuredImportOptions: ImportOption[];
importOptions: ImportOption[];
format: string = null;
fileContents: string;
formPromise: Promise<Error>;
loading: boolean = false;
importBlockedByPolicy: boolean = false;
protected organizationId: string = null;
protected successNavigate: any[] = ['vault'];
constructor(protected i18nService: I18nService, protected toasterService: ToasterService,
protected importService: ImportService, protected router: Router,
protected platformUtilsService: PlatformUtilsService, protected policyService: PolicyService,
private logService: LogService) { }
async ngOnInit() {
this.setImportOptions();
this.importOptions.sort((a, b) => {
if (a.name == null && b.name != null) {
return -1;
}
if (a.name != null && b.name == null) {
return 1;
}
if (a.name == null && b.name == null) {
return 0;
}
return this.i18nService.collator ? this.i18nService.collator.compare(a.name, b.name) :
a.name.localeCompare(b.name);
});
this.importBlockedByPolicy = await this.policyService.policyAppliesToUser(PolicyType.PersonalOwnership);
}
async submit() {
if (this.importBlockedByPolicy) {
this.platformUtilsService.showToast('error', null,
this.i18nService.t('personalOwnershipPolicyInEffectImports'));
return;
}
this.loading = true;
const importer = this.importService.getImporter(this.format, this.organizationId);
if (importer === null) {
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),
this.i18nService.t('selectFormat'));
this.loading = false;
return;
}
const fileEl = document.getElementById('file') as HTMLInputElement;
const files = fileEl.files;
if ((files == null || files.length === 0) && (this.fileContents == null || this.fileContents === '')) {
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),
this.i18nService.t('selectFile'));
this.loading = false;
return;
}
let fileContents = this.fileContents;
if (files != null && files.length > 0) {
try {
const content = await this.getFileContents(files[0]);
if (content != null) {
fileContents = content;
}
} catch (e) {
this.logService.error(e);
}
}
if (fileContents == null || fileContents === '') {
this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'),
this.i18nService.t('selectFile'));
this.loading = false;
return;
}
try {
this.formPromise = this.importService.import(importer, fileContents, this.organizationId);
const error = await this.formPromise;
if (error != null) {
this.error(error);
this.loading = false;
return;
}
this.toasterService.popAsync('success', null, this.i18nService.t('importSuccess'));
this.router.navigate(this.successNavigate);
} catch (e) {
this.logService.error(e);
}
this.loading = false;
}
getFormatInstructionTitle() {
if (this.format == null) {
return null;
}
const results = this.featuredImportOptions.concat(this.importOptions).filter(o => o.id === this.format);
if (results.length > 0) {
return this.i18nService.t('instructionsFor', results[0].name);
}
return null;
}
protected setImportOptions() {
this.featuredImportOptions = [{
id: null,
name: '-- ' + this.i18nService.t('select') + ' --',
}, ...this.importService.featuredImportOptions];
this.importOptions = this.importService.regularImportOptions;
}
private async error(error: Error) {
await Swal.fire({
heightAuto: false,
buttonsStyling: false,
icon: 'error' as SweetAlertIcon,
iconHtml: `<i class="swal-custom-icon fa fa-bolt text-danger"></i>`,
input: 'textarea',
inputValue: error.message,
inputAttributes: {
'readonly': 'true',
},
titleText: this.i18nService.t('importError'),
text: this.i18nService.t('importErrorDesc'),
showConfirmButton: true,
confirmButtonText: this.i18nService.t('ok'),
onOpen: popupEl => {
popupEl.querySelector('.swal2-textarea').scrollTo(0, 0);
},
});
}
private getFileContents(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsText(file, 'utf-8');
reader.onload = evt => {
if (this.format === 'lastpasscsv' && file.type === 'text/html') {
const parser = new DOMParser();
const doc = parser.parseFromString((evt.target as any).result, 'text/html');
const pre = doc.querySelector('pre');
if (pre != null) {
resolve(pre.textContent);
return;
}
reject();
return;
}
resolve((evt.target as any).result);
};
reader.onerror = () => {
reject();
};
});
}
}