diff --git a/apps/web/src/app/tools/import/org-import.component.ts b/apps/web/src/app/tools/import/org-import.component.ts index 8fb5a582b1..3e86f3ce1b 100644 --- a/apps/web/src/app/tools/import/org-import.component.ts +++ b/apps/web/src/app/tools/import/org-import.component.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { Component, OnInit } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; import { firstValueFrom, map } from "rxjs"; @@ -11,6 +9,7 @@ import { } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; +import { isId, OrganizationId } from "@bitwarden/common/types/guid"; import { ImportCollectionServiceAbstraction } from "@bitwarden/importer-core"; import { ImportComponent } from "@bitwarden/importer-ui"; @@ -31,7 +30,7 @@ import { ImportCollectionAdminService } from "./import-collection-admin.service" ], }) export class OrgImportComponent implements OnInit { - protected routeOrgId: string = null; + protected routeOrgId: OrganizationId | undefined = undefined; protected loading = false; protected disabled = false; @@ -43,7 +42,16 @@ export class OrgImportComponent implements OnInit { ) {} ngOnInit(): void { - this.routeOrgId = this.route.snapshot.paramMap.get("organizationId"); + const orgIdParam = this.route.snapshot.paramMap.get("organizationId"); + if (orgIdParam === undefined) { + throw new Error("`organizationId` is a required route parameter"); + } + + if (!isId(orgIdParam)) { + throw new Error("Invalid OrganizationId provided in route parameter `organizationId`"); + } + + this.routeOrgId = orgIdParam; } /** diff --git a/libs/importer/src/components/import.component.ts b/libs/importer/src/components/import.component.ts index 3c6dc22dc2..fcb79c1c5d 100644 --- a/libs/importer/src/components/import.component.ts +++ b/libs/importer/src/components/import.component.ts @@ -35,10 +35,7 @@ import { CollectionView, } from "@bitwarden/admin-console/common"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { - getOrganizationById, - OrganizationService, -} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; @@ -48,7 +45,9 @@ import { ClientType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { getById } from "@bitwarden/common/platform/misc"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { isId, OrganizationId } from "@bitwarden/common/types/guid"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; @@ -122,21 +121,34 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { collections$: Observable; organizations$: Observable; - private _organizationId: string; + private _organizationId: OrganizationId | undefined; - get organizationId(): string { + get organizationId(): OrganizationId | undefined { return this._organizationId; } - @Input() set organizationId(value: string) { + /** + * Enables the hosting control to pass in an organizationId + * If a organizationId is provided, the organization selection is disabled. + */ + @Input() set organizationId(value: OrganizationId | string | undefined) { + if (Utils.isNullOrEmpty(value)) { + this._organizationId = undefined; + this.organization = undefined; + return; + } + + if (!isId(value)) { + this._organizationId = undefined; + this.organization = undefined; + return; + } + this._organizationId = value; + getUserId(this.accountService.activeAccount$) .pipe( - switchMap((userId) => - this.organizationService - .organizations$(userId) - .pipe(getOrganizationById(this._organizationId)), - ), + switchMap((userId) => this.organizationService.organizations$(userId).pipe(getById(value))), ) .pipe(takeUntil(this.destroy$)) .subscribe((organization) => { @@ -151,7 +163,7 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { @Input() onImportFromBrowser: (browser: string, profile: string) => Promise; - protected organization: Organization; + protected organization: Organization | undefined = undefined; protected destroy$ = new Subject(); protected readonly isCardTypeRestricted$: Observable = @@ -451,7 +463,7 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { importContents, this.organizationId, this.formGroup.controls.targetSelector.value, - (await this.canAccessImport(this.organizationId)) && this.isFromAC, + this.organization?.canAccessImport && this.isFromAC, ); //No errors, display success message @@ -471,20 +483,6 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { } } - private async canAccessImport(organizationId?: string): Promise { - if (!organizationId) { - return false; - } - const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$)); - return ( - await firstValueFrom( - this.organizationService - .organizations$(userId) - .pipe(getOrganizationById(this.organizationId)), - ) - )?.canAccessImport; - } - getFormatInstructionTitle() { if (this.format == null) { return null;