1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-09 05:57:40 +02:00
bitwarden-browser/apps/cli/src/commands/convert-to-key-connector.command.ts
Matt Gibson 9459cda304
Pm-10953/add-user-context-to-sync-replaces (#10627)
* Require userId for setting masterKeyEncryptedUserKey

* Replace folders for specified user

* Require userId for collection replace

* Cipher Replace requires userId

* Require UserId to update equivalent domains

* Require userId for policy replace

* sync state updates between fake state for better testing

* Revert to public observable tests

Since they now sync, we can test single-user updates impacting active user observables

* Do not init fake states through sync

Do not sync initial null values, that might wipe out already existing data.

* Require userId for Send replace

* Include userId for organization replace

* Require userId for billing sync data

* Require user Id for key connector sync data

* Allow decode of token by userId

* Require userId for synced key connector updates

* Add userId to policy setting during organization invite accept

* Fix cli

* Handle null userId

---------

Co-authored-by: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com>
2024-08-26 20:44:08 -04:00

92 lines
3.2 KiB
TypeScript

import * as inquirer from "inquirer";
import { firstValueFrom } from "rxjs";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service";
import {
EnvironmentService,
Region,
} from "@bitwarden/common/platform/abstractions/environment.service";
import { UserId } from "@bitwarden/common/types/guid";
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { Response } from "../models/response";
import { MessageResponse } from "../models/response/message.response";
export class ConvertToKeyConnectorCommand {
constructor(
private readonly userId: UserId,
private keyConnectorService: KeyConnectorService,
private environmentService: EnvironmentService,
private syncService: SyncService,
private organizationApiService: OrganizationApiServiceAbstraction,
private logout: () => Promise<void>,
) {}
async run(): Promise<Response> {
// If no interaction available, alert user to use web vault
const canInteract = process.env.BW_NOINTERACTION !== "true";
if (!canInteract) {
await this.logout();
return Response.error(
new MessageResponse(
"An organization you are a member of is using Key Connector. " +
"In order to access the vault, you must opt-in to Key Connector now via the web vault. You have been logged out.",
null,
),
);
}
const organization = await this.keyConnectorService.getManagingOrganization();
const answer: inquirer.Answers = await inquirer.createPromptModule({ output: process.stderr })({
type: "list",
name: "convert",
message:
organization.name +
" is using a self-hosted key server. A master password is no longer required to log in for members of this organization. ",
choices: [
{
name: "Remove master password and unlock",
value: "remove",
},
{
name: "Leave organization and unlock",
value: "leave",
},
{
name: "Log out",
value: "exit",
},
],
});
if (answer.convert === "remove") {
try {
await this.keyConnectorService.migrateUser();
} catch (e) {
await this.logout();
throw e;
}
await this.keyConnectorService.removeConvertAccountRequired();
await this.keyConnectorService.setUsesKeyConnector(true, this.userId);
// Update environment URL - required for api key login
const env = await firstValueFrom(this.environmentService.environment$);
const urls = env.getUrls();
urls.keyConnector = organization.keyConnectorUrl;
await this.environmentService.setEnvironment(Region.SelfHosted, urls);
return Response.success();
} else if (answer.convert === "leave") {
await this.organizationApiService.leave(organization.id);
await this.keyConnectorService.removeConvertAccountRequired();
return Response.success();
} else {
await this.logout();
return Response.error("You have been logged out.");
}
}
}