From 2487e9b98deb32b10a43bd93cc839d4556223ad4 Mon Sep 17 00:00:00 2001 From: Jonathan Prusik Date: Mon, 12 May 2025 11:13:49 -0400 Subject: [PATCH 01/25] [PM-20637] Trigger password reprompt when updating a reprompt cipher via notification (#14575) * reprompt user on cipher update when enabled Co-authored-by: Daniel Riera * update tests * add test --------- Co-authored-by: Daniel Riera --- .../notification.background.spec.ts | 57 ++++++++++++++++++- .../background/notification.background.ts | 42 ++++++++++++-- .../overlay-notifications-content.service.ts | 1 + .../overlay-notifications-content.service.ts | 6 +- .../services/abstractions/autofill.service.ts | 6 +- .../src/autofill/services/autofill.service.ts | 9 ++- .../vault-v2/view-v2/view-v2.component.ts | 27 +++++++-- libs/common/src/autofill/constants/index.ts | 3 +- 8 files changed, 134 insertions(+), 17 deletions(-) diff --git a/apps/browser/src/autofill/background/notification.background.spec.ts b/apps/browser/src/autofill/background/notification.background.spec.ts index 63ae1193737..009efd7ff36 100644 --- a/apps/browser/src/autofill/background/notification.background.spec.ts +++ b/apps/browser/src/autofill/background/notification.background.spec.ts @@ -17,6 +17,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { SelfHostedEnvironment } from "@bitwarden/common/platform/services/default-environment.service"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; import { UserId } from "@bitwarden/common/types/guid"; +import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { CipherService } from "@bitwarden/common/vault/services/cipher.service"; @@ -828,6 +829,7 @@ describe("NotificationBackground", () => { id: "testId", name: "testItemName", login: { username: "testUser" }, + reprompt: CipherRepromptType.None, }); getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); @@ -842,6 +844,7 @@ describe("NotificationBackground", () => { message.edit, sender.tab, "testId", + false, ); expect(updateWithServerSpy).toHaveBeenCalled(); expect(tabSendMessageDataSpy).toHaveBeenCalledWith( @@ -855,6 +858,55 @@ describe("NotificationBackground", () => { ); }); + it("prompts the user for master password entry if the notification message type is for ChangePassword and the cipher reprompt is enabled", async () => { + const tab = createChromeTabMock({ id: 1, url: "https://example.com" }); + const sender = mock({ tab }); + const message: NotificationBackgroundExtensionMessage = { + command: "bgSaveCipher", + edit: false, + folder: "folder-id", + }; + const queueMessage = mock({ + type: NotificationQueueMessageType.ChangePassword, + tab, + domain: "example.com", + newPassword: "newPassword", + }); + notificationBackground["notificationQueue"] = [queueMessage]; + const cipherView = mock({ + id: "testId", + name: "testItemName", + login: { username: "testUser" }, + reprompt: CipherRepromptType.Password, + }); + getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); + + sendMockExtensionMessage(message, sender); + await flushPromises(); + + expect(editItemSpy).not.toHaveBeenCalled(); + expect(autofillService.isPasswordRepromptRequired).toHaveBeenCalled(); + expect(createWithServerSpy).not.toHaveBeenCalled(); + expect(updatePasswordSpy).toHaveBeenCalledWith( + cipherView, + queueMessage.newPassword, + message.edit, + sender.tab, + "testId", + false, + ); + expect(updateWithServerSpy).not.toHaveBeenCalled(); + expect(tabSendMessageDataSpy).not.toHaveBeenCalledWith( + sender.tab, + "saveCipherAttemptCompleted", + { + itemName: "testItemName", + cipherId: cipherView.id, + task: undefined, + }, + ); + }); + it("completes password update notification with a security task notice if any are present for the cipher, and dismisses tasks for the updated cipher", async () => { const mockCipherId = "testId"; const mockOrgId = "testOrgId"; @@ -905,6 +957,7 @@ describe("NotificationBackground", () => { id: mockCipherId, organizationId: mockOrgId, name: "Test Item", + reprompt: CipherRepromptType.None, }); getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); @@ -919,6 +972,7 @@ describe("NotificationBackground", () => { message.edit, sender.tab, mockCipherId, + false, ); expect(updateWithServerSpy).toHaveBeenCalled(); expect(tabSendMessageDataSpy).toHaveBeenCalledWith( @@ -1000,6 +1054,7 @@ describe("NotificationBackground", () => { message.edit, sender.tab, "testId", + false, ); expect(editItemSpy).toHaveBeenCalled(); expect(updateWithServerSpy).not.toHaveBeenCalled(); @@ -1170,7 +1225,7 @@ describe("NotificationBackground", () => { newPassword: "newPassword", }); notificationBackground["notificationQueue"] = [queueMessage]; - const cipherView = mock(); + const cipherView = mock({ reprompt: CipherRepromptType.None }); getDecryptedCipherByIdSpy.mockResolvedValueOnce(cipherView); const errorMessage = "fetch error"; updateWithServerSpy.mockImplementation(() => { diff --git a/apps/browser/src/autofill/background/notification.background.ts b/apps/browser/src/autofill/background/notification.background.ts index 5dd15274677..52920ec67a8 100644 --- a/apps/browser/src/autofill/background/notification.background.ts +++ b/apps/browser/src/autofill/background/notification.background.ts @@ -14,6 +14,7 @@ import { ExtensionCommand, ExtensionCommandType, NOTIFICATION_BAR_LIFESPAN_MS, + UPDATE_PASSWORD, } from "@bitwarden/common/autofill/constants"; import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; import { UserNotificationSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/user-notification-settings.service"; @@ -104,6 +105,8 @@ export default class NotificationBackground { this.removeTabFromNotificationQueue(sender.tab), bgReopenUnlockPopout: ({ sender }) => this.openUnlockPopout(sender.tab), bgSaveCipher: ({ message, sender }) => this.handleSaveCipherMessage(message, sender), + bgHandleReprompt: ({ message, sender }: any) => + this.handleCipherUpdateRepromptResponse(message), bgUnlockPopoutOpened: ({ message, sender }) => this.unlockVault(message, sender.tab), checkNotificationQueue: ({ sender }) => this.checkNotificationQueue(sender.tab), collectPageDetailsResponse: ({ message }) => @@ -631,6 +634,17 @@ export default class NotificationBackground { await this.saveOrUpdateCredentials(sender.tab, message.edit, message.folder); } + async handleCipherUpdateRepromptResponse(message: NotificationBackgroundExtensionMessage) { + if (message.success) { + await this.saveOrUpdateCredentials(message.tab, false, undefined, true); + } else { + await BrowserApi.tabSendMessageData(message.tab, "saveCipherAttemptCompleted", { + error: "Password reprompt failed", + }); + return; + } + } + /** * Saves or updates credentials based on the message within the * notification queue that is associated with the specified tab. @@ -639,7 +653,12 @@ export default class NotificationBackground { * @param edit - Identifies if the credentials should be edited or simply added * @param folderId - The folder to add the cipher to */ - private async saveOrUpdateCredentials(tab: chrome.tabs.Tab, edit: boolean, folderId?: string) { + private async saveOrUpdateCredentials( + tab: chrome.tabs.Tab, + edit: boolean, + folderId?: string, + skipReprompt: boolean = false, + ) { for (let i = this.notificationQueue.length - 1; i >= 0; i--) { const queueMessage = this.notificationQueue[i]; if ( @@ -654,18 +673,26 @@ export default class NotificationBackground { continue; } - this.notificationQueue.splice(i, 1); - const activeUserId = await firstValueFrom( this.accountService.activeAccount$.pipe(getOptionalUserId), ); if (queueMessage.type === NotificationQueueMessageType.ChangePassword) { const cipherView = await this.getDecryptedCipherById(queueMessage.cipherId, activeUserId); - await this.updatePassword(cipherView, queueMessage.newPassword, edit, tab, activeUserId); + + await this.updatePassword( + cipherView, + queueMessage.newPassword, + edit, + tab, + activeUserId, + skipReprompt, + ); return; } + this.notificationQueue.splice(i, 1); + // If the vault was locked, check if a cipher needs updating instead of creating a new one if (queueMessage.wasVaultLocked) { const allCiphers = await this.cipherService.getAllDecryptedForUrl( @@ -725,6 +752,7 @@ export default class NotificationBackground { edit: boolean, tab: chrome.tabs.Tab, userId: UserId, + skipReprompt: boolean = false, ) { cipherView.login.password = newPassword; @@ -758,6 +786,12 @@ export default class NotificationBackground { } : undefined; + if (cipherView.reprompt && !skipReprompt) { + await this.autofillService.isPasswordRepromptRequired(cipherView, tab, UPDATE_PASSWORD); + + return; + } + await this.cipherService.updateWithServer(cipher); await BrowserApi.tabSendMessageData(tab, "saveCipherAttemptCompleted", { diff --git a/apps/browser/src/autofill/overlay/notifications/abstractions/overlay-notifications-content.service.ts b/apps/browser/src/autofill/overlay/notifications/abstractions/overlay-notifications-content.service.ts index 82c03cacadf..42d7666e8a7 100644 --- a/apps/browser/src/autofill/overlay/notifications/abstractions/overlay-notifications-content.service.ts +++ b/apps/browser/src/autofill/overlay/notifications/abstractions/overlay-notifications-content.service.ts @@ -15,6 +15,7 @@ export type NotificationsExtensionMessage = { typeData?: NotificationTypeData; height?: number; error?: string; + closedByUser?: boolean; fadeOutNotification?: boolean; }; }; diff --git a/apps/browser/src/autofill/overlay/notifications/content/overlay-notifications-content.service.ts b/apps/browser/src/autofill/overlay/notifications/content/overlay-notifications-content.service.ts index 519521feaa9..c21aaa37dd4 100644 --- a/apps/browser/src/autofill/overlay/notifications/content/overlay-notifications-content.service.ts +++ b/apps/browser/src/autofill/overlay/notifications/content/overlay-notifications-content.service.ts @@ -106,13 +106,15 @@ export class OverlayNotificationsContentService * @param message - The message containing the data for closing the notification bar. */ private handleCloseNotificationBarMessage(message: NotificationsExtensionMessage) { + const closedByUser = + typeof message.data?.closedByUser === "boolean" ? message.data.closedByUser : true; if (message.data?.fadeOutNotification) { setElementStyles(this.notificationBarIframeElement, { opacity: "0" }, true); - globalThis.setTimeout(() => this.closeNotificationBar(true), 150); + globalThis.setTimeout(() => this.closeNotificationBar(closedByUser), 150); return; } - this.closeNotificationBar(true); + this.closeNotificationBar(closedByUser); } /** diff --git a/apps/browser/src/autofill/services/abstractions/autofill.service.ts b/apps/browser/src/autofill/services/abstractions/autofill.service.ts index 5b1b4b3b8bb..daafd871789 100644 --- a/apps/browser/src/autofill/services/abstractions/autofill.service.ts +++ b/apps/browser/src/autofill/services/abstractions/autofill.service.ts @@ -87,5 +87,9 @@ export abstract class AutofillService { cipherType?: CipherType, ) => Promise; setAutoFillOnPageLoadOrgPolicy: () => Promise; - isPasswordRepromptRequired: (cipher: CipherView, tab: chrome.tabs.Tab) => Promise; + isPasswordRepromptRequired: ( + cipher: CipherView, + tab: chrome.tabs.Tab, + action?: string, + ) => Promise; } diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index da46ceb0864..525010bacc1 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -593,15 +593,20 @@ export default class AutofillService implements AutofillServiceInterface { * * @param cipher - The cipher to autofill * @param tab - The tab to autofill + * @param action - override for default action once reprompt is completed successfully */ - async isPasswordRepromptRequired(cipher: CipherView, tab: chrome.tabs.Tab): Promise { + async isPasswordRepromptRequired( + cipher: CipherView, + tab: chrome.tabs.Tab, + action?: string, + ): Promise { const userHasMasterPasswordAndKeyHash = await this.userVerificationService.hasMasterPasswordAndMasterKeyHash(); if (cipher.reprompt === CipherRepromptType.Password && userHasMasterPasswordAndKeyHash) { if (!this.isDebouncingPasswordRepromptPopout()) { await this.openVaultItemPasswordRepromptPopout(tab, { cipherId: cipher.id, - action: "autofill", + action: action ?? "autofill", }); } diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts index 56db47619b0..a834314560b 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts @@ -19,6 +19,7 @@ import { COPY_USERNAME_ID, COPY_VERIFICATION_CODE_ID, SHOW_AUTOFILL_BUTTON, + UPDATE_PASSWORD, } from "@bitwarden/common/autofill/constants"; import { EventType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -49,6 +50,7 @@ import { PasswordRepromptService, } from "@bitwarden/vault"; +import { sendExtensionMessage } from "../../../../../autofill/utils/index"; import { BrowserApi } from "../../../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import { PopOutComponent } from "../../../../../platform/popup/components/pop-out.component"; @@ -72,7 +74,8 @@ type LoadAction = | typeof SHOW_AUTOFILL_BUTTON | typeof COPY_USERNAME_ID | typeof COPY_PASSWORD_ID - | typeof COPY_VERIFICATION_CODE_ID; + | typeof COPY_VERIFICATION_CODE_ID + | typeof UPDATE_PASSWORD; @Component({ selector: "app-view-v2", @@ -294,7 +297,7 @@ export class ViewV2Component { // Both vaultPopupAutofillService and copyCipherFieldService will perform password re-prompting internally. switch (loadAction) { - case "show-autofill-button": + case SHOW_AUTOFILL_BUTTON: // This action simply shows the cipher view, no need to do anything. if ( this.cipher.reprompt !== CipherRepromptType.None && @@ -303,30 +306,42 @@ export class ViewV2Component { await closeViewVaultItemPopout(`${VaultPopoutType.viewVaultItem}_${this.cipher.id}`); } return; - case "autofill": + case AUTOFILL_ID: actionSuccess = await this.vaultPopupAutofillService.doAutofill(this.cipher, false); break; - case "copy-username": + case COPY_USERNAME_ID: actionSuccess = await this.copyCipherFieldService.copy( this.cipher.login.username, "username", this.cipher, ); break; - case "copy-password": + case COPY_PASSWORD_ID: actionSuccess = await this.copyCipherFieldService.copy( this.cipher.login.password, "password", this.cipher, ); break; - case "copy-totp": + case COPY_VERIFICATION_CODE_ID: actionSuccess = await this.copyCipherFieldService.copy( this.cipher.login.totp, "totp", this.cipher, ); break; + case UPDATE_PASSWORD: { + const repromptSuccess = await this.passwordRepromptService.showPasswordPrompt(); + + await sendExtensionMessage("bgHandleReprompt", { + tab: await chrome.tabs.get(senderTabId), + success: repromptSuccess, + }); + + await closeViewVaultItemPopout(`${VaultPopoutType.viewVaultItem}_${this.cipher.id}`); + + break; + } } if (BrowserPopupUtils.inPopout(window)) { diff --git a/libs/common/src/autofill/constants/index.ts b/libs/common/src/autofill/constants/index.ts index 62ad10e9a90..dc79e27b6aa 100644 --- a/libs/common/src/autofill/constants/index.ts +++ b/libs/common/src/autofill/constants/index.ts @@ -38,7 +38,7 @@ export const ClearClipboardDelay = { FiveMinutes: 300, } as const; -/* Context Menu item Ids */ +/* Ids for context menu items and messaging events */ export const AUTOFILL_CARD_ID = "autofill-card"; export const AUTOFILL_ID = "autofill"; export const SHOW_AUTOFILL_BUTTON = "show-autofill-button"; @@ -54,6 +54,7 @@ export const GENERATE_PASSWORD_ID = "generate-password"; export const NOOP_COMMAND_SUFFIX = "noop"; export const ROOT_ID = "root"; export const SEPARATOR_ID = "separator"; +export const UPDATE_PASSWORD = "update-password"; export const NOTIFICATION_BAR_LIFESPAN_MS = 150000; // 150 seconds From 355bddc6c9d5c110e55fe74c5fcfa86ddd85572c Mon Sep 17 00:00:00 2001 From: Bryan Cunningham Date: Mon, 12 May 2025 11:50:29 -0400 Subject: [PATCH 02/25] [CL-301] Enable Storybook test runner. Run a11y tests also (#14646) * Enable Storybook test runner. Run a11y tests also * no need to return checkA11y function * add back decorator removed in error * add test runner to our ownership * add axe-playwright to our ownership --- .github/renovate.json5 | 2 + .storybook/preview.tsx | 7 + .storybook/test-runner.ts | 50 + package-lock.json | 2149 ++++++++++++++++++++++++++++++++++--- package.json | 4 + tsconfig.eslint.json | 1 + 6 files changed, 2062 insertions(+), 151 deletions(-) create mode 100644 .storybook/test-runner.ts diff --git a/.github/renovate.json5 b/.github/renovate.json5 index c1045739506..e5cd47077fb 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -312,6 +312,7 @@ "@angular/platform-browser", "@angular/platform", "@angular/router", + "axe-playwright", "@compodoc/compodoc", "@ng-select/ng-select", "@storybook/addon-a11y", @@ -320,6 +321,7 @@ "@storybook/addon-essentials", "@storybook/addon-interactions", "@storybook/addon-links", + "@storybook/test-runner", "@storybook/addon-themes", "@storybook/angular", "@storybook/manager-api", diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 6bd28cfe809..19a4fc51dc8 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -26,6 +26,13 @@ const preview: Preview = { wrapperDecorator, ], parameters: { + a11y: { + element: "#storybook-root", + manual: true, + options: { + runOnly: ["section508", "wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22aa"], + }, + }, controls: { matchers: { color: /(background|color)$/i, diff --git a/.storybook/test-runner.ts b/.storybook/test-runner.ts new file mode 100644 index 00000000000..8584a321090 --- /dev/null +++ b/.storybook/test-runner.ts @@ -0,0 +1,50 @@ +import { + // waitForPageReady, + type TestRunnerConfig, +} from "@storybook/test-runner"; +import { injectAxe, checkA11y } from "axe-playwright"; + +const testRunnerConfig: TestRunnerConfig = { + setup() {}, + + async preVisit(page, context) { + return await injectAxe(page); + }, + + async postVisit(page, context) { + await page.waitForSelector("#storybook-root"); + // https://github.com/abhinaba-ghosh/axe-playwright#parameters-on-checka11y-axerun + await checkA11y( + // Playwright page instance. + page, + + // context + "#storybook-root", + + // axeOptions, see https://www.deque.com/axe/core-documentation/api-documentation/#parameters-axerun + { + detailedReport: true, + detailedReportOptions: { + // Includes the full html for invalid nodes + html: true, + }, + verbose: false, + }, + + // skipFailures + false, + + // reporter "v2" is terminal reporter, "html" writes results to file + "v2", + + // axeHtmlReporterOptions + // NOTE: set reporter param (above) to "html" to activate these options + { + outputDir: "reports/a11y", + reportFileName: `${context.id}.html`, + }, + ); + }, +}; + +export default testRunnerConfig; diff --git a/package-lock.json b/package-lock.json index a15275a695e..81c9384fbbb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,6 +91,7 @@ "@storybook/addon-essentials": "8.6.12", "@storybook/addon-interactions": "8.6.12", "@storybook/addon-links": "8.6.12", + "@storybook/test-runner": "0.22.0", "@storybook/addon-themes": "8.6.12", "@storybook/angular": "8.6.12", "@storybook/manager-api": "8.6.12", @@ -123,6 +124,7 @@ "@yao-pkg/pkg": "5.16.1", "angular-eslint": "18.4.3", "autoprefixer": "10.4.21", + "axe-playwright": "2.1.0", "babel-loader": "9.2.1", "base64-loader": "1.0.0", "browserslist": "4.23.2", @@ -3327,7 +3329,6 @@ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -3453,7 +3454,6 @@ "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -3580,7 +3580,6 @@ "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, @@ -4714,8 +4713,7 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@bitwarden/admin-console": { "resolved": "libs/admin-console", @@ -7179,7 +7177,6 @@ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -7197,7 +7194,6 @@ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -7208,7 +7204,6 @@ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -7223,7 +7218,6 @@ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -7238,7 +7232,6 @@ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -7252,7 +7245,6 @@ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-try": "^2.0.0" }, @@ -7269,7 +7261,6 @@ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -7283,7 +7274,6 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -7293,8 +7283,7 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", @@ -7312,7 +7301,6 @@ "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -7331,7 +7319,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -7342,7 +7329,6 @@ "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/console": "^29.7.0", "@jest/reporters": "^29.7.0", @@ -7391,7 +7377,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -7405,7 +7390,6 @@ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -7420,8 +7404,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/core/node_modules/slash": { "version": "3.0.0", @@ -7429,11 +7412,23 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } }, + "node_modules/@jest/create-cache-key-function": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jest/environment": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", @@ -7456,7 +7451,6 @@ "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "expect": "^29.7.0", "jest-snapshot": "^29.7.0" @@ -7502,7 +7496,6 @@ "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -7519,7 +7512,6 @@ "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^29.7.0", @@ -7564,7 +7556,6 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -7577,7 +7568,6 @@ "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7599,7 +7589,6 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7613,7 +7602,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -7637,7 +7625,6 @@ "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", @@ -7653,7 +7640,6 @@ "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/console": "^29.7.0", "@jest/types": "^29.6.3", @@ -7670,7 +7656,6 @@ "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", @@ -7687,7 +7672,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -7698,7 +7682,6 @@ "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.3", @@ -7725,8 +7708,7 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@jest/transform/node_modules/slash": { "version": "3.0.0", @@ -7734,7 +7716,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -10819,6 +10800,43 @@ "storybook": "^8.6.12" } }, + "node_modules/@storybook/test-runner": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@storybook/test-runner/-/test-runner-0.22.0.tgz", + "integrity": "sha512-fKY6MTE/bcvMaulKXy+z0fPmRXJx1REkYMOMcGn8zn6uffyBigGgaVf/sZ+AZfibwvjzg/StWhJ9HvAM8pc14g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/template": "^7.22.5", + "@babel/types": "^7.22.5", + "@jest/types": "^29.6.3", + "@storybook/csf": "^0.1.11", + "@swc/core": "^1.5.22", + "@swc/jest": "^0.2.23", + "expect-playwright": "^0.8.0", + "jest": "^29.6.4", + "jest-circus": "^29.6.4", + "jest-environment-node": "^29.6.4", + "jest-junit": "^16.0.0", + "jest-playwright-preset": "^4.0.0", + "jest-runner": "^29.6.4", + "jest-serializer-html": "^7.1.0", + "jest-watch-typeahead": "^2.0.0", + "nyc": "^15.1.0", + "playwright": "^1.14.0" + }, + "bin": { + "test-storybook": "dist/test-storybook.js" + }, + "engines": { + "node": "^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "storybook": "^0.0.0-0 || ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 || ^9.0.0-0" + } + }, "node_modules/@storybook/theming": { "version": "8.6.12", "resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-8.6.12.tgz", @@ -10882,6 +10900,250 @@ "storybook": "^8.6.12" } }, + "node_modules/@swc/core": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.11.24.tgz", + "integrity": "sha512-MaQEIpfcEMzx3VWWopbofKJvaraqmL6HbLlw2bFZ7qYqYw3rkhM0cQVEgyzbHtTWwCwPMFZSC2DUbhlZgrMfLg==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.21" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.11.24", + "@swc/core-darwin-x64": "1.11.24", + "@swc/core-linux-arm-gnueabihf": "1.11.24", + "@swc/core-linux-arm64-gnu": "1.11.24", + "@swc/core-linux-arm64-musl": "1.11.24", + "@swc/core-linux-x64-gnu": "1.11.24", + "@swc/core-linux-x64-musl": "1.11.24", + "@swc/core-win32-arm64-msvc": "1.11.24", + "@swc/core-win32-ia32-msvc": "1.11.24", + "@swc/core-win32-x64-msvc": "1.11.24" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.17" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.11.24.tgz", + "integrity": "sha512-dhtVj0PC1APOF4fl5qT2neGjRLgHAAYfiVP8poJelhzhB/318bO+QCFWAiimcDoyMgpCXOhTp757gnoJJrheWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.11.24.tgz", + "integrity": "sha512-H/3cPs8uxcj2Fe3SoLlofN5JG6Ny5bl8DuZ6Yc2wr7gQFBmyBkbZEz+sPVgsID7IXuz7vTP95kMm1VL74SO5AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.11.24.tgz", + "integrity": "sha512-PHJgWEpCsLo/NGj+A2lXZ2mgGjsr96ULNW3+T3Bj2KTc8XtMUkE8tmY2Da20ItZOvPNC/69KroU7edyo1Flfbw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.11.24.tgz", + "integrity": "sha512-C2FJb08+n5SD4CYWCTZx1uR88BN41ZieoHvI8A55hfVf2woT8+6ZiBzt74qW2g+ntZ535Jts5VwXAKdu41HpBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.11.24.tgz", + "integrity": "sha512-ypXLIdszRo0re7PNNaXN0+2lD454G8l9LPK/rbfRXnhLWDBPURxzKlLlU/YGd2zP98wPcVooMmegRSNOKfvErw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.11.24.tgz", + "integrity": "sha512-IM7d+STVZD48zxcgo69L0yYptfhaaE9cMZ+9OoMxirNafhKKXwoZuufol1+alEFKc+Wbwp+aUPe/DeWC/Lh3dg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.11.24.tgz", + "integrity": "sha512-DZByJaMVzSfjQKKQn3cqSeqwy6lpMaQDQQ4HPlch9FWtDx/dLcpdIhxssqZXcR2rhaQVIaRQsCqwV6orSDGAGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.11.24.tgz", + "integrity": "sha512-Q64Ytn23y9aVDKN5iryFi8mRgyHw3/kyjTjT4qFCa8AEb5sGUuSj//AUZ6c0J7hQKMHlg9do5Etvoe61V98/JQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.11.24.tgz", + "integrity": "sha512-9pKLIisE/Hh2vJhGIPvSoTK4uBSPxNVyXHmOrtdDot4E1FUUI74Vi8tFdlwNbaj8/vusVnb8xPXsxF1uB0VgiQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.11.24", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.11.24.tgz", + "integrity": "sha512-sybnXtOsdB+XvzVFlBVGgRHLqp3yRpHK7CrmpuDKszhj/QhmsaZzY/GHSeALlMtLup13M0gqbcQvsTNlAHTg3w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/jest": { + "version": "0.2.38", + "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.38.tgz", + "integrity": "sha512-HMoZgXWMqChJwffdDjvplH53g9G2ALQes3HKXDEdliB/b85OQ0CTSbxG8VSeCwiAn7cOaDVEt4mwmZvbHcS52w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/create-cache-key-function": "^29.7.0", + "@swc/counter": "^0.1.3", + "jsonc-parser": "^3.2.0" + }, + "engines": { + "npm": ">= 7.0.0" + }, + "peerDependencies": { + "@swc/core": "*" + } + }, + "node_modules/@swc/types": { + "version": "0.1.21", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.21.tgz", + "integrity": "sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, "node_modules/@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -11102,7 +11364,6 @@ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -11117,7 +11378,6 @@ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/types": "^7.0.0" } @@ -11128,7 +11388,6 @@ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" @@ -11140,7 +11399,6 @@ "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/types": "^7.20.7" } @@ -11336,7 +11594,6 @@ "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/node": "*" } @@ -11506,6 +11763,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/junit-report-builder": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/junit-report-builder/-/junit-report-builder-3.0.2.tgz", + "integrity": "sha512-R5M+SYhMbwBeQcNXYWNCZkl09vkVfAtcPIaCGdzIkkbeaTrVbGQ7HVgi4s+EmM/M1K4ZuWQH0jGcvMvNePfxYA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/keygrip": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.6.tgz", @@ -11908,6 +12172,16 @@ "license": "MIT", "optional": true }, + "node_modules/@types/wait-on": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/@types/wait-on/-/wait-on-5.3.4.tgz", + "integrity": "sha512-EBsPjFMrFlMbbUFf9D1Fp+PAB2TwmUn7a3YtHyD9RLuTIk1jDd8SxXVAoez2Ciy+8Jsceo2MYEYZzJ/DvorOKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/webpack-env": { "version": "1.18.8", "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.8.tgz", @@ -13845,6 +14119,19 @@ "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", "license": "MIT" }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/archiver": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", @@ -13981,6 +14268,13 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true, + "license": "MIT" + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", @@ -14356,6 +14650,39 @@ "node": ">=4" } }, + "node_modules/axe-html-reporter": { + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/axe-html-reporter/-/axe-html-reporter-2.2.11.tgz", + "integrity": "sha512-WlF+xlNVgNVWiM6IdVrsh+N0Cw7qupe5HT9N6Uyi+aN7f6SSi92RDomiP1noW8OWIV85V6x404m5oKMeqRV3tQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mustache": "^4.0.1" + }, + "engines": { + "node": ">=8.9.0" + }, + "peerDependencies": { + "axe-core": ">=3" + } + }, + "node_modules/axe-playwright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/axe-playwright/-/axe-playwright-2.1.0.tgz", + "integrity": "sha512-tY48SX56XaAp16oHPyD4DXpybz8Jxdz9P7exTjF/4AV70EGUavk+1fUPWirM0OYBR+YyDx6hUeDvuHVA6fB9YA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/junit-report-builder": "^3.0.2", + "axe-core": "^4.10.1", + "axe-html-reporter": "2.2.11", + "junit-report-builder": "^5.1.1", + "picocolors": "^1.1.1" + }, + "peerDependencies": { + "playwright": ">1.0.0" + } + }, "node_modules/axios": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", @@ -14383,7 +14710,6 @@ "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", @@ -14406,7 +14732,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -14435,7 +14760,6 @@ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -14453,7 +14777,6 @@ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -14471,7 +14794,6 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -14482,7 +14804,6 @@ "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -14600,7 +14921,6 @@ "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -14628,7 +14948,6 @@ "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" @@ -15090,7 +15409,6 @@ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "node-int64": "^0.4.0" } @@ -15471,6 +15789,68 @@ "node": ">=8" } }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caching-transform/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/caching-transform/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/caching-transform/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", @@ -15553,7 +15933,6 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -15670,7 +16049,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" } @@ -16037,8 +16415,7 @@ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", @@ -16123,6 +16500,13 @@ "node": ">=4.0.0" } }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, "node_modules/compare-version": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", @@ -16751,7 +17135,6 @@ "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -16942,6 +17325,20 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, + "node_modules/cwd": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.10.0.tgz", + "integrity": "sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-pkg": "^0.1.2", + "fs-exists-sync": "^0.1.0" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/data-urls": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", @@ -17120,7 +17517,6 @@ "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", "dev": true, "license": "MIT", - "peer": true, "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, @@ -17216,6 +17612,22 @@ "node": ">= 10" } }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/defaults": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", @@ -17342,7 +17754,6 @@ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -17385,6 +17796,100 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/diffable-html": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/diffable-html/-/diffable-html-4.1.0.tgz", + "integrity": "sha512-++kyNek+YBLH8cLXS+iTj/Hiy2s5qkRJEJ8kgu/WHbFrVY2vz9xPFUT+fii2zGF0m1CaojDlQJjkfrCt7YWM1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "htmlparser2": "^3.9.2" + } + }, + "node_modules/diffable-html/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/diffable-html/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/diffable-html/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/diffable-html/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/diffable-html/node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/diffable-html/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/diffable-html/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/diffable-html/node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, "node_modules/dir-compare": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", @@ -18057,7 +18562,6 @@ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -18382,8 +18886,7 @@ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/es6-shim": { "version": "0.35.8", @@ -19185,7 +19688,6 @@ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, - "peer": true, "engines": { "node": ">= 0.8.0" } @@ -19200,6 +19702,19 @@ "node": ">=6" } }, + "node_modules/expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-homedir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/expect": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", @@ -19217,6 +19732,24 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/expect-playwright": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/expect-playwright/-/expect-playwright-0.8.0.tgz", + "integrity": "sha512-+kn8561vHAY+dt+0gMqqj1oY+g5xWrsuGMk4QGxotT2WS545nVqqjs37z6hrYfIuucwqthzwJfCJUEYqixyljg==", + "dev": true, + "license": "MIT" + }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/exponential-backoff": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", @@ -19596,7 +20129,6 @@ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "bser": "2.1.1" } @@ -19771,6 +20303,58 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-file-up": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-0.1.3.tgz", + "integrity": "sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-exists-sync": "^0.1.0", + "resolve-dir": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-pkg": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/find-pkg/-/find-pkg-0.1.2.tgz", + "integrity": "sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-file-up": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/find-process": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.10.tgz", + "integrity": "sha512-ncYFnWEIwL7PzmrK1yZtaccN8GhethD37RzBHG6iOZoFYB4vSmLLXfeWJjeN5nMvCJMjOtBvBBF8OgxEcikiZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "~4.1.2", + "commander": "^12.1.0", + "loglevel": "^1.9.2" + }, + "bin": { + "find-process": "bin/find-process.js" + } + }, + "node_modules/find-process/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -20305,6 +20889,27 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/front-matter": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", @@ -20349,6 +20954,16 @@ "dev": true, "license": "MIT" }, + "node_modules/fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fs-extra": { "version": "11.3.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", @@ -20527,7 +21142,6 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8.0.0" } @@ -20678,6 +21292,56 @@ "node": ">=10.0" } }, + "node_modules/global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^0.1.4", + "is-windows": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.0", + "ini": "^1.3.4", + "is-windows": "^0.2.0", + "which": "^1.2.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -20942,6 +21606,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -20964,6 +21655,19 @@ "he": "bin/he" } }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -21084,8 +21788,7 @@ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/html-loader": { "version": "5.1.0", @@ -22170,7 +22873,6 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -22475,6 +23177,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -22540,6 +23249,16 @@ "dev": true, "license": "MIT" }, + "node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -22597,6 +23316,19 @@ "node": ">=8" } }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/istanbul-lib-instrument": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", @@ -22614,13 +23346,116 @@ "node": ">=10" } }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "license": "ISC", + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/istanbul-lib-report": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", @@ -22636,7 +23471,6 @@ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -22652,7 +23486,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -22663,7 +23496,6 @@ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -22737,7 +23569,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -22765,7 +23596,6 @@ "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "execa": "^5.0.0", "jest-util": "^29.7.0", @@ -22781,7 +23611,6 @@ "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -22814,7 +23643,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -22828,7 +23656,6 @@ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -22843,8 +23670,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-circus/node_modules/slash": { "version": "3.0.0", @@ -22852,7 +23678,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -22863,7 +23688,6 @@ "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/test-result": "^29.7.0", @@ -22898,7 +23722,6 @@ "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.11.6", "@jest/test-sequencer": "^29.7.0", @@ -22945,7 +23768,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -22959,7 +23781,6 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -22972,7 +23793,6 @@ "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -22994,7 +23814,6 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -23008,7 +23827,6 @@ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -23023,8 +23841,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-config/node_modules/slash": { "version": "3.0.0", @@ -23032,7 +23849,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -23094,7 +23910,6 @@ "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "detect-newline": "^3.0.0" }, @@ -23108,7 +23923,6 @@ "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", @@ -23126,7 +23940,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -23140,7 +23953,6 @@ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -23155,8 +23967,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-environment-jsdom": { "version": "29.7.0", @@ -23385,7 +24196,6 @@ "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -23414,7 +24224,6 @@ "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", @@ -23467,7 +24276,6 @@ "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" @@ -23482,7 +24290,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -23496,7 +24303,6 @@ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -23511,8 +24317,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-matcher-utils": { "version": "29.7.0", @@ -23660,13 +24465,106 @@ "typescript": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, + "node_modules/jest-playwright-preset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jest-playwright-preset/-/jest-playwright-preset-4.0.0.tgz", + "integrity": "sha512-+dGZ1X2KqtwXaabVjTGxy0a3VzYfvYsWaRcuO8vMhyclHSOpGSI1+5cmlqzzCwQ3+fv0EjkTc7I5aV9lo08dYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect-playwright": "^0.8.0", + "jest-process-manager": "^0.4.0", + "nyc": "^15.1.0", + "playwright-core": ">=1.2.0", + "rimraf": "^3.0.2", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "jest": "^29.3.1", + "jest-circus": "^29.3.1", + "jest-environment-node": "^29.3.1", + "jest-runner": "^29.3.1" + } + }, + "node_modules/jest-playwright-preset/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jest-playwright-preset/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-playwright-preset/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jest-playwright-preset/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-playwright-preset/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" }, @@ -23743,13 +24641,58 @@ "dev": true, "license": "MIT" }, + "node_modules/jest-process-manager": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/jest-process-manager/-/jest-process-manager-0.4.0.tgz", + "integrity": "sha512-80Y6snDyb0p8GG83pDxGI/kQzwVTkCxc7ep5FPe/F6JYdvRDhwr6RzRmPSP7SEwuLhxo80lBS/NqOdUIbHIfhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/wait-on": "^5.2.0", + "chalk": "^4.1.0", + "cwd": "^0.10.0", + "exit": "^0.1.2", + "find-process": "^1.4.4", + "prompts": "^2.4.1", + "signal-exit": "^3.0.3", + "spawnd": "^5.0.0", + "tree-kill": "^1.2.2", + "wait-on": "^7.0.0" + } + }, + "node_modules/jest-process-manager/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/jest-process-manager/node_modules/wait-on": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-7.2.0.tgz", + "integrity": "sha512-wCQcHkRazgjG5XoAq9jbTMLpNIjoSlZslrJ2+N9MxDsGEv1HnFoVjOCexL0ESva7Y9cu350j+DWADdk54s4AFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "axios": "^1.6.1", + "joi": "^17.11.0", + "lodash": "^4.17.21", + "minimist": "^1.2.8", + "rxjs": "^7.8.1" + }, + "bin": { + "wait-on": "bin/wait-on" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/jest-regex-util": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -23760,7 +24703,6 @@ "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", @@ -23782,7 +24724,6 @@ "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "jest-regex-util": "^29.6.3", "jest-snapshot": "^29.7.0" @@ -23797,7 +24738,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -23808,7 +24748,6 @@ "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/console": "^29.7.0", "@jest/environment": "^29.7.0", @@ -23842,7 +24781,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -23853,7 +24791,6 @@ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -23865,7 +24802,6 @@ "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", @@ -23900,7 +24836,6 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -23913,7 +24848,6 @@ "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -23935,7 +24869,6 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -23949,18 +24882,26 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } }, + "node_modules/jest-serializer-html": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jest-serializer-html/-/jest-serializer-html-7.1.0.tgz", + "integrity": "sha512-xYL2qC7kmoYHJo8MYqJkzrl/Fdlx+fat4U1AqYg+kafqwcKPiMkOcjWHPKhueuNEgr+uemhGc+jqXYiwCyRyLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "diffable-html": "^4.1.0" + } + }, "node_modules/jest-snapshot": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", @@ -23993,7 +24934,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -24007,7 +24947,6 @@ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -24022,8 +24961,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jest-util": { "version": "29.7.0", @@ -24062,7 +25000,6 @@ "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", @@ -24081,7 +25018,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -24095,7 +25031,6 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -24109,7 +25044,6 @@ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -24124,8 +25058,111 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, + "license": "MIT" + }, + "node_modules/jest-watch-typeahead": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-2.2.2.tgz", + "integrity": "sha512-+QgOFW4o5Xlgd6jGS5X37i08tuuXNW8X0CV9WNFi+3n8ExCIP+E1melYhvYLjv5fE6D0yyzk74vsSO8I6GqtvQ==", + "dev": true, "license": "MIT", - "peer": true + "dependencies": { + "ansi-escapes": "^6.0.0", + "chalk": "^5.2.0", + "jest-regex-util": "^29.0.0", + "jest-watcher": "^29.0.0", + "slash": "^5.0.0", + "string-length": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "jest": "^27.0.0 || ^28.0.0 || ^29.0.0" + } + }, + "node_modules/jest-watch-typeahead/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watch-typeahead/node_modules/char-regex": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.2.tgz", + "integrity": "sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/jest-watch-typeahead/node_modules/string-length": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", + "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^2.0.0", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watch-typeahead/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, "node_modules/jest-watcher": { "version": "29.7.0", @@ -24133,7 +25170,6 @@ "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/test-result": "^29.7.0", "@jest/types": "^29.6.3", @@ -24154,7 +25190,6 @@ "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -24171,7 +25206,6 @@ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -24518,6 +25552,47 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/junit-report-builder": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/junit-report-builder/-/junit-report-builder-5.1.1.tgz", + "integrity": "sha512-ZNOIIGMzqCGcHQEA2Q4rIQQ3Df6gSIfne+X9Rly9Bc2y55KxAZu8iGv+n2pP0bLf0XAOctJZgeloC54hWzCahQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "make-dir": "^3.1.0", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/junit-report-builder/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/junit-report-builder/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/jwt-decode": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", @@ -24897,7 +25972,6 @@ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -25602,6 +26676,13 @@ "license": "MIT", "peer": true }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", @@ -26001,7 +27082,6 @@ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "semver": "^7.5.3" }, @@ -26097,7 +27177,6 @@ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "tmpl": "1.0.5" } @@ -27587,6 +28666,16 @@ "readable-stream": "^3.6.0" } }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "dev": true, + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, "node_modules/mute-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", @@ -28164,8 +29253,7 @@ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/node-machine-id": { "version": "1.1.12", @@ -28173,6 +29261,19 @@ "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", "dev": true }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -28844,6 +29945,350 @@ "node": ">=6" } }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc/node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/nyc/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nyc/node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nyc/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/nyc/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -29113,6 +30558,16 @@ "dev": true, "license": "MIT" }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/os-name": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz", @@ -29270,6 +30725,22 @@ "node": ">=6" } }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -29551,6 +31022,16 @@ "node": ">= 0.10" } }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/parse5": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", @@ -30112,6 +31593,53 @@ "node": ">=4" } }, + "node_modules/playwright": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz", + "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.52.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz", + "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/plist": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", @@ -30634,6 +32162,19 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, + "node_modules/process-on-spawn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.1.0.tgz", + "integrity": "sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -30808,8 +32349,7 @@ "url": "https://opencollective.com/fast-check" } ], - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/qrcode-parser": { "version": "2.1.3", @@ -31308,6 +32848,19 @@ "node": ">= 0.10" } }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/remark-gfm": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", @@ -31487,6 +33040,13 @@ "node": ">=0.10.0" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, "node_modules/requireindex": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", @@ -31550,6 +33110,20 @@ "node": ">=8" } }, + "node_modules/resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expand-tilde": "^1.2.2", + "global-modules": "^0.2.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -32444,6 +34018,13 @@ "node": ">= 0.8" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", @@ -32888,6 +34469,164 @@ "node": ">=0.10.0" } }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/spawn-wrap/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/spawn-wrap/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/spawn-wrap/node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spawn-wrap/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/spawn-wrap/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/spawn-wrap/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/spawn-wrap/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/spawn-wrap/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/spawnd": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-5.0.0.tgz", + "integrity": "sha512-28+AJr82moMVWolQvlAIv3JcYDkjkFTEmfDc503wxrF5l2rQ3dFz6DpbXp3kD4zmgGGldfM4xM4v1sFj/ZaIOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "exit": "^0.1.2", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "wait-port": "^0.2.9" + } + }, + "node_modules/spawnd/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -33234,7 +34973,6 @@ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -33364,7 +35102,6 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -33927,7 +35664,6 @@ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -33943,7 +35679,6 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -33956,7 +35691,6 @@ "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -33978,7 +35712,6 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -34148,8 +35881,7 @@ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -34899,6 +36631,16 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "license": "MIT" }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, "node_modules/typescript": { "version": "5.4.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", @@ -35490,7 +37232,6 @@ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", @@ -35505,8 +37246,7 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", @@ -36131,6 +37871,109 @@ "tslib": "^2.1.0" } }, + "node_modules/wait-port": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-0.2.14.tgz", + "integrity": "sha512-kIzjWcr6ykl7WFbZd0TMae8xovwqcqbx6FM9l+7agOgUByhzdjfzZBPK2CPufldTOMxbUivss//Sh9MFawmPRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^2.4.2", + "commander": "^3.0.2", + "debug": "^4.1.1" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wait-port/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wait-port/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wait-port/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/wait-port/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/wait-port/node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true, + "license": "MIT" + }, + "node_modules/wait-port/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/wait-port/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/wait-port/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/walk-up-path": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", @@ -36144,7 +37987,6 @@ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "makeerror": "1.0.12" } @@ -36883,6 +38725,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true, + "license": "ISC" + }, "node_modules/which-typed-array": { "version": "1.1.18", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", @@ -37030,7 +38879,6 @@ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -37044,8 +38892,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/ws": { "version": "8.18.1", diff --git a/package.json b/package.json index 904ae121cc9..8ba1c95df6a 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,8 @@ "storybook": "ng run components:storybook", "build-storybook": "ng run components:build-storybook", "build-storybook:ci": "ng run components:build-storybook --webpack-stats-json", + "test-stories": "test-storybook --url http://localhost:6006", + "test-stories:watch": "test-stories --watch", "postinstall": "patch-package" }, "workspaces": [ @@ -53,6 +55,7 @@ "@storybook/addon-essentials": "8.6.12", "@storybook/addon-interactions": "8.6.12", "@storybook/addon-links": "8.6.12", + "@storybook/test-runner": "0.22.0", "@storybook/addon-themes": "8.6.12", "@storybook/angular": "8.6.12", "@storybook/manager-api": "8.6.12", @@ -85,6 +88,7 @@ "@yao-pkg/pkg": "5.16.1", "angular-eslint": "18.4.3", "autoprefixer": "10.4.21", + "axe-playwright": "2.1.0", "babel-loader": "9.2.1", "base64-loader": "1.0.0", "browserslist": "4.23.2", diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 7ffa34df58c..e8c3f669c0c 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -45,6 +45,7 @@ "files": [ ".storybook/main.ts", ".storybook/manager.js", + ".storybook/test-runner.ts", "apps/browser/src/autofill/content/components/.lit-storybook/main.ts" ], "include": ["apps/**/*", "libs/**/*", "bitwarden_license/**/*", "scripts/**/*"], From a10b9530af5628552583f8afb31cb0d9d6928fd2 Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Mon, 12 May 2025 18:20:56 +0100 Subject: [PATCH 03/25] changes to sponsorship is showing in individual vault (#14627) --- .../app/billing/settings/sponsored-families.component.ts | 8 +++++--- .../admin-console/models/data/organization.data.spec.ts | 1 + .../src/admin-console/models/data/organization.data.ts | 2 ++ .../src/admin-console/models/domain/organization.ts | 2 ++ .../models/response/profile-organization.response.ts | 2 ++ 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/web/src/app/billing/settings/sponsored-families.component.ts b/apps/web/src/app/billing/settings/sponsored-families.component.ts index cee08bae8cd..7e493168ce2 100644 --- a/apps/web/src/app/billing/settings/sponsored-families.component.ts +++ b/apps/web/src/app/billing/settings/sponsored-families.component.ts @@ -112,13 +112,15 @@ export class SponsoredFamiliesComponent implements OnInit, OnDestroy { }); } }); - this.anyOrgsAvailable$ = this.availableSponsorshipOrgs$.pipe(map((orgs) => orgs.length > 0)); this.activeSponsorshipOrgs$ = this.organizationService .organizations$(userId) - .pipe(map((orgs) => orgs.filter((o) => o.familySponsorshipFriendlyName !== null))); - + .pipe( + map((orgs) => + orgs.filter((o) => o.familySponsorshipFriendlyName !== null && !o.isAdminInitiated), + ), + ); this.anyActiveSponsorships$ = this.activeSponsorshipOrgs$.pipe(map((orgs) => orgs.length > 0)); this.loading = false; diff --git a/libs/common/src/admin-console/models/data/organization.data.spec.ts b/libs/common/src/admin-console/models/data/organization.data.spec.ts index fae24133502..7d66e7bc0d5 100644 --- a/libs/common/src/admin-console/models/data/organization.data.spec.ts +++ b/libs/common/src/admin-console/models/data/organization.data.spec.ts @@ -59,6 +59,7 @@ describe("ORGANIZATIONS state", () => { userIsManagedByOrganization: false, useRiskInsights: false, useAdminSponsoredFamilies: false, + isAdminInitiated: false, }, }; const result = sut.deserializer(JSON.parse(JSON.stringify(expectedResult))); diff --git a/libs/common/src/admin-console/models/data/organization.data.ts b/libs/common/src/admin-console/models/data/organization.data.ts index 799d062aefa..e0783957117 100644 --- a/libs/common/src/admin-console/models/data/organization.data.ts +++ b/libs/common/src/admin-console/models/data/organization.data.ts @@ -61,6 +61,7 @@ export class OrganizationData { userIsManagedByOrganization: boolean; useRiskInsights: boolean; useAdminSponsoredFamilies: boolean; + isAdminInitiated: boolean; constructor( response?: ProfileOrganizationResponse, @@ -124,6 +125,7 @@ export class OrganizationData { this.userIsManagedByOrganization = response.userIsManagedByOrganization; this.useRiskInsights = response.useRiskInsights; this.useAdminSponsoredFamilies = response.useAdminSponsoredFamilies; + this.isAdminInitiated = response.isAdminInitiated; this.isMember = options.isMember; this.isProviderUser = options.isProviderUser; diff --git a/libs/common/src/admin-console/models/domain/organization.ts b/libs/common/src/admin-console/models/domain/organization.ts index 2e51c54b0ad..1864d56649b 100644 --- a/libs/common/src/admin-console/models/domain/organization.ts +++ b/libs/common/src/admin-console/models/domain/organization.ts @@ -91,6 +91,7 @@ export class Organization { userIsManagedByOrganization: boolean; useRiskInsights: boolean; useAdminSponsoredFamilies: boolean; + isAdminInitiated: boolean; constructor(obj?: OrganizationData) { if (obj == null) { @@ -150,6 +151,7 @@ export class Organization { this.userIsManagedByOrganization = obj.userIsManagedByOrganization; this.useRiskInsights = obj.useRiskInsights; this.useAdminSponsoredFamilies = obj.useAdminSponsoredFamilies; + this.isAdminInitiated = obj.isAdminInitiated; } get canAccess() { diff --git a/libs/common/src/admin-console/models/response/profile-organization.response.ts b/libs/common/src/admin-console/models/response/profile-organization.response.ts index da97a1034b1..3a86c764eb8 100644 --- a/libs/common/src/admin-console/models/response/profile-organization.response.ts +++ b/libs/common/src/admin-console/models/response/profile-organization.response.ts @@ -56,6 +56,7 @@ export class ProfileOrganizationResponse extends BaseResponse { userIsManagedByOrganization: boolean; useRiskInsights: boolean; useAdminSponsoredFamilies: boolean; + isAdminInitiated: boolean; constructor(response: any) { super(response); @@ -123,5 +124,6 @@ export class ProfileOrganizationResponse extends BaseResponse { this.userIsManagedByOrganization = this.getResponseProperty("UserIsManagedByOrganization"); this.useRiskInsights = this.getResponseProperty("UseRiskInsights"); this.useAdminSponsoredFamilies = this.getResponseProperty("UseAdminSponsoredFamilies"); + this.isAdminInitiated = this.getResponseProperty("IsAdminInitiated"); } } From eed18c929437ab418f35b02b866088a041a83683 Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Mon, 12 May 2025 14:26:52 -0400 Subject: [PATCH 04/25] chore(view-cache): [PM-21154] Move view-cache its own feature package and adjust imports * Moved view-cache services to directory * Fixed DI for browser extension. * Fixed tests. --- .../view-cache/popup-view-cache.service.ts | 2 +- .../src/popup/services/services.module.ts | 2 +- .../vault-popup-list-filters.service.spec.ts | 5 +- .../vault-popup-list-filters.service.ts | 5 +- libs/angular/src/platform/view-cache/index.ts | 1 + .../src/platform/view-cache/internal.ts | 1 + .../noop-view-cache.service.ts | 6 +- .../src/platform/view-cache/view-cache.md | 130 ++++++++++++++++++ .../view-cache.service.ts | 2 + .../src/services/jslib-services.module.ts | 5 +- ...auth-component-email-cache.service.spec.ts | 2 +- ...auth-email-component-cache.service.spec.ts | 2 +- ...ctor-auth-email-component-cache.service.ts | 2 +- ...actor-auth-component-cache.service.spec.ts | 2 +- ...two-factor-auth-component-cache.service.ts | 2 +- ...gin-via-auth-request-cache.service.spec.ts | 2 +- ...lt-login-via-auth-request-cache.service.ts | 2 +- .../src/cipher-form/cipher-form.stories.ts | 2 +- .../components/cipher-form.component.spec.ts | 2 +- .../default-cipher-form-cache.service.spec.ts | 2 +- .../default-cipher-form-cache.service.ts | 2 +- 21 files changed, 155 insertions(+), 26 deletions(-) create mode 100644 libs/angular/src/platform/view-cache/index.ts create mode 100644 libs/angular/src/platform/view-cache/internal.ts rename libs/angular/src/platform/{services => view-cache}/noop-view-cache.service.ts (87%) create mode 100644 libs/angular/src/platform/view-cache/view-cache.md rename libs/angular/src/platform/{abstractions => view-cache}/view-cache.service.ts (98%) diff --git a/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts b/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts index ff63b52ab3f..2a946982990 100644 --- a/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts +++ b/apps/browser/src/platform/popup/view-cache/popup-view-cache.service.ts @@ -19,7 +19,7 @@ import { FormCacheOptions, SignalCacheOptions, ViewCacheService, -} from "@bitwarden/angular/platform/abstractions/view-cache.service"; +} from "@bitwarden/angular/platform/view-cache"; import { MessageSender } from "@bitwarden/common/platform/messaging"; import { GlobalStateProvider } from "@bitwarden/common/platform/state"; diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 00b8ae81cf9..6ede88dfc13 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -5,9 +5,9 @@ import { Router } from "@angular/router"; import { merge, of, Subject } from "rxjs"; import { CollectionService } from "@bitwarden/admin-console/common"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; import { AngularThemingService } from "@bitwarden/angular/platform/services/theming/angular-theming.service"; import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { CLIENT_TYPE, DEFAULT_VAULT_TIMEOUT, diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts index 9498d953808..621ec795157 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts @@ -4,6 +4,7 @@ import { FormBuilder } from "@angular/forms"; import { BehaviorSubject, skipWhile } from "rxjs"; import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; 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"; @@ -20,8 +21,6 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; -import { PopupViewCacheService } from "../../../platform/popup/view-cache/popup-view-cache.service"; - import { CachedFilterState, MY_VAULT_ID, @@ -123,7 +122,7 @@ describe("VaultPopupListFiltersService", () => { useValue: accountService, }, { - provide: PopupViewCacheService, + provide: ViewCacheService, useValue: viewCacheService, }, ], diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts index c726678c973..db4cfeefe9f 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts @@ -15,6 +15,7 @@ import { } from "rxjs"; import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; @@ -40,8 +41,6 @@ import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { ServiceUtils } from "@bitwarden/common/vault/service-utils"; import { ChipSelectOption } from "@bitwarden/components"; -import { PopupViewCacheService } from "../../../platform/popup/view-cache/popup-view-cache.service"; - const FILTER_VISIBILITY_KEY = new KeyDefinition(VAULT_SETTINGS_DISK, "filterVisibility", { deserializer: (obj) => obj, }); @@ -178,7 +177,7 @@ export class VaultPopupListFiltersService { private policyService: PolicyService, private stateProvider: StateProvider, private accountService: AccountService, - private viewCacheService: PopupViewCacheService, + private viewCacheService: ViewCacheService, ) { this.filterForm.controls.organization.valueChanges .pipe(takeUntilDestroyed()) diff --git a/libs/angular/src/platform/view-cache/index.ts b/libs/angular/src/platform/view-cache/index.ts new file mode 100644 index 00000000000..79deef6aa5b --- /dev/null +++ b/libs/angular/src/platform/view-cache/index.ts @@ -0,0 +1 @@ +export { ViewCacheService, FormCacheOptions, SignalCacheOptions } from "./view-cache.service"; diff --git a/libs/angular/src/platform/view-cache/internal.ts b/libs/angular/src/platform/view-cache/internal.ts new file mode 100644 index 00000000000..6e0992eecbf --- /dev/null +++ b/libs/angular/src/platform/view-cache/internal.ts @@ -0,0 +1 @@ +export { NoopViewCacheService } from "./noop-view-cache.service"; diff --git a/libs/angular/src/platform/services/noop-view-cache.service.ts b/libs/angular/src/platform/view-cache/noop-view-cache.service.ts similarity index 87% rename from libs/angular/src/platform/services/noop-view-cache.service.ts rename to libs/angular/src/platform/view-cache/noop-view-cache.service.ts index 9953e80b3b0..f83a0fc0b04 100644 --- a/libs/angular/src/platform/services/noop-view-cache.service.ts +++ b/libs/angular/src/platform/view-cache/noop-view-cache.service.ts @@ -1,11 +1,7 @@ import { Injectable, signal, WritableSignal } from "@angular/core"; import type { FormGroup } from "@angular/forms"; -import { - FormCacheOptions, - SignalCacheOptions, - ViewCacheService, -} from "../abstractions/view-cache.service"; +import { FormCacheOptions, SignalCacheOptions, ViewCacheService } from "./view-cache.service"; /** * The functionality of the {@link ViewCacheService} is only needed in the browser extension popup, diff --git a/libs/angular/src/platform/view-cache/view-cache.md b/libs/angular/src/platform/view-cache/view-cache.md new file mode 100644 index 00000000000..c1f80da5800 --- /dev/null +++ b/libs/angular/src/platform/view-cache/view-cache.md @@ -0,0 +1,130 @@ +# Extension Persistence + +By default, when the browser extension popup closes, the user's current view and any data entered +without saving is lost. This introduces friction in several workflows within our client, such as: + +- Performing actions that require email OTP entry, since the user must navigate from the popup to + get to their email inbox +- Entering information to create a new vault item from a browser tab +- And many more + +Previously, we have recommended that users "pop out" the extension into its own window to persist +the extension context, but this introduces additional user actions and may leave the extension open +(and unlocked) for longer than a user intends. + +In order to provide a better user experience, we have introduced two levels of persistence to the +Bitwarden extension client: + +- We persist the route history, allowing us to re-open the last route when the popup re-opens, and +- We offer a service for teams to use to persist component-specific form data or state to survive a + popup close/re-open cycle + +## Persistence lifetime + +Since we are persisting data, it is important that the lifetime of that data be well-understood and +well-constrained. The cache of route history and form data is cleared when any of the following +events occur: + +- The account is locked +- The account is logged out +- Account switching is used to switch the active account +- The extension popup has been closed for 2 minutes + +In addition, cached form data is cleared when a browser extension navigation event occurs (e.g. +switching between tabs in the extension). + +## Types of persistence + +### Route history persistence + +Route history is persisted on the extension automatically, with no specific implementation required +on any component. + +The persistence layer ensures that the popup will open at the same route as was active when it +closed, provided that none of the lifetime expiration events have occurred. + +:::tip Excluding a route + +If a particular route should be excluded from the history and not persisted, add +`doNotSaveUrl: true` to the `data` property on the route. + +::: + +### View data persistence + +Route persistence ensures that the user will land back on the route that they were on when the popup +closed, but it does not persist any state or form data that the user may have modified. In order to +persist that data, the component is responsible for registering that data with the +[`ViewCacheService`](./view-cache.service.ts). +This is done prescriptively to ensure that only necessary data is cached and that it is done with +intention by the component. + +The `ViewCacheService` provides an interface for caching both individual state and `FormGroup`s. + +#### Caching individual data elements + +For individual pieces of state, use the `signal()` method on the `ViewCacheService` to create a +writeable [signal](https://angular.dev/guide/signals) wrapper around the desired state. + +```typescript +const mySignal = this.viewCacheService.signal({ + key: "my-state-key" + initialValue: null +}); +``` + +If a cached value exists, the returned signal will contain the cached data. + +Setting the value should be done through the signal's `set()` method: + +```typescript +const mySignal = this.viewCacheService.signal({ + key: "my-state-key" + initialValue: null +}); +mySignal.set("value") +``` + +:::note Equality comparison + +By default, signals use `Object.is` to determine equality, and `set()` will only trigger updates if +the updated value is not equal to the current signal state. See documentation +[here](https://angular.dev/guide/signals#signal-equality-functions). + +::: + +Putting this together, the most common implementation pattern would be: + +1. **Register the signal** using `ViewCacheService.signal()` on initialization of the component or + service responsible for the state being persisted. +2. **Restore state from the signal:** If cached data exists, the signal will contain that data. The + component or service should use this data to re-create the state from prior to the popup closing. +3. **Set new state** in the cache when it changes. Ensure that any updates to the data are persisted + to the cache with `set()`, so that the cache reflects the latest state. + +#### Caching form data + +For persisting form data, the `ViewCacheService` supplies a `formGroup()` method, which manages the +persistence of any entered form data to the cache and the initialization of the form from the cached +data. You can supply the `FormGroup` in the `control` parameter of the method, and the +`ViewCacheService` will: + +- Initialize the form the a cached value, if it exists +- Save form value to cache when it changes +- Mark the form dirty if the restored value is not `undefined`. + +```typescript +this.loginDetailsForm = this.viewCacheService.formGroup({ + key: "my-form", + control: this.formBuilder.group({ + username: [""], + email: [""], + }), +}); +``` + +## What about other clients? + +The `ViewCacheService` is designed to be injected into shared, client-agnostic components. A +`NoopViewCacheService` is provided and injected for non-extension clients, preserving a single +interface for your components. diff --git a/libs/angular/src/platform/abstractions/view-cache.service.ts b/libs/angular/src/platform/view-cache/view-cache.service.ts similarity index 98% rename from libs/angular/src/platform/abstractions/view-cache.service.ts rename to libs/angular/src/platform/view-cache/view-cache.service.ts index c5ae6c77d1f..498a29aa242 100644 --- a/libs/angular/src/platform/abstractions/view-cache.service.ts +++ b/libs/angular/src/platform/view-cache/view-cache.service.ts @@ -42,6 +42,8 @@ export type FormCacheOptions = BaseCacheOptions< /** * Cache for temporary component state * + * [Read more](./view-cache.md) + * * #### Implementations * - browser extension popup: used to persist UI between popup open and close * - all other clients: noop diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 4e7c558a0f0..470115ae3f0 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -325,13 +325,14 @@ import { import { DeviceTrustToastService as DeviceTrustToastServiceAbstraction } from "../auth/services/device-trust-toast.service.abstraction"; import { DeviceTrustToastService } from "../auth/services/device-trust-toast.service.implementation"; import { FormValidationErrorsService as FormValidationErrorsServiceAbstraction } from "../platform/abstractions/form-validation-errors.service"; -import { ViewCacheService } from "../platform/abstractions/view-cache.service"; import { FormValidationErrorsService } from "../platform/services/form-validation-errors.service"; import { LoggingErrorHandler } from "../platform/services/logging-error-handler"; -import { NoopViewCacheService } from "../platform/services/noop-view-cache.service"; import { AngularThemingService } from "../platform/services/theming/angular-theming.service"; import { AbstractThemingService } from "../platform/services/theming/theming.service.abstraction"; import { safeProvider, SafeProvider } from "../platform/utils/safe-provider"; +import { ViewCacheService } from "../platform/view-cache"; +// eslint-disable-next-line no-restricted-imports -- Needed for DI +import { NoopViewCacheService } from "../platform/view-cache/internal"; import { CLIENT_TYPE, diff --git a/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-component-email-cache.service.spec.ts b/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-component-email-cache.service.spec.ts index f3b904a4ea6..d2d86710b72 100644 --- a/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-component-email-cache.service.spec.ts +++ b/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-component-email-cache.service.spec.ts @@ -2,7 +2,7 @@ import { TestBed } from "@angular/core/testing"; import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; diff --git a/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-email-component-cache.service.spec.ts b/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-email-component-cache.service.spec.ts index 1613c0e4af8..36d99ee56ac 100644 --- a/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-email-component-cache.service.spec.ts +++ b/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-email-component-cache.service.spec.ts @@ -2,7 +2,7 @@ import { TestBed } from "@angular/core/testing"; import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; diff --git a/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-email-component-cache.service.ts b/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-email-component-cache.service.ts index e32b6cd1385..d274b8003d7 100644 --- a/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-email-component-cache.service.ts +++ b/libs/auth/src/angular/two-factor-auth/child-components/two-factor-auth-email/two-factor-auth-email-component-cache.service.ts @@ -1,7 +1,7 @@ import { inject, Injectable, WritableSignal } from "@angular/core"; import { Jsonify } from "type-fest"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; diff --git a/libs/auth/src/angular/two-factor-auth/two-factor-auth-component-cache.service.spec.ts b/libs/auth/src/angular/two-factor-auth/two-factor-auth-component-cache.service.spec.ts index 0993954fde1..5b5d486556b 100644 --- a/libs/auth/src/angular/two-factor-auth/two-factor-auth-component-cache.service.spec.ts +++ b/libs/auth/src/angular/two-factor-auth/two-factor-auth-component-cache.service.spec.ts @@ -2,7 +2,7 @@ import { TestBed } from "@angular/core/testing"; import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; diff --git a/libs/auth/src/angular/two-factor-auth/two-factor-auth-component-cache.service.ts b/libs/auth/src/angular/two-factor-auth/two-factor-auth-component-cache.service.ts index 61b44aa98dd..2d9fcaa5633 100644 --- a/libs/auth/src/angular/two-factor-auth/two-factor-auth-component-cache.service.ts +++ b/libs/auth/src/angular/two-factor-auth/two-factor-auth-component-cache.service.ts @@ -1,7 +1,7 @@ import { inject, Injectable, WritableSignal } from "@angular/core"; import { Jsonify } from "type-fest"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; diff --git a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts index 89b78500f1f..ab82b98f614 100644 --- a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts +++ b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts @@ -1,7 +1,7 @@ import { signal } from "@angular/core"; import { TestBed } from "@angular/core/testing"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; diff --git a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts index 493fea5c14b..8fbdb925e7c 100644 --- a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts +++ b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts @@ -1,6 +1,6 @@ import { inject, Injectable, WritableSignal } from "@angular/core"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; diff --git a/libs/vault/src/cipher-form/cipher-form.stories.ts b/libs/vault/src/cipher-form/cipher-form.stories.ts index 9943f07292d..7090502ef14 100644 --- a/libs/vault/src/cipher-form/cipher-form.stories.ts +++ b/libs/vault/src/cipher-form/cipher-form.stories.ts @@ -13,7 +13,7 @@ import { import { BehaviorSubject } from "rxjs"; import { CollectionView } from "@bitwarden/admin-console/common"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; diff --git a/libs/vault/src/cipher-form/components/cipher-form.component.spec.ts b/libs/vault/src/cipher-form/components/cipher-form.component.spec.ts index 4c61ad5d2d5..da687f33ef9 100644 --- a/libs/vault/src/cipher-form/components/cipher-form.component.spec.ts +++ b/libs/vault/src/cipher-form/components/cipher-form.component.spec.ts @@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { ReactiveFormsModule } from "@angular/forms"; import { mock } from "jest-mock-extended"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; diff --git a/libs/vault/src/cipher-form/services/default-cipher-form-cache.service.spec.ts b/libs/vault/src/cipher-form/services/default-cipher-form-cache.service.spec.ts index 6236e2d3dac..0dec46e1b20 100644 --- a/libs/vault/src/cipher-form/services/default-cipher-form-cache.service.spec.ts +++ b/libs/vault/src/cipher-form/services/default-cipher-form-cache.service.spec.ts @@ -1,7 +1,7 @@ import { signal } from "@angular/core"; import { TestBed } from "@angular/core/testing"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; diff --git a/libs/vault/src/cipher-form/services/default-cipher-form-cache.service.ts b/libs/vault/src/cipher-form/services/default-cipher-form-cache.service.ts index 268b2db306b..b4a8138e025 100644 --- a/libs/vault/src/cipher-form/services/default-cipher-form-cache.service.ts +++ b/libs/vault/src/cipher-form/services/default-cipher-form-cache.service.ts @@ -1,6 +1,6 @@ import { inject, Injectable } from "@angular/core"; -import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; +import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; From a8fb456329ab1d5eaa32684e43dffc6a8585b829 Mon Sep 17 00:00:00 2001 From: Bryan Cunningham Date: Mon, 12 May 2025 14:38:08 -0400 Subject: [PATCH 05/25] Uif/remove a11y manual flag (#14744) * remove comment left in error * remove runOnly options and manual flag --- .storybook/preview.tsx | 4 ---- .storybook/test-runner.ts | 5 +---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 19a4fc51dc8..a948fce0428 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -28,10 +28,6 @@ const preview: Preview = { parameters: { a11y: { element: "#storybook-root", - manual: true, - options: { - runOnly: ["section508", "wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22aa"], - }, }, controls: { matchers: { diff --git a/.storybook/test-runner.ts b/.storybook/test-runner.ts index 8584a321090..208adf96214 100644 --- a/.storybook/test-runner.ts +++ b/.storybook/test-runner.ts @@ -1,7 +1,4 @@ -import { - // waitForPageReady, - type TestRunnerConfig, -} from "@storybook/test-runner"; +import { type TestRunnerConfig } from "@storybook/test-runner"; import { injectAxe, checkA11y } from "axe-playwright"; const testRunnerConfig: TestRunnerConfig = { From 90d8e822ff09d6c4013cc346972712e902c0f797 Mon Sep 17 00:00:00 2001 From: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com> Date: Mon, 12 May 2025 14:08:48 -0500 Subject: [PATCH 06/25] chore: remove vault-bulk-management-action flag for the third time, refs PM-13112 (#14747) --- libs/common/src/enums/feature-flag.enum.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 08de8ada25a..aa9a9ab5d6e 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -55,7 +55,6 @@ export enum FeatureFlag { /* Vault */ PM8851_BrowserOnboardingNudge = "pm-8851-browser-onboarding-nudge", PM9111ExtensionPersistAddEditForm = "pm-9111-extension-persist-add-edit-form", - VaultBulkManagementAction = "vault-bulk-management-action", SecurityTasks = "security-tasks", CipherKeyEncryption = "cipher-key-encryption", PM18520_UpdateDesktopCipherForm = "pm-18520-desktop-cipher-forms", @@ -107,7 +106,6 @@ export const DefaultFeatureFlagValue = { /* Vault */ [FeatureFlag.PM8851_BrowserOnboardingNudge]: FALSE, [FeatureFlag.PM9111ExtensionPersistAddEditForm]: FALSE, - [FeatureFlag.VaultBulkManagementAction]: FALSE, [FeatureFlag.SecurityTasks]: FALSE, [FeatureFlag.CipherKeyEncryption]: FALSE, [FeatureFlag.PM18520_UpdateDesktopCipherForm]: FALSE, From ce8e123c447c8bdbbbc8a6bb0eb1381e837e4fbe Mon Sep 17 00:00:00 2001 From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com> Date: Mon, 12 May 2025 12:17:15 -0700 Subject: [PATCH 07/25] [PM-21480] - check for privacy granted in isBrowserAutofillSettingOverridden (#14748) * check for privacy granted in isBrowserAutofillSettingOverridden * check for privacy granted in browserAutofillSettingsOverridden --- apps/browser/src/platform/browser/browser-api.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/browser/src/platform/browser/browser-api.ts b/apps/browser/src/platform/browser/browser-api.ts index b27e8ca7c96..4ef72fa0077 100644 --- a/apps/browser/src/platform/browser/browser-api.ts +++ b/apps/browser/src/platform/browser/browser-api.ts @@ -664,6 +664,10 @@ export class BrowserApi { * Identifies if the browser autofill settings are overridden by the extension. */ static async browserAutofillSettingsOverridden(): Promise { + if (!(await BrowserApi.permissionsGranted(["privacy"]))) { + return false; + } + const checkOverrideStatus = (details: chrome.types.ChromeSettingGetResult) => details.levelOfControl === "controlled_by_this_extension" && !details.value; From b8074a6f730c0179b71f2ccde0b06920d46d57ea Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Mon, 12 May 2025 15:18:02 -0400 Subject: [PATCH 08/25] chore(feature-flag): Remove pm-9112-device-approval-persistence (#14718) --- .../login-via-auth-request.component.ts | 34 +++++------ ...gin-via-auth-request-cache.service.spec.ts | 61 ++++--------------- ...lt-login-via-auth-request-cache.service.ts | 27 -------- libs/common/src/enums/feature-flag.enum.ts | 2 - 4 files changed, 27 insertions(+), 97 deletions(-) diff --git a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts index ab5b0c09b32..4c95a1eca3e 100644 --- a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts +++ b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts @@ -23,12 +23,10 @@ import { AuthRequest } from "@bitwarden/common/auth/models/request/auth.request" import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view"; import { ClientType, HttpStatusCode } from "@bitwarden/common/enums"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -101,7 +99,6 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { private validationService: ValidationService, private loginSuccessHandlerService: LoginSuccessHandlerService, private loginViaAuthRequestCacheService: LoginViaAuthRequestCacheService, - private configService: ConfigService, ) { this.clientType = this.platformUtilsService.getClientType(); @@ -132,7 +129,6 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { async ngOnInit(): Promise { // Get the authStatus early because we use it in both flows this.authStatus = await firstValueFrom(this.authService.activeAccountStatus$); - await this.loginViaAuthRequestCacheService.init(); const userHasAuthenticatedViaSSO = this.authStatus === AuthenticationStatus.Locked; @@ -410,24 +406,22 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { const authRequestResponse: AuthRequestResponse = await this.authRequestApiService.postAuthRequest(authRequest); - if (await this.configService.getFeatureFlag(FeatureFlag.PM9112_DeviceApprovalPersistence)) { - if (!this.authRequestKeyPair.privateKey) { - this.logService.error("No private key when trying to cache the login view."); - return; - } - - if (!this.accessCode) { - this.logService.error("No access code when trying to cache the login view."); - return; - } - - this.loginViaAuthRequestCacheService.cacheLoginView( - authRequestResponse.id, - this.authRequestKeyPair.privateKey, - this.accessCode, - ); + if (!this.authRequestKeyPair.privateKey) { + this.logService.error("No private key when trying to cache the login view."); + return; } + if (!this.accessCode) { + this.logService.error("No access code when trying to cache the login view."); + return; + } + + this.loginViaAuthRequestCacheService.cacheLoginView( + authRequestResponse.id, + this.authRequestKeyPair.privateKey, + this.accessCode, + ); + if (authRequestResponse.id) { await this.anonymousHubService.createHubConnection(authRequestResponse.id); } diff --git a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts index ab82b98f614..67ac605e611 100644 --- a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts +++ b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts @@ -3,7 +3,6 @@ import { TestBed } from "@angular/core/testing"; import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { LoginViaAuthRequestCacheService } from "./default-login-via-auth-request-cache.service"; @@ -14,74 +13,40 @@ describe("LoginViaAuthRequestCache", () => { const cacheSignal = signal(null); const getCacheSignal = jest.fn().mockReturnValue(cacheSignal); - const getFeatureFlag = jest.fn().mockResolvedValue(false); const cacheSetMock = jest.spyOn(cacheSignal, "set"); beforeEach(() => { getCacheSignal.mockClear(); - getFeatureFlag.mockClear(); cacheSetMock.mockClear(); testBed = TestBed.configureTestingModule({ providers: [ { provide: ViewCacheService, useValue: { signal: getCacheSignal } }, - { provide: ConfigService, useValue: { getFeatureFlag } }, LoginViaAuthRequestCacheService, ], }); }); - describe("feature enabled", () => { - beforeEach(() => { - getFeatureFlag.mockResolvedValue(true); - }); + it("`getCachedLoginViaAuthRequestView` returns the cached data", async () => { + cacheSignal.set({ ...buildMockState() }); + service = testBed.inject(LoginViaAuthRequestCacheService); - it("`getCachedLoginViaAuthRequestView` returns the cached data", async () => { - cacheSignal.set({ ...buildMockState() }); - service = testBed.inject(LoginViaAuthRequestCacheService); - await service.init(); - - expect(service.getCachedLoginViaAuthRequestView()).toEqual({ - ...buildMockState(), - }); - }); - - it("updates the signal value", async () => { - service = testBed.inject(LoginViaAuthRequestCacheService); - await service.init(); - - const parameters = buildAuthenticMockAuthView(); - - service.cacheLoginView(parameters.id, parameters.privateKey, parameters.accessCode); - - expect(cacheSignal.set).toHaveBeenCalledWith({ - id: parameters.id, - privateKey: Utils.fromBufferToB64(parameters.privateKey), - accessCode: parameters.accessCode, - }); + expect(service.getCachedLoginViaAuthRequestView()).toEqual({ + ...buildMockState(), }); }); - describe("feature disabled", () => { - beforeEach(async () => { - cacheSignal.set({ ...buildMockState() } as LoginViaAuthRequestView); - getFeatureFlag.mockResolvedValue(false); - cacheSetMock.mockClear(); + it("updates the signal value", async () => { + service = testBed.inject(LoginViaAuthRequestCacheService); - service = testBed.inject(LoginViaAuthRequestCacheService); - await service.init(); - }); + const parameters = buildAuthenticMockAuthView(); - it("`getCachedCipherView` returns null", () => { - expect(service.getCachedLoginViaAuthRequestView()).toBeNull(); - }); + service.cacheLoginView(parameters.id, parameters.privateKey, parameters.accessCode); - it("does not update the signal value", () => { - const params = buildAuthenticMockAuthView(); - - service.cacheLoginView(params.id, params.privateKey, params.accessCode); - - expect(cacheSignal.set).not.toHaveBeenCalled(); + expect(cacheSignal.set).toHaveBeenCalledWith({ + id: parameters.id, + privateKey: Utils.fromBufferToB64(parameters.privateKey), + accessCode: parameters.accessCode, }); }); diff --git a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts index 8fbdb925e7c..80dbafd3159 100644 --- a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts +++ b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts @@ -2,8 +2,6 @@ import { inject, Injectable, WritableSignal } from "@angular/core"; import { ViewCacheService } from "@bitwarden/angular/platform/view-cache"; import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; const LOGIN_VIA_AUTH_CACHE_KEY = "login-via-auth-request-form-cache"; @@ -17,10 +15,6 @@ const LOGIN_VIA_AUTH_CACHE_KEY = "login-via-auth-request-form-cache"; @Injectable() export class LoginViaAuthRequestCacheService { private viewCacheService: ViewCacheService = inject(ViewCacheService); - private configService: ConfigService = inject(ConfigService); - - /** True when the `PM9112_DeviceApproval` flag is enabled */ - private featureEnabled: boolean = false; private defaultLoginViaAuthRequestCache: WritableSignal = this.viewCacheService.signal({ @@ -31,23 +25,10 @@ export class LoginViaAuthRequestCacheService { constructor() {} - /** - * Must be called once before interacting with the cached data, otherwise methods will be noop. - */ - async init() { - this.featureEnabled = await this.configService.getFeatureFlag( - FeatureFlag.PM9112_DeviceApprovalPersistence, - ); - } - /** * Update the cache with the new LoginView. */ cacheLoginView(id: string, privateKey: Uint8Array, accessCode: string): void { - if (!this.featureEnabled) { - return; - } - // When the keys get stored they should be converted to a B64 string to ensure // data can be properly formed when json-ified. If not done, they are not stored properly and // will not be parsable by the cryptography library after coming out of storage. @@ -59,10 +40,6 @@ export class LoginViaAuthRequestCacheService { } clearCacheLoginView(): void { - if (!this.featureEnabled) { - return; - } - this.defaultLoginViaAuthRequestCache.set(null); } @@ -70,10 +47,6 @@ export class LoginViaAuthRequestCacheService { * Returns the cached LoginViaAuthRequestView when available. */ getCachedLoginViaAuthRequestView(): LoginViaAuthRequestView | null { - if (!this.featureEnabled) { - return null; - } - return this.defaultLoginViaAuthRequestCache(); } } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index aa9a9ab5d6e..a7679a6248a 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -16,7 +16,6 @@ export enum FeatureFlag { SeparateCustomRolePermissions = "pm-19917-separate-custom-role-permissions", /* Auth */ - PM9112_DeviceApprovalPersistence = "pm-9112-device-approval-persistence", PM9115_TwoFactorExtensionDataPersistence = "pm-9115-two-factor-extension-data-persistence", /* Autofill */ @@ -112,7 +111,6 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.EndUserNotifications]: FALSE, /* Auth */ - [FeatureFlag.PM9112_DeviceApprovalPersistence]: FALSE, [FeatureFlag.PM9115_TwoFactorExtensionDataPersistence]: FALSE, /* Billing */ From 7d01c42e37e07d6642a2fbda5eb27cc12fdf4f85 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 15:42:21 -0400 Subject: [PATCH 09/25] [deps] Vault: Update multer to v1.4.5-lts.2 (#14469) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: SmithThe4th --- apps/cli/package.json | 2 +- package-lock.json | 10 +++++----- package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/cli/package.json b/apps/cli/package.json index 79d4786a23c..0a7e66d7818 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -81,7 +81,7 @@ "koa-json": "2.0.2", "lowdb": "1.0.0", "lunr": "2.3.9", - "multer": "1.4.5-lts.1", + "multer": "1.4.5-lts.2", "node-fetch": "2.6.12", "node-forge": "1.3.1", "open": "8.4.2", diff --git a/package-lock.json b/package-lock.json index 81c9384fbbb..44bebc9cbd4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,7 +54,7 @@ "lit": "3.2.1", "lowdb": "1.0.0", "lunr": "2.3.9", - "multer": "1.4.5-lts.1", + "multer": "1.4.5-lts.2", "ngx-toastr": "19.0.0", "node-fetch": "2.6.12", "node-forge": "1.3.1", @@ -217,7 +217,7 @@ "koa-json": "2.0.2", "lowdb": "1.0.0", "lunr": "2.3.9", - "multer": "1.4.5-lts.1", + "multer": "1.4.5-lts.2", "node-fetch": "2.6.12", "node-forge": "1.3.1", "open": "8.4.2", @@ -28598,9 +28598,9 @@ } }, "node_modules/multer": { - "version": "1.4.5-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", - "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", + "version": "1.4.5-lts.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.2.tgz", + "integrity": "sha512-VzGiVigcG9zUAoCNU+xShztrlr1auZOlurXynNvO9GiWD1/mTBbUljOKY+qMeazBqXgRnjzeEgJI/wyjJUHg9A==", "license": "MIT", "dependencies": { "append-field": "^1.0.0", diff --git a/package.json b/package.json index 8ba1c95df6a..47cede513ed 100644 --- a/package.json +++ b/package.json @@ -190,7 +190,7 @@ "lit": "3.2.1", "lowdb": "1.0.0", "lunr": "2.3.9", - "multer": "1.4.5-lts.1", + "multer": "1.4.5-lts.2", "ngx-toastr": "19.0.0", "node-fetch": "2.6.12", "node-forge": "1.3.1", From 9af7963609a08a5e00dd209e5614022c0d58350a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 May 2025 14:58:48 -0500 Subject: [PATCH 10/25] [deps] Vault: Update @koa/multer to v3.1.0 (#14495) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> --- apps/cli/package.json | 2 +- package-lock.json | 68 ++++++++++++++++++++----------------------- package.json | 2 +- 3 files changed, 33 insertions(+), 39 deletions(-) diff --git a/apps/cli/package.json b/apps/cli/package.json index 0a7e66d7818..82faa7d40e6 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -64,7 +64,7 @@ ] }, "dependencies": { - "@koa/multer": "3.0.2", + "@koa/multer": "3.1.0", "@koa/router": "13.1.0", "argon2": "0.41.1", "big-integer": "1.6.52", diff --git a/package-lock.json b/package-lock.json index 44bebc9cbd4..8466a4ba4c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "@bitwarden/sdk-internal": "0.2.0-main.159", "@electron/fuses": "1.8.0", "@emotion/css": "11.13.5", - "@koa/multer": "3.0.2", + "@koa/multer": "3.1.0", "@koa/router": "13.1.0", "@microsoft/signalr": "8.0.7", "@microsoft/signalr-protocol-msgpack": "8.0.7", @@ -200,7 +200,7 @@ "version": "2025.4.0", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { - "@koa/multer": "3.0.2", + "@koa/multer": "3.1.0", "@koa/router": "13.1.0", "argon2": "0.41.1", "big-integer": "1.6.52", @@ -389,6 +389,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -2745,6 +2746,7 @@ "version": "7.26.8", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -2754,6 +2756,7 @@ "version": "7.24.9", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz", "integrity": "sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==", + "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -2784,12 +2787,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, "license": "MIT" }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -2799,6 +2804,7 @@ "version": "7.26.10", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz", "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.10", @@ -2828,6 +2834,7 @@ "version": "7.26.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.26.5", @@ -2844,6 +2851,7 @@ "version": "4.24.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, "funding": [ { "type": "opencollective", @@ -2876,6 +2884,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -3015,6 +3024,7 @@ "version": "7.26.0", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.25.9", @@ -3045,6 +3055,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -3148,6 +3159,7 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -3172,6 +3184,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz", "integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.27.1", @@ -3280,23 +3293,6 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead.", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", @@ -3382,6 +3378,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" @@ -4010,6 +4007,7 @@ "version": "7.26.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.26.0", @@ -7855,15 +7853,12 @@ } }, "node_modules/@koa/multer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@koa/multer/-/multer-3.0.2.tgz", - "integrity": "sha512-Q6WfPpE06mJWyZD1fzxM6zWywaoo+zocAn2YA9QYz4RsecoASr1h/kSzG0c5seDpFVKCMZM9raEfuM7XfqbRLw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@koa/multer/-/multer-3.1.0.tgz", + "integrity": "sha512-ETf4OLpOew9XE9lyU+5HIqk3TCmdGAw9pUXgxzrlYip+PkxLGoU4meiVTxiW4B6lxdBNijb3DFQ7M2woLcDL1g==", "license": "MIT", - "dependencies": { - "fix-esm": "1.0.1" - }, "engines": { - "node": ">= 8" + "node": ">= 14" }, "peerDependencies": { "multer": "*" @@ -15362,6 +15357,7 @@ "version": "4.23.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -15951,6 +15947,7 @@ "version": "1.0.30001717", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001717.tgz", "integrity": "sha512-auPpttCq6BDEG8ZAuHJIplGw6GODhjw+/11e7IjpnYCxZcW/ONgPs0KVBJ0d1bY3e2+7PRe5RCLyP+PfwVgkYw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -18482,6 +18479,7 @@ "version": "1.5.151", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.151.tgz", "integrity": "sha512-Rl6uugut2l9sLojjS4H4SAr3A4IgACMLgpuEMPYCVcKydzfyPrn5absNRju38IhQOf/NwjJY8OGWjlteqYeBCA==", + "dev": true, "license": "ISC" }, "node_modules/electron-updater": { @@ -18965,6 +18963,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -20387,17 +20386,6 @@ "micromatch": "^4.0.2" } }, - "node_modules/fix-esm": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fix-esm/-/fix-esm-1.0.1.tgz", - "integrity": "sha512-EZtb7wPXZS54GaGxaWxMlhd1DUDCnAg5srlYdu/1ZVeW+7wwR3Tp59nu52dXByFs3MBRq+SByx1wDOJpRvLEXw==", - "license": "WTFPL OR CC0-1.0", - "dependencies": { - "@babel/core": "^7.14.6", - "@babel/plugin-proposal-export-namespace-from": "^7.14.5", - "@babel/plugin-transform-modules-commonjs": "^7.14.5" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -21084,6 +21072,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -25452,6 +25441,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -27032,6 +27022,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -29278,6 +29269,7 @@ "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, "license": "MIT" }, "node_modules/nopt": { @@ -37088,6 +37080,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -38970,6 +38963,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, "license": "ISC" }, "node_modules/yaml": { diff --git a/package.json b/package.json index 47cede513ed..2993707313f 100644 --- a/package.json +++ b/package.json @@ -163,7 +163,7 @@ "@bitwarden/sdk-internal": "0.2.0-main.159", "@electron/fuses": "1.8.0", "@emotion/css": "11.13.5", - "@koa/multer": "3.0.2", + "@koa/multer": "3.1.0", "@koa/router": "13.1.0", "@microsoft/signalr": "8.0.7", "@microsoft/signalr-protocol-msgpack": "8.0.7", From 63b224f3dd08f692c14e18109fba4463062b5c63 Mon Sep 17 00:00:00 2001 From: Daniel Riera Date: Mon, 12 May 2025 17:03:09 -0400 Subject: [PATCH 11/25] PM-21454 Firefox - "null" text is showing in Add/Update Confirmation notification (#14745) * PM-21454 * Update apps/browser/src/autofill/content/components/lit-stories/mock-data.ts Co-authored-by: Jonathan Prusik * Update apps/browser/src/autofill/content/components/lit-stories/mock-data.ts Co-authored-by: Jonathan Prusik * Update apps/browser/src/autofill/content/components/notification/confirmation/container.ts Co-authored-by: Jonathan Prusik * run lint --------- Co-authored-by: Jonathan Prusik --- apps/browser/src/_locales/en/messages.json | 19 ++---- .../components/lit-stories/mock-data.ts | 4 +- .../notification/confirmation/container.ts | 9 ++- .../notification/confirmation/message.ts | 63 ++++++++++++------- apps/browser/src/autofill/notification/bar.ts | 6 +- 5 files changed, 57 insertions(+), 44 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 57a0e78fd1b..361093b12ef 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1088,22 +1088,13 @@ } } }, - "loginSaveConfirmation": { - "message": "$ITEMNAME$ saved to Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginSaveConfirmation": { + "message": "saved to Bitwarden.", + "description": "Shown to user after item is saved." }, - "loginUpdatedConfirmation": { - "message": "$ITEMNAME$ updated in Bitwarden.", - "placeholders": { - "itemName": { - "content": "$1" - } - }, + "notificationLoginUpdatedConfirmation": { + "message": "updated in Bitwarden.", "description": "Shown to user after item is updated." }, "saveAsNewLoginAction": { diff --git a/apps/browser/src/autofill/content/components/lit-stories/mock-data.ts b/apps/browser/src/autofill/content/components/lit-stories/mock-data.ts index b8e35813c6c..d134db3ca6f 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/mock-data.ts +++ b/apps/browser/src/autofill/content/components/lit-stories/mock-data.ts @@ -107,9 +107,9 @@ export const mockI18n = { collection: "Collection", folder: "Folder", loginSaveSuccess: "Login saved", - loginSaveConfirmation: "$ITEMNAME$ saved to Bitwarden.", + notificationLoginSaveConfirmation: "saved to Bitwarden.", loginUpdateSuccess: "Login updated", - loginUpdatedConfirmation: "$ITEMNAME$ updated in Bitwarden.", + notificationLoginUpdatedConfirmation: "updated in Bitwarden.", loginUpdateTaskSuccess: "Great job! You took the steps to make you and $ORGANIZATION$ more secure.", loginUpdateTaskSuccessAdditional: diff --git a/apps/browser/src/autofill/content/components/notification/confirmation/container.ts b/apps/browser/src/autofill/content/components/notification/confirmation/container.ts index 7ad6b4542ec..d4d66c7a7be 100644 --- a/apps/browser/src/autofill/content/components/notification/confirmation/container.ts +++ b/apps/browser/src/autofill/content/components/notification/confirmation/container.ts @@ -113,9 +113,14 @@ function getConfirmationMessage(i18n: I18n, type?: NotificationType, error?: str if (error) { return i18n.saveFailureDetails; } + + /* @TODO This partial string return and later concatenation with the cipher name is needed + * to handle cipher name overflow cases, but is risky for i18n concerns. Fix concatenation + * with cipher name overflow when a tag replacement solution is available. + */ return type === NotificationTypes.Add - ? i18n.loginSaveConfirmation - : i18n.loginUpdatedConfirmation; + ? i18n.notificationLoginSaveConfirmation + : i18n.notificationLoginUpdatedConfirmation; } function getHeaderMessage(i18n: I18n, type?: NotificationType, error?: string) { diff --git a/apps/browser/src/autofill/content/components/notification/confirmation/message.ts b/apps/browser/src/autofill/content/components/notification/confirmation/message.ts index 527119aed15..2bf8caecfff 100644 --- a/apps/browser/src/autofill/content/components/notification/confirmation/message.ts +++ b/apps/browser/src/autofill/content/components/notification/confirmation/message.ts @@ -28,28 +28,31 @@ export function NotificationConfirmationMessage({
${message || buttonText ? html` - ${itemName} - - ${message || nothing} - ${buttonText - ? html` - handleButtonKeyDown(e, () => handleClick(e))} - aria-label=${buttonAria} - tabindex="0" - role="button" - > - ${buttonText} - - ` - : nothing} - +
+ ${itemName} + + ${message || nothing} + ${buttonText + ? html` + + handleButtonKeyDown(e, () => handleClick(e))} + aria-label=${buttonAria} + tabindex="0" + role="button" + > + ${buttonText} + + ` + : nothing} + +
` : nothing} ${messageDetails @@ -61,12 +64,17 @@ export function NotificationConfirmationMessage({ const containerStyles = css` display: flex; - flex-wrap: wrap; - align-items: center; + flex-direction: column; gap: ${spacing[1]}; width: 100%; `; +const singleLineWrapperStyles = css` + display: inline; + white-space: normal; + word-break: break-word; +`; + const baseTextStyles = css` overflow-x: hidden; text-align: left; @@ -81,6 +89,9 @@ const notificationConfirmationMessageStyles = (theme: Theme) => css` color: ${themes[theme].text.main}; font-weight: 400; + white-space: normal; + word-break: break-word; + display: inline; `; const itemNameStyles = (theme: Theme) => css` @@ -90,6 +101,10 @@ const itemNameStyles = (theme: Theme) => css` font-weight: 400; white-space: nowrap; max-width: 300px; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + vertical-align: bottom; `; const notificationConfirmationButtonTextStyles = (theme: Theme) => css` diff --git a/apps/browser/src/autofill/notification/bar.ts b/apps/browser/src/autofill/notification/bar.ts index 3fd6016eb33..52cbdcd47d3 100644 --- a/apps/browser/src/autofill/notification/bar.ts +++ b/apps/browser/src/autofill/notification/bar.ts @@ -59,9 +59,7 @@ function getI18n() { collection: chrome.i18n.getMessage("collection"), folder: chrome.i18n.getMessage("folder"), loginSaveSuccess: chrome.i18n.getMessage("loginSaveSuccess"), - loginSaveConfirmation: chrome.i18n.getMessage("loginSaveConfirmation"), loginUpdateSuccess: chrome.i18n.getMessage("loginUpdateSuccess"), - loginUpdatedConfirmation: chrome.i18n.getMessage("loginUpdatedConfirmation"), loginUpdateTaskSuccess: chrome.i18n.getMessage("loginUpdateTaskSuccess"), loginUpdateTaskSuccessAdditional: chrome.i18n.getMessage("loginUpdateTaskSuccessAdditional"), nextSecurityTaskAction: chrome.i18n.getMessage("nextSecurityTaskAction"), @@ -74,6 +72,10 @@ function getI18n() { notificationUpdate: chrome.i18n.getMessage("notificationChangeSave"), notificationEdit: chrome.i18n.getMessage("edit"), notificationEditTooltip: chrome.i18n.getMessage("notificationEditTooltip"), + notificationLoginSaveConfirmation: chrome.i18n.getMessage("notificationLoginSaveConfirmation"), + notificationLoginUpdatedConfirmation: chrome.i18n.getMessage( + "notificationLoginUpdatedConfirmation", + ), notificationUnlock: chrome.i18n.getMessage("notificationUnlock"), notificationUnlockDesc: chrome.i18n.getMessage("notificationUnlockDesc"), notificationViewAria: chrome.i18n.getMessage("notificationViewAria"), From 02cbc37ac56eccefacfb1d35a6a4c7e8f59c0cea Mon Sep 17 00:00:00 2001 From: Daniel Riera Date: Mon, 12 May 2025 17:23:06 -0400 Subject: [PATCH 12/25] PM-20397 Misc notification bar UI tweaks (#14558) * PM-20637 * turncate save button --- .../content/components/notification/container.ts | 2 +- .../content/components/notification/footer.ts | 15 +++++++++------ .../content/components/rows/button-row.ts | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/apps/browser/src/autofill/content/components/notification/container.ts b/apps/browser/src/autofill/content/components/notification/container.ts index c7c7ae16cde..1a78854f5dc 100644 --- a/apps/browser/src/autofill/content/components/notification/container.ts +++ b/apps/browser/src/autofill/content/components/notification/container.ts @@ -94,7 +94,7 @@ const notificationContainerStyles = (theme: Theme) => css` } [class*="${notificationBodyClassPrefix}-"] { - margin: ${spacing["3"]} 0 ${spacing["1.5"]} ${spacing["3"]}; + margin: ${spacing["3"]} 0 0 ${spacing["3"]}; padding-right: ${spacing["3"]}; } `; diff --git a/apps/browser/src/autofill/content/components/notification/footer.ts b/apps/browser/src/autofill/content/components/notification/footer.ts index 73fe9084595..03d0d475e85 100644 --- a/apps/browser/src/autofill/content/components/notification/footer.ts +++ b/apps/browser/src/autofill/content/components/notification/footer.ts @@ -8,7 +8,7 @@ import { NotificationTypes, } from "../../../notification/abstractions/notification-bar"; import { OrgView, FolderView, I18n, CollectionView } from "../common-types"; -import { spacing, themes } from "../constants/styles"; +import { spacing } from "../constants/styles"; import { NotificationButtonRow } from "./button-row"; @@ -37,7 +37,7 @@ export function NotificationFooter({ const primaryButtonText = i18n.saveAction; return html` -
+
${!isChangeNotification ? NotificationButtonRow({ collections, @@ -56,13 +56,16 @@ export function NotificationFooter({ `; } -const notificationFooterStyles = ({ theme }: { theme: Theme }) => css` +const notificationFooterStyles = ({ + isChangeNotification, +}: { + isChangeNotification: boolean; +}) => css` display: flex; - background-color: ${themes[theme].background.alt}; - padding: 0 ${spacing[3]} ${spacing[3]} ${spacing[3]}; + padding: ${spacing[2]} ${spacing[4]} ${isChangeNotification ? spacing[1] : spacing[4]} + ${spacing[4]}; :last-child { border-radius: 0 0 ${spacing["4"]} ${spacing["4"]}; - padding-bottom: ${spacing[4]}; } `; diff --git a/apps/browser/src/autofill/content/components/rows/button-row.ts b/apps/browser/src/autofill/content/components/rows/button-row.ts index 3527d050b81..7e81d846cb7 100644 --- a/apps/browser/src/autofill/content/components/rows/button-row.ts +++ b/apps/browser/src/autofill/content/components/rows/button-row.ts @@ -62,7 +62,7 @@ const buttonRowStyles = css` > button { max-width: min-content; - flex: 1 1 50%; + flex: 1 1 25%; } > div { From 7a51161d50da1b1b4e2428de943a8a83991bde82 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Tue, 13 May 2025 12:43:26 +0200 Subject: [PATCH 13/25] Move selectable avatar to auth (#14704) --- .../settings/account}/selectable-avatar.component.ts | 0 apps/web/src/app/shared/loose-components.module.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename apps/web/src/app/{components => auth/settings/account}/selectable-avatar.component.ts (100%) diff --git a/apps/web/src/app/components/selectable-avatar.component.ts b/apps/web/src/app/auth/settings/account/selectable-avatar.component.ts similarity index 100% rename from apps/web/src/app/components/selectable-avatar.component.ts rename to apps/web/src/app/auth/settings/account/selectable-avatar.component.ts diff --git a/apps/web/src/app/shared/loose-components.module.ts b/apps/web/src/app/shared/loose-components.module.ts index 30d1dd1af75..ab6c6cc5d72 100644 --- a/apps/web/src/app/shared/loose-components.module.ts +++ b/apps/web/src/app/shared/loose-components.module.ts @@ -22,6 +22,7 @@ import { DangerZoneComponent } from "../auth/settings/account/danger-zone.compon import { DeauthorizeSessionsComponent } from "../auth/settings/account/deauthorize-sessions.component"; import { DeleteAccountDialogComponent } from "../auth/settings/account/delete-account-dialog.component"; import { ProfileComponent } from "../auth/settings/account/profile.component"; +import { SelectableAvatarComponent } from "../auth/settings/account/selectable-avatar.component"; import { EmergencyAccessConfirmComponent } from "../auth/settings/emergency-access/confirm/emergency-access-confirm.component"; import { EmergencyAccessAddEditComponent } from "../auth/settings/emergency-access/emergency-access-add-edit.component"; import { EmergencyAccessComponent } from "../auth/settings/emergency-access/emergency-access.component"; @@ -39,7 +40,6 @@ import { VerifyRecoverDeleteComponent } from "../auth/verify-recover-delete.comp import { SponsoredFamiliesComponent } from "../billing/settings/sponsored-families.component"; import { SponsoringOrgRowComponent } from "../billing/settings/sponsoring-org-row.component"; import { DynamicAvatarComponent } from "../components/dynamic-avatar.component"; -import { SelectableAvatarComponent } from "../components/selectable-avatar.component"; import { ExposedPasswordsReportComponent as OrgExposedPasswordsReportComponent } from "../dirt/reports/pages/organizations/exposed-passwords-report.component"; import { InactiveTwoFactorReportComponent as OrgInactiveTwoFactorReportComponent } from "../dirt/reports/pages/organizations/inactive-two-factor-report.component"; import { ReusedPasswordsReportComponent as OrgReusedPasswordsReportComponent } from "../dirt/reports/pages/organizations/reused-passwords-report.component"; From 4cf6e19b305c693e250f9e4a29008e8f3d06c464 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Tue, 13 May 2025 09:28:25 -0400 Subject: [PATCH 14/25] Estimate tax for trial initiation flow when trial length is 0 (#14674) --- .../trial-billing-step.component.html | 41 +++++++- .../trial-billing-step.component.ts | 94 ++++++++++++++++++- .../abstractions/tax.service.abstraction.ts | 6 ++ .../src/billing/models/request/tax/index.ts | 1 + ...x-amount-for-organization-trial.request.ts | 11 +++ .../src/billing/models/response/tax/index.ts | 1 + .../tax/preview-tax-amount.response.ts | 11 +++ .../src/billing/services/tax.service.ts | 15 +++ 8 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 libs/common/src/billing/models/request/tax/index.ts create mode 100644 libs/common/src/billing/models/request/tax/preview-tax-amount-for-organization-trial.request.ts create mode 100644 libs/common/src/billing/models/response/tax/index.ts create mode 100644 libs/common/src/billing/models/response/tax/preview-tax-amount.response.ts diff --git a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.html b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.html index d947ea96dfb..64a9781b7cf 100644 --- a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.html +++ b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.html @@ -51,8 +51,38 @@

{{ "paymentType" | i18n }}

+ + @if (trialLength === 0) { + @let priceLabel = + subscriptionProduct === SubscriptionProduct.PasswordManager + ? "passwordManagerPlanPrice" + : "secretsManagerPlanPrice"; + +
+
+ {{ priceLabel | i18n }}: {{ getPriceFor(formGroup.value.cadence) | currency: "USD $" }} +
+ {{ "estimatedTax" | i18n }}: + @if (fetchingTaxAmount) { + + } @else { + {{ taxAmount | currency: "USD $" }} + } +
+
+
+

+ {{ "total" | i18n }}: + @if (fetchingTaxAmount) { + + } @else { + {{ total | currency: "USD $" }}/{{ interval | i18n }} + } +

+
+ }
+ + + + {{ "loading" | i18n }} + diff --git a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts index c6248a06a89..614d8bf5f97 100644 --- a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts +++ b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts @@ -1,7 +1,16 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from "@angular/core"; +import { + Component, + EventEmitter, + Input, + OnDestroy, + OnInit, + Output, + ViewChild, +} from "@angular/core"; import { FormBuilder, Validators } from "@angular/forms"; +import { from, Subject, switchMap, takeUntil } from "rxjs"; import { ManageTaxInformationComponent } from "@bitwarden/angular/billing/components"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; @@ -12,7 +21,14 @@ import { PaymentInformation, PlanInformation, } from "@bitwarden/common/billing/abstractions/organization-billing.service"; -import { PaymentMethodType, PlanType, ProductTierType } from "@bitwarden/common/billing/enums"; +import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; +import { + PaymentMethodType, + PlanType, + ProductTierType, + ProductType, +} from "@bitwarden/common/billing/enums"; +import { PreviewTaxAmountForOrganizationTrialRequest } from "@bitwarden/common/billing/models/request/tax"; import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; @@ -50,7 +66,7 @@ export enum SubscriptionProduct { imports: [BillingSharedModule], standalone: true, }) -export class TrialBillingStepComponent implements OnInit { +export class TrialBillingStepComponent implements OnInit, OnDestroy { @ViewChild(PaymentComponent) paymentComponent: PaymentComponent; @ViewChild(ManageTaxInformationComponent) taxInfoComponent: ManageTaxInformationComponent; @Input() organizationInfo: OrganizationInfo; @@ -60,6 +76,7 @@ export class TrialBillingStepComponent implements OnInit { @Output() organizationCreated = new EventEmitter(); loading = true; + fetchingTaxAmount = false; annualCadence = SubscriptionCadence.Annual; monthlyCadence = SubscriptionCadence.Monthly; @@ -73,6 +90,12 @@ export class TrialBillingStepComponent implements OnInit { annualPlan?: PlanResponse; monthlyPlan?: PlanResponse; + taxAmount = 0; + + private destroy$ = new Subject(); + + protected readonly SubscriptionProduct = SubscriptionProduct; + constructor( private apiService: ApiService, private i18nService: I18nService, @@ -80,6 +103,7 @@ export class TrialBillingStepComponent implements OnInit { private messagingService: MessagingService, private organizationBillingService: OrganizationBillingService, private toastService: ToastService, + private taxService: TaxServiceAbstraction, ) {} async ngOnInit(): Promise { @@ -87,9 +111,26 @@ export class TrialBillingStepComponent implements OnInit { this.applicablePlans = plans.data.filter(this.isApplicable); this.annualPlan = this.findPlanFor(SubscriptionCadence.Annual); this.monthlyPlan = this.findPlanFor(SubscriptionCadence.Monthly); + + if (this.trialLength === 0) { + this.formGroup.controls.cadence.valueChanges + .pipe( + switchMap((cadence) => from(this.previewTaxAmount(cadence))), + takeUntil(this.destroy$), + ) + .subscribe((taxAmount) => { + this.taxAmount = taxAmount; + }); + } + this.loading = false; } + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + async submit(): Promise { if (!this.taxInfoComponent.validate()) { return; @@ -115,7 +156,11 @@ export class TrialBillingStepComponent implements OnInit { this.messagingService.send("organizationCreated", { organizationId }); } - protected changedCountry() { + async onTaxInformationChanged() { + if (this.trialLength === 0) { + this.taxAmount = await this.previewTaxAmount(this.formGroup.value.cadence); + } + this.paymentComponent.showBankAccount = this.taxInfoComponent.getTaxInformation().country === "US"; if ( @@ -250,4 +295,45 @@ export class TrialBillingStepComponent implements OnInit { const notDisabledOrLegacy = !plan.disabled && !plan.legacyYear; return hasCorrectProductType && notDisabledOrLegacy; } + + private previewTaxAmount = async (cadence: SubscriptionCadence): Promise => { + this.fetchingTaxAmount = true; + + if (!this.taxInfoComponent.validate()) { + return 0; + } + + const plan = this.findPlanFor(cadence); + + const productType = + this.subscriptionProduct === SubscriptionProduct.PasswordManager + ? ProductType.PasswordManager + : ProductType.SecretsManager; + + const taxInformation = this.taxInfoComponent.getTaxInformation(); + + const request: PreviewTaxAmountForOrganizationTrialRequest = { + planType: plan.type, + productType, + taxInformation: { + ...taxInformation, + }, + }; + + const response = await this.taxService.previewTaxAmountForOrganizationTrial(request); + this.fetchingTaxAmount = false; + return response.taxAmount; + }; + + get price() { + return this.getPriceFor(this.formGroup.value.cadence); + } + + get total() { + return this.price + this.taxAmount; + } + + get interval() { + return this.formGroup.value.cadence === SubscriptionCadence.Annual ? "year" : "month"; + } } diff --git a/libs/common/src/billing/abstractions/tax.service.abstraction.ts b/libs/common/src/billing/abstractions/tax.service.abstraction.ts index 7a744dae856..73dc848c95f 100644 --- a/libs/common/src/billing/abstractions/tax.service.abstraction.ts +++ b/libs/common/src/billing/abstractions/tax.service.abstraction.ts @@ -1,7 +1,9 @@ import { CountryListItem } from "../models/domain"; import { PreviewIndividualInvoiceRequest } from "../models/request/preview-individual-invoice.request"; import { PreviewOrganizationInvoiceRequest } from "../models/request/preview-organization-invoice.request"; +import { PreviewTaxAmountForOrganizationTrialRequest } from "../models/request/tax"; import { PreviewInvoiceResponse } from "../models/response/preview-invoice.response"; +import { PreviewTaxAmountResponse } from "../models/response/tax"; export abstract class TaxServiceAbstraction { abstract getCountries(): CountryListItem[]; @@ -15,4 +17,8 @@ export abstract class TaxServiceAbstraction { abstract previewOrganizationInvoice( request: PreviewOrganizationInvoiceRequest, ): Promise; + + abstract previewTaxAmountForOrganizationTrial: ( + request: PreviewTaxAmountForOrganizationTrialRequest, + ) => Promise; } diff --git a/libs/common/src/billing/models/request/tax/index.ts b/libs/common/src/billing/models/request/tax/index.ts new file mode 100644 index 00000000000..cda1930c614 --- /dev/null +++ b/libs/common/src/billing/models/request/tax/index.ts @@ -0,0 +1 @@ +export * from "./preview-tax-amount-for-organization-trial.request"; diff --git a/libs/common/src/billing/models/request/tax/preview-tax-amount-for-organization-trial.request.ts b/libs/common/src/billing/models/request/tax/preview-tax-amount-for-organization-trial.request.ts new file mode 100644 index 00000000000..3f366335a47 --- /dev/null +++ b/libs/common/src/billing/models/request/tax/preview-tax-amount-for-organization-trial.request.ts @@ -0,0 +1,11 @@ +import { PlanType, ProductType } from "../../../enums"; + +export type PreviewTaxAmountForOrganizationTrialRequest = { + planType: PlanType; + productType: ProductType; + taxInformation: { + country: string; + postalCode: string; + taxId?: string; + }; +}; diff --git a/libs/common/src/billing/models/response/tax/index.ts b/libs/common/src/billing/models/response/tax/index.ts new file mode 100644 index 00000000000..525d6d7c80a --- /dev/null +++ b/libs/common/src/billing/models/response/tax/index.ts @@ -0,0 +1 @@ +export * from "./preview-tax-amount.response"; diff --git a/libs/common/src/billing/models/response/tax/preview-tax-amount.response.ts b/libs/common/src/billing/models/response/tax/preview-tax-amount.response.ts new file mode 100644 index 00000000000..cf15156551a --- /dev/null +++ b/libs/common/src/billing/models/response/tax/preview-tax-amount.response.ts @@ -0,0 +1,11 @@ +import { BaseResponse } from "../../../../models/response/base.response"; + +export class PreviewTaxAmountResponse extends BaseResponse { + taxAmount: number; + + constructor(response: any) { + super(response); + + this.taxAmount = this.getResponseProperty("TaxAmount"); + } +} diff --git a/libs/common/src/billing/services/tax.service.ts b/libs/common/src/billing/services/tax.service.ts index aa27c99adc8..2632ca7083b 100644 --- a/libs/common/src/billing/services/tax.service.ts +++ b/libs/common/src/billing/services/tax.service.ts @@ -1,3 +1,6 @@ +import { PreviewTaxAmountForOrganizationTrialRequest } from "@bitwarden/common/billing/models/request/tax"; +import { PreviewTaxAmountResponse } from "@bitwarden/common/billing/models/response/tax"; + import { ApiService } from "../../abstractions/api.service"; import { TaxServiceAbstraction } from "../abstractions/tax.service.abstraction"; import { CountryListItem } from "../models/domain"; @@ -300,4 +303,16 @@ export class TaxService implements TaxServiceAbstraction { ); return new PreviewInvoiceResponse(response); } + + async previewTaxAmountForOrganizationTrial( + request: PreviewTaxAmountForOrganizationTrialRequest, + ): Promise { + return await this.apiService.send( + "POST", + "/tax/preview-amount/organization-trial", + request, + true, + true, + ); + } } From 992b1456a82ef5626501bbdf35277d3b8078a4db Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Tue, 13 May 2025 09:31:47 -0400 Subject: [PATCH 15/25] Send SkipTrial = true to organization create when trial length is 0 (#14701) --- .../accounts/trial-initiation/trial-billing-step.component.ts | 1 + .../admin-console/models/request/organization-create.request.ts | 1 + .../src/billing/abstractions/organization-billing.service.ts | 1 + libs/common/src/billing/services/organization-billing.service.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts index 614d8bf5f97..9f910ad9d23 100644 --- a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts +++ b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts @@ -215,6 +215,7 @@ export class TrialBillingStepComponent implements OnInit, OnDestroy { const payment: PaymentInformation = { paymentMethod, billing: this.getBillingInformationFromTaxInfoComponent(), + skipTrial: this.trialLength === 0, }; const response = await this.organizationBillingService.purchaseSubscription({ diff --git a/libs/common/src/admin-console/models/request/organization-create.request.ts b/libs/common/src/admin-console/models/request/organization-create.request.ts index e8561307b20..d9c62f1e20a 100644 --- a/libs/common/src/admin-console/models/request/organization-create.request.ts +++ b/libs/common/src/admin-console/models/request/organization-create.request.ts @@ -6,4 +6,5 @@ import { OrganizationNoPaymentMethodCreateRequest } from "../../../billing/model export class OrganizationCreateRequest extends OrganizationNoPaymentMethodCreateRequest { paymentMethodType: PaymentMethodType; paymentToken: string; + skipTrial?: boolean; } diff --git a/libs/common/src/billing/abstractions/organization-billing.service.ts b/libs/common/src/billing/abstractions/organization-billing.service.ts index 8024a120b0a..58c537c99cc 100644 --- a/libs/common/src/billing/abstractions/organization-billing.service.ts +++ b/libs/common/src/billing/abstractions/organization-billing.service.ts @@ -39,6 +39,7 @@ export type BillingInformation = { export type PaymentInformation = { paymentMethod: [string, PaymentMethodType]; billing: BillingInformation; + skipTrial?: boolean; }; export type SubscriptionInformation = { diff --git a/libs/common/src/billing/services/organization-billing.service.ts b/libs/common/src/billing/services/organization-billing.service.ts index c6bd88d8dd6..fe5623fd5e6 100644 --- a/libs/common/src/billing/services/organization-billing.service.ts +++ b/libs/common/src/billing/services/organization-billing.service.ts @@ -174,6 +174,7 @@ export class OrganizationBillingService implements OrganizationBillingServiceAbs const [paymentToken, paymentMethodType] = information.paymentMethod; request.paymentToken = paymentToken; request.paymentMethodType = paymentMethodType; + request.skipTrial = information.skipTrial; const billingInformation = information.billing; request.billingAddressPostalCode = billingInformation.postalCode; From b2c118d607c7be1298b39cd6c3ea3012411e5a78 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Tue, 13 May 2025 15:41:57 +0200 Subject: [PATCH 16/25] Move admin-console code to new encrypt service interface (#14547) --- .../organization-user-reset-password.service.ts | 2 +- .../providers/services/web-provider.service.ts | 2 +- .../services/default-collection-admin.service.ts | 4 ++-- .../collections/services/default-collection.service.spec.ts | 5 ++++- .../collections/services/default-collection.service.ts | 2 +- .../services/default-vnext-collection.service.spec.ts | 6 ++++++ .../services/default-vnext-collection.service.ts | 2 +- .../models/domain/encrypted-organization-key.ts | 4 ++-- 8 files changed, 18 insertions(+), 9 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts index 78d2d8fd165..ecf4d26eb52 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts @@ -112,7 +112,7 @@ export class OrganizationUserResetPasswordService if (orgSymKey == null) { throw new Error("No org key found"); } - const decPrivateKey = await this.encryptService.decryptToBytes( + const decPrivateKey = await this.encryptService.unwrapDecapsulationKey( new EncString(response.encryptedPrivateKey), orgSymKey, ); diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts index 844c6b779a9..418b7020ff9 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/services/web-provider.service.ts @@ -74,7 +74,7 @@ export class WebProviderService { const [publicKey, encryptedPrivateKey] = await this.keyService.makeKeyPair(organizationKey); - const encryptedCollectionName = await this.encryptService.encrypt( + const encryptedCollectionName = await this.encryptService.encryptString( this.i18nService.t("defaultCollection"), organizationKey, ); diff --git a/libs/admin-console/src/common/collections/services/default-collection-admin.service.ts b/libs/admin-console/src/common/collections/services/default-collection-admin.service.ts index 890353d9039..293090ce315 100644 --- a/libs/admin-console/src/common/collections/services/default-collection-admin.service.ts +++ b/libs/admin-console/src/common/collections/services/default-collection-admin.service.ts @@ -116,7 +116,7 @@ export class DefaultCollectionAdminService implements CollectionAdminService { const promises = collections.map(async (c) => { const view = new CollectionAdminView(); view.id = c.id; - view.name = await this.encryptService.decryptToUtf8(new EncString(c.name), orgKey); + view.name = await this.encryptService.decryptString(new EncString(c.name), orgKey); view.externalId = c.externalId; view.organizationId = c.organizationId; @@ -146,7 +146,7 @@ export class DefaultCollectionAdminService implements CollectionAdminService { } const collection = new CollectionRequest(); collection.externalId = model.externalId; - collection.name = (await this.encryptService.encrypt(model.name, key)).encryptedString; + collection.name = (await this.encryptService.encryptString(model.name, key)).encryptedString; collection.groups = model.groups.map( (group) => new SelectionReadOnlyRequest(group.id, group.readOnly, group.hidePasswords, group.manage), diff --git a/libs/admin-console/src/common/collections/services/default-collection.service.spec.ts b/libs/admin-console/src/common/collections/services/default-collection.service.spec.ts index 7fe81ade4d2..c5f57f38dd3 100644 --- a/libs/admin-console/src/common/collections/services/default-collection.service.spec.ts +++ b/libs/admin-console/src/common/collections/services/default-collection.service.spec.ts @@ -120,9 +120,12 @@ const mockStateProvider = () => { const mockCryptoService = () => { const keyService = mock(); const encryptService = mock(); - encryptService.decryptToUtf8 + encryptService.decryptString .calledWith(expect.any(EncString), expect.anything()) .mockResolvedValue("DECRYPTED_STRING"); + encryptService.decryptToUtf8 + .calledWith(expect.any(EncString), expect.anything(), expect.anything()) + .mockResolvedValue("DECRYPTED_STRING"); (window as any).bitwardenContainerService = new ContainerService(keyService, encryptService); diff --git a/libs/admin-console/src/common/collections/services/default-collection.service.ts b/libs/admin-console/src/common/collections/services/default-collection.service.ts index 1ae58d3eef3..a1dd0419e2c 100644 --- a/libs/admin-console/src/common/collections/services/default-collection.service.ts +++ b/libs/admin-console/src/common/collections/services/default-collection.service.ts @@ -113,7 +113,7 @@ export class DefaultCollectionService implements CollectionService { collection.organizationId = model.organizationId; collection.readOnly = model.readOnly; collection.externalId = model.externalId; - collection.name = await this.encryptService.encrypt(model.name, key); + collection.name = await this.encryptService.encryptString(model.name, key); return collection; } diff --git a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts index 9700fcb695a..d4bc026b5bd 100644 --- a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts +++ b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.spec.ts @@ -46,6 +46,11 @@ describe("DefaultvNextCollectionService", () => { keyService.orgKeys$.mockReturnValue(cryptoKeys); // Set up mock decryption + encryptService.decryptString + .calledWith(expect.any(EncString), expect.any(SymmetricCryptoKey)) + .mockImplementation((encString, key) => + Promise.resolve(encString.data.replace("ENC_", "DEC_")), + ); encryptService.decryptToUtf8 .calledWith(expect.any(EncString), expect.any(SymmetricCryptoKey), expect.any(String)) .mockImplementation((encString, key) => @@ -103,6 +108,7 @@ describe("DefaultvNextCollectionService", () => { ]); // Assert that the correct org keys were used for each encrypted string + // This should be replaced with decryptString when the platform PR (https://github.com/bitwarden/clients/pull/14544) is merged expect(encryptService.decryptToUtf8).toHaveBeenCalledWith( expect.objectContaining(new EncString(collection1.name)), orgKey1, diff --git a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.ts b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.ts index 0ef8ae99ab3..4dcda795afe 100644 --- a/libs/admin-console/src/common/collections/services/default-vnext-collection.service.ts +++ b/libs/admin-console/src/common/collections/services/default-vnext-collection.service.ts @@ -113,7 +113,7 @@ export class DefaultvNextCollectionService implements vNextCollectionService { collection.organizationId = model.organizationId; collection.readOnly = model.readOnly; collection.externalId = model.externalId; - collection.name = await this.encryptService.encrypt(model.name, key); + collection.name = await this.encryptService.encryptString(model.name, key); return collection; } diff --git a/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts b/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts index 984d80ba519..297bcf08d8c 100644 --- a/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts +++ b/libs/common/src/admin-console/models/domain/encrypted-organization-key.ts @@ -56,14 +56,14 @@ export class ProviderEncryptedOrganizationKey implements BaseEncryptedOrganizati ) {} async decrypt(encryptService: EncryptService, providerKeys: Record) { - const decValue = await encryptService.decryptToBytes( + const decValue = await encryptService.unwrapSymmetricKey( new EncString(this.key), providerKeys[this.providerId], ); if (decValue == null) { throw new Error("Failed to decrypt organization key"); } - return new SymmetricCryptoKey(decValue) as OrgKey; + return decValue as OrgKey; } get encryptedOrganizationKey() { From 00beef617caf0bc3aa81efdc5d4f34e53c1f2e08 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Tue, 13 May 2025 15:42:48 +0200 Subject: [PATCH 17/25] [PM-21586] Return null in decryptUserKeyWithMasterKey if decrypt fails (#14756) * Return null in decryptUserKeyWithMasterKey if decrypt fails * Show error on invalid master password * Add logs --- .../master-password.service.abstraction.ts | 4 ++-- .../services/master-password.service.ts | 20 ++++++++++++++----- .../src/lock/components/lock.component.ts | 9 +++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts b/libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts index 221ce8ed6ef..fded0cea023 100644 --- a/libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts +++ b/libs/common/src/key-management/master-password/abstractions/master-password.service.abstraction.ts @@ -37,13 +37,13 @@ export abstract class MasterPasswordServiceAbstraction { * @param userKey The user's encrypted symmetric key * @throws If either the MasterKey or UserKey are not resolved, or if the UserKey encryption type * is neither AesCbc256_B64 nor AesCbc256_HmacSha256_B64 - * @returns The user key + * @returns The user key or null if the masterkey is wrong */ abstract decryptUserKeyWithMasterKey: ( masterKey: MasterKey, userId: string, userKey?: EncString, - ) => Promise; + ) => Promise; } export abstract class InternalMasterPasswordServiceAbstraction extends MasterPasswordServiceAbstraction { diff --git a/libs/common/src/key-management/master-password/services/master-password.service.ts b/libs/common/src/key-management/master-password/services/master-password.service.ts index b9b11d6cbe8..9e58680d453 100644 --- a/libs/common/src/key-management/master-password/services/master-password.service.ts +++ b/libs/common/src/key-management/master-password/services/master-password.service.ts @@ -166,7 +166,7 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr masterKey: MasterKey, userId: UserId, userKey?: EncString, - ): Promise { + ): Promise { userKey ??= await this.getMasterKeyEncryptedUserKey(userId); masterKey ??= await firstValueFrom(this.masterKey$(userId)); @@ -177,16 +177,26 @@ export class MasterPasswordService implements InternalMasterPasswordServiceAbstr let decUserKey: SymmetricCryptoKey; if (userKey.encryptionType === EncryptionType.AesCbc256_B64) { - decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, masterKey); + try { + decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, masterKey); + } catch { + this.logService.warning("Failed to decrypt user key with master key."); + return null; + } } else if (userKey.encryptionType === EncryptionType.AesCbc256_HmacSha256_B64) { - const newKey = await this.keyGenerationService.stretchKey(masterKey); - decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, newKey); + try { + const newKey = await this.keyGenerationService.stretchKey(masterKey); + decUserKey = await this.encryptService.unwrapSymmetricKey(userKey, newKey); + } catch { + this.logService.warning("Failed to decrypt user key with stretched master key."); + return null; + } } else { throw new Error("Unsupported encryption type."); } if (decUserKey == null) { - this.logService.warning("Failed to decrypt user key with master key."); + this.logService.warning("Failed to decrypt user key with master key, user key is null."); return null; } diff --git a/libs/key-management-ui/src/lock/components/lock.component.ts b/libs/key-management-ui/src/lock/components/lock.component.ts index 80d64e17b84..3cb0dbaca52 100644 --- a/libs/key-management-ui/src/lock/components/lock.component.ts +++ b/libs/key-management-ui/src/lock/components/lock.component.ts @@ -556,6 +556,15 @@ export class LockComponent implements OnInit, OnDestroy { masterPasswordVerificationResponse!.masterKey, this.activeAccount.id, ); + if (userKey == null) { + this.toastService.showToast({ + variant: "error", + title: this.i18nService.t("errorOccurred"), + message: this.i18nService.t("invalidMasterPassword"), + }); + return; + } + await this.setUserKeyAndContinue(userKey, true); } From 9f3310ed7edecb2afc68a284dedd37f68dae72f9 Mon Sep 17 00:00:00 2001 From: Tom <144813356+ttalty@users.noreply.github.com> Date: Tue, 13 May 2025 09:44:54 -0400 Subject: [PATCH 18/25] Redoing the PR for get by domain due to file move (#14746) --- .../services/risk-insights-report.service.spec.ts | 10 +++++----- .../services/risk-insights-report.service.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.spec.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.spec.ts index 705eb1231a9..f9177bf1bf7 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.spec.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.spec.ts @@ -50,7 +50,7 @@ describe("RiskInsightsReportService", () => { let testCase = testCaseResults[0]; expect(testCase).toBeTruthy(); expect(testCase.cipherMembers).toHaveLength(2); - expect(testCase.trimmedUris).toHaveLength(3); + expect(testCase.trimmedUris).toHaveLength(2); expect(testCase.weakPasswordDetail).toBeTruthy(); expect(testCase.exposedPasswordDetail).toBeTruthy(); expect(testCase.reusedPasswordCount).toEqual(2); @@ -69,7 +69,7 @@ describe("RiskInsightsReportService", () => { it("should generate the raw data + uri report correctly", async () => { const result = await firstValueFrom(service.generateRawDataUriReport$("orgId")); - expect(result).toHaveLength(9); + expect(result).toHaveLength(8); // Two ciphers that have google.com as their uri. There should be 2 results const googleResults = result.filter((x) => x.trimmedUri === "google.com"); @@ -88,7 +88,7 @@ describe("RiskInsightsReportService", () => { it("should generate applications health report data correctly", async () => { const result = await firstValueFrom(service.generateApplicationsReport$("orgId")); - expect(result).toHaveLength(6); + expect(result).toHaveLength(5); // Two ciphers have google.com associated with them. The first cipher // has 2 members and the second has 4. However, the 2 members in the first @@ -132,7 +132,7 @@ describe("RiskInsightsReportService", () => { expect(reportSummary.totalMemberCount).toEqual(7); expect(reportSummary.totalAtRiskMemberCount).toEqual(6); - expect(reportSummary.totalApplicationCount).toEqual(6); - expect(reportSummary.totalAtRiskApplicationCount).toEqual(5); + expect(reportSummary.totalApplicationCount).toEqual(5); + expect(reportSummary.totalAtRiskApplicationCount).toEqual(4); }); }); diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.ts index 027760f678c..8a6eb5000cd 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/services/risk-insights-report.service.ts @@ -428,7 +428,7 @@ export class RiskInsightsReportService { const cipherUris: string[] = []; const uris = cipher.login?.uris ?? []; uris.map((u: { uri: string }) => { - const uri = Utils.getHostname(u.uri).replace("www.", ""); + const uri = Utils.getDomain(u.uri); if (!cipherUris.includes(uri)) { cipherUris.push(uri); } From 0b0397c3f05d94e1ea8cbedd97b7706fba968e9b Mon Sep 17 00:00:00 2001 From: Patrick-Pimentel-Bitwarden Date: Tue, 13 May 2025 10:07:38 -0400 Subject: [PATCH 19/25] fix(enums-eslint): Enum Rule for ESLint (#14650) * fix(enums-eslint): Enum Rule for ESLint - Added enums in the warnings for eslint. * fix(enums-eslint): Enum Rule for ESLint - Updated to error in both places for enums. * fix(enums-eslint): Enum Rule for ESLint - Added new eslint plugin for warning on enums. * fix(enums-eslint): Enum Rule for ESLint - Changed based on suggestion. Co-authored-by: Andreas Coroiu * refactor(browser-platform-utils): Remove Deprecation and Fix Code - Changed usages of firefox to private and moved the usages to the preferred public method and removed the deprecations. * fix(enums-eslint): Enum Rule for ESLint - Updated to error and added disable rules for all other places. * fix(enums-eslint): Enum Rule for ESLint - Undid other changes by accident --- .../autofill/enums/autofill-overlay.enum.ts | 2 + .../fido2/content/messaging/message.ts | 2 + .../tools/popup/send-v2/send-v2.component.ts | 2 + .../at-risk-carousel-dialog.component.ts | 2 + .../vault-generator-dialog.component.ts | 2 + .../components/vault-v2/vault-v2.component.ts | 2 + .../src/ipc.service.ts | 2 + .../src/app/tools/send/send.component.ts | 2 + .../src/autofill/models/ssh-agent-setting.ts | 2 + apps/desktop/src/types/biometric-message.ts | 2 + .../credential-generator-dialog.component.ts | 2 + .../bulk-collections-dialog.component.ts | 2 + .../collections/vault.component.ts | 2 + .../manage/group-add-edit.component.ts | 4 ++ .../member-dialog/member-dialog.component.ts | 4 ++ .../components/reset-password.component.ts | 2 + .../policies/policy-edit.component.ts | 2 + .../delete-organization-dialog.component.ts | 2 + .../access-selector.component.ts | 2 + .../access-selector/access-selector.models.ts | 4 ++ .../collection-dialog.component.ts | 6 ++ ...bauthn-login-credential-prf-status.enum.ts | 2 + .../enums/emergency-access-status-type.ts | 2 + .../enums/emergency-access-type.ts | 2 + .../emergency-access-confirm.component.ts | 2 + .../emergency-access-add-edit.component.ts | 2 + .../emergency-access-takeover.component.ts | 2 + .../create-credential-dialog.component.ts | 2 + .../trial-billing-step.component.ts | 4 ++ .../change-plan-dialog.component.ts | 4 ++ .../download-license.component.ts | 2 + ...ization-subscription-selfhost.component.ts | 2 + .../shared/add-credit-dialog.component.ts | 2 + .../adjust-payment-dialog.component.ts | 2 + .../adjust-storage-dialog.component.ts | 2 + .../shared/offboarding-survey.component.ts | 2 + .../billing/shared/update-license-types.ts | 2 + apps/web/src/app/dirt/reports/reports.ts | 2 + .../reports/shared/models/report-variant.ts | 2 + .../vault-item-dialog.component.ts | 2 + .../web-generator-dialog.component.ts | 2 + .../individual-vault/add-edit-v2.component.ts | 2 + .../bulk-delete-dialog.component.ts | 2 + .../bulk-move-dialog.component.ts | 2 + .../folder-add-edit.component.ts | 2 + .../services/vault-banners.service.ts | 2 + .../models/vault-filter-section.type.ts | 2 + .../vault/individual-vault/view.component.ts | 2 + .../browser-extension-prompt.service.ts | 2 + .../risk-insights/models/password-health.ts | 2 + .../add-edit-member-dialog.component.ts | 2 + ...-existing-organization-dialog.component.ts | 2 + .../clients/create-client-dialog.component.ts | 2 + .../manage-client-name-dialog.component.ts | 2 + ...ge-client-subscription-dialog.component.ts | 2 + .../risk-insights.component.ts | 2 + .../dialog/project-dialog.component.ts | 2 + .../secrets/dialog/secret-dialog.component.ts | 4 ++ .../service-account-dialog.component.ts | 2 + .../models/enums/ap-item.enum.ts | 2 + .../models/enums/ap-permission.enum.ts | 2 + .../bulk-confirmation-dialog.component.ts | 2 + eslint.config.mjs | 1 + .../add-account-credit-dialog.component.ts | 2 + .../src/tools/send/add-edit.component.ts | 2 + .../input-password.component.ts | 2 + .../login-decryption-options.component.ts | 2 + .../login-via-auth-request.component.ts | 2 + .../auth/src/angular/login/login.component.ts | 2 + .../registration-start.component.ts | 2 + .../two-factor-auth-component.service.ts | 4 ++ .../active-client-verification-option.enum.ts | 2 + .../validators/compare-inputs.validator.ts | 2 + .../enums/organization-api-key-type.enum.ts | 2 + .../organization-connection-type.enum.ts | 2 + .../organization-user-status-type.enum.ts | 2 + .../enums/organization-user-type.enum.ts | 2 + .../admin-console/enums/policy-type.enum.ts | 2 + .../enums/provider-status-type.enum.ts | 2 + .../admin-console/enums/provider-type.enum.ts | 2 + .../enums/provider-user-status-type.enum.ts | 2 + .../enums/provider-user-type.enum.ts | 2 + .../enums/scim-provider-type.enum.ts | 2 + .../src/auth/enums/auth-request-type.ts | 2 + .../src/auth/enums/authentication-status.ts | 2 + .../src/auth/enums/authentication-type.ts | 2 + libs/common/src/auth/enums/sso.ts | 12 ++++ .../auth/enums/two-factor-provider-type.ts | 2 + .../src/auth/enums/verification-type.ts | 2 + .../domain/force-set-password-reason.ts | 2 + .../common/src/auth/services/token.service.ts | 2 + .../enums/bitwarden-product-type.enum.ts | 2 + .../billing/enums/payment-method-type.enum.ts | 2 + .../src/billing/enums/plan-interval.enum.ts | 2 + .../enums/plan-sponsorship-type.enum.ts | 2 + .../src/billing/enums/plan-type.enum.ts | 2 + .../billing/enums/product-tier-type.enum.ts | 2 + .../src/billing/enums/product-type.enum.ts | 2 + .../billing/enums/transaction-type.enum.ts | 2 + libs/common/src/enums/client-type.enum.ts | 2 + libs/common/src/enums/device-type.enum.ts | 2 + .../src/enums/event-system-user.enum.ts | 2 + libs/common/src/enums/event-type.enum.ts | 2 + libs/common/src/enums/feature-flag.enum.ts | 2 + .../common/src/enums/http-status-code.enum.ts | 2 + .../common/src/enums/integration-type.enum.ts | 2 + .../enums/native-messaging-version.enum.ts | 2 + .../src/enums/notification-type.enum.ts | 2 + libs/common/src/enums/push-technology.enum.ts | 2 + .../enums/vault-timeout-action.enum.ts | 2 + .../abstractions/environment.service.ts | 2 + ...fido2-authenticator.service.abstraction.ts | 4 ++ .../platform/enums/encryption-type.enum.ts | 2 + .../platform/enums/file-upload-type.enum.ts | 2 + .../src/platform/enums/hash-purpose.enum.ts | 2 + .../enums/html-storage-location.enum.ts | 2 + .../platform/enums/key-suffix-options.enum.ts | 2 + .../src/platform/enums/log-level-type.enum.ts | 2 + .../platform/enums/storage-location.enum.ts | 2 + .../src/platform/enums/theme-type.enum.ts | 2 + .../services/cryptography/initializer-key.ts | 2 + ...8-move-provider-state-to-state-provider.ts | 4 ++ .../30-move-policy-state-to-state-provider.ts | 2 + ...ve-organization-state-to-state-provider.ts | 8 +++ .../migrations/54-move-encrypted-sends.ts | 2 + .../59-move-kdf-config-to-state-provider.ts | 2 + ...-timeout-settings-svc-to-state-provider.ts | 2 + libs/common/src/tools/send/enums/send-type.ts | 2 + .../src/vault/enums/cipher-reprompt-type.ts | 2 + libs/common/src/vault/enums/cipher-type.ts | 2 + .../common/src/vault/enums/field-type.enum.ts | 2 + .../src/vault/enums/linked-id-type.enum.ts | 6 ++ .../src/vault/enums/secure-note-type.enum.ts | 2 + .../tasks/enums/security-task-status.enum.ts | 2 + .../tasks/enums/security-task-type.enum.ts | 2 + .../color-password.component.ts | 2 + libs/eslint/platform/index.mjs | 3 +- libs/eslint/platform/no-enums.mjs | 23 ++++++ libs/eslint/platform/no-enums.spec.mjs | 71 +++++++++++++++++++ .../importers/fsecure/fsecure-fsk-types.ts | 2 + .../lastpass/access/enums/idp-provider.ts | 2 + .../access/enums/lastpass-login-type.ts | 2 + .../lastpass/access/enums/otp-method.ts | 2 + .../lastpass/access/enums/platform.ts | 2 + .../types/onepassword-1pux-importer-types.ts | 4 ++ .../protonpass/types/protonpass-json-type.ts | 2 + .../src/biometrics/biometrics-commands.ts | 2 + .../src/biometrics/biometrics-status.ts | 2 + .../key-management/src/enums/kdf-type.enum.ts | 2 + .../src/enums/encrypted-export-type.enum.ts | 2 + .../send-add-edit-dialog.component.ts | 2 + .../send-details/send-details.component.ts | 2 + .../attachments/attachments-v2.component.ts | 2 + .../add-edit-folder-dialog.component.ts | 2 + .../assign-collections.component.ts | 2 + .../src/services/vault-nudges.service.ts | 2 + 156 files changed, 445 insertions(+), 1 deletion(-) create mode 100644 libs/eslint/platform/no-enums.mjs create mode 100644 libs/eslint/platform/no-enums.spec.mjs diff --git a/apps/browser/src/autofill/enums/autofill-overlay.enum.ts b/apps/browser/src/autofill/enums/autofill-overlay.enum.ts index 9cc457f3c1a..d0b970671a8 100644 --- a/apps/browser/src/autofill/enums/autofill-overlay.enum.ts +++ b/apps/browser/src/autofill/enums/autofill-overlay.enum.ts @@ -21,6 +21,8 @@ export const RedirectFocusDirection = { Next: "next", } as const; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum InlineMenuFillType { AccountCreationUsername = 5, PasswordGeneration = 6, diff --git a/apps/browser/src/autofill/fido2/content/messaging/message.ts b/apps/browser/src/autofill/fido2/content/messaging/message.ts index 5815be9eb60..640af22ab9a 100644 --- a/apps/browser/src/autofill/fido2/content/messaging/message.ts +++ b/apps/browser/src/autofill/fido2/content/messaging/message.ts @@ -5,6 +5,8 @@ import { AssertCredentialResult, } from "@bitwarden/common/platform/abstractions/fido2/fido2-client.service.abstraction"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum MessageType { CredentialCreationRequest, CredentialCreationResponse, diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.ts index 49804abda5d..def425a51a5 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.ts @@ -26,6 +26,8 @@ import { PopOutComponent } from "../../../platform/popup/components/pop-out.comp import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SendState { Empty, NoResults, diff --git a/apps/browser/src/vault/popup/components/at-risk-carousel-dialog/at-risk-carousel-dialog.component.ts b/apps/browser/src/vault/popup/components/at-risk-carousel-dialog/at-risk-carousel-dialog.component.ts index fcca125c2b6..0133bccd25c 100644 --- a/apps/browser/src/vault/popup/components/at-risk-carousel-dialog/at-risk-carousel-dialog.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-carousel-dialog/at-risk-carousel-dialog.component.ts @@ -10,6 +10,8 @@ import { import { I18nPipe } from "@bitwarden/ui-common"; import { DarkImageSourceDirective, VaultCarouselModule } from "@bitwarden/vault"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AtRiskCarouselDialogResult { Dismissed = "dismissed", } diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.ts index 137f2a9dac3..4daffa6a9b8 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-generator-dialog/vault-generator-dialog.component.ts @@ -30,6 +30,8 @@ export interface GeneratorDialogResult { generatedValue?: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum GeneratorDialogAction { Selected = "selected", Canceled = "canceled", diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts index 64805a02394..4a8625f982c 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts @@ -55,6 +55,8 @@ import { VaultPageService } from "./vault-page.service"; import { AutofillVaultListItemsComponent, VaultListItemsContainerComponent } from "."; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum VaultState { Empty, NoResults, diff --git a/apps/desktop/native-messaging-test-runner/src/ipc.service.ts b/apps/desktop/native-messaging-test-runner/src/ipc.service.ts index b02ff1a4225..d8616e9757a 100644 --- a/apps/desktop/native-messaging-test-runner/src/ipc.service.ts +++ b/apps/desktop/native-messaging-test-runner/src/ipc.service.ts @@ -15,6 +15,8 @@ const DEFAULT_MESSAGE_TIMEOUT = 10 * 1000; // 10 seconds export type MessageHandler = (MessageCommon) => void; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum IPCConnectionState { Disconnected = "disconnected", Connecting = "connecting", diff --git a/apps/desktop/src/app/tools/send/send.component.ts b/apps/desktop/src/app/tools/send/send.component.ts index cc3007ae133..6c2c3ed53c6 100644 --- a/apps/desktop/src/app/tools/send/send.component.ts +++ b/apps/desktop/src/app/tools/send/send.component.ts @@ -25,6 +25,8 @@ import { SearchBarService } from "../../layout/search/search-bar.service"; import { AddEditComponent } from "./add-edit.component"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum Action { None = "", Add = "add", diff --git a/apps/desktop/src/autofill/models/ssh-agent-setting.ts b/apps/desktop/src/autofill/models/ssh-agent-setting.ts index f332cc93ee1..1775cf35588 100644 --- a/apps/desktop/src/autofill/models/ssh-agent-setting.ts +++ b/apps/desktop/src/autofill/models/ssh-agent-setting.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SshAgentPromptType { Always = "always", Never = "never", diff --git a/apps/desktop/src/types/biometric-message.ts b/apps/desktop/src/types/biometric-message.ts index f7a7ef0c507..7616b265005 100644 --- a/apps/desktop/src/types/biometric-message.ts +++ b/apps/desktop/src/types/biometric-message.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BiometricAction { Authenticate = "authenticate", GetStatus = "status", diff --git a/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts b/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts index 2858d7330e5..204615443ba 100644 --- a/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts +++ b/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts @@ -31,6 +31,8 @@ export interface CredentialGeneratorDialogResult { generatedValue?: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CredentialGeneratorDialogAction { Selected = "selected", Canceled = "canceled", diff --git a/apps/web/src/app/admin-console/organizations/collections/bulk-collections-dialog/bulk-collections-dialog.component.ts b/apps/web/src/app/admin-console/organizations/collections/bulk-collections-dialog/bulk-collections-dialog.component.ts index dd19c66f21e..147340e6a00 100644 --- a/apps/web/src/app/admin-console/organizations/collections/bulk-collections-dialog/bulk-collections-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/collections/bulk-collections-dialog/bulk-collections-dialog.component.ts @@ -43,6 +43,8 @@ export interface BulkCollectionsDialogParams { collections: CollectionView[]; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BulkCollectionsDialogResult { Saved = "saved", Canceled = "canceled", diff --git a/apps/web/src/app/admin-console/organizations/collections/vault.component.ts b/apps/web/src/app/admin-console/organizations/collections/vault.component.ts index 687aef9b671..96c00faceb2 100644 --- a/apps/web/src/app/admin-console/organizations/collections/vault.component.ts +++ b/apps/web/src/app/admin-console/organizations/collections/vault.component.ts @@ -132,6 +132,8 @@ import { VaultHeaderComponent } from "./vault-header/vault-header.component"; const BroadcasterSubscriptionId = "OrgVaultComponent"; const SearchTextDebounceInterval = 200; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum AddAccessStatusType { All = 0, AddAccess = 1, diff --git a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.ts b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.ts index 2a5af32ecc2..f29b4b642cb 100644 --- a/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/group-add-edit.component.ts @@ -58,6 +58,8 @@ import { AddEditGroupDetail } from "./../core/views/add-edit-group-detail"; /** * Indices for the available tabs in the dialog */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum GroupAddEditTabType { Info = 0, Members = 1, @@ -82,6 +84,8 @@ export interface GroupAddEditDialogParams { initialTab?: GroupAddEditTabType; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum GroupAddEditDialogResultType { Saved = "saved", Canceled = "canceled", diff --git a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.ts b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.ts index c90a2a657e7..8349b44c735 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.ts @@ -64,6 +64,8 @@ import { commaSeparatedEmails } from "./validators/comma-separated-emails.valida import { inputEmailLimitValidator } from "./validators/input-email-limit.validator"; import { orgSeatLimitReachedValidator } from "./validators/org-seat-limit-reached.validator"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum MemberDialogTab { Role = 0, Groups = 1, @@ -92,6 +94,8 @@ export interface EditMemberDialogParams extends CommonMemberDialogParams { export type MemberDialogParams = EditMemberDialogParams | AddMemberDialogParams; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum MemberDialogResult { Saved = "saved", Canceled = "canceled", diff --git a/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts b/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts index f08cb0b7d7c..4e78d4dc91f 100644 --- a/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/components/reset-password.component.ts @@ -50,6 +50,8 @@ export type ResetPasswordDialogData = { organizationId: string; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ResetPasswordDialogResult { Ok = "ok", } diff --git a/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts b/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts index 49f4d15a100..4d722840e23 100644 --- a/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts +++ b/apps/web/src/app/admin-console/organizations/policies/policy-edit.component.ts @@ -41,6 +41,8 @@ export type PolicyEditDialogData = { organizationId: string; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PolicyEditDialogResult { Saved = "saved", UpgradePlan = "upgrade-plan", diff --git a/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts index c23dcf2c8f2..e942eecbd37 100644 --- a/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/components/delete-organization-dialog.component.ts @@ -71,6 +71,8 @@ export interface DeleteOrganizationDialogParams { requestType: "InvalidFamiliesForEnterprise" | "RegularDelete"; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum DeleteOrganizationDialogResult { Deleted = "deleted", Canceled = "canceled", diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts index edd0bfcaada..1db1fc8a06e 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.ts @@ -26,6 +26,8 @@ import { Permission, } from "./access-selector.models"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PermissionMode { /** * No permission controls or column present. No permission values are emitted. diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.models.ts b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.models.ts index 8702c0f7a6c..884483d32b0 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.models.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.models.ts @@ -15,6 +15,8 @@ import { GroupView } from "../../../core"; /** * Permission options that replace/correspond with manage, readOnly, and hidePassword server fields. */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CollectionPermission { View = "view", ViewExceptPass = "viewExceptPass", @@ -23,6 +25,8 @@ export enum CollectionPermission { Manage = "manage", } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AccessItemType { Collection, Group, diff --git a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.ts index 37d0ebbd195..07bff3aba64 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/collection-dialog/collection-dialog.component.ts @@ -65,6 +65,8 @@ import { } from "../access-selector/access-selector.models"; import { AccessSelectorModule } from "../access-selector/access-selector.module"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CollectionDialogTabType { Info = 0, Access = 1, @@ -76,6 +78,8 @@ export enum CollectionDialogTabType { * @readonly * @enum {string} */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum ButtonType { /** Displayed when the user has reached the maximum number of collections allowed for the organization. */ Upgrade = "upgrade", @@ -103,6 +107,8 @@ export interface CollectionDialogResult { collection: CollectionResponse | CollectionView; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CollectionDialogAction { Saved = "saved", Canceled = "canceled", diff --git a/apps/web/src/app/auth/core/enums/webauthn-login-credential-prf-status.enum.ts b/apps/web/src/app/auth/core/enums/webauthn-login-credential-prf-status.enum.ts index 7dc8217fde5..3073917e57b 100644 --- a/apps/web/src/app/auth/core/enums/webauthn-login-credential-prf-status.enum.ts +++ b/apps/web/src/app/auth/core/enums/webauthn-login-credential-prf-status.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum WebauthnLoginCredentialPrfStatus { Enabled = 0, Supported = 1, diff --git a/apps/web/src/app/auth/emergency-access/enums/emergency-access-status-type.ts b/apps/web/src/app/auth/emergency-access/enums/emergency-access-status-type.ts index 94400f34e6e..16aa2546101 100644 --- a/apps/web/src/app/auth/emergency-access/enums/emergency-access-status-type.ts +++ b/apps/web/src/app/auth/emergency-access/enums/emergency-access-status-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessStatusType { Invited = 0, Accepted = 1, diff --git a/apps/web/src/app/auth/emergency-access/enums/emergency-access-type.ts b/apps/web/src/app/auth/emergency-access/enums/emergency-access-type.ts index 61a366c433e..ecb0c5a3d07 100644 --- a/apps/web/src/app/auth/emergency-access/enums/emergency-access-type.ts +++ b/apps/web/src/app/auth/emergency-access/enums/emergency-access-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessType { View = 0, Takeover = 1, diff --git a/apps/web/src/app/auth/settings/emergency-access/confirm/emergency-access-confirm.component.ts b/apps/web/src/app/auth/settings/emergency-access/confirm/emergency-access-confirm.component.ts index f3fd19a4e8b..95afc167374 100644 --- a/apps/web/src/app/auth/settings/emergency-access/confirm/emergency-access-confirm.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/confirm/emergency-access-confirm.component.ts @@ -8,6 +8,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { DialogConfig, DialogRef, DIALOG_DATA, DialogService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessConfirmDialogResult { Confirmed = "confirmed", } diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts index cf52969c244..1a6510ef011 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access-add-edit.component.ts @@ -26,6 +26,8 @@ export type EmergencyAccessAddEditDialogData = { readOnly: boolean; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessAddEditDialogResult { Saved = "saved", Canceled = "canceled", diff --git a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts index c80f82ae126..edb85dc0f1a 100644 --- a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts @@ -24,6 +24,8 @@ import { KdfType, KdfConfigService, KeyService } from "@bitwarden/key-management import { EmergencyAccessService } from "../../../emergency-access"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EmergencyAccessTakeoverResultType { Done = "done", } diff --git a/apps/web/src/app/auth/settings/webauthn-login-settings/create-credential-dialog/create-credential-dialog.component.ts b/apps/web/src/app/auth/settings/webauthn-login-settings/create-credential-dialog/create-credential-dialog.component.ts index 591fe3816dc..8e7e25896ab 100644 --- a/apps/web/src/app/auth/settings/webauthn-login-settings/create-credential-dialog/create-credential-dialog.component.ts +++ b/apps/web/src/app/auth/settings/webauthn-login-settings/create-credential-dialog/create-credential-dialog.component.ts @@ -19,6 +19,8 @@ import { PendingWebauthnLoginCredentialView } from "../../../core/views/pending- import { CreatePasskeyFailedIcon } from "./create-passkey-failed.icon"; import { CreatePasskeyIcon } from "./create-passkey.icon"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CreateCredentialDialogResult { Success, } diff --git a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts index 9f910ad9d23..63c42139648 100644 --- a/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts +++ b/apps/web/src/app/billing/accounts/trial-initiation/trial-billing-step.component.ts @@ -50,11 +50,15 @@ export interface OrganizationCreatedEvent { planDescription: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum SubscriptionCadence { Annual, Monthly, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SubscriptionProduct { PasswordManager, SecretsManager, diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts index 8cff90edd5b..49c5bb775b1 100644 --- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts @@ -74,11 +74,15 @@ type ChangePlanDialogParams = { productTierType: ProductTierType; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ChangePlanDialogResultType { Closed = "closed", Submitted = "submitted", } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PlanCardState { Selected = "selected", NotSelected = "not_selected", diff --git a/apps/web/src/app/billing/organizations/download-license.component.ts b/apps/web/src/app/billing/organizations/download-license.component.ts index fecb58a7a9d..66778aec50f 100644 --- a/apps/web/src/app/billing/organizations/download-license.component.ts +++ b/apps/web/src/app/billing/organizations/download-license.component.ts @@ -7,6 +7,8 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { DialogConfig, DIALOG_DATA, DialogRef, DialogService } from "@bitwarden/components"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum DownloadLicenseDialogResult { Cancelled = "cancelled", Downloaded = "downloaded", diff --git a/apps/web/src/app/billing/organizations/organization-subscription-selfhost.component.ts b/apps/web/src/app/billing/organizations/organization-subscription-selfhost.component.ts index e6854a5216b..2189bfa830f 100644 --- a/apps/web/src/app/billing/organizations/organization-subscription-selfhost.component.ts +++ b/apps/web/src/app/billing/organizations/organization-subscription-selfhost.component.ts @@ -27,6 +27,8 @@ import { DialogService, ToastService } from "@bitwarden/components"; import { BillingSyncKeyComponent } from "./billing-sync-key.component"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum LicenseOptions { SYNC = 0, UPLOAD = 1, diff --git a/apps/web/src/app/billing/shared/add-credit-dialog.component.ts b/apps/web/src/app/billing/shared/add-credit-dialog.component.ts index 45dab542ce8..ec6e251418b 100644 --- a/apps/web/src/app/billing/shared/add-credit-dialog.component.ts +++ b/apps/web/src/app/billing/shared/add-credit-dialog.component.ts @@ -21,6 +21,8 @@ export interface AddCreditDialogData { organizationId: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AddCreditDialogResult { Added = "added", Cancelled = "cancelled", diff --git a/apps/web/src/app/billing/shared/adjust-payment-dialog/adjust-payment-dialog.component.ts b/apps/web/src/app/billing/shared/adjust-payment-dialog/adjust-payment-dialog.component.ts index e7b7cc78250..9d32becd1bb 100644 --- a/apps/web/src/app/billing/shared/adjust-payment-dialog/adjust-payment-dialog.component.ts +++ b/apps/web/src/app/billing/shared/adjust-payment-dialog/adjust-payment-dialog.component.ts @@ -30,6 +30,8 @@ export interface AdjustPaymentDialogParams { providerId?: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AdjustPaymentDialogResultType { Closed = "closed", Submitted = "submitted", diff --git a/apps/web/src/app/billing/shared/adjust-storage-dialog/adjust-storage-dialog.component.ts b/apps/web/src/app/billing/shared/adjust-storage-dialog/adjust-storage-dialog.component.ts index 3acba414df4..6cd17218f02 100644 --- a/apps/web/src/app/billing/shared/adjust-storage-dialog/adjust-storage-dialog.component.ts +++ b/apps/web/src/app/billing/shared/adjust-storage-dialog/adjust-storage-dialog.component.ts @@ -22,6 +22,8 @@ export interface AdjustStorageDialogParams { organizationId?: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AdjustStorageDialogResultType { Submitted = "submitted", Closed = "closed", diff --git a/apps/web/src/app/billing/shared/offboarding-survey.component.ts b/apps/web/src/app/billing/shared/offboarding-survey.component.ts index cecbc302f40..62213c1fe94 100644 --- a/apps/web/src/app/billing/shared/offboarding-survey.component.ts +++ b/apps/web/src/app/billing/shared/offboarding-survey.component.ts @@ -25,6 +25,8 @@ type OrganizationOffboardingParams = { export type OffboardingSurveyDialogParams = UserOffboardingParams | OrganizationOffboardingParams; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OffboardingSurveyDialogResultType { Closed = "closed", Submitted = "submitted", diff --git a/apps/web/src/app/billing/shared/update-license-types.ts b/apps/web/src/app/billing/shared/update-license-types.ts index 8f939ac62a9..8ba13541ba8 100644 --- a/apps/web/src/app/billing/shared/update-license-types.ts +++ b/apps/web/src/app/billing/shared/update-license-types.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum UpdateLicenseDialogResult { Updated = "updated", Cancelled = "cancelled", diff --git a/apps/web/src/app/dirt/reports/reports.ts b/apps/web/src/app/dirt/reports/reports.ts index 500ae23e5cf..c47928af1e9 100644 --- a/apps/web/src/app/dirt/reports/reports.ts +++ b/apps/web/src/app/dirt/reports/reports.ts @@ -7,6 +7,8 @@ import { ReportUnsecuredWebsites } from "./icons/report-unsecured-websites.icon" import { ReportWeakPasswords } from "./icons/report-weak-passwords.icon"; import { ReportEntry } from "./shared"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ReportType { ExposedPasswords = "exposedPasswords", ReusedPasswords = "reusedPasswords", diff --git a/apps/web/src/app/dirt/reports/shared/models/report-variant.ts b/apps/web/src/app/dirt/reports/shared/models/report-variant.ts index 3beba65f7d9..48b213f4cf6 100644 --- a/apps/web/src/app/dirt/reports/shared/models/report-variant.ts +++ b/apps/web/src/app/dirt/reports/shared/models/report-variant.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ReportVariant { Enabled = "Enabled", RequiresPremium = "RequiresPremium", diff --git a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts index 460b8d58d63..10c35f861b9 100644 --- a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts +++ b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts @@ -95,6 +95,8 @@ export interface VaultItemDialogParams { restore?: (c: CipherView) => Promise; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum VaultItemDialogResult { /** * A cipher was saved (created or updated). diff --git a/apps/web/src/app/vault/components/web-generator-dialog/web-generator-dialog.component.ts b/apps/web/src/app/vault/components/web-generator-dialog/web-generator-dialog.component.ts index 2d0aa0231f1..e20efa9dbb8 100644 --- a/apps/web/src/app/vault/components/web-generator-dialog/web-generator-dialog.component.ts +++ b/apps/web/src/app/vault/components/web-generator-dialog/web-generator-dialog.component.ts @@ -26,6 +26,8 @@ export interface WebVaultGeneratorDialogResult { generatedValue?: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum WebVaultGeneratorDialogAction { Selected = "selected", Canceled = "canceled", diff --git a/apps/web/src/app/vault/individual-vault/add-edit-v2.component.ts b/apps/web/src/app/vault/individual-vault/add-edit-v2.component.ts index 5dcbf0d4e78..621e0ec88c5 100644 --- a/apps/web/src/app/vault/individual-vault/add-edit-v2.component.ts +++ b/apps/web/src/app/vault/individual-vault/add-edit-v2.component.ts @@ -35,6 +35,8 @@ import { WebCipherFormGenerationService } from "../services/web-cipher-form-gene /** * The result of the AddEditCipherDialogV2 component. */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AddEditCipherDialogResult { Edited = "edited", Added = "added", diff --git a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts index f8084b03e33..1650b0f371f 100644 --- a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts +++ b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts @@ -29,6 +29,8 @@ export interface BulkDeleteDialogParams { unassignedCiphers?: string[]; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BulkDeleteDialogResult { Deleted = "deleted", Canceled = "canceled", diff --git a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-move-dialog/bulk-move-dialog.component.ts b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-move-dialog/bulk-move-dialog.component.ts index 8f0827e4b51..d287c430d49 100644 --- a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-move-dialog/bulk-move-dialog.component.ts +++ b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-move-dialog/bulk-move-dialog.component.ts @@ -23,6 +23,8 @@ export interface BulkMoveDialogParams { cipherIds?: string[]; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BulkMoveDialogResult { Moved = "moved", Canceled = "canceled", diff --git a/apps/web/src/app/vault/individual-vault/folder-add-edit.component.ts b/apps/web/src/app/vault/individual-vault/folder-add-edit.component.ts index ad6cbfad43d..6a3c5663d93 100644 --- a/apps/web/src/app/vault/individual-vault/folder-add-edit.component.ts +++ b/apps/web/src/app/vault/individual-vault/folder-add-edit.component.ts @@ -113,6 +113,8 @@ export interface FolderAddEditDialogParams { folderId: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum FolderAddEditDialogResult { Deleted = "deleted", Canceled = "canceled", diff --git a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts index 1fa5ae1ad8b..ca16541f88f 100644 --- a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts +++ b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts @@ -17,6 +17,8 @@ import { UserId } from "@bitwarden/common/types/guid"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { PBKDF2KdfConfig, KdfConfigService, KdfType } from "@bitwarden/key-management"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum VisibleVaultBanner { KDFSettings = "kdf-settings", OutdatedBrowser = "outdated-browser", diff --git a/apps/web/src/app/vault/individual-vault/vault-filter/shared/models/vault-filter-section.type.ts b/apps/web/src/app/vault/individual-vault/vault-filter/shared/models/vault-filter-section.type.ts index 0f949e17146..7566dbdc507 100644 --- a/apps/web/src/app/vault/individual-vault/vault-filter/shared/models/vault-filter-section.type.ts +++ b/apps/web/src/app/vault/individual-vault/vault-filter/shared/models/vault-filter-section.type.ts @@ -15,6 +15,8 @@ export type VaultFilterType = | FolderFilter | CollectionFilter; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum VaultFilterLabel { OrganizationFilter = "organizationFilter", TypeFilter = "typeFilter", diff --git a/apps/web/src/app/vault/individual-vault/view.component.ts b/apps/web/src/app/vault/individual-vault/view.component.ts index e7b06cbb8d6..f52a4da3ffb 100644 --- a/apps/web/src/app/vault/individual-vault/view.component.ts +++ b/apps/web/src/app/vault/individual-vault/view.component.ts @@ -54,6 +54,8 @@ export interface ViewCipherDialogParams { disableEdit?: boolean; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ViewCipherDialogResult { Edited = "edited", Deleted = "deleted", diff --git a/apps/web/src/app/vault/services/browser-extension-prompt.service.ts b/apps/web/src/app/vault/services/browser-extension-prompt.service.ts index 5617d4aef75..f928404a2a9 100644 --- a/apps/web/src/app/vault/services/browser-extension-prompt.service.ts +++ b/apps/web/src/app/vault/services/browser-extension-prompt.service.ts @@ -7,6 +7,8 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { Utils } from "@bitwarden/common/platform/misc/utils"; import { VaultMessages } from "@bitwarden/common/vault/enums/vault-messages.enum"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BrowserPromptState { Loading = "loading", Error = "error", diff --git a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/password-health.ts b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/password-health.ts index 723d737d5bd..b8333828693 100644 --- a/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/password-health.ts +++ b/bitwarden_license/bit-common/src/dirt/reports/risk-insights/models/password-health.ts @@ -149,6 +149,8 @@ export interface PasswordHealthReportApplicationsRequest { url: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum DrawerType { None = 0, AppAtRiskMembers = 1, diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.ts index 0213903c4d9..67f2382cf91 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/manage/dialogs/add-edit-member-dialog.component.ts @@ -25,6 +25,8 @@ export type AddEditMemberDialogParams = { }; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AddEditMemberDialogResultType { Closed = "closed", Deleted = "deleted", diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.ts index 0d1602946c7..4bb2c36ef15 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/add-existing-organization-dialog.component.ts @@ -18,6 +18,8 @@ export type AddExistingOrganizationDialogParams = { provider: Provider; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AddExistingOrganizationDialogResultType { Closed = "closed", Submitted = "submitted", diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts index d3245916ad7..d71e18cd539 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/create-client-dialog.component.ts @@ -22,6 +22,8 @@ type CreateClientDialogParams = { plans: PlanResponse[]; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CreateClientDialogResultType { Closed = "closed", Submitted = "submitted", diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-name-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-name-dialog.component.ts index bbcd5f7ed63..45abeab1f4a 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-name-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-name-dialog.component.ts @@ -23,6 +23,8 @@ type ManageClientNameDialogParams = { }; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ManageClientNameDialogResultType { Closed = "closed", Submitted = "submitted", diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts index b79c887e77e..ced48bfdbea 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-subscription-dialog.component.ts @@ -18,6 +18,8 @@ type ManageClientSubscriptionDialogParams = { provider: Provider; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ManageClientSubscriptionDialogResultType { Closed = "closed", Submitted = "submitted", diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/risk-insights.component.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/risk-insights.component.ts index ab74869bfc9..5aca124a46a 100644 --- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/risk-insights.component.ts +++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/risk-insights.component.ts @@ -37,6 +37,8 @@ import { PasswordHealthMembersURIComponent } from "./password-health-members-uri import { PasswordHealthMembersComponent } from "./password-health-members.component"; import { PasswordHealthComponent } from "./password-health.component"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum RiskInsightsTabType { AllApps = 0, CriticalApps = 1, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-dialog.component.ts index 74824de00e0..c96887cc9ac 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-dialog.component.ts @@ -11,6 +11,8 @@ import { DialogRef, DIALOG_DATA, BitValidators, ToastService } from "@bitwarden/ import { ProjectView } from "../../models/view/project.view"; import { ProjectService } from "../../projects/project.service"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OperationType { Add, Edit, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts index 88b3e5e2172..09a78e02c44 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts @@ -44,11 +44,15 @@ import { SecretService } from "../secret.service"; import { SecretDeleteDialogComponent, SecretDeleteOperation } from "./secret-delete.component"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OperationType { Add, Edit, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SecretDialogTabType { NameValuePair = 0, People = 1, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts index e1cd7a77b28..241c736fb7a 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts @@ -10,6 +10,8 @@ import { DialogRef, DIALOG_DATA, BitValidators, ToastService } from "@bitwarden/ import { ServiceAccountView } from "../../models/view/service-account.view"; import { ServiceAccountService } from "../service-account.service"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OperationType { Add, Edit, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/enums/ap-item.enum.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/enums/ap-item.enum.ts index 6d060ac255d..6b92fd7458a 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/enums/ap-item.enum.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/enums/ap-item.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ApItemEnum { User, Group, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/enums/ap-permission.enum.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/enums/ap-permission.enum.ts index eb442b0af5d..a57f9636178 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/enums/ap-permission.enum.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/enums/ap-permission.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ApPermissionEnum { CanRead = "canRead", CanReadWrite = "canReadWrite", diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/dialogs/bulk-confirmation-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/dialogs/bulk-confirmation-dialog.component.ts index a43207ed75e..935ee1c8518 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/dialogs/bulk-confirmation-dialog.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/dialogs/bulk-confirmation-dialog.component.ts @@ -15,6 +15,8 @@ export interface BulkConfirmationStatus { description: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BulkConfirmationResult { Continue, Cancel, diff --git a/eslint.config.mjs b/eslint.config.mjs index 9d93d1118c0..7928224dc00 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -73,6 +73,7 @@ export default tseslint.config( "@angular-eslint/use-lifecycle-interface": "error", "@angular-eslint/use-pipe-transform-interface": 0, "@bitwarden/platform/required-using": "error", + "@bitwarden/platform/no-enums": "error", "@typescript-eslint/explicit-member-accessibility": ["error", { accessibility: "no-public" }], "@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled "@typescript-eslint/no-floating-promises": "error", diff --git a/libs/angular/src/billing/components/add-account-credit-dialog/add-account-credit-dialog.component.ts b/libs/angular/src/billing/components/add-account-credit-dialog/add-account-credit-dialog.component.ts index 7c068c51d86..871895c2ede 100644 --- a/libs/angular/src/billing/components/add-account-credit-dialog/add-account-credit-dialog.component.ts +++ b/libs/angular/src/billing/components/add-account-credit-dialog/add-account-credit-dialog.component.ts @@ -22,6 +22,8 @@ export type AddAccountCreditDialogParams = { providerId?: string; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AddAccountCreditDialogResultType { Closed = "closed", Submitted = "submitted", diff --git a/libs/angular/src/tools/send/add-edit.component.ts b/libs/angular/src/tools/send/add-edit.component.ts index 7e6180e5849..0289664c365 100644 --- a/libs/angular/src/tools/send/add-edit.component.ts +++ b/libs/angular/src/tools/send/add-edit.component.ts @@ -36,6 +36,8 @@ import { SendService } from "@bitwarden/common/tools/send/services/send.service. import { DialogService, ToastService } from "@bitwarden/components"; // Value = hours +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum DatePreset { OneHour = 1, OneDay = 24, diff --git a/libs/auth/src/angular/input-password/input-password.component.ts b/libs/auth/src/angular/input-password/input-password.component.ts index bffb8a56b5e..dff4eafc3c2 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -36,6 +36,8 @@ import { PasswordInputResult } from "./password-input-result"; /** * Determines which form input elements will be displayed in the UI. */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum InputPasswordFlow { /** * - Input: New password diff --git a/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts index 945e6bbaaf5..3ea9416b7e2 100644 --- a/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts +++ b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts @@ -41,6 +41,8 @@ import { AnonLayoutWrapperDataService } from "../anon-layout/anon-layout-wrapper import { LoginDecryptionOptionsService } from "./login-decryption-options.service"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum State { NewUser, ExistingUserUntrustedDevice, diff --git a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts index 4c95a1eca3e..d74deb443f5 100644 --- a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts +++ b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts @@ -40,6 +40,8 @@ import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legac import { AuthRequestApiService } from "../../common/abstractions/auth-request-api.service"; import { LoginViaAuthRequestCacheService } from "../../common/services/auth-request/default-login-via-auth-request-cache.service"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum Flow { StandardAuthRequest, // when user clicks "Login with device" from /login or "Approve from your other device" from /login-initiated AdminAuthRequest, // when user clicks "Request admin approval" from /login-initiated diff --git a/libs/auth/src/angular/login/login.component.ts b/libs/auth/src/angular/login/login.component.ts index cd226cddcec..d5180f56785 100644 --- a/libs/auth/src/angular/login/login.component.ts +++ b/libs/auth/src/angular/login/login.component.ts @@ -46,6 +46,8 @@ import { LoginComponentService, PasswordPolicies } from "./login-component.servi const BroadcasterSubscriptionId = "LoginComponent"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum LoginUiState { EMAIL_ENTRY = "EmailEntry", MASTER_PASSWORD_ENTRY = "MasterPasswordEntry", diff --git a/libs/auth/src/angular/registration/registration-start/registration-start.component.ts b/libs/auth/src/angular/registration/registration-start/registration-start.component.ts index e365ff09aa2..44d1d720a8d 100644 --- a/libs/auth/src/angular/registration/registration-start/registration-start.component.ts +++ b/libs/auth/src/angular/registration/registration-start/registration-start.component.ts @@ -26,6 +26,8 @@ import { RegistrationUserAddIcon } from "../../icons"; import { RegistrationCheckEmailIcon } from "../../icons/registration-check-email.icon"; import { RegistrationEnvSelectorComponent } from "../registration-env-selector/registration-env-selector.component"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum RegistrationStartState { USER_DATA_ENTRY = "UserDataEntry", CHECK_EMAIL = "CheckEmail", diff --git a/libs/auth/src/angular/two-factor-auth/two-factor-auth-component.service.ts b/libs/auth/src/angular/two-factor-auth/two-factor-auth-component.service.ts index 2bb354a8cc3..c99722fb8e4 100644 --- a/libs/auth/src/angular/two-factor-auth/two-factor-auth-component.service.ts +++ b/libs/auth/src/angular/two-factor-auth/two-factor-auth-component.service.ts @@ -1,10 +1,14 @@ import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum LegacyKeyMigrationAction { PREVENT_LOGIN_AND_SHOW_REQUIRE_MIGRATION_WARNING, NAVIGATE_TO_MIGRATION_COMPONENT, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum DuoLaunchAction { DIRECT_LAUNCH, SINGLE_ACTION_POPOUT, diff --git a/libs/auth/src/angular/user-verification/active-client-verification-option.enum.ts b/libs/auth/src/angular/user-verification/active-client-verification-option.enum.ts index bceccc7f965..ef2bd1855c6 100644 --- a/libs/auth/src/angular/user-verification/active-client-verification-option.enum.ts +++ b/libs/auth/src/angular/user-verification/active-client-verification-option.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ActiveClientVerificationOption { MasterPassword = "masterPassword", Pin = "pin", diff --git a/libs/auth/src/angular/validators/compare-inputs.validator.ts b/libs/auth/src/angular/validators/compare-inputs.validator.ts index 24568ade0e3..79d547859a4 100644 --- a/libs/auth/src/angular/validators/compare-inputs.validator.ts +++ b/libs/auth/src/angular/validators/compare-inputs.validator.ts @@ -1,5 +1,7 @@ import { AbstractControl, FormGroup, ValidationErrors, ValidatorFn } from "@angular/forms"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ValidationGoal { InputsShouldMatch, InputsShouldNotMatch, diff --git a/libs/common/src/admin-console/enums/organization-api-key-type.enum.ts b/libs/common/src/admin-console/enums/organization-api-key-type.enum.ts index 44ba7f8391d..bb98ea8718b 100644 --- a/libs/common/src/admin-console/enums/organization-api-key-type.enum.ts +++ b/libs/common/src/admin-console/enums/organization-api-key-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OrganizationApiKeyType { Default = 0, BillingSync = 1, diff --git a/libs/common/src/admin-console/enums/organization-connection-type.enum.ts b/libs/common/src/admin-console/enums/organization-connection-type.enum.ts index d2f9700a6a0..3cd11a29496 100644 --- a/libs/common/src/admin-console/enums/organization-connection-type.enum.ts +++ b/libs/common/src/admin-console/enums/organization-connection-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OrganizationConnectionType { CloudBillingSync = 1, Scim = 2, diff --git a/libs/common/src/admin-console/enums/organization-user-status-type.enum.ts b/libs/common/src/admin-console/enums/organization-user-status-type.enum.ts index f5fa0e25c91..df9ccc8b430 100644 --- a/libs/common/src/admin-console/enums/organization-user-status-type.enum.ts +++ b/libs/common/src/admin-console/enums/organization-user-status-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OrganizationUserStatusType { Invited = 0, Accepted = 1, diff --git a/libs/common/src/admin-console/enums/organization-user-type.enum.ts b/libs/common/src/admin-console/enums/organization-user-type.enum.ts index da50bfbdc20..098374becb4 100644 --- a/libs/common/src/admin-console/enums/organization-user-type.enum.ts +++ b/libs/common/src/admin-console/enums/organization-user-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OrganizationUserType { Owner = 0, Admin = 1, diff --git a/libs/common/src/admin-console/enums/policy-type.enum.ts b/libs/common/src/admin-console/enums/policy-type.enum.ts index 336b834ca56..42ab798eabf 100644 --- a/libs/common/src/admin-console/enums/policy-type.enum.ts +++ b/libs/common/src/admin-console/enums/policy-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PolicyType { TwoFactorAuthentication = 0, // Requires users to have 2fa enabled MasterPassword = 1, // Sets minimum requirements for master password complexity diff --git a/libs/common/src/admin-console/enums/provider-status-type.enum.ts b/libs/common/src/admin-console/enums/provider-status-type.enum.ts index 8da60af0eb3..32b730510e0 100644 --- a/libs/common/src/admin-console/enums/provider-status-type.enum.ts +++ b/libs/common/src/admin-console/enums/provider-status-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ProviderStatusType { Pending = 0, Created = 1, diff --git a/libs/common/src/admin-console/enums/provider-type.enum.ts b/libs/common/src/admin-console/enums/provider-type.enum.ts index eb48e362e7d..dbb60fb3638 100644 --- a/libs/common/src/admin-console/enums/provider-type.enum.ts +++ b/libs/common/src/admin-console/enums/provider-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ProviderType { Msp = 0, Reseller = 1, diff --git a/libs/common/src/admin-console/enums/provider-user-status-type.enum.ts b/libs/common/src/admin-console/enums/provider-user-status-type.enum.ts index 38d6c2e4961..253128aa25f 100644 --- a/libs/common/src/admin-console/enums/provider-user-status-type.enum.ts +++ b/libs/common/src/admin-console/enums/provider-user-status-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ProviderUserStatusType { Invited = 0, Accepted = 1, diff --git a/libs/common/src/admin-console/enums/provider-user-type.enum.ts b/libs/common/src/admin-console/enums/provider-user-type.enum.ts index 00490adcfca..d20755c3196 100644 --- a/libs/common/src/admin-console/enums/provider-user-type.enum.ts +++ b/libs/common/src/admin-console/enums/provider-user-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ProviderUserType { ProviderAdmin = 0, ServiceUser = 1, diff --git a/libs/common/src/admin-console/enums/scim-provider-type.enum.ts b/libs/common/src/admin-console/enums/scim-provider-type.enum.ts index 43c518fdfbf..cd33a1cf891 100644 --- a/libs/common/src/admin-console/enums/scim-provider-type.enum.ts +++ b/libs/common/src/admin-console/enums/scim-provider-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ScimProviderType { Default = 0, AzureAd = 1, diff --git a/libs/common/src/auth/enums/auth-request-type.ts b/libs/common/src/auth/enums/auth-request-type.ts index 31db2467861..d23fec03205 100644 --- a/libs/common/src/auth/enums/auth-request-type.ts +++ b/libs/common/src/auth/enums/auth-request-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AuthRequestType { AuthenticateAndUnlock = 0, Unlock = 1, diff --git a/libs/common/src/auth/enums/authentication-status.ts b/libs/common/src/auth/enums/authentication-status.ts index 17b4f1f21e8..6a6f9467ae7 100644 --- a/libs/common/src/auth/enums/authentication-status.ts +++ b/libs/common/src/auth/enums/authentication-status.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AuthenticationStatus { LoggedOut = 0, Locked = 1, diff --git a/libs/common/src/auth/enums/authentication-type.ts b/libs/common/src/auth/enums/authentication-type.ts index 35b50e6400a..13a3d70ddda 100644 --- a/libs/common/src/auth/enums/authentication-type.ts +++ b/libs/common/src/auth/enums/authentication-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AuthenticationType { Password = 0, Sso = 1, diff --git a/libs/common/src/auth/enums/sso.ts b/libs/common/src/auth/enums/sso.ts index 0c86a27151f..1e5766c7afd 100644 --- a/libs/common/src/auth/enums/sso.ts +++ b/libs/common/src/auth/enums/sso.ts @@ -1,25 +1,35 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SsoType { None = 0, OpenIdConnect = 1, Saml2 = 2, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum MemberDecryptionType { MasterPassword = 0, KeyConnector = 1, TrustedDeviceEncryption = 2, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OpenIdConnectRedirectBehavior { RedirectGet = 0, FormPost = 1, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum Saml2BindingType { HttpRedirect = 1, HttpPost = 2, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum Saml2NameIdFormat { NotConfigured = 0, Unspecified = 1, @@ -32,6 +42,8 @@ export enum Saml2NameIdFormat { Transient = 8, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum Saml2SigningBehavior { IfIdpWantAuthnRequestsSigned = 0, Always = 1, diff --git a/libs/common/src/auth/enums/two-factor-provider-type.ts b/libs/common/src/auth/enums/two-factor-provider-type.ts index b3308b6c12f..9be22bf90c8 100644 --- a/libs/common/src/auth/enums/two-factor-provider-type.ts +++ b/libs/common/src/auth/enums/two-factor-provider-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum TwoFactorProviderType { Authenticator = 0, Email = 1, diff --git a/libs/common/src/auth/enums/verification-type.ts b/libs/common/src/auth/enums/verification-type.ts index c1991162f91..f0ad4c0d19c 100644 --- a/libs/common/src/auth/enums/verification-type.ts +++ b/libs/common/src/auth/enums/verification-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum VerificationType { MasterPassword = 0, OTP = 1, diff --git a/libs/common/src/auth/models/domain/force-set-password-reason.ts b/libs/common/src/auth/models/domain/force-set-password-reason.ts index 56d52860443..68392125281 100644 --- a/libs/common/src/auth/models/domain/force-set-password-reason.ts +++ b/libs/common/src/auth/models/domain/force-set-password-reason.ts @@ -2,6 +2,8 @@ * This enum is used to determine if a user should be forced to initially set or reset their password * on login (server flag) or unlock via MP (client evaluation). */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ForceSetPasswordReason { /** * A password reset should not be forced. diff --git a/libs/common/src/auth/services/token.service.ts b/libs/common/src/auth/services/token.service.ts index c27afa6805a..61c00f69215 100644 --- a/libs/common/src/auth/services/token.service.ts +++ b/libs/common/src/auth/services/token.service.ts @@ -43,6 +43,8 @@ import { SECURITY_STAMP_MEMORY, } from "./token.state"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum TokenStorageLocation { Disk = "disk", SecureStorage = "secureStorage", diff --git a/libs/common/src/billing/enums/bitwarden-product-type.enum.ts b/libs/common/src/billing/enums/bitwarden-product-type.enum.ts index 76b0899fd9c..4389d283c00 100644 --- a/libs/common/src/billing/enums/bitwarden-product-type.enum.ts +++ b/libs/common/src/billing/enums/bitwarden-product-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BitwardenProductType { PasswordManager = 0, SecretsManager = 1, diff --git a/libs/common/src/billing/enums/payment-method-type.enum.ts b/libs/common/src/billing/enums/payment-method-type.enum.ts index 9b29263175c..6ea98fdc5ec 100644 --- a/libs/common/src/billing/enums/payment-method-type.enum.ts +++ b/libs/common/src/billing/enums/payment-method-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PaymentMethodType { Card = 0, BankAccount = 1, diff --git a/libs/common/src/billing/enums/plan-interval.enum.ts b/libs/common/src/billing/enums/plan-interval.enum.ts index 546336748cd..c048160310b 100644 --- a/libs/common/src/billing/enums/plan-interval.enum.ts +++ b/libs/common/src/billing/enums/plan-interval.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PlanInterval { Monthly = 0, Annually = 1, diff --git a/libs/common/src/billing/enums/plan-sponsorship-type.enum.ts b/libs/common/src/billing/enums/plan-sponsorship-type.enum.ts index 3b4c00467c2..845b698f509 100644 --- a/libs/common/src/billing/enums/plan-sponsorship-type.enum.ts +++ b/libs/common/src/billing/enums/plan-sponsorship-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PlanSponsorshipType { FamiliesForEnterprise = 0, } diff --git a/libs/common/src/billing/enums/plan-type.enum.ts b/libs/common/src/billing/enums/plan-type.enum.ts index c8977703454..5c356ce42fe 100644 --- a/libs/common/src/billing/enums/plan-type.enum.ts +++ b/libs/common/src/billing/enums/plan-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PlanType { Free = 0, FamiliesAnnually2019 = 1, diff --git a/libs/common/src/billing/enums/product-tier-type.enum.ts b/libs/common/src/billing/enums/product-tier-type.enum.ts index fadf57ccdc5..e94243de588 100644 --- a/libs/common/src/billing/enums/product-tier-type.enum.ts +++ b/libs/common/src/billing/enums/product-tier-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ProductTierType { Free = 0, Families = 1, diff --git a/libs/common/src/billing/enums/product-type.enum.ts b/libs/common/src/billing/enums/product-type.enum.ts index 3072ad0f96a..0c11eb92c79 100644 --- a/libs/common/src/billing/enums/product-type.enum.ts +++ b/libs/common/src/billing/enums/product-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ProductType { PasswordManager = 0, SecretsManager = 1, diff --git a/libs/common/src/billing/enums/transaction-type.enum.ts b/libs/common/src/billing/enums/transaction-type.enum.ts index 34731a2ec33..d4c48253a39 100644 --- a/libs/common/src/billing/enums/transaction-type.enum.ts +++ b/libs/common/src/billing/enums/transaction-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum TransactionType { Charge = 0, Credit = 1, diff --git a/libs/common/src/enums/client-type.enum.ts b/libs/common/src/enums/client-type.enum.ts index 54653f74462..25e9d6f3371 100644 --- a/libs/common/src/enums/client-type.enum.ts +++ b/libs/common/src/enums/client-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ClientType { Web = "web", Browser = "browser", diff --git a/libs/common/src/enums/device-type.enum.ts b/libs/common/src/enums/device-type.enum.ts index ff6329b9ac4..d5628536ff7 100644 --- a/libs/common/src/enums/device-type.enum.ts +++ b/libs/common/src/enums/device-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum DeviceType { Android = 0, iOS = 1, diff --git a/libs/common/src/enums/event-system-user.enum.ts b/libs/common/src/enums/event-system-user.enum.ts index e2d43a4f113..f4abbb1e3e9 100644 --- a/libs/common/src/enums/event-system-user.enum.ts +++ b/libs/common/src/enums/event-system-user.enum.ts @@ -1,4 +1,6 @@ // Note: the enum key is used to describe the EventSystemUser in the UI. Be careful about changing it. +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EventSystemUser { SCIM = 1, DomainVerification = 2, diff --git a/libs/common/src/enums/event-type.enum.ts b/libs/common/src/enums/event-type.enum.ts index 51b324bb434..9efe49b1b0f 100644 --- a/libs/common/src/enums/event-type.enum.ts +++ b/libs/common/src/enums/event-type.enum.ts @@ -1,4 +1,6 @@ // Increment by 100 for each new set of events +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EventType { User_LoggedIn = 1000, User_ChangedPassword = 1001, diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index a7679a6248a..ddc75eb0d66 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -7,6 +7,8 @@ import { ServerConfig } from "../platform/abstractions/config/server-config"; * * Flags should be grouped by team to have visibility of ownership and cleanup. */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum FeatureFlag { /* Admin Console Team */ VerifiedSsoDomainEndpoint = "pm-12337-refactor-sso-details-endpoint", diff --git a/libs/common/src/enums/http-status-code.enum.ts b/libs/common/src/enums/http-status-code.enum.ts index 94226c82552..d2dba5d8d4c 100644 --- a/libs/common/src/enums/http-status-code.enum.ts +++ b/libs/common/src/enums/http-status-code.enum.ts @@ -4,6 +4,8 @@ * @see {@link https://en.wikipedia.org/wiki/List_of_HTTP_status_codes} * src: https://gist.github.com/RWOverdijk/6cef816cfdf5722228e01cc05fd4b094 */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum HttpStatusCode { /** * The server has received the request headers and the client should proceed to send the request body diff --git a/libs/common/src/enums/integration-type.enum.ts b/libs/common/src/enums/integration-type.enum.ts index 42c385fe715..ac8bb9c6afa 100644 --- a/libs/common/src/enums/integration-type.enum.ts +++ b/libs/common/src/enums/integration-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum IntegrationType { Integration = "integration", SDK = "sdk", diff --git a/libs/common/src/enums/native-messaging-version.enum.ts b/libs/common/src/enums/native-messaging-version.enum.ts index f7cf411a40a..f83ec8f4b25 100644 --- a/libs/common/src/enums/native-messaging-version.enum.ts +++ b/libs/common/src/enums/native-messaging-version.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum NativeMessagingVersion { One = 1, // Original implementation Latest = One, diff --git a/libs/common/src/enums/notification-type.enum.ts b/libs/common/src/enums/notification-type.enum.ts index 0e4d0bfee3d..6d731253ce3 100644 --- a/libs/common/src/enums/notification-type.enum.ts +++ b/libs/common/src/enums/notification-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum NotificationType { SyncCipherUpdate = 0, SyncCipherCreate = 1, diff --git a/libs/common/src/enums/push-technology.enum.ts b/libs/common/src/enums/push-technology.enum.ts index 9452c144bb7..1bc4e62cc9d 100644 --- a/libs/common/src/enums/push-technology.enum.ts +++ b/libs/common/src/enums/push-technology.enum.ts @@ -1,6 +1,8 @@ /** * The preferred push technology of the server. */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum PushTechnology { /** * Indicates that we should use SignalR over web sockets to receive push notifications from the server. diff --git a/libs/common/src/key-management/vault-timeout/enums/vault-timeout-action.enum.ts b/libs/common/src/key-management/vault-timeout/enums/vault-timeout-action.enum.ts index 239a7490191..9e70b7ebb12 100644 --- a/libs/common/src/key-management/vault-timeout/enums/vault-timeout-action.enum.ts +++ b/libs/common/src/key-management/vault-timeout/enums/vault-timeout-action.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum VaultTimeoutAction { Lock = "lock", LogOut = "logOut", diff --git a/libs/common/src/platform/abstractions/environment.service.ts b/libs/common/src/platform/abstractions/environment.service.ts index 4a10f856893..b8931656848 100644 --- a/libs/common/src/platform/abstractions/environment.service.ts +++ b/libs/common/src/platform/abstractions/environment.service.ts @@ -17,6 +17,8 @@ export type Urls = { /** * A subset of available regions, additional regions can be loaded through configuration. */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum Region { US = "US", EU = "EU", diff --git a/libs/common/src/platform/abstractions/fido2/fido2-authenticator.service.abstraction.ts b/libs/common/src/platform/abstractions/fido2/fido2-authenticator.service.abstraction.ts index e9e68ca92c3..15655393362 100644 --- a/libs/common/src/platform/abstractions/fido2/fido2-authenticator.service.abstraction.ts +++ b/libs/common/src/platform/abstractions/fido2/fido2-authenticator.service.abstraction.ts @@ -46,11 +46,15 @@ export abstract class Fido2AuthenticatorService { silentCredentialDiscovery: (rpId: string) => Promise; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum Fido2AlgorithmIdentifier { ES256 = -7, RS256 = -257, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum Fido2AuthenticatorErrorCode { Unknown = "UnknownError", NotSupported = "NotSupportedError", diff --git a/libs/common/src/platform/enums/encryption-type.enum.ts b/libs/common/src/platform/enums/encryption-type.enum.ts index fd484dc2fdf..7f4b5048a45 100644 --- a/libs/common/src/platform/enums/encryption-type.enum.ts +++ b/libs/common/src/platform/enums/encryption-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EncryptionType { AesCbc256_B64 = 0, // Type 1 was the unused and removed AesCbc128_HmacSha256_B64 diff --git a/libs/common/src/platform/enums/file-upload-type.enum.ts b/libs/common/src/platform/enums/file-upload-type.enum.ts index 4cf654fd0ff..a94797b9ef3 100644 --- a/libs/common/src/platform/enums/file-upload-type.enum.ts +++ b/libs/common/src/platform/enums/file-upload-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum FileUploadType { Direct = 0, Azure = 1, diff --git a/libs/common/src/platform/enums/hash-purpose.enum.ts b/libs/common/src/platform/enums/hash-purpose.enum.ts index 887931b9edd..4b61db914a1 100644 --- a/libs/common/src/platform/enums/hash-purpose.enum.ts +++ b/libs/common/src/platform/enums/hash-purpose.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum HashPurpose { ServerAuthorization = 1, LocalAuthorization = 2, diff --git a/libs/common/src/platform/enums/html-storage-location.enum.ts b/libs/common/src/platform/enums/html-storage-location.enum.ts index 19c84fe88c7..1d018a72869 100644 --- a/libs/common/src/platform/enums/html-storage-location.enum.ts +++ b/libs/common/src/platform/enums/html-storage-location.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum HtmlStorageLocation { Local = "local", Memory = "memory", diff --git a/libs/common/src/platform/enums/key-suffix-options.enum.ts b/libs/common/src/platform/enums/key-suffix-options.enum.ts index 98fa215be6a..7cc412f563b 100644 --- a/libs/common/src/platform/enums/key-suffix-options.enum.ts +++ b/libs/common/src/platform/enums/key-suffix-options.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum KeySuffixOptions { Auto = "auto", Pin = "pin", diff --git a/libs/common/src/platform/enums/log-level-type.enum.ts b/libs/common/src/platform/enums/log-level-type.enum.ts index 709871dd5e9..b5f84467d6e 100644 --- a/libs/common/src/platform/enums/log-level-type.enum.ts +++ b/libs/common/src/platform/enums/log-level-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum LogLevelType { Debug, Info, diff --git a/libs/common/src/platform/enums/storage-location.enum.ts b/libs/common/src/platform/enums/storage-location.enum.ts index 46d50d1d38d..9f6e22babec 100644 --- a/libs/common/src/platform/enums/storage-location.enum.ts +++ b/libs/common/src/platform/enums/storage-location.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum StorageLocation { Both = "both", Disk = "disk", diff --git a/libs/common/src/platform/enums/theme-type.enum.ts b/libs/common/src/platform/enums/theme-type.enum.ts index d1767c4990a..c0f9aa2d52f 100644 --- a/libs/common/src/platform/enums/theme-type.enum.ts +++ b/libs/common/src/platform/enums/theme-type.enum.ts @@ -1,6 +1,8 @@ /** * @deprecated prefer the `ThemeTypes` constants and `Theme` type over unsafe enum types **/ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ThemeType { System = "system", Light = "light", diff --git a/libs/common/src/platform/services/cryptography/initializer-key.ts b/libs/common/src/platform/services/cryptography/initializer-key.ts index 88e36d90515..59287a62c46 100644 --- a/libs/common/src/platform/services/cryptography/initializer-key.ts +++ b/libs/common/src/platform/services/cryptography/initializer-key.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum InitializerKey { Cipher = 0, CipherView = 1, diff --git a/libs/common/src/state-migrations/migrations/28-move-provider-state-to-state-provider.ts b/libs/common/src/state-migrations/migrations/28-move-provider-state-to-state-provider.ts index 96f0a9acd5d..5ae943438d2 100644 --- a/libs/common/src/state-migrations/migrations/28-move-provider-state-to-state-provider.ts +++ b/libs/common/src/state-migrations/migrations/28-move-provider-state-to-state-provider.ts @@ -5,6 +5,8 @@ import { Jsonify } from "type-fest"; import { KeyDefinitionLike, MigrationHelper } from "../migration-helper"; import { Migrator } from "../migrator"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum ProviderUserStatusType { Invited = 0, Accepted = 1, @@ -12,6 +14,8 @@ enum ProviderUserStatusType { Revoked = -1, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum ProviderUserType { ProviderAdmin = 0, ServiceUser = 1, diff --git a/libs/common/src/state-migrations/migrations/30-move-policy-state-to-state-provider.ts b/libs/common/src/state-migrations/migrations/30-move-policy-state-to-state-provider.ts index 0b4c95cb55c..f188bc0a33e 100644 --- a/libs/common/src/state-migrations/migrations/30-move-policy-state-to-state-provider.ts +++ b/libs/common/src/state-migrations/migrations/30-move-policy-state-to-state-provider.ts @@ -3,6 +3,8 @@ import { KeyDefinitionLike, MigrationHelper } from "../migration-helper"; import { Migrator } from "../migrator"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum PolicyType { TwoFactorAuthentication = 0, // Requires users to have 2fa enabled MasterPassword = 1, // Sets minimum requirements for master password complexity diff --git a/libs/common/src/state-migrations/migrations/40-move-organization-state-to-state-provider.ts b/libs/common/src/state-migrations/migrations/40-move-organization-state-to-state-provider.ts index 862fe33bd4e..b23b712aefe 100644 --- a/libs/common/src/state-migrations/migrations/40-move-organization-state-to-state-provider.ts +++ b/libs/common/src/state-migrations/migrations/40-move-organization-state-to-state-provider.ts @@ -7,6 +7,8 @@ import { Migrator } from "../migrator"; // Local declarations of `OrganizationData` and the types of it's properties. // Duplicated to remain frozen in time when migration occurs. +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum OrganizationUserStatusType { Invited = 0, Accepted = 1, @@ -14,6 +16,8 @@ enum OrganizationUserStatusType { Revoked = -1, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum OrganizationUserType { Owner = 0, Admin = 1, @@ -40,11 +44,15 @@ type PermissionsApi = { manageScim: boolean; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum ProviderType { Msp = 0, Reseller = 1, } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum ProductType { Free = 0, Families = 1, diff --git a/libs/common/src/state-migrations/migrations/54-move-encrypted-sends.ts b/libs/common/src/state-migrations/migrations/54-move-encrypted-sends.ts index 7d3a2bebbf9..489fb2258ee 100644 --- a/libs/common/src/state-migrations/migrations/54-move-encrypted-sends.ts +++ b/libs/common/src/state-migrations/migrations/54-move-encrypted-sends.ts @@ -3,6 +3,8 @@ import { KeyDefinitionLike, MigrationHelper } from "../migration-helper"; import { Migrator } from "../migrator"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SendType { Text = 0, File = 1, diff --git a/libs/common/src/state-migrations/migrations/59-move-kdf-config-to-state-provider.ts b/libs/common/src/state-migrations/migrations/59-move-kdf-config-to-state-provider.ts index 81ee193867b..a01ef42a8ff 100644 --- a/libs/common/src/state-migrations/migrations/59-move-kdf-config-to-state-provider.ts +++ b/libs/common/src/state-migrations/migrations/59-move-kdf-config-to-state-provider.ts @@ -3,6 +3,8 @@ import { KeyDefinitionLike, MigrationHelper } from "../migration-helper"; import { Migrator } from "../migrator"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum KdfType { PBKDF2_SHA256 = 0, Argon2id = 1, diff --git a/libs/common/src/state-migrations/migrations/62-migrate-vault-timeout-settings-svc-to-state-provider.ts b/libs/common/src/state-migrations/migrations/62-migrate-vault-timeout-settings-svc-to-state-provider.ts index 5874a80dc60..3557bfae083 100644 --- a/libs/common/src/state-migrations/migrations/62-migrate-vault-timeout-settings-svc-to-state-provider.ts +++ b/libs/common/src/state-migrations/migrations/62-migrate-vault-timeout-settings-svc-to-state-provider.ts @@ -57,6 +57,8 @@ const vaultTimeoutTypeRollbackRecord: Record = { onIdle: -4, }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ClientType { Web = "web", Browser = "browser", diff --git a/libs/common/src/tools/send/enums/send-type.ts b/libs/common/src/tools/send/enums/send-type.ts index 487930c90c7..5b03c71d22a 100644 --- a/libs/common/src/tools/send/enums/send-type.ts +++ b/libs/common/src/tools/send/enums/send-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SendType { Text = 0, File = 1, diff --git a/libs/common/src/vault/enums/cipher-reprompt-type.ts b/libs/common/src/vault/enums/cipher-reprompt-type.ts index 1d0a523ced0..190a9bad042 100644 --- a/libs/common/src/vault/enums/cipher-reprompt-type.ts +++ b/libs/common/src/vault/enums/cipher-reprompt-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CipherRepromptType { None = 0, Password = 1, diff --git a/libs/common/src/vault/enums/cipher-type.ts b/libs/common/src/vault/enums/cipher-type.ts index 0b7bbf1ee17..30d80cdef7e 100644 --- a/libs/common/src/vault/enums/cipher-type.ts +++ b/libs/common/src/vault/enums/cipher-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CipherType { Login = 1, SecureNote = 2, diff --git a/libs/common/src/vault/enums/field-type.enum.ts b/libs/common/src/vault/enums/field-type.enum.ts index d6deb30e691..df5016890b2 100644 --- a/libs/common/src/vault/enums/field-type.enum.ts +++ b/libs/common/src/vault/enums/field-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum FieldType { Text = 0, Hidden = 1, diff --git a/libs/common/src/vault/enums/linked-id-type.enum.ts b/libs/common/src/vault/enums/linked-id-type.enum.ts index c38ebc1c6e8..b329aecb3f4 100644 --- a/libs/common/src/vault/enums/linked-id-type.enum.ts +++ b/libs/common/src/vault/enums/linked-id-type.enum.ts @@ -1,12 +1,16 @@ export type LinkedIdType = LoginLinkedId | CardLinkedId | IdentityLinkedId; // LoginView +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum LoginLinkedId { Username = 100, Password = 101, } // CardView +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CardLinkedId { CardholderName = 300, ExpMonth = 301, @@ -17,6 +21,8 @@ export enum CardLinkedId { } // IdentityView +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum IdentityLinkedId { Title = 400, MiddleName = 401, diff --git a/libs/common/src/vault/enums/secure-note-type.enum.ts b/libs/common/src/vault/enums/secure-note-type.enum.ts index 8015236d148..4fbd05e6bd4 100644 --- a/libs/common/src/vault/enums/secure-note-type.enum.ts +++ b/libs/common/src/vault/enums/secure-note-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SecureNoteType { Generic = 0, } diff --git a/libs/common/src/vault/tasks/enums/security-task-status.enum.ts b/libs/common/src/vault/tasks/enums/security-task-status.enum.ts index 1c6e7decc20..c8c26266e66 100644 --- a/libs/common/src/vault/tasks/enums/security-task-status.enum.ts +++ b/libs/common/src/vault/tasks/enums/security-task-status.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SecurityTaskStatus { /** * Default status for newly created tasks that have not been completed. diff --git a/libs/common/src/vault/tasks/enums/security-task-type.enum.ts b/libs/common/src/vault/tasks/enums/security-task-type.enum.ts index 264cd88696b..79a2d23c8b3 100644 --- a/libs/common/src/vault/tasks/enums/security-task-type.enum.ts +++ b/libs/common/src/vault/tasks/enums/security-task-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SecurityTaskType { /** * Task to update a cipher's password that was found to be at-risk by an administrator diff --git a/libs/components/src/color-password/color-password.component.ts b/libs/components/src/color-password/color-password.component.ts index 86ccb41ba3c..2dd78e8525d 100644 --- a/libs/components/src/color-password/color-password.component.ts +++ b/libs/components/src/color-password/color-password.component.ts @@ -2,6 +2,8 @@ import { Component, computed, HostBinding, input } from "@angular/core"; import { Utils } from "@bitwarden/common/platform/misc/utils"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums enum CharacterType { Letter, Emoji, diff --git a/libs/eslint/platform/index.mjs b/libs/eslint/platform/index.mjs index 049d95e2074..c7ea3f1dd89 100644 --- a/libs/eslint/platform/index.mjs +++ b/libs/eslint/platform/index.mjs @@ -1,3 +1,4 @@ import requiredUsing from "./required-using.mjs"; +import noEnums from "./no-enums.mjs"; -export default { rules: { "required-using": requiredUsing } }; +export default { rules: { "required-using": requiredUsing, "no-enums": noEnums } }; diff --git a/libs/eslint/platform/no-enums.mjs b/libs/eslint/platform/no-enums.mjs new file mode 100644 index 00000000000..4f3039f7e34 --- /dev/null +++ b/libs/eslint/platform/no-enums.mjs @@ -0,0 +1,23 @@ +export const errorMessage = "Enums are discouraged, please use a const object instead"; + +export default { + meta: { + type: "suggestion", + docs: { + description: "Enforce using consts instead of enums", + category: "Best Practices", + recommended: false, + }, + schema: [], + }, + create(context) { + return { + TSEnumDeclaration(node) { + context.report({ + node, + message: errorMessage, + }); + }, + }; + }, +}; diff --git a/libs/eslint/platform/no-enums.spec.mjs b/libs/eslint/platform/no-enums.spec.mjs new file mode 100644 index 00000000000..5ded12d6ed3 --- /dev/null +++ b/libs/eslint/platform/no-enums.spec.mjs @@ -0,0 +1,71 @@ +import { RuleTester } from "@typescript-eslint/rule-tester"; + +import rule, { errorMessage } from "./no-enums.mjs"; + +const ruleTester = new RuleTester({ + languageOptions: { + parserOptions: { + project: [__dirname + "/../tsconfig.spec.json"], + projectService: { + allowDefaultProject: ["*.ts*"], + }, + tsconfigRootDir: __dirname + "/..", + }, + }, +}); + +ruleTester.run("no-enums", rule.default, { + valid: [ + { + name: "Using const instead of enum", + code: ` + const Status = { + Active: "active", + Inactive: "inactive", + } as const; + `, + }, + { + name: "Using const with type", + code: ` + const Status = { + Active: "active", + Inactive: "inactive", + } as const; + type Status = typeof Status[keyof typeof Status]; + `, + }, + ], + invalid: [ + { + name: "Using enum declaration", + code: ` + enum Status { + Active = "active", + Inactive = "inactive", + } + `, + errors: [ + { + message: errorMessage, + }, + ], + }, + { + name: "Using enum with numeric values", + code: ` + enum Direction { + Up = 1, + Down = 2, + Left = 3, + Right = 4, + } + `, + errors: [ + { + message: errorMessage, + }, + ], + }, + ], +}); diff --git a/libs/importer/src/importers/fsecure/fsecure-fsk-types.ts b/libs/importer/src/importers/fsecure/fsecure-fsk-types.ts index 71797a0f8cd..1235426d683 100644 --- a/libs/importer/src/importers/fsecure/fsecure-fsk-types.ts +++ b/libs/importer/src/importers/fsecure/fsecure-fsk-types.ts @@ -6,6 +6,8 @@ export interface Data { [key: string]: FskEntry; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum FskEntryTypesEnum { Login = 1, CreditCard = 2, diff --git a/libs/importer/src/importers/lastpass/access/enums/idp-provider.ts b/libs/importer/src/importers/lastpass/access/enums/idp-provider.ts index 32e74c36ee1..01c4572fcf9 100644 --- a/libs/importer/src/importers/lastpass/access/enums/idp-provider.ts +++ b/libs/importer/src/importers/lastpass/access/enums/idp-provider.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum IdpProvider { Azure = 0, OktaAuthServer = 1, diff --git a/libs/importer/src/importers/lastpass/access/enums/lastpass-login-type.ts b/libs/importer/src/importers/lastpass/access/enums/lastpass-login-type.ts index 611dd0b6dab..a3be36c790e 100644 --- a/libs/importer/src/importers/lastpass/access/enums/lastpass-login-type.ts +++ b/libs/importer/src/importers/lastpass/access/enums/lastpass-login-type.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum LastpassLoginType { MasterPassword = 0, // Not sure what Types 1 and 2 are? diff --git a/libs/importer/src/importers/lastpass/access/enums/otp-method.ts b/libs/importer/src/importers/lastpass/access/enums/otp-method.ts index 6b940486ff0..f1237160179 100644 --- a/libs/importer/src/importers/lastpass/access/enums/otp-method.ts +++ b/libs/importer/src/importers/lastpass/access/enums/otp-method.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum OtpMethod { GoogleAuth, MicrosoftAuth, diff --git a/libs/importer/src/importers/lastpass/access/enums/platform.ts b/libs/importer/src/importers/lastpass/access/enums/platform.ts index 283e0c36ce2..6870fc28c24 100644 --- a/libs/importer/src/importers/lastpass/access/enums/platform.ts +++ b/libs/importer/src/importers/lastpass/access/enums/platform.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum Platform { Desktop, Mobile, diff --git a/libs/importer/src/importers/onepassword/types/onepassword-1pux-importer-types.ts b/libs/importer/src/importers/onepassword/types/onepassword-1pux-importer-types.ts index 63a0427b2c7..d7f4dec8f95 100644 --- a/libs/importer/src/importers/onepassword/types/onepassword-1pux-importer-types.ts +++ b/libs/importer/src/importers/onepassword/types/onepassword-1pux-importer-types.ts @@ -25,6 +25,8 @@ export interface VaultAttributes { type: string; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CategoryEnum { Login = "001", CreditCard = "002", @@ -67,6 +69,8 @@ export interface Details { password?: string | null; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum LoginFieldTypeEnum { TextOrHtml = "T", EmailAddress = "E", diff --git a/libs/importer/src/importers/protonpass/types/protonpass-json-type.ts b/libs/importer/src/importers/protonpass/types/protonpass-json-type.ts index 20fa314a314..af2eb15a740 100644 --- a/libs/importer/src/importers/protonpass/types/protonpass-json-type.ts +++ b/libs/importer/src/importers/protonpass/types/protonpass-json-type.ts @@ -27,6 +27,8 @@ export type ProtonPassItem = { pinned: boolean; }; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum ProtonPassItemState { ACTIVE = 1, TRASHED = 2, diff --git a/libs/key-management/src/biometrics/biometrics-commands.ts b/libs/key-management/src/biometrics/biometrics-commands.ts index 81f0ea747e4..1ef31a31fb4 100644 --- a/libs/key-management/src/biometrics/biometrics-commands.ts +++ b/libs/key-management/src/biometrics/biometrics-commands.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BiometricsCommands { /** Perform biometric authentication for the system's user. Does not require setup, and does not return cryptographic material, only yes or no. */ AuthenticateWithBiometrics = "authenticateWithBiometrics", diff --git a/libs/key-management/src/biometrics/biometrics-status.ts b/libs/key-management/src/biometrics/biometrics-status.ts index fb46ed1c4be..e436574ff7d 100644 --- a/libs/key-management/src/biometrics/biometrics-status.ts +++ b/libs/key-management/src/biometrics/biometrics-status.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum BiometricsStatus { /** For the biometrics interface, this means that biometric unlock is available and can be used. Querying for the user specifically, this means that biometric can be used for to unlock this user */ Available, diff --git a/libs/key-management/src/enums/kdf-type.enum.ts b/libs/key-management/src/enums/kdf-type.enum.ts index 29fcd9f1f8e..4f468e63a29 100644 --- a/libs/key-management/src/enums/kdf-type.enum.ts +++ b/libs/key-management/src/enums/kdf-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum KdfType { PBKDF2_SHA256 = 0, Argon2id = 1, diff --git a/libs/tools/export/vault-export/vault-export-ui/src/enums/encrypted-export-type.enum.ts b/libs/tools/export/vault-export/vault-export-ui/src/enums/encrypted-export-type.enum.ts index 4767869f7d0..2f416e4a49a 100644 --- a/libs/tools/export/vault-export/vault-export-ui/src/enums/encrypted-export-type.enum.ts +++ b/libs/tools/export/vault-export/vault-export-ui/src/enums/encrypted-export-type.enum.ts @@ -1,3 +1,5 @@ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum EncryptedExportType { AccountEncrypted = 0, FileEncrypted = 1, diff --git a/libs/tools/send/send-ui/src/add-edit/send-add-edit-dialog.component.ts b/libs/tools/send/send-ui/src/add-edit/send-add-edit-dialog.component.ts index 5da2c6f8bed..0bb753d3f37 100644 --- a/libs/tools/send/send-ui/src/add-edit/send-add-edit-dialog.component.ts +++ b/libs/tools/send/send-ui/src/add-edit/send-add-edit-dialog.component.ts @@ -35,6 +35,8 @@ export interface SendItemDialogParams { disableForm?: boolean; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum SendItemDialogResult { /** * A Send was saved (created or updated). diff --git a/libs/tools/send/send-ui/src/send-form/components/send-details/send-details.component.ts b/libs/tools/send/send-ui/src/send-form/components/send-details/send-details.component.ts index c77c44467d8..9ca9aefb4ac 100644 --- a/libs/tools/send/send-ui/src/send-form/components/send-details/send-details.component.ts +++ b/libs/tools/send/send-ui/src/send-form/components/send-details/send-details.component.ts @@ -30,6 +30,8 @@ import { SendFileDetailsComponent } from "./send-file-details.component"; import { SendTextDetailsComponent } from "./send-text-details.component"; // Value = hours +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum DatePreset { OneHour = 1, OneDay = 24, diff --git a/libs/vault/src/cipher-view/attachments/attachments-v2.component.ts b/libs/vault/src/cipher-view/attachments/attachments-v2.component.ts index 68660c4bbd9..b34d0d3a312 100644 --- a/libs/vault/src/cipher-view/attachments/attachments-v2.component.ts +++ b/libs/vault/src/cipher-view/attachments/attachments-v2.component.ts @@ -24,6 +24,8 @@ export interface AttachmentsDialogParams { /** * Enum representing the possible results of the attachment dialog. */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AttachmentDialogResult { Uploaded = "uploaded", Removed = "removed", diff --git a/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.ts b/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.ts index c8559799eec..dd3cbc4c5c9 100644 --- a/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.ts +++ b/libs/vault/src/components/add-edit-folder-dialog/add-edit-folder-dialog.component.ts @@ -34,6 +34,8 @@ import { } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum AddEditFolderDialogResult { Created = "created", Deleted = "deleted", diff --git a/libs/vault/src/components/assign-collections.component.ts b/libs/vault/src/components/assign-collections.component.ts index 45d25a037e9..6a0c45cfbe3 100644 --- a/libs/vault/src/components/assign-collections.component.ts +++ b/libs/vault/src/components/assign-collections.component.ts @@ -80,6 +80,8 @@ export interface CollectionAssignmentParams { isSingleCipherAdmin?: boolean; } +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum CollectionAssignmentResult { Saved = "saved", Canceled = "canceled", diff --git a/libs/vault/src/services/vault-nudges.service.ts b/libs/vault/src/services/vault-nudges.service.ts index be6e978eaa0..d27cd09e954 100644 --- a/libs/vault/src/services/vault-nudges.service.ts +++ b/libs/vault/src/services/vault-nudges.service.ts @@ -23,6 +23,8 @@ export type NudgeStatus = { /** * Enum to list the various nudge types, to be used by components/badges to show/hide the nudge */ +// FIXME: update to use a const object instead of a typescript enum +// eslint-disable-next-line @bitwarden/platform/no-enums export enum VaultNudgeType { /** Nudge to show when user has no items in their vault * Add future nudges here From 4c68f61d47a2fc8deb4300d9beec568c4a11d555 Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Tue, 13 May 2025 10:58:48 -0400 Subject: [PATCH 20/25] feat(CLI-SSO-Login): [Auth/PM-21116] CLI - SSO Login - Add SSO Org Identifier option (#14605) * Add --identifier option for SSO on CLI * Add option for identifier * Moved auto-submit after the setting of client arguments * Adjusted comment * Changed to pass in as SSO option * Renamed to orgSsoIdentifier for clarity * Added more changes to orgSsoIdentifier. --- apps/cli/src/auth/commands/login.command.ts | 7 +++++- apps/cli/src/program.ts | 5 +++- libs/auth/src/angular/sso/sso.component.ts | 16 ++++++------- .../sso-redirect/sso-url.service.spec.ts | 23 +++++++++++++++++++ .../services/sso-redirect/sso-url.service.ts | 6 +++++ 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/apps/cli/src/auth/commands/login.command.ts b/apps/cli/src/auth/commands/login.command.ts index 3ad71c62e66..cd5c8ef9bcd 100644 --- a/apps/cli/src/auth/commands/login.command.ts +++ b/apps/cli/src/auth/commands/login.command.ts @@ -106,6 +106,8 @@ export class LoginCommand { return Response.badRequest("client_secret is required."); } } else if (options.sso != null && this.canInteract) { + // If the optional Org SSO Identifier isn't provided, the option value is `true`. + const orgSsoIdentifier = options.sso === true ? null : options.sso; const passwordOptions: any = { type: "password", length: 64, @@ -119,7 +121,7 @@ export class LoginCommand { const codeVerifierHash = await this.cryptoFunctionService.hash(ssoCodeVerifier, "sha256"); const codeChallenge = Utils.fromBufferToUrlB64(codeVerifierHash); try { - const ssoParams = await this.openSsoPrompt(codeChallenge, state); + const ssoParams = await this.openSsoPrompt(codeChallenge, state, orgSsoIdentifier); ssoCode = ssoParams.ssoCode; orgIdentifier = ssoParams.orgIdentifier; } catch { @@ -664,6 +666,7 @@ export class LoginCommand { private async openSsoPrompt( codeChallenge: string, state: string, + orgSsoIdentifier: string, ): Promise<{ ssoCode: string; orgIdentifier: string }> { const env = await firstValueFrom(this.environmentService.environment$); @@ -712,6 +715,8 @@ export class LoginCommand { this.ssoRedirectUri, state, codeChallenge, + null, + orgSsoIdentifier, ); this.platformUtilsService.launchUri(webAppSsoUrl); }); diff --git a/apps/cli/src/program.ts b/apps/cli/src/program.ts index dca4effcdc9..d85f1b366e6 100644 --- a/apps/cli/src/program.ts +++ b/apps/cli/src/program.ts @@ -118,7 +118,10 @@ export class Program extends BaseProgram { .description("Log into a user account.") .option("--method ", "Two-step login method.") .option("--code ", "Two-step login code.") - .option("--sso", "Log in with Single-Sign On.") + .option( + "--sso [identifier]", + "Log in with Single-Sign On with optional organization identifier.", + ) .option("--apikey", "Log in with an Api Key.") .option("--passwordenv ", "Environment variable storing your password") .option( diff --git a/libs/auth/src/angular/sso/sso.component.ts b/libs/auth/src/angular/sso/sso.component.ts index a91a8ed20e9..968a05bf850 100644 --- a/libs/auth/src/angular/sso/sso.component.ts +++ b/libs/auth/src/angular/sso/sso.component.ts @@ -155,7 +155,14 @@ export class SsoComponent implements OnInit { return; } - // Detect if we have landed here but only have an SSO identifier in the URL. + // Detect if we are on the first portion of the SSO flow + // and have been sent here from another client with the info in query params. + // If so, we want to initialize the SSO flow with those values. + if (this.hasParametersFromOtherClientRedirect(qParams)) { + this.initializeFromRedirectFromOtherClient(qParams); + } + + // Detect if we have landed here with an SSO identifier in the URL. // This is used by integrations that want to "short-circuit" the login to send users // directly to their IdP to simulate IdP-initiated SSO, so we submit automatically. if (qParams.identifier != null) { @@ -165,13 +172,6 @@ export class SsoComponent implements OnInit { return; } - // Detect if we are on the first portion of the SSO flow - // and have been sent here from another client with the info in query params. - // If so, we want to initialize the SSO flow with those values. - if (this.hasParametersFromOtherClientRedirect(qParams)) { - this.initializeFromRedirectFromOtherClient(qParams); - } - // Try to determine the identifier using claimed domain or local state // persisted from the user's last login attempt. await this.initializeIdentifierFromEmailOrStorage(); diff --git a/libs/auth/src/common/services/sso-redirect/sso-url.service.spec.ts b/libs/auth/src/common/services/sso-redirect/sso-url.service.spec.ts index 074c3a1e0b1..632a2812cfe 100644 --- a/libs/auth/src/common/services/sso-redirect/sso-url.service.spec.ts +++ b/libs/auth/src/common/services/sso-redirect/sso-url.service.spec.ts @@ -92,4 +92,27 @@ describe("SsoUrlService", () => { ); expect(result).toBe(expectedUrl); }); + + it("should build CLI SSO URL with Org SSO Identifier correctly", () => { + const baseUrl = "https://web-vault.bitwarden.com"; + const clientType = ClientType.Cli; + const redirectUri = "https://localhost:1000"; + const state = "abc123"; + const codeChallenge = "xyz789"; + const email = "test@bitwarden.com"; + const orgSsoIdentifier = "test-org"; + + const expectedUrl = `${baseUrl}/#/sso?clientId=cli&redirectUri=${encodeURIComponent(redirectUri)}&state=${state}&codeChallenge=${codeChallenge}&email=${encodeURIComponent(email)}&identifier=${encodeURIComponent(orgSsoIdentifier)}`; + + const result = service.buildSsoUrl( + baseUrl, + clientType, + redirectUri, + state, + codeChallenge, + email, + orgSsoIdentifier, + ); + expect(result).toBe(expectedUrl); + }); }); diff --git a/libs/auth/src/common/services/sso-redirect/sso-url.service.ts b/libs/auth/src/common/services/sso-redirect/sso-url.service.ts index 667a27ad598..b2d6231db7c 100644 --- a/libs/auth/src/common/services/sso-redirect/sso-url.service.ts +++ b/libs/auth/src/common/services/sso-redirect/sso-url.service.ts @@ -11,6 +11,7 @@ export class SsoUrlService { * @param state A state value that will be peristed through the SSO flow * @param codeChallenge A challenge value that will be used to verify the SSO code after authentication * @param email The optional email adddress of the user initiating SSO, which will be used to look up the org SSO identifier + * @param orgSsoIdentifier The optional SSO identifier of the org that is initiating SSO * @returns The URL for redirecting users to the web app SSO component */ buildSsoUrl( @@ -20,6 +21,7 @@ export class SsoUrlService { state: string, codeChallenge: string, email?: string, + orgSsoIdentifier?: string, ): string { let url = webAppUrl + @@ -36,6 +38,10 @@ export class SsoUrlService { url += "&email=" + encodeURIComponent(email); } + if (orgSsoIdentifier) { + url += "&identifier=" + encodeURIComponent(orgSsoIdentifier); + } + return url; } } From 9a7089594efac32006eacd1e013488447f1f4214 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Tue, 13 May 2025 16:59:56 +0200 Subject: [PATCH 21/25] [PM-19878] Add core-js to cli (#14696) * Add core-js to cli * Add core-js to bit-cli --- apps/cli/package.json | 1 + bitwarden_license/bit-cli/src/bw.ts | 2 ++ package-lock.json | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/cli/package.json b/apps/cli/package.json index 82faa7d40e6..b01c96b23d1 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -71,6 +71,7 @@ "browser-hrtime": "1.1.8", "chalk": "4.1.2", "commander": "11.1.0", + "core-js": "3.40.0", "form-data": "4.0.1", "https-proxy-agent": "7.0.6", "inquirer": "8.2.6", diff --git a/bitwarden_license/bit-cli/src/bw.ts b/bitwarden_license/bit-cli/src/bw.ts index ffbc186d9e0..2e4e945b9c8 100644 --- a/bitwarden_license/bit-cli/src/bw.ts +++ b/bitwarden_license/bit-cli/src/bw.ts @@ -1,3 +1,5 @@ +import "core-js/proposals/explicit-resource-management"; + import { program } from "commander"; import { registerOssPrograms } from "@bitwarden/cli/register-oss-programs"; diff --git a/package-lock.json b/package-lock.json index 8466a4ba4c6..d1378d63ec3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -207,6 +207,7 @@ "browser-hrtime": "1.1.8", "chalk": "4.1.2", "commander": "11.1.0", + "core-js": "3.40.0", "form-data": "4.0.1", "https-proxy-agent": "7.0.6", "inquirer": "8.2.6", @@ -16960,7 +16961,6 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", "hasInstallScript": true, - "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" From 0750ff38f580e85e7ec6296e3883ac7c38676349 Mon Sep 17 00:00:00 2001 From: SmithThe4th Date: Tue, 13 May 2025 11:21:07 -0400 Subject: [PATCH 22/25] Route to vault page when user doesn't have access (#14633) --- apps/browser/src/_locales/en/messages.json | 3 +++ .../src/vault/guards/at-risk-passwords.guard.ts | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 361093b12ef..e1a3234a61f 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -5321,5 +5321,8 @@ "message": "Learn more about SSH agent", "description": "Two part message", "example": "Store your keys and connect with the SSH agent for fast, encrypted authentication. Learn more about SSH agent" + }, + "noPermissionsViewPage": { + "message": "You do not have permissions to view this page. Try logging in with a different account." } } diff --git a/apps/browser/src/vault/guards/at-risk-passwords.guard.ts b/apps/browser/src/vault/guards/at-risk-passwords.guard.ts index 6bcdddfde81..fc302dd6c36 100644 --- a/apps/browser/src/vault/guards/at-risk-passwords.guard.ts +++ b/apps/browser/src/vault/guards/at-risk-passwords.guard.ts @@ -1,6 +1,6 @@ import { inject } from "@angular/core"; -import { CanActivateFn } from "@angular/router"; -import { switchMap, tap } from "rxjs"; +import { CanActivateFn, Router } from "@angular/router"; +import { map, switchMap } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -13,18 +13,22 @@ export const canAccessAtRiskPasswords: CanActivateFn = () => { const taskService = inject(TaskService); const toastService = inject(ToastService); const i18nService = inject(I18nService); + const router = inject(Router); return accountService.activeAccount$.pipe( filterOutNullish(), switchMap((user) => taskService.tasksEnabled$(user.id)), - tap((tasksEnabled) => { + map((tasksEnabled) => { if (!tasksEnabled) { toastService.showToast({ variant: "error", title: "", - message: i18nService.t("accessDenied"), + message: i18nService.t("noPermissionsViewPage"), }); + + return router.createUrlTree(["/tabs/vault"]); } + return true; }), ); }; From 1f72dd7710a160058cd39316ac00d97cdbfe5aad Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Tue, 13 May 2025 11:30:36 -0400 Subject: [PATCH 23/25] PM-21286 add aria label to nudge settings badge (#14750) --- apps/browser/src/_locales/en/messages.json | 3 +++ .../src/tools/popup/settings/settings-v2.component.html | 3 +++ 2 files changed, 6 insertions(+) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index e1a3234a61f..dcdfe7df4d6 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -5258,6 +5258,9 @@ "secureDevicesBody": { "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." }, + "nudgeBadgeAria": { + "message": "1 notification" + }, "emptyVaultNudgeTitle": { "message": "Import existing passwords" }, diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.html b/apps/browser/src/tools/popup/settings/settings-v2.component.html index 22e2d9a28d0..8d31ccf8371 100644 --- a/apps/browser/src/tools/popup/settings/settings-v2.component.html +++ b/apps/browser/src/tools/popup/settings/settings-v2.component.html @@ -23,6 +23,7 @@ *ngIf="!isBrowserAutofillSettingOverridden && (showAutofillBadge$ | async)" bitBadge variant="notification" + [attr.aria-label]="'nudgeBadgeAria' | i18n" >1
@@ -53,6 +54,7 @@ *ngIf="!(showVaultBadge$ | async)?.hasBadgeDismissed" bitBadge variant="notification" + [attr.aria-label]="'nudgeBadgeAria' | i18n" >1 @@ -83,6 +85,7 @@ *ngIf="(downloadBitwardenNudgeStatus$ | async)?.hasBadgeDismissed === false" bitBadge variant="notification" + [attr.aria-label]="'nudgeBadgeAria' | i18n" >1 From 5fb46df3415aefced0b52f2db86c873962255448 Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Tue, 13 May 2025 16:49:06 +0100 Subject: [PATCH 24/25] [PM 21106]Remove button not responsive for admin Console Remove Sponorship (#14743) * Resolve the remove button inactive * Resolve the lint error --- .../free-bitwarden-families.component.ts | 2 +- .../settings/sponsoring-org-row.component.ts | 2 +- .../src/services/jslib-services.module.ts | 2 +- libs/common/src/abstractions/api.service.ts | 1 - ...ion-sponsorship-api.service.abstraction.ts | 5 ++++ .../organization-sponsorship-api.service.ts | 23 ++++++++++++++++++- libs/common/src/services/api.service.ts | 12 ---------- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/apps/web/src/app/billing/members/free-bitwarden-families.component.ts b/apps/web/src/app/billing/members/free-bitwarden-families.component.ts index eb6bfdf368b..b482007e30b 100644 --- a/apps/web/src/app/billing/members/free-bitwarden-families.component.ts +++ b/apps/web/src/app/billing/members/free-bitwarden-families.component.ts @@ -179,7 +179,7 @@ export class FreeBitwardenFamiliesComponent implements OnInit { return; } - await this.apiService.deleteRevokeSponsorship(this.organizationId); + await this.organizationSponsorshipApiService.deleteRevokeSponsorship(this.organizationId, true); this.toastService.showToast({ variant: "success", diff --git a/apps/web/src/app/billing/settings/sponsoring-org-row.component.ts b/apps/web/src/app/billing/settings/sponsoring-org-row.component.ts index 33e6334c577..39a7531082a 100644 --- a/apps/web/src/app/billing/settings/sponsoring-org-row.component.ts +++ b/apps/web/src/app/billing/settings/sponsoring-org-row.component.ts @@ -109,7 +109,7 @@ export class SponsoringOrgRowComponent implements OnInit { return; } - await this.apiService.deleteRevokeSponsorship(this.sponsoringOrg.id); + await this.organizationSponsorshipApiService.deleteRevokeSponsorship(this.sponsoringOrg.id); this.toastService.showToast({ variant: "success", title: null, diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 470115ae3f0..3ffca776034 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1079,7 +1079,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: OrganizationSponsorshipApiServiceAbstraction, useClass: OrganizationSponsorshipApiService, - deps: [ApiServiceAbstraction], + deps: [ApiServiceAbstraction, PlatformUtilsServiceAbstraction], }), safeProvider({ provide: OrganizationBillingApiServiceAbstraction, diff --git a/libs/common/src/abstractions/api.service.ts b/libs/common/src/abstractions/api.service.ts index 1e13a3064f4..e4453359015 100644 --- a/libs/common/src/abstractions/api.service.ts +++ b/libs/common/src/abstractions/api.service.ts @@ -475,7 +475,6 @@ export abstract class ApiService { getSponsorshipSyncStatus: ( sponsoredOrgId: string, ) => Promise; - deleteRevokeSponsorship: (sponsoringOrganizationId: string) => Promise; deleteRemoveSponsorship: (sponsoringOrgId: string) => Promise; postPreValidateSponsorshipToken: ( sponsorshipToken: string, diff --git a/libs/common/src/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction.ts b/libs/common/src/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction.ts index 7bd6aac17bd..5e69f57ca19 100644 --- a/libs/common/src/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction.ts +++ b/libs/common/src/billing/abstractions/organizations/organization-sponsorship-api.service.abstraction.ts @@ -10,4 +10,9 @@ export abstract class OrganizationSponsorshipApiServiceAbstraction { sponsoringOrgId: string, friendlyName?: string, ): Promise; + + abstract deleteRevokeSponsorship: ( + sponsoringOrganizationId: string, + isAdminInitiated?: boolean, + ) => Promise; } diff --git a/libs/common/src/billing/services/organization/organization-sponsorship-api.service.ts b/libs/common/src/billing/services/organization/organization-sponsorship-api.service.ts index 22ab3ec86ee..99440b10dec 100644 --- a/libs/common/src/billing/services/organization/organization-sponsorship-api.service.ts +++ b/libs/common/src/billing/services/organization/organization-sponsorship-api.service.ts @@ -1,12 +1,16 @@ import { ApiService } from "../../../abstractions/api.service"; import { ListResponse } from "../../../models/response/list.response"; +import { PlatformUtilsService } from "../../../platform/abstractions/platform-utils.service"; import { OrganizationSponsorshipApiServiceAbstraction } from "../../abstractions/organizations/organization-sponsorship-api.service.abstraction"; import { OrganizationSponsorshipInvitesResponse } from "../../models/response/organization-sponsorship-invites.response"; export class OrganizationSponsorshipApiService implements OrganizationSponsorshipApiServiceAbstraction { - constructor(private apiService: ApiService) {} + constructor( + private apiService: ApiService, + private platformUtilsService: PlatformUtilsService, + ) {} async getOrganizationSponsorship( sponsoredOrgId: string, ): Promise> { @@ -33,4 +37,21 @@ export class OrganizationSponsorshipApiService return await this.apiService.send("POST", url, null, true, false); } + + async deleteRevokeSponsorship( + sponsoringOrganizationId: string, + isAdminInitiated: boolean = false, + ): Promise { + const basePath = "/organization/sponsorship/"; + const hostPath = this.platformUtilsService.isSelfHost() ? "self-hosted/" : ""; + const queryParam = `?isAdminInitiated=${isAdminInitiated}`; + + return await this.apiService.send( + "DELETE", + basePath + hostPath + sponsoringOrganizationId + queryParam, + null, + true, + false, + ); + } } diff --git a/libs/common/src/services/api.service.ts b/libs/common/src/services/api.service.ts index 5c4bcdedb26..639daa7c658 100644 --- a/libs/common/src/services/api.service.ts +++ b/libs/common/src/services/api.service.ts @@ -1621,18 +1621,6 @@ export class ApiService implements ApiServiceAbstraction { return new OrganizationSponsorshipSyncStatusResponse(response); } - async deleteRevokeSponsorship(sponsoringOrganizationId: string): Promise { - return await this.send( - "DELETE", - "/organization/sponsorship/" + - (this.platformUtilsService.isSelfHost() ? "self-hosted/" : "") + - sponsoringOrganizationId, - null, - true, - false, - ); - } - async deleteRemoveSponsorship(sponsoringOrgId: string): Promise { return await this.send( "DELETE", From b3df8a6c13781a41ce5b82b83b35c90c5e32e0f2 Mon Sep 17 00:00:00 2001 From: Vicki League Date: Tue, 13 May 2025 14:16:18 -0400 Subject: [PATCH 25/25] [PM-17091][PM-17043] Support system zoom in browser extension (#14435) --- .../popup/layout/popup-size.service.ts | 37 +++++++++++--- apps/browser/src/popup/app.component.ts | 3 ++ apps/browser/src/popup/scss/base.scss | 49 ++++++++++++------- 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/apps/browser/src/platform/popup/layout/popup-size.service.ts b/apps/browser/src/platform/popup/layout/popup-size.service.ts index 3ae9a633cab..69d3102d24e 100644 --- a/apps/browser/src/platform/popup/layout/popup-size.service.ts +++ b/apps/browser/src/platform/popup/layout/popup-size.service.ts @@ -50,17 +50,40 @@ export class PopupSizeService { PopupSizeService.setStyle(width); localStorage.setItem(PopupSizeService.LocalStorageKey, width); }); + } + async setHeight() { const isInChromeTab = await BrowserPopupUtils.isInTab(); + /** + * To support both browser default zoom and system default zoom, we need to take into account + * the full screen height. When system default zoom is >100%, window.innerHeight still outputs + * a height equivalent to what it would be at 100%, which can cause the extension window to + * render as too tall. So if the screen height is smaller than the max possible extension height, + * we should use that to set our extension height. Otherwise, we want to use the window.innerHeight + * to support browser zoom. + * + * This is basically a workaround for what we consider a bug with browsers reporting the wrong + * available innerHeight when system zoom is turned on. If that gets fixed, we can remove the code + * checking the screen height. + */ + const MAX_EXT_HEIGHT = 600; + const extensionInnerHeight = window.innerHeight; + // Use a 100px offset when calculating screen height to account for browser container elements + const screenAvailHeight = window.screen.availHeight - 100; + const availHeight = + screenAvailHeight < MAX_EXT_HEIGHT ? screenAvailHeight : extensionInnerHeight; + if (!BrowserPopupUtils.inPopup(window) || isInChromeTab) { - window.document.body.classList.add("body-full"); - } else if (window.innerHeight < 400) { - window.document.body.classList.add("body-xxs"); - } else if (window.innerHeight < 500) { - window.document.body.classList.add("body-xs"); - } else if (window.innerHeight < 600) { - window.document.body.classList.add("body-sm"); + window.document.documentElement.classList.add("body-full"); + } else if (availHeight < 300) { + window.document.documentElement.classList.add("body-3xs"); + } else if (availHeight < 400) { + window.document.documentElement.classList.add("body-xxs"); + } else if (availHeight < 500) { + window.document.documentElement.classList.add("body-xs"); + } else if (availHeight < 600) { + window.document.documentElement.classList.add("body-sm"); } } diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts index 49579f889b3..a480e1d6ba3 100644 --- a/apps/browser/src/popup/app.component.ts +++ b/apps/browser/src/popup/app.component.ts @@ -26,6 +26,7 @@ import { import { BiometricsService, BiometricStateService } from "@bitwarden/key-management"; import { PopupCompactModeService } from "../platform/popup/layout/popup-compact-mode.service"; +import { PopupSizeService } from "../platform/popup/layout/popup-size.service"; import { initPopupClosedListener } from "../platform/services/popup-view-cache-background.service"; import { VaultBrowserStateService } from "../vault/services/vault-browser-state.service"; @@ -71,6 +72,7 @@ export class AppComponent implements OnInit, OnDestroy { private biometricStateService: BiometricStateService, private biometricsService: BiometricsService, private deviceTrustToastService: DeviceTrustToastService, + private popupSizeService: PopupSizeService, ) { this.deviceTrustToastService.setupListeners$.pipe(takeUntilDestroyed()).subscribe(); } @@ -79,6 +81,7 @@ export class AppComponent implements OnInit, OnDestroy { initPopupClosedListener(); this.compactModeService.init(); + await this.popupSizeService.setHeight(); // Component states must not persist between closing and reopening the popup, otherwise they become dead objects // Clear them aggressively to make sure this doesn't occur diff --git a/apps/browser/src/popup/scss/base.scss b/apps/browser/src/popup/scss/base.scss index 59893b5050d..80ada61f868 100644 --- a/apps/browser/src/popup/scss/base.scss +++ b/apps/browser/src/popup/scss/base.scss @@ -8,6 +8,34 @@ html { overflow: hidden; + min-height: 600px; + height: 100%; + + &.body-sm { + min-height: 500px; + } + + &.body-xs { + min-height: 400px; + } + + &.body-xxs { + min-height: 300px; + } + + &.body-3xs { + min-height: 240px; + } + + &.body-full { + min-height: unset; + width: 100%; + height: 100%; + + & body { + width: 100%; + } + } } html, @@ -20,9 +48,9 @@ body { body { width: 380px; - height: 600px; + height: 100%; position: relative; - min-height: 100vh; + min-height: inherit; overflow: hidden; color: $text-color; background-color: $background-color; @@ -31,23 +59,6 @@ body { color: themed("textColor"); background-color: themed("backgroundColor"); } - - &.body-sm { - height: 500px; - } - - &.body-xs { - height: 400px; - } - - &.body-xxs { - height: 300px; - } - - &.body-full { - width: 100%; - height: 100%; - } } h1,