mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 16:53:34 +00:00
[PM-23920] Admin Console - adopt strongly typed guids (#15814)
Update organization, collection and policy to use strongly typed IDs
This commit is contained in:
@@ -9,6 +9,7 @@ import { normalizeExpiryYearFormat } from "@bitwarden/common/autofill/utils";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
|
||||
import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { FieldType, SecureNoteType, CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { FieldView } from "@bitwarden/common/vault/models/view/field.view";
|
||||
@@ -20,7 +21,7 @@ import { SecureNoteView } from "@bitwarden/common/vault/models/view/secure-note.
|
||||
import { ImportResult } from "../models/import-result";
|
||||
|
||||
export abstract class BaseImporter {
|
||||
organizationId: string = null;
|
||||
organizationId: OrganizationId = null;
|
||||
|
||||
// FIXME: This should be replaced by injecting the log service.
|
||||
protected logService: LogService = new ConsoleLogService(false);
|
||||
@@ -279,7 +280,7 @@ export abstract class BaseImporter {
|
||||
result.collections = result.folders.map((f) => {
|
||||
const collection = new CollectionView();
|
||||
collection.name = f.name;
|
||||
collection.id = f.id ?? undefined; // folder id may be null, which is not suitable for collections.
|
||||
collection.id = (f.id as CollectionId) ?? undefined; // folder id may be null, which is not suitable for collections.
|
||||
return collection;
|
||||
});
|
||||
result.folderRelationships = [];
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import {
|
||||
testData as TestData,
|
||||
@@ -103,7 +104,7 @@ describe("Keeper CSV Importer", () => {
|
||||
});
|
||||
|
||||
it("should create collections, with subcollections and relationships", async () => {
|
||||
importer.organizationId = Utils.newGuid();
|
||||
importer.organizationId = Utils.newGuid() as OrganizationId;
|
||||
const result = await importer.parse(TestData);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
@@ -126,7 +127,7 @@ describe("Keeper CSV Importer", () => {
|
||||
});
|
||||
|
||||
it("should create collections tree, with child collections and relationships", async () => {
|
||||
importer.organizationId = Utils.newGuid();
|
||||
importer.organizationId = Utils.newGuid() as OrganizationId;
|
||||
const result = await importer.parse(testDataMultiCollection);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { testData as TestData } from "../spec-data/keeper-json/testdata.json";
|
||||
|
||||
@@ -93,7 +94,7 @@ describe("Keeper Json Importer", () => {
|
||||
});
|
||||
|
||||
it("should create collections if part of an organization", async () => {
|
||||
importer.organizationId = Utils.newGuid();
|
||||
importer.organizationId = Utils.newGuid() as OrganizationId;
|
||||
const result = await importer.parse(testDataJson);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import {
|
||||
credentialsData,
|
||||
@@ -79,7 +80,7 @@ describe("Netwrix Password Secure CSV Importer", () => {
|
||||
});
|
||||
|
||||
it("should parse an item and create a collection when importing into an organization", async () => {
|
||||
importer.organizationId = Utils.newGuid();
|
||||
importer.organizationId = Utils.newGuid() as OrganizationId;
|
||||
const result = await importer.parse(credentialsData);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
@@ -93,7 +94,7 @@ describe("Netwrix Password Secure CSV Importer", () => {
|
||||
});
|
||||
|
||||
it("should parse multiple collections", async () => {
|
||||
importer.organizationId = Utils.newGuid();
|
||||
importer.organizationId = Utils.newGuid() as OrganizationId;
|
||||
const result = await importer.parse(credentialsDataWithFolders);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { SecureNoteType, CipherType, FieldType } from "@bitwarden/common/vault/enums";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { IdentityView } from "@bitwarden/common/vault/models/view/identity.view";
|
||||
@@ -224,7 +225,7 @@ describe("NordPass CSV Importer", () => {
|
||||
});
|
||||
|
||||
it("should parse an item and create a collection if organizationId is set", async () => {
|
||||
importer.organizationId = Utils.newGuid();
|
||||
importer.organizationId = Utils.newGuid() as OrganizationId;
|
||||
const result = await importer.parse(secureNoteData);
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { FieldType, SecureNoteType, CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { FieldView } from "@bitwarden/common/vault/models/view/field.view";
|
||||
|
||||
@@ -691,7 +692,7 @@ describe("1Password 1Pux Importer", () => {
|
||||
|
||||
it("should create collections if part of an organization", async () => {
|
||||
const importer = new OnePassword1PuxImporter();
|
||||
importer.organizationId = Utils.newGuid();
|
||||
importer.organizationId = Utils.newGuid() as OrganizationId;
|
||||
const result = await importer.parse(SanitizedExportJson);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
|
||||
import { ImportResult } from "../../models/import-result";
|
||||
@@ -146,7 +147,7 @@ describe("PasswordXPCsvImporter", () => {
|
||||
});
|
||||
|
||||
it("should convert folders to collections when importing into an organization", async () => {
|
||||
importer.organizationId = "someOrg";
|
||||
importer.organizationId = "someOrg" as OrganizationId;
|
||||
const result: ImportResult = await importer.parse(withFolders);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.ciphers.length).toBe(5);
|
||||
@@ -172,7 +173,7 @@ describe("PasswordXPCsvImporter", () => {
|
||||
});
|
||||
|
||||
it("should convert multi-level folders to collections when importing into an organization", async () => {
|
||||
importer.organizationId = "someOrg";
|
||||
importer.organizationId = "someOrg" as OrganizationId;
|
||||
const result: ImportResult = await importer.parse(withMultipleFolders);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.ciphers.length).toBe(5);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop.
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { FieldType, SecureNoteType } from "@bitwarden/common/vault/enums";
|
||||
import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
|
||||
import { CipherType } from "@bitwarden/sdk-internal";
|
||||
@@ -485,7 +486,7 @@ describe("Password Depot 17 Xml Importer", () => {
|
||||
|
||||
it("should parse groups nodes into collections when importing into an organization", async () => {
|
||||
const importer = new PasswordDepot17XmlImporter();
|
||||
importer.organizationId = "someOrgId";
|
||||
importer.organizationId = "someOrgId" as OrganizationId;
|
||||
const collection = new CollectionView();
|
||||
collection.name = "tempDB";
|
||||
const actual = [collection];
|
||||
|
||||
@@ -2,6 +2,7 @@ import { MockProxy } from "jest-mock-extended";
|
||||
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { FieldType, CipherType } from "@bitwarden/common/vault/enums";
|
||||
|
||||
import { testData } from "../spec-data/protonpass-json/protonpass.json";
|
||||
@@ -90,7 +91,7 @@ describe("Protonpass Json Importer", () => {
|
||||
|
||||
it("should create collections if part of an organization", async () => {
|
||||
const testDataJson = JSON.stringify(testData);
|
||||
importer.organizationId = Utils.newGuid();
|
||||
importer.organizationId = Utils.newGuid() as OrganizationId;
|
||||
const result = await importer.parse(testDataJson);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { FieldType, CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { FieldView } from "@bitwarden/common/vault/models/view/field.view";
|
||||
|
||||
@@ -236,7 +237,7 @@ describe("PSONO JSON Importer", () => {
|
||||
|
||||
it("should create collections if part of an organization", async () => {
|
||||
const importer = new PsonoJsonImporter();
|
||||
importer.organizationId = "someOrg";
|
||||
importer.organizationId = "someOrg" as OrganizationId;
|
||||
const result = await importer.parse(FoldersTestDataJson);
|
||||
expect(result != null).toBe(true);
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view";
|
||||
import { LoginView } from "@bitwarden/common/vault/models/view/login.view";
|
||||
@@ -73,7 +74,7 @@ describe("Zoho Vault CSV Importer", () => {
|
||||
|
||||
it("should create collection and assign ciphers when importing into an organization", async () => {
|
||||
const importer = new ZohoVaultCsvImporter();
|
||||
importer.organizationId = "someOrgId";
|
||||
importer.organizationId = "someOrgId" as OrganizationId;
|
||||
const result = await importer.parse(samplezohovaultcsvdata);
|
||||
expect(result != null).toBe(true);
|
||||
expect(result.success).toBe(true);
|
||||
|
||||
@@ -9,6 +9,7 @@ import { PinServiceAbstraction } from "@bitwarden/common/key-management/pin/pin.
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { MockSdkService } from "@bitwarden/common/platform/spec/mock-sdk.service";
|
||||
import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
@@ -67,7 +68,7 @@ describe("ImportService", () => {
|
||||
describe("getImporterInstance", () => {
|
||||
describe("Get bitPasswordProtected importer", () => {
|
||||
let importer: Importer;
|
||||
const organizationId = Utils.newGuid();
|
||||
const organizationId = Utils.newGuid() as OrganizationId;
|
||||
const password = Utils.newGuid();
|
||||
const promptForPassword_callback = async () => {
|
||||
return password;
|
||||
@@ -98,7 +99,7 @@ describe("ImportService", () => {
|
||||
});
|
||||
|
||||
describe("setImportTarget", () => {
|
||||
const organizationId = Utils.newGuid();
|
||||
const organizationId = Utils.newGuid() as OrganizationId;
|
||||
|
||||
let importResult: ImportResult;
|
||||
|
||||
@@ -145,19 +146,19 @@ describe("ImportService", () => {
|
||||
});
|
||||
|
||||
const mockImportTargetCollection = new CollectionView();
|
||||
mockImportTargetCollection.id = "myImportTarget";
|
||||
mockImportTargetCollection.id = "myImportTarget" as CollectionId;
|
||||
mockImportTargetCollection.name = "myImportTarget";
|
||||
mockImportTargetCollection.organizationId = organizationId;
|
||||
|
||||
const mockCollection1 = new CollectionView();
|
||||
mockCollection1.id = "collection1";
|
||||
mockCollection1.id = "collection1" as CollectionId;
|
||||
mockCollection1.name = "collection1";
|
||||
mockCollection1.organizationId = organizationId;
|
||||
|
||||
const mockCollection2 = new CollectionView();
|
||||
mockCollection1.id = "collection2";
|
||||
mockCollection1.name = "collection2";
|
||||
mockCollection1.organizationId = organizationId;
|
||||
mockCollection2.id = "collection2" as CollectionId;
|
||||
mockCollection2.name = "collection2";
|
||||
mockCollection2.organizationId = organizationId;
|
||||
|
||||
it("passing importTarget adds it to collections", async () => {
|
||||
await importService["setImportTarget"](
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ErrorResponse } from "@bitwarden/common/models/response/error.response"
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { SdkService } from "@bitwarden/common/platform/abstractions/sdk/sdk.service";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
|
||||
import { CipherType, toCipherTypeName } from "@bitwarden/common/vault/enums";
|
||||
@@ -130,7 +131,7 @@ export class ImportService implements ImportServiceAbstraction {
|
||||
async import(
|
||||
importer: Importer,
|
||||
fileContents: string,
|
||||
organizationId: string = null,
|
||||
organizationId: OrganizationId = null,
|
||||
selectedImportTarget: FolderView | CollectionView = null,
|
||||
canAccessImportExport: boolean,
|
||||
): Promise<ImportResult> {
|
||||
@@ -204,7 +205,7 @@ export class ImportService implements ImportServiceAbstraction {
|
||||
getImporter(
|
||||
format: ImportType | "bitwardenpasswordprotected",
|
||||
promptForPassword_callback: () => Promise<string>,
|
||||
organizationId: string = null,
|
||||
organizationId: OrganizationId = null,
|
||||
): Importer {
|
||||
if (promptForPassword_callback == null) {
|
||||
return null;
|
||||
@@ -393,7 +394,10 @@ export class ImportService implements ImportServiceAbstraction {
|
||||
return await this.importApiService.postImportCiphers(request);
|
||||
}
|
||||
|
||||
private async handleOrganizationalImport(importResult: ImportResult, organizationId: string) {
|
||||
private async handleOrganizationalImport(
|
||||
importResult: ImportResult,
|
||||
organizationId: OrganizationId,
|
||||
) {
|
||||
const request = new ImportOrganizationCiphersRequest();
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
|
||||
Reference in New Issue
Block a user