mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 22:33:35 +00:00
[AC-1492] Split export service (#7462)
* Split export service into vault and org export service * Changed CLI logic to use split export logic * correct unit tests * Created individual export service, export service making the calls for org and ind vault * Improved code readability * Merged PasswordProtectedExport with Export methods to simplify calls * Some small refactor * [AC-1492] Managed collections export (#7556) * Added managed collections export method Added logic to show orgs on export that the user can export from * Merge branch 'tools/AC-1492/split-export-services' into tools/AC-1492/export-flexible-collections # Conflicts: # apps/web/src/app/admin-console/organizations/tools/vault-export/org-vault-export.component.ts # apps/web/src/app/tools/vault-export/export.component.ts * Change export to use new organization.flexiblecollection flag * Little refactor changing parameter names and reduzing the size of export.component.ts ngOnInit * Removed unused service from export constructor and removed unnecessary default value from org export service parameter * Simplified organizations selection for vault export to only verify if it has flexiblecollections * removed unecessary services from ExportComponent constructor on popup * Fixed possible race condition on managed export
This commit is contained in:
@@ -172,6 +172,10 @@ import { TotpService } from "@bitwarden/common/vault/services/totp.service";
|
||||
import {
|
||||
VaultExportService,
|
||||
VaultExportServiceAbstraction,
|
||||
OrganizationVaultExportService,
|
||||
OrganizationVaultExportServiceAbstraction,
|
||||
IndividualVaultExportService,
|
||||
IndividualVaultExportServiceAbstraction,
|
||||
} from "@bitwarden/exporter/vault-export";
|
||||
import {
|
||||
ImportApiService,
|
||||
@@ -537,17 +541,33 @@ import { ModalService } from "./modal.service";
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: VaultExportServiceAbstraction,
|
||||
useClass: VaultExportService,
|
||||
provide: IndividualVaultExportServiceAbstraction,
|
||||
useClass: IndividualVaultExportService,
|
||||
deps: [
|
||||
FolderServiceAbstraction,
|
||||
CipherServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
CryptoFunctionServiceAbstraction,
|
||||
StateServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: OrganizationVaultExportServiceAbstraction,
|
||||
useClass: OrganizationVaultExportService,
|
||||
deps: [
|
||||
CipherServiceAbstraction,
|
||||
ApiServiceAbstraction,
|
||||
CryptoServiceAbstraction,
|
||||
CryptoFunctionServiceAbstraction,
|
||||
StateServiceAbstraction,
|
||||
CollectionServiceAbstraction,
|
||||
],
|
||||
},
|
||||
{
|
||||
provide: VaultExportServiceAbstraction,
|
||||
useClass: VaultExportService,
|
||||
deps: [IndividualVaultExportServiceAbstraction, OrganizationVaultExportServiceAbstraction],
|
||||
},
|
||||
{
|
||||
provide: SearchServiceAbstraction,
|
||||
useClass: SearchService,
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { Directive, EventEmitter, OnDestroy, OnInit, Output, ViewChild } from "@angular/core";
|
||||
import { UntypedFormBuilder, Validators } from "@angular/forms";
|
||||
import { concat, map, merge, Observable, startWith, Subject, takeUntil } from "rxjs";
|
||||
import { map, merge, Observable, startWith, Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import {
|
||||
OrganizationService,
|
||||
canAccessImportExport,
|
||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||
import { PolicyType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
@@ -31,6 +28,7 @@ export class ExportComponent implements OnInit, OnDestroy {
|
||||
filePasswordValue: string = null;
|
||||
formPromise: Promise<string>;
|
||||
private _disabledByPolicy = false;
|
||||
|
||||
protected organizationId: string = null;
|
||||
organizations$: Observable<Organization[]>;
|
||||
|
||||
@@ -76,13 +74,6 @@ export class ExportComponent implements OnInit, OnDestroy {
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.organizations$ = concat(
|
||||
this.organizationService.memberOrganizations$.pipe(
|
||||
canAccessImportExport(this.i18nService),
|
||||
map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name"))),
|
||||
),
|
||||
);
|
||||
|
||||
this.policyService
|
||||
.policyAppliesToActiveUser$(PolicyType.DisablePersonalVaultExport)
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
@@ -93,19 +84,6 @@ export class ExportComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
|
||||
if (this.organizationId) {
|
||||
this.exportForm.controls.vaultSelector.patchValue(this.organizationId);
|
||||
this.exportForm.controls.vaultSelector.disable();
|
||||
} else {
|
||||
this.exportForm.controls.vaultSelector.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((value) => {
|
||||
this.organizationId = value != "myVault" ? value : undefined;
|
||||
});
|
||||
|
||||
this.exportForm.controls.vaultSelector.setValue("myVault");
|
||||
}
|
||||
|
||||
merge(
|
||||
this.exportForm.get("format").valueChanges,
|
||||
this.exportForm.get("fileEncryptionType").valueChanges,
|
||||
@@ -113,6 +91,31 @@ export class ExportComponent implements OnInit, OnDestroy {
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.pipe(startWith(0))
|
||||
.subscribe(() => this.adjustValidators());
|
||||
|
||||
if (this.organizationId) {
|
||||
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
|
||||
map((orgs) => orgs.filter((org) => org.id == this.organizationId)),
|
||||
);
|
||||
this.exportForm.controls.vaultSelector.patchValue(this.organizationId);
|
||||
this.exportForm.controls.vaultSelector.disable();
|
||||
return;
|
||||
}
|
||||
|
||||
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
|
||||
map((orgs) =>
|
||||
orgs
|
||||
.filter((org) => org.flexibleCollections)
|
||||
.sort(Utils.getSortFunction(this.i18nService, "name")),
|
||||
),
|
||||
);
|
||||
|
||||
this.exportForm.controls.vaultSelector.valueChanges
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((value) => {
|
||||
this.organizationId = value != "myVault" ? value : undefined;
|
||||
});
|
||||
|
||||
this.exportForm.controls.vaultSelector.setValue("myVault");
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
@@ -188,15 +191,15 @@ export class ExportComponent implements OnInit, OnDestroy {
|
||||
this.onSaved.emit();
|
||||
}
|
||||
|
||||
protected getExportData() {
|
||||
if (
|
||||
this.format === "encrypted_json" &&
|
||||
this.fileEncryptionType === EncryptedExportType.FileEncrypted
|
||||
) {
|
||||
return this.exportService.getPasswordProtectedExport(this.filePassword);
|
||||
} else {
|
||||
return this.exportService.getExport(this.format, null);
|
||||
}
|
||||
protected async getExportData(): Promise<string> {
|
||||
return Utils.isNullOrWhitespace(this.organizationId)
|
||||
? this.exportService.getExport(this.format, this.filePassword)
|
||||
: this.exportService.getOrganizationExport(
|
||||
this.organizationId,
|
||||
this.format,
|
||||
this.filePassword,
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
protected getFileName(prefix?: string) {
|
||||
|
||||
Reference in New Issue
Block a user