1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00
Files
browser/apps/cli/src/commands/export.command.ts
Daniel James Smith 80f5a883e0 [PS-1884] [TDL-189] [TDL-203] Move libs/node files to CLI and rename per ADR12 (#4069)
* Extract files only used in cli out of libs/node

Move commands from libs/node to cli
Move program from libs/node to cli
Move services from libs/node to cli
Move specs from libs/node to cli

Naming changes based on ADR 12
Rename commands
Rename models/request
Rename models/response
Remove entries from whitelist-capital-letters.txt

* Merge lowDbStorageService into base class

Move logic from extended lowdbStorage.service.ts into base-lowdb-storage.service.ts
Delete lowdb-storage.service.ts
Rename base-lowdb-storage.service.ts to lowdb-storage.service.ts

* Merge login.command with base class

program.ts - changed import temporarily to make it easier to review
Remove passing in clientId, set "cli" when constructing ssoRedirectUri call
Remove setting callbacks, use private methods instead
Remove i18nService from constructor params
Add syncService, keyConnectorService and logoutCallback to constructor
Merge successCallback with handleSuccessResponse
Remove validatedParams callback and added private method
Move options(program.OptionValues) and set in run()
Delete login.command.ts

* Rename base-login.command.ts to login.command.ts

* Merge base.program.ts with program.ts
2022-11-18 13:20:19 +01:00

98 lines
3.4 KiB
TypeScript

import * as program from "commander";
import * as inquirer from "inquirer";
import { ExportFormat, ExportService } from "@bitwarden/common/abstractions/export.service";
import { PolicyService } from "@bitwarden/common/abstractions/policy/policy.service.abstraction";
import { PolicyType } from "@bitwarden/common/enums/policyType";
import { Utils } from "@bitwarden/common/misc/utils";
import { Response } from "../models/response";
import { CliUtils } from "../utils";
export class ExportCommand {
constructor(private exportService: ExportService, private policyService: PolicyService) {}
async run(options: program.OptionValues): Promise<Response> {
if (
options.organizationid == null &&
(await this.policyService.policyAppliesToUser(PolicyType.DisablePersonalVaultExport))
) {
return Response.badRequest(
"One or more organization policies prevents you from exporting your personal vault."
);
}
const format = options.format ?? "csv";
if (options.organizationid != null && !Utils.isGuid(options.organizationid)) {
return Response.error("`" + options.organizationid + "` is not a GUID.");
}
let exportContent: string = null;
try {
exportContent =
format === "encrypted_json"
? await this.getProtectedExport(options.password, options.organizationid)
: await this.getUnprotectedExport(format, options.organizationid);
} catch (e) {
return Response.error(e);
}
return await this.saveFile(exportContent, options, format);
}
private async getProtectedExport(passwordOption: string | boolean, organizationId?: string) {
const password = await this.promptPassword(passwordOption);
return password == null
? await this.exportService.getExport("encrypted_json", organizationId)
: await this.exportService.getPasswordProtectedExport(password, organizationId);
}
private async getUnprotectedExport(format: ExportFormat, organizationId?: string) {
return this.exportService.getExport(format, organizationId);
}
private async saveFile(
exportContent: string,
options: program.OptionValues,
format: ExportFormat
): Promise<Response> {
try {
const fileName = this.getFileName(format, options.organizationid != null ? "org" : null);
return await CliUtils.saveResultToFile(exportContent, options.output, fileName);
} catch (e) {
return Response.error(e.toString());
}
}
private getFileName(format: ExportFormat, prefix?: string) {
if (format === "encrypted_json") {
if (prefix == null) {
prefix = "encrypted";
} else {
prefix = "encrypted_" + prefix;
}
format = "json";
}
return this.exportService.getFileName(prefix, format);
}
private async promptPassword(password: string | boolean) {
// boolean => flag set with no value, we need to prompt for password
// string => flag set with value, use this value for password
// undefined/null/false => account protect, not password, no password needed
if (typeof password === "string") {
return password;
} else if (password) {
const answer: inquirer.Answers = await inquirer.createPromptModule({
output: process.stderr,
})({
type: "password",
name: "password",
message: "Export file password:",
});
return answer.password as string;
}
return null;
}
}