diff --git a/.eslintrc.json b/.eslintrc.json index dd57ca69d5..47d45f23c3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -99,7 +99,7 @@ // Import/export "./libs/importer/**/*", - "./libs/exporter/**/*" + "./libs/tools/export/vault-export/vault-export-core/**/*" ] }, { @@ -183,9 +183,12 @@ } }, { - "files": ["libs/exporter/src/**/*.ts"], + "files": ["libs/tools/export/vault-export/vault-export-core/src/**/*.ts"], "rules": { - "no-restricted-imports": ["error", { "patterns": ["@bitwarden/exporter/*", "src/**/*"] }] + "no-restricted-imports": [ + "error", + { "patterns": ["@bitwarden/vault-export-core/*", "src/**/*"] } + ] } }, { diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6a56162b3b..00cad6b2bf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -27,7 +27,6 @@ apps/web/src/app/tools @bitwarden/team-tools-dev libs/angular/src/tools @bitwarden/team-tools-dev libs/common/src/models/export @bitwarden/team-tools-dev libs/common/src/tools @bitwarden/team-tools-dev -libs/exporter @bitwarden/team-tools-dev libs/importer @bitwarden/team-tools-dev libs/tools @bitwarden/team-tools-dev diff --git a/.github/whitelist-capital-letters.txt b/.github/whitelist-capital-letters.txt index 353cc05610..99ce80376d 100644 --- a/.github/whitelist-capital-letters.txt +++ b/.github/whitelist-capital-letters.txt @@ -20,6 +20,7 @@ ./libs/billing/README.md ./libs/platform/README.md ./libs/tools/README.md +./libs/tools/export/vault-export/README.md ./libs/vault/README.md ./README.md ./LICENSE_BITWARDEN.txt diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index ddd1737fa7..77be810cf3 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -136,6 +136,12 @@ import { SyncNotifierService } from "@bitwarden/common/vault/services/sync/sync- import { SyncService } from "@bitwarden/common/vault/services/sync/sync.service"; import { TotpService } from "@bitwarden/common/vault/services/totp.service"; import { VaultSettingsService } from "@bitwarden/common/vault/services/vault-settings/vault-settings.service"; +import { + ImportApiService, + ImportApiServiceAbstraction, + ImportService, + ImportServiceAbstraction, +} from "@bitwarden/importer/core"; import { IndividualVaultExportService, IndividualVaultExportServiceAbstraction, @@ -143,13 +149,7 @@ import { OrganizationVaultExportServiceAbstraction, VaultExportService, VaultExportServiceAbstraction, -} from "@bitwarden/exporter/vault-export"; -import { - ImportApiService, - ImportApiServiceAbstraction, - ImportService, - ImportServiceAbstraction, -} from "@bitwarden/importer/core"; +} from "@bitwarden/vault-export-core"; import { BrowserOrganizationService } from "../admin-console/services/browser-organization.service"; import { BrowserPolicyService } from "../admin-console/services/browser-policy.service"; diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index ead8442af3..99d6c80f69 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -95,8 +95,8 @@ import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.serv import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; import { FolderApiService } from "@bitwarden/common/vault/services/folder/folder-api.service"; import { DialogService } from "@bitwarden/components"; -import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export"; import { ImportServiceAbstraction } from "@bitwarden/importer/core"; +import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core"; import { BrowserOrganizationService } from "../../admin-console/services/browser-organization.service"; import { BrowserPolicyService } from "../../admin-console/services/browser-policy.service"; diff --git a/apps/browser/src/tools/popup/settings/export.component.ts b/apps/browser/src/tools/popup/settings/export.component.ts index dd18bb1e94..70735b5184 100644 --- a/apps/browser/src/tools/popup/settings/export.component.ts +++ b/apps/browser/src/tools/popup/settings/export.component.ts @@ -12,7 +12,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { DialogService } from "@bitwarden/components"; -import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export"; +import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core"; @Component({ selector: "app-export", diff --git a/apps/browser/tsconfig.json b/apps/browser/tsconfig.json index 5e202c054e..442e153ef2 100644 --- a/apps/browser/tsconfig.json +++ b/apps/browser/tsconfig.json @@ -17,7 +17,9 @@ "@bitwarden/billing": ["../../libs/billing/src"], "@bitwarden/common/*": ["../../libs/common/src/*"], "@bitwarden/components": ["../../libs/components/src"], - "@bitwarden/exporter/*": ["../../libs/exporter/src/*"], + "@bitwarden/vault-export-core": [ + "../../libs/tools/export/vault-export/vault-export-core/src" + ], "@bitwarden/importer/core": ["../../libs/importer/src"], "@bitwarden/importer/ui": ["../../libs/importer/src/components"], "@bitwarden/platform": ["../../libs/platform/src"], diff --git a/apps/cli/src/bw.ts b/apps/cli/src/bw.ts index 51e4d0af99..a3f163a77f 100644 --- a/apps/cli/src/bw.ts +++ b/apps/cli/src/bw.ts @@ -94,14 +94,6 @@ import { FolderService } from "@bitwarden/common/vault/services/folder/folder.se import { SyncNotifierService } from "@bitwarden/common/vault/services/sync/sync-notifier.service"; import { SyncService } from "@bitwarden/common/vault/services/sync/sync.service"; import { TotpService } from "@bitwarden/common/vault/services/totp.service"; -import { - IndividualVaultExportService, - IndividualVaultExportServiceAbstraction, - OrganizationVaultExportService, - OrganizationVaultExportServiceAbstraction, - VaultExportService, - VaultExportServiceAbstraction, -} from "@bitwarden/exporter/vault-export"; import { ImportApiService, ImportApiServiceAbstraction, @@ -109,6 +101,14 @@ import { ImportServiceAbstraction, } from "@bitwarden/importer/core"; import { NodeCryptoFunctionService } from "@bitwarden/node/services/node-crypto-function.service"; +import { + IndividualVaultExportService, + IndividualVaultExportServiceAbstraction, + OrganizationVaultExportService, + OrganizationVaultExportServiceAbstraction, + VaultExportService, + VaultExportServiceAbstraction, +} from "@bitwarden/vault-export-core"; import { CliConfigService } from "./platform/services/cli-config.service"; import { CliPlatformUtilsService } from "./platform/services/cli-platform-utils.service"; diff --git a/apps/cli/src/tools/export.command.ts b/apps/cli/src/tools/export.command.ts index dbb0f86e06..71858a9c95 100644 --- a/apps/cli/src/tools/export.command.ts +++ b/apps/cli/src/tools/export.command.ts @@ -10,7 +10,7 @@ import { ExportFormat, EXPORT_FORMATS, VaultExportServiceAbstraction, -} from "@bitwarden/exporter/vault-export"; +} from "@bitwarden/vault-export-core"; import { Response } from "../models/response"; import { CliUtils } from "../utils"; diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json index 7be2480a26..b5e9b5a190 100644 --- a/apps/cli/tsconfig.json +++ b/apps/cli/tsconfig.json @@ -17,7 +17,9 @@ "@bitwarden/auth/angular": ["../../libs/auth/src/angular"], "@bitwarden/common/*": ["../../libs/common/src/*"], "@bitwarden/importer/core": ["../../libs/importer/src"], - "@bitwarden/exporter/*": ["../../libs/exporter/src/*"], + "@bitwarden/vault-export-core": [ + "../../libs/tools/export/vault-export/vault-export-core/src" + ], "@bitwarden/node/*": ["../../libs/node/src/*"] } }, diff --git a/apps/desktop/src/app/tools/export/export.component.ts b/apps/desktop/src/app/tools/export/export.component.ts index b44453cb57..3a740122eb 100644 --- a/apps/desktop/src/app/tools/export/export.component.ts +++ b/apps/desktop/src/app/tools/export/export.component.ts @@ -11,7 +11,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { DialogService } from "@bitwarden/components"; -import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export"; +import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core"; @Component({ selector: "app-export", diff --git a/apps/desktop/tsconfig.json b/apps/desktop/tsconfig.json index e2be86acec..63a1af06d7 100644 --- a/apps/desktop/tsconfig.json +++ b/apps/desktop/tsconfig.json @@ -17,7 +17,9 @@ "@bitwarden/billing": ["../../libs/billing/src"], "@bitwarden/common/*": ["../../libs/common/src/*"], "@bitwarden/components": ["../../libs/components/src"], - "@bitwarden/exporter/*": ["../../libs/exporter/src/*"], + "@bitwarden/vault-export-core": [ + "../../libs/tools/export/vault-export/vault-export-core/src" + ], "@bitwarden/importer/core": ["../../libs/importer/src"], "@bitwarden/importer/ui": ["../../libs/importer/src/components"], "@bitwarden/node/*": ["../../libs/node/src/*"], diff --git a/apps/web/src/app/admin-console/organizations/tools/vault-export/org-vault-export.component.ts b/apps/web/src/app/admin-console/organizations/tools/vault-export/org-vault-export.component.ts index 38c2f99c87..7a2a67b69c 100644 --- a/apps/web/src/app/admin-console/organizations/tools/vault-export/org-vault-export.component.ts +++ b/apps/web/src/app/admin-console/organizations/tools/vault-export/org-vault-export.component.ts @@ -12,7 +12,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { DialogService } from "@bitwarden/components"; -import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export"; +import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core"; import { ExportComponent } from "../../../../tools/vault-export/export.component"; diff --git a/apps/web/src/app/tools/event-export/event-export.service.ts b/apps/web/src/app/tools/event-export/event-export.service.ts index a96dc8e59c..68df258b13 100644 --- a/apps/web/src/app/tools/event-export/event-export.service.ts +++ b/apps/web/src/app/tools/event-export/event-export.service.ts @@ -2,7 +2,6 @@ import { Injectable } from "@angular/core"; import * as papa from "papaparse"; import { EventView } from "@bitwarden/common/models/view/event.view"; -import { ExportHelper } from "@bitwarden/exporter/export-helper"; import { EventExport } from "./event.export"; @@ -15,6 +14,25 @@ export class EventExportService { } getFileName(prefix: string = null, extension = "csv"): string { - return ExportHelper.getFileName(prefix, extension); + const now = new Date(); + const dateString = + now.getFullYear() + + "" + + this.padNumber(now.getMonth() + 1, 2) + + "" + + this.padNumber(now.getDate(), 2) + + this.padNumber(now.getHours(), 2) + + "" + + this.padNumber(now.getMinutes(), 2) + + this.padNumber(now.getSeconds(), 2); + + return "bitwarden" + (prefix ? "_" + prefix : "") + "_export_" + dateString + "." + extension; + } + + private padNumber(num: number, width: number, padCharacter = "0"): string { + const numString = num.toString(); + return numString.length >= width + ? numString + : new Array(width - numString.length + 1).join(padCharacter) + numString; } } diff --git a/apps/web/src/app/tools/vault-export/export.component.ts b/apps/web/src/app/tools/vault-export/export.component.ts index c55a2a38f7..e3b153bfcc 100644 --- a/apps/web/src/app/tools/vault-export/export.component.ts +++ b/apps/web/src/app/tools/vault-export/export.component.ts @@ -13,7 +13,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { EncryptedExportType } from "@bitwarden/common/tools/enums/encrypted-export-type.enum"; import { DialogService } from "@bitwarden/components"; -import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export"; +import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core"; import { openUserVerificationPrompt } from "../../auth/shared/components/user-verification"; diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 00610326a0..3add11f84c 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -12,7 +12,9 @@ "@bitwarden/billing": ["../../libs/billing/src"], "@bitwarden/common/*": ["../../libs/common/src/*"], "@bitwarden/components": ["../../libs/components/src"], - "@bitwarden/exporter/*": ["../../libs/exporter/src/*"], + "@bitwarden/vault-export-core": [ + "../../libs/tools/export/vault-export/vault-export-core/src" + ], "@bitwarden/importer/core": ["../../libs/importer/src"], "@bitwarden/importer/ui": ["../../libs/importer/src/components"], "@bitwarden/platform": ["../../libs/platform/src"], diff --git a/bitwarden_license/bit-web/tsconfig.json b/bitwarden_license/bit-web/tsconfig.json index c94e20a2a8..01610c5e4a 100644 --- a/bitwarden_license/bit-web/tsconfig.json +++ b/bitwarden_license/bit-web/tsconfig.json @@ -8,7 +8,9 @@ "@bitwarden/billing": ["../../libs/billing/src"], "@bitwarden/common/*": ["../../libs/common/src/*"], "@bitwarden/components": ["../../libs/components/src"], - "@bitwarden/exporter/*": ["../../libs/exporter/src/*"], + "@bitwarden/vault-export-core": [ + "../../libs/tools/export/vault-export/vault-export-core/src" + ], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/vault": ["../../libs/vault/src"], "@bitwarden/web-vault/*": ["../../apps/web/src/*"] diff --git a/jest.config.js b/jest.config.js index 41249c2397..72c5ba7e5e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -26,7 +26,7 @@ module.exports = { "/libs/billing/jest.config.js", "/libs/common/jest.config.js", "/libs/components/jest.config.js", - "/libs/exporter/jest.config.js", + "/libs/tools/export/vault-export/vault-export-core/jest.config.js", "/libs/importer/jest.config.js", "/libs/platform/jest.config.js", "/libs/node/jest.config.js", diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index f27756dfa1..da797aec9f 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -190,14 +190,6 @@ import { SyncNotifierService } from "@bitwarden/common/vault/services/sync/sync- import { SyncService } from "@bitwarden/common/vault/services/sync/sync.service"; import { TotpService } from "@bitwarden/common/vault/services/totp.service"; import { VaultSettingsService } from "@bitwarden/common/vault/services/vault-settings/vault-settings.service"; -import { - VaultExportService, - VaultExportServiceAbstraction, - OrganizationVaultExportService, - OrganizationVaultExportServiceAbstraction, - IndividualVaultExportService, - IndividualVaultExportServiceAbstraction, -} from "@bitwarden/exporter/vault-export"; import { ImportApiService, ImportApiServiceAbstraction, @@ -205,6 +197,14 @@ import { ImportServiceAbstraction, } from "@bitwarden/importer/core"; import { PasswordRepromptService } from "@bitwarden/vault"; +import { + VaultExportService, + VaultExportServiceAbstraction, + OrganizationVaultExportService, + OrganizationVaultExportServiceAbstraction, + IndividualVaultExportService, + IndividualVaultExportServiceAbstraction, +} from "@bitwarden/vault-export-core"; import { AuthGuard } from "../auth/guards/auth.guard"; import { UnauthGuard } from "../auth/guards/unauth.guard"; diff --git a/libs/angular/src/tools/export/components/export.component.ts b/libs/angular/src/tools/export/components/export.component.ts index 987b0a8433..6c7ac0f365 100644 --- a/libs/angular/src/tools/export/components/export.component.ts +++ b/libs/angular/src/tools/export/components/export.component.ts @@ -16,7 +16,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncryptedExportType } from "@bitwarden/common/tools/enums/encrypted-export-type.enum"; import { DialogService } from "@bitwarden/components"; -import { VaultExportServiceAbstraction } from "@bitwarden/exporter/vault-export"; +import { VaultExportServiceAbstraction } from "@bitwarden/vault-export-core"; import { PasswordStrengthComponent } from "../../password-strength/password-strength.component"; diff --git a/libs/importer/package.json b/libs/importer/package.json index d510f1589e..9379e9244f 100644 --- a/libs/importer/package.json +++ b/libs/importer/package.json @@ -19,6 +19,6 @@ }, "dependencies": { "@bitwarden/common": "file:../common", - "@bitwarden/exporter": "file:../exporter" + "@bitwarden/vault-export-core": "file:../tools/export/vault-export/vault-export-core" } } diff --git a/libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts b/libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts index b63e3b50a7..5c323ffa99 100644 --- a/libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts +++ b/libs/importer/src/importers/bitwarden/bitwarden-json-importer.ts @@ -15,7 +15,7 @@ import { BitwardenJsonExport, BitwardenUnEncryptedIndividualJsonExport, BitwardenUnEncryptedOrgJsonExport, -} from "@bitwarden/exporter/vault-export/bitwarden-json-export-types"; +} from "@bitwarden/vault-export-core"; import { ImportResult } from "../../models/import-result"; import { BaseImporter } from "../base-importer"; diff --git a/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts b/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts index 7215496b30..9e047b063c 100644 --- a/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts +++ b/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts @@ -5,7 +5,7 @@ import { KdfType } from "@bitwarden/common/platform/enums"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { BitwardenPasswordProtectedFileFormat } from "@bitwarden/exporter/vault-export/bitwarden-json-export-types"; +import { BitwardenPasswordProtectedFileFormat } from "@bitwarden/vault-export-core"; import { ImportResult } from "../../models/import-result"; import { Importer } from "../importer"; diff --git a/libs/shared/tsconfig.libs.json b/libs/shared/tsconfig.libs.json index e90cf58c2d..079a49fbd5 100644 --- a/libs/shared/tsconfig.libs.json +++ b/libs/shared/tsconfig.libs.json @@ -9,7 +9,7 @@ "@bitwarden/billing": ["../billing/src"], "@bitwarden/common/*": ["../common/src/*"], "@bitwarden/components": ["../components/src"], - "@bitwarden/exporter/*": ["../exporter/src/*"], + "@bitwarden/vault-export-core": ["../tools/export/vault-export/vault-export-core/src"], "@bitwarden/importer/core": ["../importer/src"], "@bitwarden/importer/ui": ["../importer/src/components"], "@bitwarden/platform": ["../platform/src"], diff --git a/libs/tools/export/vault-export/README.md b/libs/tools/export/vault-export/README.md new file mode 100644 index 0000000000..45d9e08e5e --- /dev/null +++ b/libs/tools/export/vault-export/README.md @@ -0,0 +1,15 @@ +# Vault Export + +This folder contains 2 packages that can be used to export a users or an organizational vault. + +## vault-export-core + +Package name: `@bitwarden/vault-export-core` + +Contains all types, models, and services to export a user or organization's vault. + +Currently in use by the Bitwarden Web Vault, CLI, desktop app and browser extension + +## vault-export-ui + +Package name: `@bitwarden/vault-export-ui` diff --git a/libs/exporter/jest.config.js b/libs/tools/export/vault-export/vault-export-core/jest.config.js similarity index 59% rename from libs/exporter/jest.config.js rename to libs/tools/export/vault-export/vault-export-core/jest.config.js index 68daba3d40..955b8e7763 100644 --- a/libs/exporter/jest.config.js +++ b/libs/tools/export/vault-export/vault-export-core/jest.config.js @@ -1,15 +1,13 @@ const { pathsToModuleNameMapper } = require("ts-jest"); -const { compilerOptions } = require("../shared/tsconfig.libs"); - -const sharedConfig = require("../shared/jest.config.ts"); +const { compilerOptions } = require("../../../../shared/tsconfig.libs"); /** @type {import('jest').Config} */ module.exports = { - ...sharedConfig, + testMatch: ["**/+(*.)+(spec).+(ts)"], preset: "ts-jest", testEnvironment: "jsdom", moduleNameMapper: pathsToModuleNameMapper(compilerOptions?.paths || {}, { - prefix: "/", + prefix: "/../../../", }), }; diff --git a/libs/exporter/package.json b/libs/tools/export/vault-export/vault-export-core/package.json similarity index 72% rename from libs/exporter/package.json rename to libs/tools/export/vault-export/vault-export-core/package.json index e3c3427ca3..2d6503630b 100644 --- a/libs/exporter/package.json +++ b/libs/tools/export/vault-export/vault-export-core/package.json @@ -1,7 +1,7 @@ { - "name": "@bitwarden/exporter", + "name": "@bitwarden/vault-export-core", "version": "0.0.0", - "description": "Home for all Bitwarden exporters.", + "description": "Home for all Bitwarden vault exporters.", "keywords": [ "bitwarden" ], @@ -18,6 +18,6 @@ "build:watch": "npm run clean && tsc -watch" }, "dependencies": { - "@bitwarden/common": "file:../common" + "@bitwarden/common": "file:../../../../common" } } diff --git a/libs/exporter/src/vault-export/index.ts b/libs/tools/export/vault-export/vault-export-core/src/index.ts similarity index 93% rename from libs/exporter/src/vault-export/index.ts rename to libs/tools/export/vault-export/vault-export-core/src/index.ts index e7eae409d5..8189bd9801 100644 --- a/libs/exporter/src/vault-export/index.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/index.ts @@ -1,3 +1,5 @@ +export * from "./types"; + export * from "./services/vault-export.service.abstraction"; export * from "./services/vault-export.service"; export * from "./services/org-vault-export.service.abstraction"; diff --git a/libs/exporter/src/vault-export/services/base-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts similarity index 95% rename from libs/exporter/src/vault-export/services/base-vault-export.service.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts index 53cfd04174..1865c94c7d 100644 --- a/libs/exporter/src/vault-export/services/base-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts @@ -7,9 +7,7 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { BitwardenCsvExportType } from "../bitwarden-csv-export-type"; -import { BitwardenPasswordProtectedFileFormat } from "../bitwarden-json-export-types"; - +import { BitwardenCsvExportType, BitwardenPasswordProtectedFileFormat } from "../types"; export class BaseVaultExportService { constructor( protected cryptoService: CryptoService, diff --git a/libs/exporter/src/export-helper.ts b/libs/tools/export/vault-export/vault-export-core/src/services/export-helper.ts similarity index 100% rename from libs/exporter/src/export-helper.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/export-helper.ts diff --git a/libs/exporter/src/vault-export/services/individual-vault-export.service.abstraction.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.abstraction.ts similarity index 100% rename from libs/exporter/src/vault-export/services/individual-vault-export.service.abstraction.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.abstraction.ts diff --git a/libs/exporter/src/vault-export/services/individual-vault-export.service.spec.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts similarity index 99% rename from libs/exporter/src/vault-export/services/individual-vault-export.service.spec.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts index f1bd2d130c..fc8faa4b5b 100644 --- a/libs/exporter/src/vault-export/services/individual-vault-export.service.spec.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts @@ -18,7 +18,7 @@ import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; -import { BuildTestObject, GetUniqueString } from "../../../../common/spec"; +import { BuildTestObject, GetUniqueString } from "../../../../../../common/spec"; import { IndividualVaultExportService } from "./individual-vault-export.service"; diff --git a/libs/exporter/src/vault-export/services/individual-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts similarity index 97% rename from libs/exporter/src/vault-export/services/individual-vault-export.service.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts index 6dcece2634..5f3bd9de52 100644 --- a/libs/exporter/src/vault-export/services/individual-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts @@ -13,11 +13,11 @@ import { Folder } from "@bitwarden/common/vault/models/domain/folder"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; -import { BitwardenCsvIndividualExportType } from "../bitwarden-csv-export-type"; import { + BitwardenCsvIndividualExportType, BitwardenEncryptedIndividualJsonExport, BitwardenUnEncryptedIndividualJsonExport, -} from "../bitwarden-json-export-types"; +} from "../types"; import { BaseVaultExportService } from "./base-vault-export.service"; import { IndividualVaultExportServiceAbstraction } from "./individual-vault-export.service.abstraction"; diff --git a/libs/exporter/src/vault-export/services/org-vault-export.service.abstraction.ts b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.abstraction.ts similarity index 100% rename from libs/exporter/src/vault-export/services/org-vault-export.service.abstraction.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.abstraction.ts diff --git a/libs/exporter/src/vault-export/services/org-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts similarity index 98% rename from libs/exporter/src/vault-export/services/org-vault-export.service.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts index fad4fd2f1a..2346545231 100644 --- a/libs/exporter/src/vault-export/services/org-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts @@ -17,11 +17,11 @@ import { CollectionDetailsResponse } from "@bitwarden/common/vault/models/respon import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; -import { BitwardenCsvOrgExportType } from "../bitwarden-csv-export-type"; import { + BitwardenCsvOrgExportType, BitwardenEncryptedOrgJsonExport, BitwardenUnEncryptedOrgJsonExport, -} from "../bitwarden-json-export-types"; +} from "../types"; import { BaseVaultExportService } from "./base-vault-export.service"; import { OrganizationVaultExportServiceAbstraction } from "./org-vault-export.service.abstraction"; diff --git a/libs/exporter/src/vault-export/services/vault-export.service.abstraction.ts b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.abstraction.ts similarity index 100% rename from libs/exporter/src/vault-export/services/vault-export.service.abstraction.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.abstraction.ts diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts new file mode 100644 index 0000000000..fc8faa4b5b --- /dev/null +++ b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts @@ -0,0 +1,289 @@ +import { mock, MockProxy } from "jest-mock-extended"; + +import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; +import { CipherWithIdExport } from "@bitwarden/common/models/export/cipher-with-ids.export"; +import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; +import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; +import { KdfType, PBKDF2_ITERATIONS } from "@bitwarden/common/platform/enums"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string"; +import { StateService } from "@bitwarden/common/platform/services/state.service"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; +import { CipherType } from "@bitwarden/common/vault/enums"; +import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; +import { Folder } from "@bitwarden/common/vault/models/domain/folder"; +import { Login } from "@bitwarden/common/vault/models/domain/login"; +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; +import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; + +import { BuildTestObject, GetUniqueString } from "../../../../../../common/spec"; + +import { IndividualVaultExportService } from "./individual-vault-export.service"; + +const UserCipherViews = [ + generateCipherView(false), + generateCipherView(false), + generateCipherView(true), +]; + +const UserCipherDomains = [ + generateCipherDomain(false), + generateCipherDomain(false), + generateCipherDomain(true), +]; + +const UserFolderViews = [generateFolderView(), generateFolderView()]; + +const UserFolders = [generateFolder(), generateFolder()]; + +function generateCipherView(deleted: boolean) { + return BuildTestObject( + { + id: GetUniqueString("id"), + notes: GetUniqueString("notes"), + type: CipherType.Login, + login: BuildTestObject( + { + username: GetUniqueString("username"), + password: GetUniqueString("password"), + }, + LoginView, + ), + collectionIds: null, + deletedDate: deleted ? new Date() : null, + }, + CipherView, + ); +} + +function generateCipherDomain(deleted: boolean) { + return BuildTestObject( + { + id: GetUniqueString("id"), + notes: new EncString(GetUniqueString("notes")), + type: CipherType.Login, + login: BuildTestObject( + { + username: new EncString(GetUniqueString("username")), + password: new EncString(GetUniqueString("password")), + }, + Login, + ), + collectionIds: null, + deletedDate: deleted ? new Date() : null, + }, + Cipher, + ); +} + +function generateFolderView() { + return BuildTestObject( + { + id: GetUniqueString("id"), + name: GetUniqueString("name"), + revisionDate: new Date(), + }, + FolderView, + ); +} + +function generateFolder() { + const actual = Folder.fromJSON({ + revisionDate: new Date("2022-08-04T01:06:40.441Z").toISOString(), + name: "name" as EncryptedString, + id: "id", + }); + return actual; +} + +function expectEqualCiphers(ciphers: CipherView[] | Cipher[], jsonResult: string) { + const actual = JSON.stringify(JSON.parse(jsonResult).items); + const items: CipherWithIdExport[] = []; + ciphers.forEach((c: CipherView | Cipher) => { + const item = new CipherWithIdExport(); + item.build(c); + items.push(item); + }); + + expect(actual).toEqual(JSON.stringify(items)); +} + +function expectEqualFolderViews(folderviews: FolderView[] | Folder[], jsonResult: string) { + const actual = JSON.stringify(JSON.parse(jsonResult).folders); + const folders: FolderResponse[] = []; + folderviews.forEach((c) => { + const folder = new FolderResponse(); + folder.id = c.id; + folder.name = c.name.toString(); + folders.push(folder); + }); + + expect(actual.length).toBeGreaterThan(0); + expect(actual).toEqual(JSON.stringify(folders)); +} + +function expectEqualFolders(folders: Folder[], jsonResult: string) { + const actual = JSON.stringify(JSON.parse(jsonResult).folders); + const items: Folder[] = []; + folders.forEach((c) => { + const item = new Folder(); + item.id = c.id; + item.name = c.name; + items.push(item); + }); + + expect(actual.length).toBeGreaterThan(0); + expect(actual).toEqual(JSON.stringify(items)); +} + +describe("VaultExportService", () => { + let exportService: IndividualVaultExportService; + let cryptoFunctionService: MockProxy; + let cipherService: MockProxy; + let folderService: MockProxy; + let cryptoService: MockProxy; + let stateService: MockProxy; + + beforeEach(() => { + cryptoFunctionService = mock(); + cipherService = mock(); + folderService = mock(); + cryptoService = mock(); + stateService = mock(); + + folderService.getAllDecryptedFromState.mockResolvedValue(UserFolderViews); + folderService.getAllFromState.mockResolvedValue(UserFolders); + stateService.getKdfType.mockResolvedValue(KdfType.PBKDF2_SHA256); + stateService.getKdfConfig.mockResolvedValue(new KdfConfig(PBKDF2_ITERATIONS.defaultValue)); + cryptoService.encrypt.mockResolvedValue(new EncString("encrypted")); + + exportService = new IndividualVaultExportService( + folderService, + cipherService, + cryptoService, + cryptoFunctionService, + stateService, + ); + }); + + it("exports unencrypted user ciphers", async () => { + cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews.slice(0, 1)); + + const actual = await exportService.getExport("json"); + + expectEqualCiphers(UserCipherViews.slice(0, 1), actual); + }); + + it("exports encrypted json user ciphers", async () => { + cipherService.getAll.mockResolvedValue(UserCipherDomains.slice(0, 1)); + + const actual = await exportService.getExport("encrypted_json"); + + expectEqualCiphers(UserCipherDomains.slice(0, 1), actual); + }); + + it("does not unencrypted export trashed user items", async () => { + cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews); + + const actual = await exportService.getExport("json"); + + expectEqualCiphers(UserCipherViews.slice(0, 2), actual); + }); + + it("does not encrypted export trashed user items", async () => { + cipherService.getAll.mockResolvedValue(UserCipherDomains); + + const actual = await exportService.getExport("encrypted_json"); + + expectEqualCiphers(UserCipherDomains.slice(0, 2), actual); + }); + + describe("password protected export", () => { + let exportString: string; + let exportObject: any; + let mac: MockProxy; + let data: MockProxy; + const password = "password"; + const salt = "salt"; + + describe("export json object", () => { + beforeEach(async () => { + mac = mock(); + data = mock(); + + mac.encryptedString = "mac" as EncryptedString; + data.encryptedString = "encData" as EncryptedString; + + jest.spyOn(Utils, "fromBufferToB64").mockReturnValue(salt); + cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews.slice(0, 1)); + + exportString = await exportService.getPasswordProtectedExport(password); + exportObject = JSON.parse(exportString); + }); + + it("specifies it is encrypted", () => { + expect(exportObject.encrypted).toBe(true); + }); + + it("specifies it's password protected", () => { + expect(exportObject.passwordProtected).toBe(true); + }); + + it("specifies salt", () => { + expect(exportObject.salt).toEqual("salt"); + }); + + it("specifies kdfIterations", () => { + expect(exportObject.kdfIterations).toEqual(PBKDF2_ITERATIONS.defaultValue); + }); + + it("has kdfType", () => { + expect(exportObject.kdfType).toEqual(KdfType.PBKDF2_SHA256); + }); + + it("has a mac property", async () => { + cryptoService.encrypt.mockResolvedValue(mac); + exportString = await exportService.getPasswordProtectedExport(password); + exportObject = JSON.parse(exportString); + + expect(exportObject.encKeyValidation_DO_NOT_EDIT).toEqual(mac.encryptedString); + }); + + it("has data property", async () => { + cryptoService.encrypt.mockResolvedValue(data); + exportString = await exportService.getPasswordProtectedExport(password); + exportObject = JSON.parse(exportString); + + expect(exportObject.data).toEqual(data.encryptedString); + }); + + it("encrypts the data property", async () => { + const unencrypted = await exportService.getExport(); + expect(exportObject.data).not.toEqual(unencrypted); + }); + }); + }); + + it("exported unencrypted object contains folders", async () => { + cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews.slice(0, 1)); + await folderService.getAllDecryptedFromState(); + const actual = await exportService.getExport("json"); + + expectEqualFolderViews(UserFolderViews, actual); + }); + + it("exported encrypted json contains folders", async () => { + cipherService.getAll.mockResolvedValue(UserCipherDomains.slice(0, 1)); + await folderService.getAllFromState(); + const actual = await exportService.getExport("encrypted_json"); + + expectEqualFolders(UserFolders, actual); + }); +}); + +export class FolderResponse { + id: string = null; + name: string = null; +} diff --git a/libs/exporter/src/vault-export/services/vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.ts similarity index 97% rename from libs/exporter/src/vault-export/services/vault-export.service.ts rename to libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.ts index 00e2a61f7c..5afb19134d 100644 --- a/libs/exporter/src/vault-export/services/vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.ts @@ -1,7 +1,6 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { ExportHelper } from "../../export-helper"; - +import { ExportHelper } from "./export-helper"; import { IndividualVaultExportServiceAbstraction } from "./individual-vault-export.service.abstraction"; import { OrganizationVaultExportServiceAbstraction } from "./org-vault-export.service.abstraction"; import { ExportFormat, VaultExportServiceAbstraction } from "./vault-export.service.abstraction"; diff --git a/libs/exporter/src/vault-export/bitwarden-csv-export-type.ts b/libs/tools/export/vault-export/vault-export-core/src/types/bitwarden-csv-export-type.ts similarity index 100% rename from libs/exporter/src/vault-export/bitwarden-csv-export-type.ts rename to libs/tools/export/vault-export/vault-export-core/src/types/bitwarden-csv-export-type.ts diff --git a/libs/exporter/src/vault-export/bitwarden-json-export-types.ts b/libs/tools/export/vault-export/vault-export-core/src/types/bitwarden-json-export-types.ts similarity index 100% rename from libs/exporter/src/vault-export/bitwarden-json-export-types.ts rename to libs/tools/export/vault-export/vault-export-core/src/types/bitwarden-json-export-types.ts diff --git a/libs/tools/export/vault-export/vault-export-core/src/types/index.ts b/libs/tools/export/vault-export/vault-export-core/src/types/index.ts new file mode 100644 index 0000000000..172c88e95d --- /dev/null +++ b/libs/tools/export/vault-export/vault-export-core/src/types/index.ts @@ -0,0 +1,2 @@ +export * from "./bitwarden-csv-export-type"; +export * from "./bitwarden-json-export-types"; diff --git a/libs/exporter/tsconfig.json b/libs/tools/export/vault-export/vault-export-core/tsconfig.json similarity index 56% rename from libs/exporter/tsconfig.json rename to libs/tools/export/vault-export/vault-export-core/tsconfig.json index 4952ed5adb..5cb9026037 100644 --- a/libs/exporter/tsconfig.json +++ b/libs/tools/export/vault-export/vault-export-core/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../shared/tsconfig.libs", + "extends": "../../../../shared/tsconfig.libs", "include": ["src"], "exclude": ["node_modules", "dist"] } diff --git a/libs/exporter/tsconfig.spec.json b/libs/tools/export/vault-export/vault-export-core/tsconfig.spec.json similarity index 100% rename from libs/exporter/tsconfig.spec.json rename to libs/tools/export/vault-export/vault-export-core/tsconfig.spec.json diff --git a/package-lock.json b/package-lock.json index eef9b7258d..def0b436d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -295,21 +295,13 @@ "name": "@bitwarden/components", "version": "0.0.0" }, - "libs/exporter": { - "name": "@bitwarden/exporter", - "version": "0.0.0", - "license": "GPL-3.0", - "dependencies": { - "@bitwarden/common": "file:../common" - } - }, "libs/importer": { "name": "@bitwarden/importer", "version": "0.0.0", "license": "GPL-3.0", "dependencies": { "@bitwarden/common": "file:../common", - "@bitwarden/exporter": "file:../exporter" + "@bitwarden/vault-export-core": "file:../tools/export/vault-export/vault-export-core" } }, "libs/node": { @@ -325,6 +317,14 @@ "version": "0.0.0", "license": "GPL-3.0" }, + "libs/tools/export/vault-export/vault-export-core": { + "name": "@bitwarden/vault-export-core", + "version": "0.0.0", + "license": "GPL-3.0", + "dependencies": { + "@bitwarden/common": "file:../../../../common" + } + }, "libs/vault": { "name": "@bitwarden/vault", "version": "0.0.0", @@ -3658,10 +3658,6 @@ "resolved": "apps/desktop/desktop_native", "link": true }, - "node_modules/@bitwarden/exporter": { - "resolved": "libs/exporter", - "link": true - }, "node_modules/@bitwarden/importer": { "resolved": "libs/importer", "link": true @@ -3678,6 +3674,10 @@ "resolved": "libs/vault", "link": true }, + "node_modules/@bitwarden/vault-export-core": { + "resolved": "libs/tools/export/vault-export/vault-export-core", + "link": true + }, "node_modules/@bitwarden/web-vault": { "resolved": "apps/web", "link": true diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 72c3f9bde9..6dd355c8da 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -21,7 +21,7 @@ "@bitwarden/billing": ["./libs/billing/src"], "@bitwarden/common/*": ["./libs/common/src/*"], "@bitwarden/components": ["./libs/components/src"], - "@bitwarden/exporter/*": ["./libs/exporter/src/*"], + "@bitwarden/vault-export-core": [".libs/tools/export/vault-export/vault-export-core/src"], "@bitwarden/importer/core": ["./libs/importer/src"], "@bitwarden/importer/ui": ["./libs/importer/src/components"], "@bitwarden/platform": ["./libs/platform/src"], diff --git a/tsconfig.json b/tsconfig.json index 15f282a8c5..4aaf670dbc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,7 +22,7 @@ "@bitwarden/billing": ["./libs/billing/src"], "@bitwarden/common/*": ["./libs/common/src/*"], "@bitwarden/components": ["./libs/components/src"], - "@bitwarden/exporter/*": ["./libs/exporter/src/*"], + "@bitwarden/vault-export-core": ["./libs/tools/export/vault-export/vault-export-core/src"], "@bitwarden/importer/core": ["./libs/importer/src"], "@bitwarden/importer/ui": ["./libs/importer/src/components"], "@bitwarden/platform": ["./libs/platform/src"],