1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-26 17:43:22 +00:00

Update ciphers to use CollectionId and OrganizationId

This commit is contained in:
Thomas Rittson
2025-07-19 09:58:31 +10:00
parent e532d30b16
commit c22451ed14
8 changed files with 42 additions and 26 deletions

View File

@@ -145,7 +145,7 @@ export class RoutedVaultFilterBridge implements VaultFilter {
get folderId(): string {
return this.legacyFilter.folderId;
}
get collectionId(): string {
get collectionId(): CollectionId {
return this.legacyFilter.collectionId;
}
resetFilter(): void {

View File

@@ -1,5 +1,6 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { CollectionId } from "@bitwarden/common/types/guid";
import { CipherType, isCipherType } from "@bitwarden/common/vault/enums";
import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
@@ -94,7 +95,7 @@ export class VaultFilter {
return this.selectedFolderNode?.node.id;
}
get collectionId(): string {
get collectionId(): CollectionId {
return this.selectedCollectionNode?.node.id;
}

View File

@@ -1,6 +1,7 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { EncString } from "../../key-management/crypto/models/enc-string";
import { CollectionId, OrganizationId } from "../../types/guid";
import { CipherRepromptType } from "../../vault/enums/cipher-reprompt-type";
import { CipherType } from "../../vault/enums/cipher-type";
import { Cipher as CipherDomain } from "../../vault/models/domain/cipher";
@@ -43,10 +44,12 @@ export class CipherExport {
view.type = req.type;
view.folderId = req.folderId;
if (view.organizationId == null) {
view.organizationId = req.organizationId;
view.organizationId = req.organizationId as OrganizationId;
}
if (view.collectionIds || req.collectionIds) {
const set = new Set((view.collectionIds ?? []).concat(req.collectionIds ?? []));
const set = new Set(
(view.collectionIds ?? []).concat((req.collectionIds as CollectionId[]) ?? []),
);
view.collectionIds = Array.from(set.values());
}
view.name = req.name;
@@ -90,7 +93,7 @@ export class CipherExport {
domain.type = req.type;
domain.folderId = req.folderId;
if (domain.organizationId == null) {
domain.organizationId = req.organizationId;
domain.organizationId = req.organizationId as OrganizationId;
}
domain.name = req.name != null ? new EncString(req.name) : null;
domain.notes = req.notes != null ? new EncString(req.notes) : null;

View File

@@ -10,6 +10,7 @@ import { Utils } from "../../../platform/misc/utils";
import Domain from "../../../platform/models/domain/domain-base";
import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key";
import { InitializerKey } from "../../../platform/services/cryptography/initializer-key";
import { CollectionId, OrganizationId } from "../../../types/guid";
import { CipherRepromptType } from "../../enums/cipher-reprompt-type";
import { CipherType } from "../../enums/cipher-type";
import { CipherPermissionsApi } from "../api/cipher-permissions.api";
@@ -33,7 +34,7 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
readonly initializerKey = InitializerKey.Cipher;
id: string;
organizationId: string;
organizationId: OrganizationId;
folderId: string;
name: EncString;
notes: EncString;
@@ -53,7 +54,7 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
attachments: Attachment[];
fields: Field[];
passwordHistory: Password[];
collectionIds: string[];
collectionIds: CollectionId[];
creationDate: Date;
deletedDate: Date;
reprompt: CipherRepromptType;
@@ -90,7 +91,7 @@ export class Cipher extends Domain implements Decryptable<CipherView> {
}
this.permissions = obj.permissions;
this.revisionDate = obj.revisionDate != null ? new Date(obj.revisionDate) : null;
this.collectionIds = obj.collectionIds;
this.collectionIds = obj.collectionIds as CollectionId[];
this.localData = localData;
this.creationDate = obj.creationDate != null ? new Date(obj.creationDate) : null;
this.deletedDate = obj.deletedDate != null ? new Date(obj.deletedDate) : null;

View File

@@ -6,6 +6,7 @@ import { View } from "../../../models/view/view";
import { InitializerMetadata } from "../../../platform/interfaces/initializer-metadata.interface";
import { InitializerKey } from "../../../platform/services/cryptography/initializer-key";
import { DeepJsonify } from "../../../types/deep-jsonify";
import { CollectionId, OrganizationId } from "../../../types/guid";
import { CipherType, LinkedIdType } from "../../enums";
import { CipherRepromptType } from "../../enums/cipher-reprompt-type";
import { CipherPermissionsApi } from "../api/cipher-permissions.api";
@@ -25,7 +26,7 @@ export class CipherView implements View, InitializerMetadata {
readonly initializerKey = InitializerKey.CipherView;
id: string = null;
organizationId: string | undefined = null;
organizationId: OrganizationId | undefined = null;
folderId: string = null;
name: string = null;
notes: string = null;
@@ -44,7 +45,7 @@ export class CipherView implements View, InitializerMetadata {
attachments: AttachmentView[] = null;
fields: FieldView[] = null;
passwordHistory: PasswordHistoryView[] = null;
collectionIds: string[] = null;
collectionIds: CollectionId[] = null;
revisionDate: Date = null;
creationDate: Date = null;
deletedDate: Date = null;
@@ -237,7 +238,7 @@ export class CipherView implements View, InitializerMetadata {
const cipherView = new CipherView();
cipherView.id = obj.id ?? null;
cipherView.organizationId = obj.organizationId ?? null;
cipherView.organizationId = (obj.organizationId as OrganizationId) ?? null;
cipherView.folderId = obj.folderId ?? null;
cipherView.name = obj.name;
cipherView.notes = obj.notes ?? null;
@@ -262,7 +263,7 @@ export class CipherView implements View, InitializerMetadata {
cipherView.fields = obj.fields?.map((f) => FieldView.fromSdkFieldView(f)) ?? null;
cipherView.passwordHistory =
obj.passwordHistory?.map((ph) => PasswordHistoryView.fromSdkPasswordHistoryView(ph)) ?? null;
cipherView.collectionIds = obj.collectionIds ?? null;
cipherView.collectionIds = (obj.collectionIds as CollectionId[]) ?? null;
cipherView.revisionDate = obj.revisionDate == null ? null : new Date(obj.revisionDate);
cipherView.creationDate = obj.creationDate == null ? null : new Date(obj.creationDate);
cipherView.deletedDate = obj.deletedDate == null ? null : new Date(obj.deletedDate);

View File

@@ -546,7 +546,7 @@ export class CipherService implements CipherServiceAbstraction {
}
async getAllDecryptedForGrouping(
groupingId: string,
groupingId: string | CollectionId, // may be a FolderId or a CollectionId
userId: UserId,
folder = true,
): Promise<CipherView[]> {
@@ -561,7 +561,7 @@ export class CipherService implements CipherServiceAbstraction {
} else if (
!folder &&
cipher.collectionIds != null &&
cipher.collectionIds.indexOf(groupingId) > -1
cipher.collectionIds.indexOf(groupingId as CollectionId) > -1
) {
return true;
}
@@ -851,8 +851,8 @@ export class CipherService implements CipherServiceAbstraction {
async shareWithServer(
cipher: CipherView,
organizationId: string,
collectionIds: string[],
organizationId: OrganizationId,
collectionIds: CollectionId[],
userId: UserId,
): Promise<Cipher> {
const attachmentPromises: Promise<any>[] = [];
@@ -879,8 +879,8 @@ export class CipherService implements CipherServiceAbstraction {
async shareManyWithServer(
ciphers: CipherView[],
organizationId: string,
collectionIds: string[],
organizationId: OrganizationId,
collectionIds: CollectionId[],
userId: UserId,
) {
const promises: Promise<any>[] = [];

View File

@@ -1,3 +1,5 @@
import { CollectionId } from "@bitwarden/common/types/guid";
export type SelectItemView = {
id: string; // Unique ID used for comparisons
listName: string; // Default bindValue -> this is what will be displayed in list items
@@ -5,3 +7,11 @@ export type SelectItemView = {
icon?: string; // Icon to display within the list
parentGrouping?: string; // Used to group items by parent
};
export type SelectCollectionView = {
id: CollectionId; // Unique ID used for comparisons
listName: string; // Default bindValue -> this is what will be displayed in list items
labelName: string; // This is what will be displayed in the selection option badge
icon?: string; // Icon to display within the list
parentGrouping?: string; // Used to group items by parent
};

View File

@@ -49,7 +49,7 @@ import {
DialogModule,
FormFieldModule,
MultiSelectModule,
SelectItemView,
SelectCollectionView,
SelectModule,
ToastService,
} from "@bitwarden/components";
@@ -125,7 +125,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
formGroup = this.formBuilder.group({
selectedOrg: [null],
collections: [<SelectItemView[]>[], [Validators.required]],
collections: [<SelectCollectionView[]>[], [Validators.required]],
});
/**
@@ -138,7 +138,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
protected editableItemCount: number;
protected readonlyItemCount: number;
protected personalItemsCount: number;
protected availableCollections: SelectItemView[] = [];
protected availableCollections: SelectCollectionView[] = [];
protected orgName: string;
protected showOrgSelector: boolean = false;
@@ -240,8 +240,8 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
this.destroy$.complete();
}
selectCollections(items: SelectItemView[]) {
const currentCollections = this.formGroup.controls.collections.value as SelectItemView[];
selectCollections(items: SelectCollectionView[]) {
const currentCollections = this.formGroup.controls.collections.value as SelectCollectionView[];
const updatedCollections = [...currentCollections, ...items].sort(this.sortItems);
this.formGroup.patchValue({ collections: updatedCollections });
}
@@ -288,7 +288,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
this.onCollectionAssign.emit(CollectionAssignmentResult.Saved);
};
private sortItems = (a: SelectItemView, b: SelectItemView) =>
private sortItems = (a: SelectCollectionView, b: SelectCollectionView) =>
this.i18nService.collator.compare(a.labelName, b.labelName);
private async handleOrganizationCiphers(organizationId: OrganizationId) {
@@ -415,7 +415,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
this.formGroup.controls.collections.setValue([], { emitEvent: false });
}),
switchMap((orgId) => {
return this.getCollectionsForOrganization(orgId as OrganizationId);
return this.getCollectionsForOrganization(orgId);
}),
takeUntil(this.destroy$),
)
@@ -482,7 +482,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
this.selectedOrgId,
userId,
cipherIds,
this.formGroup.controls.collections.value.map((i) => i.id as CollectionId),
this.formGroup.controls.collections.value.map((i) => i.id),
false,
);
}