mirror of
https://github.com/bitwarden/browser
synced 2025-12-12 06:13:38 +00:00
[AC-2631] Add device-approval command scaffolding (#9351)
* Add device-approval scaffolding * Refactor: move helpers to BaseProgram * Update CODEOWNERS
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import * as chalk from "chalk";
|
||||
import { program, Command, OptionValues } from "commander";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
|
||||
@@ -8,6 +8,7 @@ import { LockCommand } from "./auth/commands/lock.command";
|
||||
import { LoginCommand } from "./auth/commands/login.command";
|
||||
import { LogoutCommand } from "./auth/commands/logout.command";
|
||||
import { UnlockCommand } from "./auth/commands/unlock.command";
|
||||
import { BaseProgram } from "./base-program";
|
||||
import { CompletionCommand } from "./commands/completion.command";
|
||||
import { ConfigCommand } from "./commands/config.command";
|
||||
import { EncodeCommand } from "./commands/encode.command";
|
||||
@@ -15,20 +16,14 @@ import { ServeCommand } from "./commands/serve.command";
|
||||
import { StatusCommand } from "./commands/status.command";
|
||||
import { UpdateCommand } from "./commands/update.command";
|
||||
import { Response } from "./models/response";
|
||||
import { ListResponse } from "./models/response/list.response";
|
||||
import { MessageResponse } from "./models/response/message.response";
|
||||
import { StringResponse } from "./models/response/string.response";
|
||||
import { TemplateResponse } from "./models/response/template.response";
|
||||
import { ServiceContainer } from "./service-container";
|
||||
import { GenerateCommand } from "./tools/generate.command";
|
||||
import { CliUtils } from "./utils";
|
||||
import { SyncCommand } from "./vault/sync.command";
|
||||
|
||||
const writeLn = CliUtils.writeLn;
|
||||
|
||||
export class Program {
|
||||
constructor(protected serviceContainer: ServiceContainer) {}
|
||||
|
||||
export class Program extends BaseProgram {
|
||||
async register() {
|
||||
program
|
||||
.option("--pretty", "Format output. JSON is tabbed with two spaces.")
|
||||
@@ -517,147 +512,4 @@ export class Program {
|
||||
await command.run(cmd);
|
||||
});
|
||||
}
|
||||
|
||||
protected processResponse(response: Response, exitImmediately = false) {
|
||||
if (!response.success) {
|
||||
if (process.env.BW_QUIET !== "true") {
|
||||
if (process.env.BW_RESPONSE === "true") {
|
||||
writeLn(this.getJson(response), true, false);
|
||||
} else {
|
||||
writeLn(chalk.redBright(response.message), true, true);
|
||||
}
|
||||
}
|
||||
const exitCode = process.env.BW_CLEANEXIT ? 0 : 1;
|
||||
if (exitImmediately) {
|
||||
process.exit(exitCode);
|
||||
} else {
|
||||
process.exitCode = exitCode;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.env.BW_RESPONSE === "true") {
|
||||
writeLn(this.getJson(response), true, false);
|
||||
} else if (response.data != null) {
|
||||
let out: string = null;
|
||||
|
||||
if (response.data.object === "template") {
|
||||
out = this.getJson((response.data as TemplateResponse).template);
|
||||
}
|
||||
|
||||
if (out == null) {
|
||||
if (response.data.object === "string") {
|
||||
const data = (response.data as StringResponse).data;
|
||||
if (data != null) {
|
||||
out = data;
|
||||
}
|
||||
} else if (response.data.object === "list") {
|
||||
out = this.getJson((response.data as ListResponse).data);
|
||||
} else if (response.data.object === "message") {
|
||||
out = this.getMessage(response);
|
||||
} else {
|
||||
out = this.getJson(response.data);
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null && process.env.BW_QUIET !== "true") {
|
||||
writeLn(out, true, false);
|
||||
}
|
||||
}
|
||||
if (exitImmediately) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
process.exitCode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private getJson(obj: any): string {
|
||||
if (process.env.BW_PRETTY === "true") {
|
||||
return JSON.stringify(obj, null, " ");
|
||||
} else {
|
||||
return JSON.stringify(obj);
|
||||
}
|
||||
}
|
||||
|
||||
private getMessage(response: Response): string {
|
||||
const message = response.data as MessageResponse;
|
||||
if (process.env.BW_RAW === "true") {
|
||||
return message.raw;
|
||||
}
|
||||
|
||||
let out = "";
|
||||
if (message.title != null) {
|
||||
if (message.noColor) {
|
||||
out = message.title;
|
||||
} else {
|
||||
out = chalk.greenBright(message.title);
|
||||
}
|
||||
}
|
||||
if (message.message != null) {
|
||||
if (message.title != null) {
|
||||
out += "\n";
|
||||
}
|
||||
out += message.message;
|
||||
}
|
||||
return out.trim() === "" ? null : out;
|
||||
}
|
||||
|
||||
private async exitIfAuthed() {
|
||||
const authed = await firstValueFrom(
|
||||
this.serviceContainer.authService.activeAccountStatus$.pipe(
|
||||
map((status) => status > AuthenticationStatus.LoggedOut),
|
||||
),
|
||||
);
|
||||
if (authed) {
|
||||
const email = await firstValueFrom(
|
||||
this.serviceContainer.accountService.activeAccount$.pipe(map((a) => a?.email)),
|
||||
);
|
||||
this.processResponse(Response.error("You are already logged in as " + email + "."), true);
|
||||
}
|
||||
}
|
||||
|
||||
private async exitIfNotAuthed() {
|
||||
const authed = await this.serviceContainer.stateService.getIsAuthenticated();
|
||||
if (!authed) {
|
||||
this.processResponse(Response.error("You are not logged in."), true);
|
||||
}
|
||||
}
|
||||
|
||||
protected async exitIfLocked() {
|
||||
await this.exitIfNotAuthed();
|
||||
if (await this.serviceContainer.cryptoService.hasUserKey()) {
|
||||
return;
|
||||
} else if (process.env.BW_NOINTERACTION !== "true") {
|
||||
// must unlock
|
||||
if (await this.serviceContainer.keyConnectorService.getUsesKeyConnector()) {
|
||||
const response = Response.error(
|
||||
"Your vault is locked. You must unlock your vault using your session key.\n" +
|
||||
"If you do not have your session key, you can get a new one by logging out and logging in again.",
|
||||
);
|
||||
this.processResponse(response, true);
|
||||
} else {
|
||||
const command = new UnlockCommand(
|
||||
this.serviceContainer.accountService,
|
||||
this.serviceContainer.masterPasswordService,
|
||||
this.serviceContainer.cryptoService,
|
||||
this.serviceContainer.stateService,
|
||||
this.serviceContainer.cryptoFunctionService,
|
||||
this.serviceContainer.apiService,
|
||||
this.serviceContainer.logService,
|
||||
this.serviceContainer.keyConnectorService,
|
||||
this.serviceContainer.environmentService,
|
||||
this.serviceContainer.syncService,
|
||||
this.serviceContainer.organizationApiService,
|
||||
this.serviceContainer.logout,
|
||||
this.serviceContainer.kdfConfigService,
|
||||
);
|
||||
const response = await command.run(null, null);
|
||||
if (!response.success) {
|
||||
this.processResponse(response, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.processResponse(Response.error("Vault is locked."), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user