diff --git a/angular.json b/angular.json index 1670491b6fd..7053050262e 100644 --- a/angular.json +++ b/angular.json @@ -128,10 +128,10 @@ "builder": "@angular-devkit/build-angular:dev-server", "configurations": { "production": { - "browserTarget": "test-storybook:build:production" + "buildTarget": "test-storybook:build:production" }, "development": { - "browserTarget": "test-storybook:build:development" + "buildTarget": "test-storybook:build:development" } }, "defaultConfiguration": "development" diff --git a/apps/browser/package.json b/apps/browser/package.json index 4ff4615983b..5909c802b36 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/browser", - "version": "2024.10.999", + "version": "2024.11.0", "scripts": { "build": "cross-env MANIFEST_VERSION=3 webpack", "build:mv2": "webpack", diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index 29ae35d5cef..6ec3c0a9b5a 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -32,6 +32,7 @@ import { } from "@bitwarden/common/spec"; import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -106,6 +107,7 @@ describe("OverlayBackground", () => { let selectedThemeMock$: BehaviorSubject; let inlineMenuFieldQualificationService: InlineMenuFieldQualificationService; let themeStateService: MockProxy; + let totpService: MockProxy; let overlayBackground: OverlayBackground; let portKeyForTabSpy: Record; let pageDetailsForTabSpy: PageDetailsForTab; @@ -184,6 +186,7 @@ describe("OverlayBackground", () => { inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService(); themeStateService = mock(); themeStateService.selectedTheme$ = selectedThemeMock$; + totpService = mock(); overlayBackground = new OverlayBackground( logService, cipherService, @@ -198,6 +201,7 @@ describe("OverlayBackground", () => { fido2ActiveRequestManager, inlineMenuFieldQualificationService, themeStateService, + totpService, generatedPasswordCallbackMock, addPasswordCallbackMock, ); diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index a2b3e33d74f..c42d1f7e640 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -33,6 +33,7 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { Utils } from "@bitwarden/common/platform/misc/utils"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; +import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service"; import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { buildCipherIcon } from "@bitwarden/common/vault/icon/build-cipher-icon"; @@ -217,6 +218,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { private fido2ActiveRequestManager: Fido2ActiveRequestManager, private inlineMenuFieldQualificationService: InlineMenuFieldQualificationService, private themeStateService: ThemeStateService, + private totpService: TotpService, private generatePasswordCallback: () => Promise, private addPasswordCallback: (password: string) => Promise, ) { @@ -1058,7 +1060,6 @@ export class OverlayBackground implements OverlayBackgroundInterface { } const cipher = this.inlineMenuCiphers.get(inlineMenuCipherId); - if (usePasskey && cipher.login?.hasFido2Credentials) { await this.authenticatePasskeyCredential( sender, @@ -1066,6 +1067,11 @@ export class OverlayBackground implements OverlayBackgroundInterface { ); this.updateLastUsedInlineMenuCipher(inlineMenuCipherId, cipher); + if (cipher.login?.totp) { + this.platformUtilsService.copyToClipboard( + await this.totpService.getCode(cipher.login.totp), + ); + } return; } diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index c3ecb5d3fe7..27d83af1321 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -1678,6 +1678,7 @@ export default class MainBackground { this.fido2ActiveRequestManager, inlineMenuFieldQualificationService, this.themeStateService, + this.totpService, () => this.generatePassword(), (password) => this.addPasswordToHistory(password), ); diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index 4997b368471..0d9a4189578 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2024.10.999", + "version": "2024.11.0", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index 3161f119a75..f805b701551 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -3,7 +3,7 @@ "minimum_chrome_version": "102.0", "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2024.10.999", + "version": "2024.11.0", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/apps/cli/package.json b/apps/cli/package.json index 6aa48d5d4a5..622c1273823 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/cli", "description": "A secure and free password manager for all of your devices.", - "version": "2024.10.0", + "version": "2024.11.0", "keywords": [ "bitwarden", "password", @@ -80,7 +80,7 @@ "papaparse": "5.4.1", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", - "tldts": "6.1.56", + "tldts": "6.1.58", "zxcvbn": "4.4.2" } } diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 8c89da0e85f..c9e33b7110a 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2024.10.3", + "version": "2024.11.0", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index 669467d3569..21075252981 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2024.10.3", + "version": "2024.11.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2024.10.3", + "version": "2024.11.0", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-napi": "file:../desktop_native/napi", diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index bc711455185..3f4bb0fc0cf 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2024.10.3", + "version": "2024.11.0", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/apps/web/package.json b/apps/web/package.json index 21274fbd804..5dd0e442f2d 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2024.10.5", + "version": "2024.11.0", "scripts": { "build:oss": "webpack", "build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js", diff --git a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html index a8ecf255f33..b2812727473 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html +++ b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html @@ -23,15 +23,14 @@

{{ "inviteUserDesc" | i18n }}

- + {{ "email" | i18n }} - {{ - "inviteMultipleEmailDesc" | i18n: remainingSeats + {{ + "inviteMultipleEmailDesc" + | i18n + : (organization.productTierType === ProductTierType.TeamsStarter ? "10" : "20") }} - - {{ "inviteSingleEmailDesc" | i18n: remainingSeats }} -
@@ -265,6 +264,16 @@ + + diff --git a/apps/web/src/app/admin-console/organizations/members/members.component.ts b/apps/web/src/app/admin-console/organizations/members/members.component.ts index db1d4d42dfc..9ace5d1f0b5 100644 --- a/apps/web/src/app/admin-console/organizations/members/members.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/members.component.ts @@ -486,7 +486,7 @@ export class MembersComponent extends BaseMembersComponent const enableUpgradePasswordManagerSub = await firstValueFrom( this.enableUpgradePasswordManagerSub$, ); - if (enableUpgradePasswordManagerSub) { + if (enableUpgradePasswordManagerSub && this.organization.canEditSubscription) { const reference = openChangePlanDialog(this.dialogService, { data: { organizationId: this.organization.id, @@ -518,6 +518,7 @@ export class MembersComponent extends BaseMembersComponent isOnSecretsManagerStandalone: this.orgIsOnSecretsManagerStandalone, initialTab: initialTab, numConfirmedMembers: this.dataSource.confirmedUserCount, + managedByOrganization: user?.managedByOrganization, }, }); @@ -725,6 +726,40 @@ export class MembersComponent extends BaseMembersComponent return true; } + async deleteUser(user: OrganizationUserView) { + const confirmed = await this.dialogService.openSimpleDialog({ + title: { + key: "deleteOrganizationUser", + placeholders: [this.userNamePipe.transform(user)], + }, + content: { key: "deleteOrganizationUserWarning" }, + type: "warning", + acceptButtonText: { key: "delete" }, + cancelButtonText: { key: "cancel" }, + }); + + if (!confirmed) { + return false; + } + + this.actionPromise = this.organizationUserApiService.deleteOrganizationUser( + this.organization.id, + user.id, + ); + try { + await this.actionPromise; + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("organizationUserDeleted", this.userNamePipe.transform(user)), + }); + this.dataSource.removeUser(user); + } catch (e) { + this.validationService.showError(e); + } + this.actionPromise = null; + } + private async noMasterPasswordConfirmationDialog(user: OrganizationUserView) { return this.dialogService.openSimpleDialog({ title: { diff --git a/apps/web/src/app/auth/settings/account/account.component.html b/apps/web/src/app/auth/settings/account/account.component.html index a5e5329fce7..4055f14219c 100644 --- a/apps/web/src/app/auth/settings/account/account.component.html +++ b/apps/web/src/app/auth/settings/account/account.component.html @@ -21,7 +21,13 @@ > {{ "purgeVault" | i18n }} - diff --git a/apps/web/src/app/auth/settings/account/account.component.ts b/apps/web/src/app/auth/settings/account/account.component.ts index 51bf4276960..eed88476e27 100644 --- a/apps/web/src/app/auth/settings/account/account.component.ts +++ b/apps/web/src/app/auth/settings/account/account.component.ts @@ -23,6 +23,7 @@ export class AccountComponent implements OnInit { showChangeEmail$: Observable; showPurgeVault$: Observable; + showDeleteAccount$: Observable; constructor( private modalService: ModalService, @@ -63,6 +64,16 @@ export class AccountComponent implements OnInit { !isAccountDeprovisioningEnabled || !userIsManagedByOrganization, ), ); + + this.showDeleteAccount$ = combineLatest([ + isAccountDeprovisioningEnabled$, + userIsManagedByOrganization$, + ]).pipe( + map( + ([isAccountDeprovisioningEnabled, userIsManagedByOrganization]) => + !isAccountDeprovisioningEnabled || !userIsManagedByOrganization, + ), + ); } async deauthorizeSessions() { diff --git a/apps/web/src/app/tools/access-intelligence/access-intelligence.component.html b/apps/web/src/app/tools/access-intelligence/access-intelligence.component.html index 738b3433890..0f62a434648 100644 --- a/apps/web/src/app/tools/access-intelligence/access-intelligence.component.html +++ b/apps/web/src/app/tools/access-intelligence/access-intelligence.component.html @@ -15,7 +15,7 @@ {{ "refresh" | i18n }} - + diff --git a/apps/web/src/app/tools/access-intelligence/access-intelligence.component.ts b/apps/web/src/app/tools/access-intelligence/access-intelligence.component.ts index da48039ce3e..557ae73625a 100644 --- a/apps/web/src/app/tools/access-intelligence/access-intelligence.component.ts +++ b/apps/web/src/app/tools/access-intelligence/access-intelligence.component.ts @@ -1,8 +1,7 @@ import { CommonModule } from "@angular/common"; import { Component } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { ActivatedRoute } from "@angular/router"; -import { first } from "rxjs"; +import { ActivatedRoute, Router } from "@angular/router"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { AsyncActionsModule, ButtonModule, TabsModule } from "@bitwarden/components"; @@ -18,7 +17,7 @@ import { PasswordHealthComponent } from "./password-health.component"; export enum AccessIntelligenceTabType { AllApps = 0, - PriorityApps = 1, + CriticalApps = 1, NotifiedMembers = 2, } @@ -58,8 +57,19 @@ export class AccessIntelligenceComponent { ); } - constructor(route: ActivatedRoute) { - route.queryParams.pipe(takeUntilDestroyed(), first()).subscribe(({ tabIndex }) => { + onTabChange = async (newIndex: number) => { + await this.router.navigate([], { + relativeTo: this.route, + queryParams: { tabIndex: newIndex }, + queryParamsHandling: "merge", + }); + }; + + constructor( + protected route: ActivatedRoute, + private router: Router, + ) { + route.queryParams.pipe(takeUntilDestroyed()).subscribe(({ tabIndex }) => { this.tabIndex = !isNaN(tabIndex) ? tabIndex : AccessIntelligenceTabType.AllApps; }); } diff --git a/apps/web/src/app/tools/access-intelligence/all-applications.component.html b/apps/web/src/app/tools/access-intelligence/all-applications.component.html index bd0a90859ac..5dfaa202402 100644 --- a/apps/web/src/app/tools/access-intelligence/all-applications.component.html +++ b/apps/web/src/app/tools/access-intelligence/all-applications.component.html @@ -14,13 +14,15 @@ -

- {{ "noAppsInOrgDescription" | i18n }} +

+ + {{ "noAppsInOrgDescription" | i18n }} + {{ "learnMore" | i18n }} -

+
- @@ -50,7 +52,15 @@ class="tw-grow" [formControl]="searchControl" > - diff --git a/apps/web/src/app/tools/access-intelligence/all-applications.component.ts b/apps/web/src/app/tools/access-intelligence/all-applications.component.ts index 245314673a5..1b648567df2 100644 --- a/apps/web/src/app/tools/access-intelligence/all-applications.component.ts +++ b/apps/web/src/app/tools/access-intelligence/all-applications.component.ts @@ -40,6 +40,7 @@ export class AllApplicationsComponent implements OnInit { protected loading = false; protected organization: Organization; noItemsIcon = Icons.Security; + protected markingAsCritical = false; // MOCK DATA protected mockData = applicationTableMockData; @@ -76,8 +77,18 @@ export class AllApplicationsComponent implements OnInit { .subscribe((v) => (this.dataSource.filter = v)); } + goToCreateNewLoginItem = async () => { + // TODO: implement + this.toastService.showToast({ + variant: "warning", + title: null, + message: "Not yet implemented", + }); + }; + markAppsAsCritical = async () => { // TODO: Send to API once implemented + this.markingAsCritical = true; return new Promise((resolve) => { setTimeout(() => { this.selectedIds.clear(); @@ -87,6 +98,7 @@ export class AllApplicationsComponent implements OnInit { message: this.i18nService.t("appsMarkedAsCritical"), }); resolve(true); + this.markingAsCritical = false; }, 1000); }); }; diff --git a/apps/web/src/app/tools/access-intelligence/critical-applications.component.html b/apps/web/src/app/tools/access-intelligence/critical-applications.component.html index e03988fbf9e..1c503f3d786 100644 --- a/apps/web/src/app/tools/access-intelligence/critical-applications.component.html +++ b/apps/web/src/app/tools/access-intelligence/critical-applications.component.html @@ -19,7 +19,9 @@

- + diff --git a/apps/web/src/app/tools/access-intelligence/critical-applications.component.ts b/apps/web/src/app/tools/access-intelligence/critical-applications.component.ts index 545ba14d21c..a5df519fd80 100644 --- a/apps/web/src/app/tools/access-intelligence/critical-applications.component.ts +++ b/apps/web/src/app/tools/access-intelligence/critical-applications.component.ts @@ -1,7 +1,7 @@ import { Component, DestroyRef, inject, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormControl } from "@angular/forms"; -import { ActivatedRoute } from "@angular/router"; +import { ActivatedRoute, Router } from "@angular/router"; import { debounceTime, map } from "rxjs"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -12,6 +12,7 @@ import { HeaderModule } from "../../layouts/header/header.module"; import { SharedModule } from "../../shared"; import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module"; +import { AccessIntelligenceTabType } from "./access-intelligence.component"; import { applicationTableMockData } from "./application-table.mock"; @Component({ @@ -26,8 +27,10 @@ export class CriticalApplicationsComponent implements OnInit { protected searchControl = new FormControl("", { nonNullable: true }); private destroyRef = inject(DestroyRef); protected loading = false; + protected organizationId: string; noItemsIcon = Icons.Security; // MOCK DATA + protected mockData = applicationTableMockData; protected mockAtRiskMembersCount = 0; protected mockAtRiskAppsCount = 0; protected mockTotalMembersCount = 0; @@ -38,18 +41,26 @@ export class CriticalApplicationsComponent implements OnInit { .pipe( takeUntilDestroyed(this.destroyRef), map(async (params) => { - // const organizationId = params.get("organizationId"); + this.organizationId = params.get("organizationId"); // TODO: use organizationId to fetch data }), ) .subscribe(); } + goToAllAppsTab = async () => { + await this.router.navigate([`organizations/${this.organizationId}/access-intelligence`], { + queryParams: { tabIndex: AccessIntelligenceTabType.AllApps }, + queryParamsHandling: "merge", + }); + }; + constructor( protected i18nService: I18nService, protected activatedRoute: ActivatedRoute, + protected router: Router, ) { - this.dataSource.data = applicationTableMockData; + this.dataSource.data = []; //applicationTableMockData; this.searchControl.valueChanges .pipe(debounceTime(200), takeUntilDestroyed()) .subscribe((v) => (this.dataSource.filter = v)); diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 619d2407be2..7e441ae4ba2 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -3218,9 +3218,6 @@ } } }, - "inviteSingleEmailDesc": { - "message": "You have 1 invite remaining." - }, "userUsingTwoStep": { "message": "This user is using two-step login to protect their account." }, @@ -9557,5 +9554,31 @@ }, "single-org-revoked-user-warning": { "message": "Non-compliant members will be revoked. Administrators can restore members once they leave all other organizations." + }, + "deleteOrganizationUser": { + "message": "Delete $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "John Doe" + }, + "description": "Title for the delete organization user dialog" + } + }, + "deleteOrganizationUserWarning": { + "message": "When a member is deleted, their Bitwarden account and individual vault data will be permanently deleted. Collection data will remain in the organization. To reinstate them they must create an account and be onboarded again.", + "description": "Warning for the delete organization user dialog" + }, + "organizationUserDeleted": { + "message": "Deleted $NAME$", + "placeholders": { + "name": { + "content": "$1", + "example": "John Doe" + } + } + }, + "organizationUserDeletedDesc": { + "message": "The user was removed from the organization and all associated user data has been deleted." } } diff --git a/apps/web/src/polyfills.ts b/apps/web/src/polyfills.ts index cc26cd13ab7..33af553f786 100644 --- a/apps/web/src/polyfills.ts +++ b/apps/web/src/polyfills.ts @@ -1,10 +1,9 @@ import "core-js/stable"; -require("zone.js/dist/zone"); +import "zone.js"; if (process.env.NODE_ENV === "production") { // Production } else { // Development and test Error["stackTraceLimit"] = Infinity; - require("zone.js/dist/long-stack-trace-zone"); } diff --git a/libs/admin-console/src/common/organization-user/abstractions/organization-user-api.service.ts b/libs/admin-console/src/common/organization-user/abstractions/organization-user-api.service.ts index ff7f9c5df6c..42cbe1438d1 100644 --- a/libs/admin-console/src/common/organization-user/abstractions/organization-user-api.service.ts +++ b/libs/admin-console/src/common/organization-user/abstractions/organization-user-api.service.ts @@ -275,4 +275,11 @@ export abstract class OrganizationUserApiService { organizationId: string, ids: string[], ): Promise>; + + /** + * Remove an organization user's access to the organization and delete their account data + * @param organizationId - Identifier for the organization the user belongs to + * @param id - Organization user identifier + */ + abstract deleteOrganizationUser(organizationId: string, id: string): Promise; } diff --git a/libs/admin-console/src/common/organization-user/services/default-organization-user-api.service.ts b/libs/admin-console/src/common/organization-user/services/default-organization-user-api.service.ts index 6a9911e732c..d9e069dc934 100644 --- a/libs/admin-console/src/common/organization-user/services/default-organization-user-api.service.ts +++ b/libs/admin-console/src/common/organization-user/services/default-organization-user-api.service.ts @@ -359,4 +359,14 @@ export class DefaultOrganizationUserApiService implements OrganizationUserApiSer ); return new ListResponse(r, OrganizationUserBulkResponse); } + + deleteOrganizationUser(organizationId: string, id: string): Promise { + return this.apiService.send( + "DELETE", + "/organizations/" + organizationId + "/users/" + id + "/delete-account", + null, + true, + false, + ); + } } diff --git a/libs/common/src/platform/state/implementations/default-active-user-state.spec.ts b/libs/common/src/platform/state/implementations/default-active-user-state.spec.ts index 99cc785f9ba..b73415d6b79 100644 --- a/libs/common/src/platform/state/implementations/default-active-user-state.spec.ts +++ b/libs/common/src/platform/state/implementations/default-active-user-state.spec.ts @@ -220,7 +220,8 @@ describe("DefaultActiveUserState", () => { it("should not emit a previous users value if that user is no longer active", async () => { const user1Data: Jsonify = { date: "2020-09-21T13:14:17.648Z", - array: ["value"], + // NOTE: `as any` is here until we migrate to Nx: https://bitwarden.atlassian.net/browse/PM-6493 + array: ["value"] as any, }; const user2Data: Jsonify = { date: "2020-09-21T13:14:17.648Z", diff --git a/libs/common/src/platform/state/key-definition.spec.ts b/libs/common/src/platform/state/key-definition.spec.ts index 4eed0384811..3406a4e9014 100644 --- a/libs/common/src/platform/state/key-definition.spec.ts +++ b/libs/common/src/platform/state/key-definition.spec.ts @@ -192,7 +192,8 @@ describe("KeyDefinition", () => { expect(arrayDefinition).toBeTruthy(); expect(arrayDefinition.deserializer).toBeTruthy(); - const deserializedValue = arrayDefinition.deserializer([false, true]); + // NOTE: `as any` is here until we migrate to Nx: https://bitwarden.atlassian.net/browse/PM-6493 + const deserializedValue = arrayDefinition.deserializer([false, true] as any); expect(deserializedValue).toBeTruthy(); expect(deserializedValue).toHaveLength(2); diff --git a/libs/common/src/vault/models/domain/login.spec.ts b/libs/common/src/vault/models/domain/login.spec.ts index e420a953e68..4f9e4546220 100644 --- a/libs/common/src/vault/models/domain/login.spec.ts +++ b/libs/common/src/vault/models/domain/login.spec.ts @@ -151,6 +151,7 @@ describe("Login DTO", () => { password: "myPassword" as EncryptedString, passwordRevisionDate: passwordRevisionDate.toISOString(), totp: "myTotp" as EncryptedString, + // NOTE: `as any` is here until we migrate to Nx: https://bitwarden.atlassian.net/browse/PM-6493 fido2Credentials: [ { credentialId: "keyId" as EncryptedString, @@ -167,7 +168,7 @@ describe("Login DTO", () => { discoverable: "discoverable" as EncryptedString, creationDate: fido2CreationDate.toISOString(), }, - ], + ] as any, }); expect(actual).toEqual({ diff --git a/libs/components/src/item/item.mdx b/libs/components/src/item/item.mdx index b5c7da80baa..ca697ebb436 100644 --- a/libs/components/src/item/item.mdx +++ b/libs/components/src/item/item.mdx @@ -71,7 +71,7 @@ The content can be a button, anchor, or static container.