mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[PM-12047] Remove usage of ActiveUserState from cipher.service (#12814)
* Cipher service web changes * Updated browser client to pass user id to cipher service observable changes * Cli changes * desktop changes * Fixed test * Libs changes * Fixed merge conflicts * Fixed merge conflicts * removed duplicate reference fixed conflict * Fixed test * Fixed test * Fixed test * Fixed desturcturing issue on failed to decrypt ciphers cipher service * Updated abstraction to use method syntax * Fixed conflicts * Fixed test on add edit v2 Passed active userId to delete function * Used getUserId utility function * made vault changes * made suggestion changes * made suggestion changes * made suggestion changes * Replace getUserId function calls with pipe operator syntax for better consistency * fixed merge conflicts * revert mistake made of usinf account activity during merge conflict fix * fixed conflicts * fixed tests
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
|
||||
import { Response } from "../../models/response";
|
||||
@@ -48,7 +49,9 @@ export class ShareCommand {
|
||||
organizationId = organizationId.toLowerCase();
|
||||
}
|
||||
|
||||
const cipher = await this.cipherService.get(id);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
|
||||
const cipher = await this.cipherService.get(id, activeUserId);
|
||||
if (cipher == null) {
|
||||
return Response.notFound();
|
||||
}
|
||||
@@ -56,15 +59,12 @@ export class ShareCommand {
|
||||
return Response.badRequest("This item already belongs to an organization.");
|
||||
}
|
||||
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
);
|
||||
const cipherView = await cipher.decrypt(
|
||||
await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId),
|
||||
);
|
||||
try {
|
||||
await this.cipherService.shareWithServer(cipherView, organizationId, req, activeUserId);
|
||||
const updatedCipher = await this.cipherService.get(cipher.id);
|
||||
const updatedCipher = await this.cipherService.get(cipher.id, activeUserId);
|
||||
const decCipher = await updatedCipher.decrypt(
|
||||
await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId),
|
||||
);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { CollectionRequest } from "@bitwarden/admin-console/common";
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models/request/selection-read-only.request";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||
import { CipherExport } from "@bitwarden/common/models/export/cipher.export";
|
||||
import { CollectionExport } from "@bitwarden/common/models/export/collection.export";
|
||||
@@ -25,8 +26,6 @@ import { CipherResponse } from "../vault/models/cipher.response";
|
||||
import { FolderResponse } from "../vault/models/folder.response";
|
||||
|
||||
export class EditCommand {
|
||||
private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id));
|
||||
|
||||
constructor(
|
||||
private cipherService: CipherService,
|
||||
private folderService: FolderService,
|
||||
@@ -85,14 +84,12 @@ export class EditCommand {
|
||||
}
|
||||
|
||||
private async editCipher(id: string, req: CipherExport) {
|
||||
const cipher = await this.cipherService.get(id);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const cipher = await this.cipherService.get(id, activeUserId);
|
||||
if (cipher == null) {
|
||||
return Response.notFound();
|
||||
}
|
||||
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
);
|
||||
let cipherView = await cipher.decrypt(
|
||||
await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId),
|
||||
);
|
||||
@@ -114,7 +111,9 @@ export class EditCommand {
|
||||
}
|
||||
|
||||
private async editCipherCollections(id: string, req: string[]) {
|
||||
const cipher = await this.cipherService.get(id);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
|
||||
const cipher = await this.cipherService.get(id, activeUserId);
|
||||
if (cipher == null) {
|
||||
return Response.notFound();
|
||||
}
|
||||
@@ -129,11 +128,14 @@ export class EditCommand {
|
||||
|
||||
cipher.collectionIds = req;
|
||||
try {
|
||||
const updatedCipher = await this.cipherService.saveCollectionsWithServer(cipher);
|
||||
const updatedCipher = await this.cipherService.saveCollectionsWithServer(
|
||||
cipher,
|
||||
activeUserId,
|
||||
);
|
||||
const decCipher = await updatedCipher.decrypt(
|
||||
await this.cipherService.getKeyForCipherKeyDecryption(
|
||||
updatedCipher,
|
||||
await firstValueFrom(this.activeUserId$),
|
||||
await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)),
|
||||
),
|
||||
);
|
||||
const res = new CipherResponse(decCipher);
|
||||
@@ -144,7 +146,7 @@ export class EditCommand {
|
||||
}
|
||||
|
||||
private async editFolder(id: string, req: FolderExport) {
|
||||
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const folder = await this.folderService.getFromState(id, activeUserId);
|
||||
if (folder == null) {
|
||||
return Response.notFound();
|
||||
|
||||
@@ -52,8 +52,6 @@ import { FolderResponse } from "../vault/models/folder.response";
|
||||
import { DownloadCommand } from "./download.command";
|
||||
|
||||
export class GetCommand extends DownloadCommand {
|
||||
private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id));
|
||||
|
||||
constructor(
|
||||
private cipherService: CipherService,
|
||||
private folderService: FolderService,
|
||||
@@ -114,16 +112,16 @@ export class GetCommand extends DownloadCommand {
|
||||
|
||||
private async getCipherView(id: string): Promise<CipherView | CipherView[]> {
|
||||
let decCipher: CipherView = null;
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
if (Utils.isGuid(id)) {
|
||||
const cipher = await this.cipherService.get(id);
|
||||
const cipher = await this.cipherService.get(id, activeUserId);
|
||||
if (cipher != null) {
|
||||
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||
decCipher = await cipher.decrypt(
|
||||
await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId),
|
||||
);
|
||||
}
|
||||
} else if (id.trim() !== "") {
|
||||
let ciphers = await this.cipherService.getAllDecrypted();
|
||||
let ciphers = await this.cipherService.getAllDecrypted(activeUserId);
|
||||
ciphers = this.searchService.searchCiphersBasic(ciphers, id);
|
||||
if (ciphers.length > 1) {
|
||||
return ciphers;
|
||||
@@ -265,8 +263,10 @@ export class GetCommand extends DownloadCommand {
|
||||
const canAccessPremium = await firstValueFrom(
|
||||
this.accountProfileService.hasPremiumFromAnySource$(account.id),
|
||||
);
|
||||
|
||||
if (!canAccessPremium) {
|
||||
const originalCipher = await this.cipherService.get(cipher.id);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const originalCipher = await this.cipherService.get(cipher.id, activeUserId);
|
||||
if (
|
||||
originalCipher == null ||
|
||||
originalCipher.organizationId == null ||
|
||||
@@ -352,7 +352,8 @@ export class GetCommand extends DownloadCommand {
|
||||
this.accountProfileService.hasPremiumFromAnySource$(account.id),
|
||||
);
|
||||
if (!canAccessPremium) {
|
||||
const originalCipher = await this.cipherService.get(cipher.id);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const originalCipher = await this.cipherService.get(cipher.id, activeUserId);
|
||||
if (originalCipher == null || originalCipher.organizationId == null) {
|
||||
return Response.error("Premium status is required to use this feature.");
|
||||
}
|
||||
@@ -384,7 +385,7 @@ export class GetCommand extends DownloadCommand {
|
||||
|
||||
private async getFolder(id: string) {
|
||||
let decFolder: FolderView = null;
|
||||
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
if (Utils.isGuid(id)) {
|
||||
const folder = await this.folderService.getFromState(id, activeUserId);
|
||||
if (folder != null) {
|
||||
@@ -561,7 +562,7 @@ export class GetCommand extends DownloadCommand {
|
||||
private async getFingerprint(id: string) {
|
||||
let fingerprint: string[] = null;
|
||||
if (id === "me") {
|
||||
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const publicKey = await firstValueFrom(this.keyService.userPublicKey$(activeUserId));
|
||||
fingerprint = await this.keyService.getFingerprint(activeUserId, publicKey);
|
||||
} else if (Utils.isGuid(id)) {
|
||||
|
||||
@@ -65,11 +65,14 @@ export class ListCommand {
|
||||
|
||||
private async listCiphers(options: Options) {
|
||||
let ciphers: CipherView[];
|
||||
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
|
||||
options.trash = options.trash || false;
|
||||
if (options.url != null && options.url.trim() !== "") {
|
||||
ciphers = await this.cipherService.getAllDecryptedForUrl(options.url);
|
||||
ciphers = await this.cipherService.getAllDecryptedForUrl(options.url, activeUserId);
|
||||
} else {
|
||||
ciphers = await this.cipherService.getAllDecrypted();
|
||||
ciphers = await this.cipherService.getAllDecrypted(activeUserId);
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -138,9 +141,8 @@ export class ListCommand {
|
||||
}
|
||||
|
||||
private async listFolders(options: Options) {
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
|
||||
let folders = await this.folderService.getAllDecryptedFromState(activeUserId);
|
||||
|
||||
if (options.search != null && options.search.trim() !== "") {
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
|
||||
import { Response } from "../models/response";
|
||||
|
||||
export class RestoreCommand {
|
||||
constructor(private cipherService: CipherService) {}
|
||||
constructor(
|
||||
private cipherService: CipherService,
|
||||
private accountService: AccountService,
|
||||
) {}
|
||||
|
||||
async run(object: string, id: string): Promise<Response> {
|
||||
if (id != null) {
|
||||
@@ -19,7 +26,9 @@ export class RestoreCommand {
|
||||
}
|
||||
|
||||
private async restoreCipher(id: string) {
|
||||
const cipher = await this.cipherService.get(id);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
|
||||
const cipher = await this.cipherService.get(id, activeUserId);
|
||||
if (cipher == null) {
|
||||
return Response.notFound();
|
||||
}
|
||||
@@ -28,7 +37,7 @@ export class RestoreCommand {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.cipherService.restoreWithServer(id);
|
||||
await this.cipherService.restoreWithServer(id, activeUserId);
|
||||
return Response.success();
|
||||
} catch (e) {
|
||||
return Response.error(e);
|
||||
|
||||
@@ -124,7 +124,10 @@ export class OssServeConfigurator {
|
||||
this.serviceContainer.encryptService,
|
||||
this.serviceContainer.organizationUserApiService,
|
||||
);
|
||||
this.restoreCommand = new RestoreCommand(this.serviceContainer.cipherService);
|
||||
this.restoreCommand = new RestoreCommand(
|
||||
this.serviceContainer.cipherService,
|
||||
this.serviceContainer.accountService,
|
||||
);
|
||||
this.shareCommand = new ShareCommand(
|
||||
this.serviceContainer.cipherService,
|
||||
this.serviceContainer.accountService,
|
||||
|
||||
@@ -347,7 +347,10 @@ export class VaultProgram extends BaseProgram {
|
||||
}
|
||||
|
||||
await this.exitIfLocked();
|
||||
const command = new RestoreCommand(this.serviceContainer.cipherService);
|
||||
const command = new RestoreCommand(
|
||||
this.serviceContainer.cipherService,
|
||||
this.serviceContainer.accountService,
|
||||
);
|
||||
const response = await command.run(object, id);
|
||||
this.processResponse(response);
|
||||
});
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models/request/selection-read-only.request";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service";
|
||||
import { CipherExport } from "@bitwarden/common/models/export/cipher.export";
|
||||
@@ -30,8 +31,6 @@ import { CipherResponse } from "./models/cipher.response";
|
||||
import { FolderResponse } from "./models/folder.response";
|
||||
|
||||
export class CreateCommand {
|
||||
private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id));
|
||||
|
||||
constructor(
|
||||
private cipherService: CipherService,
|
||||
private folderService: FolderService,
|
||||
@@ -90,7 +89,7 @@ export class CreateCommand {
|
||||
}
|
||||
|
||||
private async createCipher(req: CipherExport) {
|
||||
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const cipher = await this.cipherService.encrypt(CipherExport.toView(req), activeUserId);
|
||||
try {
|
||||
const newCipher = await this.cipherService.createWithServer(cipher);
|
||||
@@ -132,14 +131,14 @@ export class CreateCommand {
|
||||
return Response.badRequest("File name not provided.");
|
||||
}
|
||||
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
|
||||
const itemId = options.itemId.toLowerCase();
|
||||
const cipher = await this.cipherService.get(itemId);
|
||||
const cipher = await this.cipherService.get(itemId, activeUserId);
|
||||
if (cipher == null) {
|
||||
return Response.notFound();
|
||||
}
|
||||
|
||||
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||
|
||||
const canAccessPremium = await firstValueFrom(
|
||||
this.accountProfileService.hasPremiumFromAnySource$(activeUserId),
|
||||
);
|
||||
@@ -173,7 +172,7 @@ export class CreateCommand {
|
||||
}
|
||||
|
||||
private async createFolder(req: FolderExport) {
|
||||
const activeUserId = await firstValueFrom(this.activeUserId$);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId);
|
||||
const folder = await this.folderService.encrypt(FolderExport.toView(req), userKey);
|
||||
try {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
@@ -44,7 +45,9 @@ export class DeleteCommand {
|
||||
}
|
||||
|
||||
private async deleteCipher(id: string, options: Options) {
|
||||
const cipher = await this.cipherService.get(id);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
|
||||
const cipher = await this.cipherService.get(id, activeUserId);
|
||||
if (cipher == null) {
|
||||
return Response.notFound();
|
||||
}
|
||||
@@ -59,9 +62,9 @@ export class DeleteCommand {
|
||||
|
||||
try {
|
||||
if (options.permanent) {
|
||||
await this.cipherService.deleteWithServer(id);
|
||||
await this.cipherService.deleteWithServer(id, activeUserId);
|
||||
} else {
|
||||
await this.cipherService.softDeleteWithServer(id);
|
||||
await this.cipherService.softDeleteWithServer(id, activeUserId);
|
||||
}
|
||||
return Response.success();
|
||||
} catch (e) {
|
||||
@@ -74,8 +77,10 @@ export class DeleteCommand {
|
||||
return Response.badRequest("`itemid` option is required.");
|
||||
}
|
||||
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
|
||||
const itemId = options.itemId.toLowerCase();
|
||||
const cipher = await this.cipherService.get(itemId);
|
||||
const cipher = await this.cipherService.get(itemId, activeUserId);
|
||||
if (cipher == null) {
|
||||
return Response.notFound();
|
||||
}
|
||||
@@ -89,16 +94,19 @@ export class DeleteCommand {
|
||||
return Response.error("Attachment `" + id + "` was not found.");
|
||||
}
|
||||
|
||||
const account = await firstValueFrom(this.accountService.activeAccount$);
|
||||
const canAccessPremium = await firstValueFrom(
|
||||
this.accountProfileService.hasPremiumFromAnySource$(account.id),
|
||||
this.accountProfileService.hasPremiumFromAnySource$(activeUserId),
|
||||
);
|
||||
if (cipher.organizationId == null && !canAccessPremium) {
|
||||
return Response.error("Premium status is required to use this feature.");
|
||||
}
|
||||
|
||||
try {
|
||||
await this.cipherService.deleteAttachmentWithServer(cipher.id, attachments[0].id);
|
||||
await this.cipherService.deleteAttachmentWithServer(
|
||||
cipher.id,
|
||||
attachments[0].id,
|
||||
activeUserId,
|
||||
);
|
||||
return Response.success();
|
||||
} catch (e) {
|
||||
return Response.error(e);
|
||||
@@ -106,9 +114,7 @@ export class DeleteCommand {
|
||||
}
|
||||
|
||||
private async deleteFolder(id: string) {
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
);
|
||||
const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId));
|
||||
const folder = await this.folderService.getFromState(id, activeUserId);
|
||||
if (folder == null) {
|
||||
return Response.notFound();
|
||||
|
||||
Reference in New Issue
Block a user