1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-12 14:23:32 +00:00

[AC-2579] Set up bit-cli folder (#9092)

* Create bit-cli folder with configs

* Add bit-cli to workspace

* Refactor CLI app structure
  * services are managed by the ServiceContainer
  * programs are registered by register(Oss|Bit)Program
  * the app is bootstrapped by Main

* Reapply changes from #9099

* Reapply changes from #8604

* Reapply changes from #9115
This commit is contained in:
Thomas Rittson
2024-05-16 00:09:24 +10:00
committed by GitHub
parent 0812f00d24
commit b14bb92d78
21 changed files with 1200 additions and 1038 deletions

View File

@@ -8,7 +8,6 @@ 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 { Main } from "./bw";
import { CompletionCommand } from "./commands/completion.command";
import { ConfigCommand } from "./commands/config.command";
import { EncodeCommand } from "./commands/encode.command";
@@ -20,6 +19,7 @@ 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";
@@ -27,7 +27,7 @@ import { SyncCommand } from "./vault/sync.command";
const writeLn = CliUtils.writeLn;
export class Program {
constructor(protected main: Main) {}
constructor(protected serviceContainer: ServiceContainer) {}
async register() {
program
@@ -38,7 +38,10 @@ export class Program {
.option("--quiet", "Don't return anything to stdout.")
.option("--nointeraction", "Do not prompt for interactive user input.")
.option("--session <session>", "Pass session key instead of reading from env.")
.version(await this.main.platformUtilsService.getApplicationVersion(), "-v, --version");
.version(
await this.serviceContainer.platformUtilsService.getApplicationVersion(),
"-v, --version",
);
program.on("option:pretty", () => {
process.env.BW_PRETTY = "true";
@@ -68,9 +71,11 @@ export class Program {
process.env.BW_SESSION = key;
// once we have the session key, we can set the user key in memory
const activeAccount = await firstValueFrom(this.main.accountService.activeAccount$);
const activeAccount = await firstValueFrom(
this.serviceContainer.accountService.activeAccount$,
);
if (activeAccount) {
await this.main.userAutoUnlockKeyService.setUserKeyInMemoryIfAutoUserKeySet(
await this.serviceContainer.userAutoUnlockKeyService.setUserKeyInMemoryIfAutoUserKeySet(
activeAccount.id,
);
}
@@ -122,7 +127,7 @@ export class Program {
"Path to a file containing your password as its first line",
)
.option("--check", "Check login status.", async () => {
const authed = await this.main.stateService.getIsAuthenticated();
const authed = await this.serviceContainer.stateService.getIsAuthenticated();
if (authed) {
const res = new MessageResponse("You are logged in!", null);
this.processResponse(Response.success(res), true);
@@ -148,24 +153,24 @@ export class Program {
if (!options.check) {
await this.exitIfAuthed();
const command = new LoginCommand(
this.main.loginStrategyService,
this.main.authService,
this.main.apiService,
this.main.cryptoFunctionService,
this.main.environmentService,
this.main.passwordGenerationService,
this.main.passwordStrengthService,
this.main.platformUtilsService,
this.main.stateService,
this.main.cryptoService,
this.main.policyService,
this.main.twoFactorService,
this.main.syncService,
this.main.keyConnectorService,
this.main.policyApiService,
this.main.organizationService,
async () => await this.main.logout(),
this.main.kdfConfigService,
this.serviceContainer.loginStrategyService,
this.serviceContainer.authService,
this.serviceContainer.apiService,
this.serviceContainer.cryptoFunctionService,
this.serviceContainer.environmentService,
this.serviceContainer.passwordGenerationService,
this.serviceContainer.passwordStrengthService,
this.serviceContainer.platformUtilsService,
this.serviceContainer.stateService,
this.serviceContainer.cryptoService,
this.serviceContainer.policyService,
this.serviceContainer.twoFactorService,
this.serviceContainer.syncService,
this.serviceContainer.keyConnectorService,
this.serviceContainer.policyApiService,
this.serviceContainer.organizationService,
async () => await this.serviceContainer.logout(),
this.serviceContainer.kdfConfigService,
);
const response = await command.run(email, password, options);
this.processResponse(response, true);
@@ -184,9 +189,9 @@ export class Program {
.action(async (cmd) => {
await this.exitIfNotAuthed();
const command = new LogoutCommand(
this.main.authService,
this.main.i18nService,
async () => await this.main.logout(),
this.serviceContainer.authService,
this.serviceContainer.i18nService,
async () => await this.serviceContainer.logout(),
);
const response = await command.run();
this.processResponse(response);
@@ -204,11 +209,11 @@ export class Program {
.action(async (cmd) => {
await this.exitIfNotAuthed();
if (await this.main.keyConnectorService.getUsesKeyConnector()) {
if (await this.serviceContainer.keyConnectorService.getUsesKeyConnector()) {
const logoutCommand = new LogoutCommand(
this.main.authService,
this.main.i18nService,
async () => await this.main.logout(),
this.serviceContainer.authService,
this.serviceContainer.i18nService,
async () => await this.serviceContainer.logout(),
);
await logoutCommand.run();
this.processResponse(
@@ -221,7 +226,7 @@ export class Program {
return;
}
const command = new LockCommand(this.main.vaultTimeoutService);
const command = new LockCommand(this.serviceContainer.vaultTimeoutService);
const response = await command.run();
this.processResponse(response);
});
@@ -246,7 +251,7 @@ export class Program {
.option("--check", "Check lock status.", async () => {
await this.exitIfNotAuthed();
const authStatus = await this.main.authService.getAuthStatus();
const authStatus = await this.serviceContainer.authService.getAuthStatus();
if (authStatus === AuthenticationStatus.Unlocked) {
const res = new MessageResponse("Vault is unlocked!", null);
this.processResponse(Response.success(res), true);
@@ -263,19 +268,19 @@ export class Program {
if (!cmd.check) {
await this.exitIfNotAuthed();
const command = new UnlockCommand(
this.main.accountService,
this.main.masterPasswordService,
this.main.cryptoService,
this.main.stateService,
this.main.cryptoFunctionService,
this.main.apiService,
this.main.logService,
this.main.keyConnectorService,
this.main.environmentService,
this.main.syncService,
this.main.organizationApiService,
async () => await this.main.logout(),
this.main.kdfConfigService,
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,
async () => await this.serviceContainer.logout(),
this.serviceContainer.kdfConfigService,
);
const response = await command.run(password, cmd);
this.processResponse(response);
@@ -297,7 +302,7 @@ export class Program {
})
.action(async (cmd) => {
await this.exitIfNotAuthed();
const command = new SyncCommand(this.main.syncService);
const command = new SyncCommand(this.serviceContainer.syncService);
const response = await command.run(cmd);
this.processResponse(response);
});
@@ -340,8 +345,8 @@ export class Program {
})
.action(async (options) => {
const command = new GenerateCommand(
this.main.passwordGenerationService,
this.main.stateService,
this.serviceContainer.passwordGenerationService,
this.serviceContainer.stateService,
);
const response = await command.run(options);
this.processResponse(response);
@@ -401,7 +406,7 @@ export class Program {
writeLn("", true);
})
.action(async (setting, value, options) => {
const command = new ConfigCommand(this.main.environmentService);
const command = new ConfigCommand(this.serviceContainer.environmentService);
const response = await command.run(setting, value, options);
this.processResponse(response);
});
@@ -423,7 +428,7 @@ export class Program {
writeLn("", true);
})
.action(async () => {
const command = new UpdateCommand(this.main.platformUtilsService);
const command = new UpdateCommand(this.serviceContainer.platformUtilsService);
const response = await command.run();
this.processResponse(response);
});
@@ -474,10 +479,10 @@ export class Program {
})
.action(async () => {
const command = new StatusCommand(
this.main.environmentService,
this.main.syncService,
this.main.stateService,
this.main.authService,
this.serviceContainer.environmentService,
this.serviceContainer.syncService,
this.serviceContainer.stateService,
this.serviceContainer.authService,
);
const response = await command.run();
this.processResponse(response);
@@ -508,7 +513,7 @@ export class Program {
})
.action(async (cmd) => {
await this.exitIfNotAuthed();
const command = new ServeCommand(this.main);
const command = new ServeCommand(this.serviceContainer);
await command.run(cmd);
});
}
@@ -598,15 +603,15 @@ export class Program {
}
private async exitIfAuthed() {
const authed = await this.main.stateService.getIsAuthenticated();
const authed = await this.serviceContainer.stateService.getIsAuthenticated();
if (authed) {
const email = await this.main.stateService.getEmail();
const email = await this.serviceContainer.stateService.getEmail();
this.processResponse(Response.error("You are already logged in as " + email + "."), true);
}
}
private async exitIfNotAuthed() {
const authed = await this.main.stateService.getIsAuthenticated();
const authed = await this.serviceContainer.stateService.getIsAuthenticated();
if (!authed) {
this.processResponse(Response.error("You are not logged in."), true);
}
@@ -614,11 +619,11 @@ export class Program {
protected async exitIfLocked() {
await this.exitIfNotAuthed();
if (await this.main.cryptoService.hasUserKey()) {
if (await this.serviceContainer.cryptoService.hasUserKey()) {
return;
} else if (process.env.BW_NOINTERACTION !== "true") {
// must unlock
if (await this.main.keyConnectorService.getUsesKeyConnector()) {
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.",
@@ -626,19 +631,19 @@ export class Program {
this.processResponse(response, true);
} else {
const command = new UnlockCommand(
this.main.accountService,
this.main.masterPasswordService,
this.main.cryptoService,
this.main.stateService,
this.main.cryptoFunctionService,
this.main.apiService,
this.main.logService,
this.main.keyConnectorService,
this.main.environmentService,
this.main.syncService,
this.main.organizationApiService,
this.main.logout,
this.main.kdfConfigService,
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) {