mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 13:53:34 +00:00
* allow admin console to see all collections when viewing a cipher - When "manage all" option is selected all collections should be editable * update cipher form service to use admin endpoints * when saving a cipher, choose to move to collections first before saving any other edits - This handles the case where a cipher is moving from unassigned to assigned and needs to have a collection to save any other edits * set admin flag when the original cipher has zero collections - handling the case where the user un-assigns themselves from a cipher * add check for the users ability to edit items within the collection * save cipher edit first to handle when the user unassigns themselves from the cipher * update filter order of collections * use cipher returned from the collections endpoint rather than re-fetching it * fix unit tests by adding canEditItems * re-enable collection control when orgId is present * fetch the updated cipher from the respective service for editing a cipher
180 lines
7.8 KiB
TypeScript
180 lines
7.8 KiB
TypeScript
import { Observable } from "rxjs";
|
|
|
|
import { LocalData } from "@bitwarden/common/vault/models/data/local.data";
|
|
import { UserKeyRotationDataProvider } from "@bitwarden/key-management";
|
|
|
|
import { UriMatchStrategySetting } from "../../models/domain/domain-service";
|
|
import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key";
|
|
import { CipherId, CollectionId, OrganizationId, UserId } from "../../types/guid";
|
|
import { UserKey } from "../../types/key";
|
|
import { CipherType } from "../enums/cipher-type";
|
|
import { CipherData } from "../models/data/cipher.data";
|
|
import { Cipher } from "../models/domain/cipher";
|
|
import { Field } from "../models/domain/field";
|
|
import { CipherWithIdRequest } from "../models/request/cipher-with-id.request";
|
|
import { CipherView } from "../models/view/cipher.view";
|
|
import { FieldView } from "../models/view/field.view";
|
|
import { AddEditCipherInfo } from "../types/add-edit-cipher-info";
|
|
|
|
export abstract class CipherService implements UserKeyRotationDataProvider<CipherWithIdRequest> {
|
|
cipherViews$: Observable<CipherView[]>;
|
|
ciphers$: Observable<Record<CipherId, CipherData>>;
|
|
localData$: Observable<Record<CipherId, LocalData>>;
|
|
/**
|
|
* An observable monitoring the add/edit cipher info saved to memory.
|
|
*/
|
|
addEditCipherInfo$: Observable<AddEditCipherInfo>;
|
|
clearCache: (userId?: string) => Promise<void>;
|
|
encrypt: (
|
|
model: CipherView,
|
|
userId: UserId,
|
|
keyForEncryption?: SymmetricCryptoKey,
|
|
keyForCipherKeyDecryption?: SymmetricCryptoKey,
|
|
originalCipher?: Cipher,
|
|
) => Promise<Cipher>;
|
|
encryptFields: (fieldsModel: FieldView[], key: SymmetricCryptoKey) => Promise<Field[]>;
|
|
encryptField: (fieldModel: FieldView, key: SymmetricCryptoKey) => Promise<Field>;
|
|
get: (id: string) => Promise<Cipher>;
|
|
getAll: () => Promise<Cipher[]>;
|
|
getAllDecrypted: () => Promise<CipherView[]>;
|
|
getAllDecryptedForGrouping: (groupingId: string, folder?: boolean) => Promise<CipherView[]>;
|
|
getAllDecryptedForUrl: (
|
|
url: string,
|
|
includeOtherTypes?: CipherType[],
|
|
defaultMatch?: UriMatchStrategySetting,
|
|
) => Promise<CipherView[]>;
|
|
filterCiphersForUrl: (
|
|
ciphers: CipherView[],
|
|
url: string,
|
|
includeOtherTypes?: CipherType[],
|
|
defaultMatch?: UriMatchStrategySetting,
|
|
) => Promise<CipherView[]>;
|
|
getAllFromApiForOrganization: (organizationId: string) => Promise<CipherView[]>;
|
|
/**
|
|
* Gets ciphers belonging to the specified organization that the user has explicit collection level access to.
|
|
* Ciphers that are not assigned to any collections are only included for users with admin access.
|
|
*/
|
|
getManyFromApiForOrganization: (organizationId: string) => Promise<CipherView[]>;
|
|
getLastUsedForUrl: (url: string, autofillOnPageLoad: boolean) => Promise<CipherView>;
|
|
getLastLaunchedForUrl: (url: string, autofillOnPageLoad: boolean) => Promise<CipherView>;
|
|
getNextCipherForUrl: (url: string) => Promise<CipherView>;
|
|
updateLastUsedIndexForUrl: (url: string) => void;
|
|
updateLastUsedDate: (id: string) => Promise<void>;
|
|
updateLastLaunchedDate: (id: string) => Promise<void>;
|
|
saveNeverDomain: (domain: string) => Promise<void>;
|
|
/**
|
|
* Create a cipher with the server
|
|
*
|
|
* @param cipher The cipher to create
|
|
* @param orgAdmin If true, the request is submitted as an organization admin request
|
|
*
|
|
* @returns A promise that resolves to the created cipher
|
|
*/
|
|
createWithServer: (cipher: Cipher, orgAdmin?: boolean) => Promise<Cipher>;
|
|
/**
|
|
* Update a cipher with the server
|
|
* @param cipher The cipher to update
|
|
* @param orgAdmin If true, the request is submitted as an organization admin request
|
|
* @param isNotClone If true, the cipher is not a clone and should be treated as a new cipher
|
|
*
|
|
* @returns A promise that resolves to the updated cipher
|
|
*/
|
|
updateWithServer: (cipher: Cipher, orgAdmin?: boolean, isNotClone?: boolean) => Promise<Cipher>;
|
|
shareWithServer: (
|
|
cipher: CipherView,
|
|
organizationId: string,
|
|
collectionIds: string[],
|
|
userId: UserId,
|
|
) => Promise<any>;
|
|
shareManyWithServer: (
|
|
ciphers: CipherView[],
|
|
organizationId: string,
|
|
collectionIds: string[],
|
|
userId: UserId,
|
|
) => Promise<any>;
|
|
saveAttachmentWithServer: (
|
|
cipher: Cipher,
|
|
unencryptedFile: any,
|
|
userId: UserId,
|
|
admin?: boolean,
|
|
) => Promise<Cipher>;
|
|
saveAttachmentRawWithServer: (
|
|
cipher: Cipher,
|
|
filename: string,
|
|
data: ArrayBuffer,
|
|
userId: UserId,
|
|
admin?: boolean,
|
|
) => Promise<Cipher>;
|
|
/**
|
|
* Save the collections for a cipher with the server
|
|
*
|
|
* @param cipher The cipher to save collections for
|
|
*
|
|
* @returns A promise that resolves when the collections have been saved
|
|
*/
|
|
saveCollectionsWithServer: (cipher: Cipher) => Promise<Cipher>;
|
|
|
|
/**
|
|
* Save the collections for a cipher with the server as an admin.
|
|
* Used for Unassigned ciphers or when the user only has admin access to the cipher (not assigned normally).
|
|
* @param cipher
|
|
*/
|
|
saveCollectionsWithServerAdmin: (cipher: Cipher) => Promise<Cipher>;
|
|
/**
|
|
* Bulk update collections for many ciphers with the server
|
|
* @param orgId
|
|
* @param cipherIds
|
|
* @param collectionIds
|
|
* @param removeCollections - If true, the collections will be removed from the ciphers, otherwise they will be added
|
|
*/
|
|
bulkUpdateCollectionsWithServer: (
|
|
orgId: OrganizationId,
|
|
cipherIds: CipherId[],
|
|
collectionIds: CollectionId[],
|
|
removeCollections: boolean,
|
|
) => Promise<void>;
|
|
/**
|
|
* Update the local store of CipherData with the provided data. Values are upserted into the existing store.
|
|
*
|
|
* @param cipher The cipher data to upsert. Can be a single CipherData object or an array of CipherData objects.
|
|
* @returns A promise that resolves to a record of updated cipher store, keyed by their cipher ID. Returns all ciphers, not just those updated
|
|
*/
|
|
upsert: (cipher: CipherData | CipherData[]) => Promise<Record<CipherId, CipherData>>;
|
|
replace: (ciphers: { [id: string]: CipherData }, userId: UserId) => Promise<any>;
|
|
clear: (userId?: string) => Promise<void>;
|
|
moveManyWithServer: (ids: string[], folderId: string) => Promise<any>;
|
|
delete: (id: string | string[]) => Promise<any>;
|
|
deleteWithServer: (id: string, asAdmin?: boolean) => Promise<any>;
|
|
deleteManyWithServer: (ids: string[], asAdmin?: boolean) => Promise<any>;
|
|
deleteAttachment: (id: string, attachmentId: string) => Promise<void>;
|
|
deleteAttachmentWithServer: (id: string, attachmentId: string) => Promise<void>;
|
|
sortCiphersByLastUsed: (a: CipherView, b: CipherView) => number;
|
|
sortCiphersByLastUsedThenName: (a: CipherView, b: CipherView) => number;
|
|
getLocaleSortingFunction: () => (a: CipherView, b: CipherView) => number;
|
|
softDelete: (id: string | string[]) => Promise<any>;
|
|
softDeleteWithServer: (id: string, asAdmin?: boolean) => Promise<any>;
|
|
softDeleteManyWithServer: (ids: string[], asAdmin?: boolean) => Promise<any>;
|
|
restore: (
|
|
cipher: { id: string; revisionDate: string } | { id: string; revisionDate: string }[],
|
|
) => Promise<any>;
|
|
restoreWithServer: (id: string, asAdmin?: boolean) => Promise<any>;
|
|
restoreManyWithServer: (ids: string[], orgId?: string) => Promise<void>;
|
|
getKeyForCipherKeyDecryption: (cipher: Cipher, userId: UserId) => Promise<any>;
|
|
setAddEditCipherInfo: (value: AddEditCipherInfo) => Promise<void>;
|
|
/**
|
|
* Returns user ciphers re-encrypted with the new user key.
|
|
* @param originalUserKey the original user key
|
|
* @param newUserKey the new user key
|
|
* @param userId the user id
|
|
* @throws Error if new user key is null
|
|
* @returns a list of user ciphers that have been re-encrypted with the new user key
|
|
*/
|
|
getRotatedData: (
|
|
originalUserKey: UserKey,
|
|
newUserKey: UserKey,
|
|
userId: UserId,
|
|
) => Promise<CipherWithIdRequest[]>;
|
|
getNextCardCipher: () => Promise<CipherView>;
|
|
getNextIdentityCipher: () => Promise<CipherView>;
|
|
}
|