diff --git a/apps/browser/src/autofill/background/abstractions/overlay.background.ts b/apps/browser/src/autofill/background/abstractions/overlay.background.ts index 6ad9b8e06f..5e2b755ad4 100644 --- a/apps/browser/src/autofill/background/abstractions/overlay.background.ts +++ b/apps/browser/src/autofill/background/abstractions/overlay.background.ts @@ -4,7 +4,7 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { InlineMenuFillTypes } from "../../enums/autofill-overlay.enum"; +import { InlineMenuFillType } from "../../enums/autofill-overlay.enum"; import AutofillPageDetails from "../../models/autofill-page-details"; import { PageDetail } from "../../services/abstractions/autofill.service"; @@ -43,7 +43,7 @@ export type UpdateOverlayCiphersParams = { export type FocusedFieldData = { focusedFieldStyles: Partial; focusedFieldRects: Partial; - inlineMenuFillType?: InlineMenuFillTypes; + inlineMenuFillType?: InlineMenuFillType; tabId?: number; frameId?: number; accountCreationFieldType?: string; diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index 0fe4a45904..92b2135c97 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -45,7 +45,7 @@ import { AutofillOverlayElement, AutofillOverlayPort, InlineMenuAccountCreationFieldType, - InlineMenuFillType, + InlineMenuFillTypes, MAX_SUB_FRAME_DEPTH, RedirectFocusDirection, } from "../enums/autofill-overlay.enum"; @@ -1025,7 +1025,7 @@ describe("OverlayBackground", () => { overlayBackground["focusedFieldData"] = createFocusedFieldDataMock({ tabId: tab.id, accountCreationFieldType: "text", - inlineMenuFillType: InlineMenuFillType.AccountCreationUsername, + inlineMenuFillType: InlineMenuFillTypes.AccountCreationUsername, }); cipherService.getAllDecryptedForUrl.mockResolvedValue([loginCipher1, identityCipher]); cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1); @@ -1383,7 +1383,7 @@ describe("OverlayBackground", () => { { command: "updateFocusedFieldData", focusedFieldData: createFocusedFieldDataMock({ - inlineMenuFillType: InlineMenuFillType.CurrentPasswordUpdate, + inlineMenuFillType: InlineMenuFillTypes.CurrentPasswordUpdate, }), }, mock({ tab }), @@ -2045,7 +2045,7 @@ describe("OverlayBackground", () => { }); it("displays the password generator when the focused field is for password generation", async () => { - focusedFieldData.inlineMenuFillType = InlineMenuFillType.PasswordGeneration; + focusedFieldData.inlineMenuFillType = InlineMenuFillTypes.PasswordGeneration; sendMockExtensionMessage({ command: "updateFocusedFieldData", focusedFieldData }, sender); await flushPromises(); @@ -2103,7 +2103,7 @@ describe("OverlayBackground", () => { }); it("shows the save login menu when the focused field type is for password generation and the field is filled", async () => { - focusedFieldData.inlineMenuFillType = InlineMenuFillType.PasswordGeneration; + focusedFieldData.inlineMenuFillType = InlineMenuFillTypes.PasswordGeneration; sendMockExtensionMessage( { command: "updateFocusedFieldData", focusedFieldData, focusedFieldHasValue: true }, @@ -3409,7 +3409,7 @@ describe("OverlayBackground", () => { { command: "updateFocusedFieldData", focusedFieldData: createFocusedFieldDataMock({ - inlineMenuFillType: InlineMenuFillType.CurrentPasswordUpdate, + inlineMenuFillType: InlineMenuFillTypes.CurrentPasswordUpdate, }), }, sender, @@ -3607,7 +3607,7 @@ describe("OverlayBackground", () => { describe("fillGeneratedPassword", () => { const focusedFieldData = createFocusedFieldDataMock({ - inlineMenuFillType: InlineMenuFillType.PasswordGeneration, + inlineMenuFillType: InlineMenuFillTypes.PasswordGeneration, }); beforeEach(() => { diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index ab5dd4abb8..ce0dbe5bb2 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -797,7 +797,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { * @param focusedFieldData - Optional focused field data to validate against */ private focusedFieldMatchesFillType( - fillType: InlineMenuFillTypes, + fillType: InlineMenuFillType, focusedFieldData?: FocusedFieldData, ) { const focusedFieldFillType = focusedFieldData @@ -806,7 +806,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { // When updating the current password for a field, it should fill with a login cipher if ( - focusedFieldFillType === InlineMenuFillType.CurrentPasswordUpdate && + focusedFieldFillType === InlineMenuFillTypes.CurrentPasswordUpdate && fillType === CipherType.Login ) { return true; @@ -819,7 +819,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { * Identifies whether the inline menu is being shown on an account creation field. */ private shouldShowInlineMenuAccountCreation(): boolean { - if (this.focusedFieldMatchesFillType(InlineMenuFillType.AccountCreationUsername)) { + if (this.focusedFieldMatchesFillType(InlineMenuFillTypes.AccountCreationUsername)) { return true; } @@ -1152,7 +1152,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { } let pageDetails = Array.from(pageDetailsForTab.values()); - if (this.focusedFieldMatchesFillType(InlineMenuFillType.CurrentPasswordUpdate)) { + if (this.focusedFieldMatchesFillType(InlineMenuFillTypes.CurrentPasswordUpdate)) { pageDetails = this.getFilteredPageDetails( pageDetails, this.inlineMenuFieldQualificationService.isUpdateCurrentPasswordField, @@ -1705,7 +1705,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { private shouldUpdatePasswordGeneratorMenuOnFieldFocus() { return ( this.isInlineMenuButtonVisible && - this.focusedFieldMatchesFillType(InlineMenuFillType.PasswordGeneration) + this.focusedFieldMatchesFillType(InlineMenuFillTypes.PasswordGeneration) ); } @@ -1767,9 +1767,9 @@ export class OverlayBackground implements OverlayBackgroundInterface { private shouldUpdateAccountCreationMenuOnFieldFocus(previousFocusedFieldData: FocusedFieldData) { const accountCreationFieldBlurred = this.focusedFieldMatchesFillType( - InlineMenuFillType.AccountCreationUsername, + InlineMenuFillTypes.AccountCreationUsername, previousFocusedFieldData, - ) && !this.focusedFieldMatchesFillType(InlineMenuFillType.AccountCreationUsername); + ) && !this.focusedFieldMatchesFillType(InlineMenuFillTypes.AccountCreationUsername); return accountCreationFieldBlurred || this.shouldShowInlineMenuAccountCreation(); } @@ -1876,7 +1876,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { return ( (this.shouldShowInlineMenuAccountCreation() || - this.focusedFieldMatchesFillType(InlineMenuFillType.PasswordGeneration)) && + this.focusedFieldMatchesFillType(InlineMenuFillTypes.PasswordGeneration)) && !!(loginData.password || loginData.newPassword) ); } @@ -3036,7 +3036,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { } const focusFieldShouldShowPasswordGenerator = - this.focusedFieldMatchesFillType(InlineMenuFillType.PasswordGeneration) || + this.focusedFieldMatchesFillType(InlineMenuFillTypes.PasswordGeneration) || (showInlineMenuAccountCreation && this.focusedFieldMatchesAccountCreationType(InlineMenuAccountCreationFieldType.Password)); if (!focusFieldShouldShowPasswordGenerator) { diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/action-button.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/action-button.mdx index d3c1968b32..73cd6fb93a 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/action-button.mdx +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/action-button.mdx @@ -20,7 +20,7 @@ It is designed with accessibility and responsive design in mind. | `buttonAction` | `(e: Event) => void` | Yes | The function to execute when the button is clicked. | | `buttonText` | `string` | Yes | The text to display on the button. | | `disabled` | `boolean` (default: false) | No | Disables the button when set to `true`. | -| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` enum. | +| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` type. | ## Installation and Setup diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/badge-button.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/badge-button.mdx index e0740ced76..47d82ad68d 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/badge-button.mdx +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/badge-button.mdx @@ -20,7 +20,7 @@ handling, and a disabled state. The component is optimized for accessibility and | `buttonAction` | `(e: Event) => void` | Yes | The function to execute when the button is clicked. | | `buttonText` | `string` | Yes | The text to display on the badge button. | | `disabled` | `boolean` (default: false) | No | Disables the button when set to `true`. | -| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` enum. | +| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` type. | ## Installation and Setup diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/body.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/body.mdx index 3a6a955e28..a298594e17 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/body.mdx +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/body.mdx @@ -19,7 +19,7 @@ presenting actionable information. | ------------------ | ------------------ | ------------ | --------------------------------------------------------------------------------------------------------- | | `ciphers` | `CipherData[]` | Yes | An array of cipher data objects. Each cipher includes metadata such as ID, name, type, and login details. | | `notificationType` | `NotificationType` | Yes | Specifies the type of notification, such as `add`, `change`, `unlock`, or `fileless-import`. | -| `theme` | `Theme` | Yes | Defines the theme used for styling the notification. Must match the `Theme` enum. | +| `theme` | `Theme` | Yes | Defines the theme used for styling the notification. Must match the `Theme` type. | --- diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/close-button.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/close-button.mdx index dcdd38710b..da9c15246f 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/close-button.mdx +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/close-button.mdx @@ -17,7 +17,7 @@ a close icon for visual clarity. The component is designed to be intuitive and a | **Prop** | **Type** | **Required** | **Description** | | ------------------------- | -------------------- | ------------ | ----------------------------------------------------------- | | `handleCloseNotification` | `(e: Event) => void` | Yes | The function to execute when the button is clicked. | -| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` enum. | +| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` type. | ## Installation and Setup diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/edit-button.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/edit-button.mdx index 0f38df1891..c6c4262806 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/edit-button.mdx +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/edit-button.mdx @@ -20,7 +20,7 @@ or settings where inline editing is required. | `buttonAction` | `(e: Event) => void` | Yes | The function to execute when the button is clicked. | | `buttonText` | `string` | Yes | The text displayed as the button's tooltip. | | `disabled` | `boolean` (default: false) | No | Disables the button when set to `true`. | -| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` enum. | +| `theme` | `Theme` | Yes | The theme to style the button. Must match the `Theme` type. | ## Installation and Setup diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/footer.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/footer.mdx index baaad4d815..6a816f811e 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/footer.mdx +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/footer.mdx @@ -17,7 +17,7 @@ customization based on the `theme` and `notificationType`. | **Prop** | **Type** | **Required** | **Description** | | ------------------ | ------------------ | ------------ | -------------------------------------------------------------------------------------------------- | | `notificationType` | `NotificationType` | Yes | The type of notification footer to display. Options: `add`, `change`, `unlock`, `fileless-import`. | -| `theme` | `Theme` | Yes | Defines the theme of the notification footer. Must match the `Theme` enum. | +| `theme` | `Theme` | Yes | Defines the theme of the notification footer. Must match the `Theme` type. | --- diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/header.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/header.mdx index fd03fd2f95..ebe35a3dd9 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/header.mdx +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/header.mdx @@ -19,7 +19,7 @@ and an optional close button. This component is versatile and can be styled dyna | ------------------------- | -------------------- | ------------ | ------------------------------------------------------------------- | | `message` | `string` | Yes | The text message to be displayed in the notification. | | `standalone` | `boolean` | No | Determines if the notification is displayed independently. | -| `theme` | `Theme` | Yes | Defines the theme of the notification. Must match the `Theme` enum. | +| `theme` | `Theme` | Yes | Defines the theme of the notification. Must match the `Theme` type. | | `handleCloseNotification` | `(e: Event) => void` | No | A callback function triggered when the close button is clicked. | --- diff --git a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/icons.mdx b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/icons.mdx index 571ed10285..7ec18d0f7b 100644 --- a/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/icons.mdx +++ b/apps/browser/src/autofill/content/components/lit-stories/.lit-docs/icons.mdx @@ -28,7 +28,7 @@ like size, color, and theme. Each story is an example of how a specific icon can | `iconLink` | `URL` | No | Defines an external URL associated with the icon, prop exclusive to `Brand Icon`. | | `color` | `string` | No | Sets the color of the icon. | | `disabled` | `boolean` | No | Disables the icon visually and functionally. | -| `theme` | `Theme` | Yes | Defines the theme used to style the icons. Must match the `Theme` enum. | +| `theme` | `Theme` | Yes | Defines the theme used to style the icons. Must match the `Theme` type. | | `size` | `number` | Yes | Sets the width and height of the icon in pixels. | --- diff --git a/apps/browser/src/autofill/enums/autofill-overlay.enum.ts b/apps/browser/src/autofill/enums/autofill-overlay.enum.ts index d0b970671a..4e4b32b903 100644 --- a/apps/browser/src/autofill/enums/autofill-overlay.enum.ts +++ b/apps/browser/src/autofill/enums/autofill-overlay.enum.ts @@ -21,14 +21,16 @@ 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, - CurrentPasswordUpdate = 7, -} -export type InlineMenuFillTypes = InlineMenuFillType | CipherType; +export const InlineMenuFillTypes = { + AccountCreationUsername: 5, + PasswordGeneration: 6, + CurrentPasswordUpdate: 7, +} as const; + +export type InlineMenuFillTypeValue = + (typeof InlineMenuFillTypes)[keyof typeof InlineMenuFillTypes]; + +export type InlineMenuFillType = InlineMenuFillTypeValue | CipherType; export const InlineMenuAccountCreationFieldType = { Text: "text", diff --git a/apps/browser/src/autofill/fido2/content/fido2-content-script.spec.ts b/apps/browser/src/autofill/fido2/content/fido2-content-script.spec.ts index 8885ed6299..af7344beb6 100644 --- a/apps/browser/src/autofill/fido2/content/fido2-content-script.spec.ts +++ b/apps/browser/src/autofill/fido2/content/fido2-content-script.spec.ts @@ -6,7 +6,7 @@ import { createPortSpyMock } from "../../../autofill/spec/autofill-mocks"; import { triggerPortOnDisconnectEvent } from "../../../autofill/spec/testing-utils"; import { Fido2PortName } from "../enums/fido2-port-name.enum"; -import { InsecureCreateCredentialParams, MessageType } from "./messaging/message"; +import { InsecureCreateCredentialParams, MessageTypes } from "./messaging/message"; import { MessageWithMetadata, Messenger } from "./messaging/messenger"; jest.mock("../../../autofill/utils", () => ({ @@ -71,7 +71,7 @@ describe("Fido2 Content Script", () => { it("handles a FIDO2 credential creation request message from the window message listener, formats the message and sends the formatted message to the extension background", async () => { const message = mock({ - type: MessageType.CredentialCreationRequest, + type: MessageTypes.CredentialCreationRequest, data: mock(), }); const mockResult = { credentialId: "mock" } as CreateCredentialResult; @@ -92,14 +92,14 @@ describe("Fido2 Content Script", () => { requestId: expect.any(String), }); expect(response).toEqual({ - type: MessageType.CredentialCreationResponse, + type: MessageTypes.CredentialCreationResponse, result: mockResult, }); }); it("handles a FIDO2 credential get request message from the window message listener, formats the message and sends the formatted message to the extension background", async () => { const message = mock({ - type: MessageType.CredentialGetRequest, + type: MessageTypes.CredentialGetRequest, data: mock(), }); @@ -121,7 +121,7 @@ describe("Fido2 Content Script", () => { it("removes the abort handler when the FIDO2 request is complete", async () => { const message = mock({ - type: MessageType.CredentialCreationRequest, + type: MessageTypes.CredentialCreationRequest, data: mock(), }); const abortController = new AbortController(); @@ -138,16 +138,14 @@ describe("Fido2 Content Script", () => { it("sends an extension message to abort the FIDO2 request when the abort controller is signaled", async () => { const message = mock({ - type: MessageType.CredentialCreationRequest, + type: MessageTypes.CredentialCreationRequest, data: mock(), }); const abortController = new AbortController(); const abortSpy = jest.spyOn(abortController.signal, "addEventListener"); - jest - .spyOn(chrome.runtime, "sendMessage") - .mockImplementationOnce(async (extensionId: string, message: unknown, options: any) => { - abortController.abort(); - }); + jest.spyOn(chrome.runtime, "sendMessage").mockImplementationOnce(async () => { + abortController.abort(); + }); // FIXME: Remove when updating file. Eslint update // eslint-disable-next-line @typescript-eslint/no-require-imports @@ -165,7 +163,7 @@ describe("Fido2 Content Script", () => { it("rejects credential requests and returns an error result", async () => { const errorMessage = "Test error"; const message = mock({ - type: MessageType.CredentialCreationRequest, + type: MessageTypes.CredentialCreationRequest, data: mock(), }); const abortController = new AbortController(); diff --git a/apps/browser/src/autofill/fido2/content/fido2-content-script.ts b/apps/browser/src/autofill/fido2/content/fido2-content-script.ts index f8352fc27a..03816f2b38 100644 --- a/apps/browser/src/autofill/fido2/content/fido2-content-script.ts +++ b/apps/browser/src/autofill/fido2/content/fido2-content-script.ts @@ -12,7 +12,7 @@ import { InsecureAssertCredentialParams, InsecureCreateCredentialParams, Message, - MessageType, + MessageTypes, } from "./messaging/message"; import { MessageWithMetadata, Messenger } from "./messaging/messenger"; @@ -49,21 +49,21 @@ import { MessageWithMetadata, Messenger } from "./messaging/messenger"; abortController.signal.addEventListener("abort", abortHandler); try { - if (message.type === MessageType.CredentialCreationRequest) { + if (message.type === MessageTypes.CredentialCreationRequest) { return handleCredentialCreationRequestMessage( requestId, message.data as InsecureCreateCredentialParams, ); } - if (message.type === MessageType.CredentialGetRequest) { + if (message.type === MessageTypes.CredentialGetRequest) { return handleCredentialGetRequestMessage( requestId, message.data as InsecureAssertCredentialParams, ); } - if (message.type === MessageType.AbortRequest) { + if (message.type === MessageTypes.AbortRequest) { return sendExtensionMessage("fido2AbortRequest", { abortedRequestId: requestId }); } } finally { @@ -83,7 +83,7 @@ import { MessageWithMetadata, Messenger } from "./messaging/messenger"; ): Promise { return respondToCredentialRequest( "fido2RegisterCredentialRequest", - MessageType.CredentialCreationResponse, + MessageTypes.CredentialCreationResponse, requestId, data, ); @@ -101,7 +101,7 @@ import { MessageWithMetadata, Messenger } from "./messaging/messenger"; ): Promise { return respondToCredentialRequest( "fido2GetCredentialRequest", - MessageType.CredentialGetResponse, + MessageTypes.CredentialGetResponse, requestId, data, ); @@ -118,7 +118,9 @@ import { MessageWithMetadata, Messenger } from "./messaging/messenger"; */ async function respondToCredentialRequest( command: string, - type: MessageType.CredentialCreationResponse | MessageType.CredentialGetResponse, + type: + | typeof MessageTypes.CredentialCreationResponse + | typeof MessageTypes.CredentialGetResponse, requestId: string, messageData: InsecureCreateCredentialParams | InsecureAssertCredentialParams, ): Promise { diff --git a/apps/browser/src/autofill/fido2/content/fido2-page-script.ts b/apps/browser/src/autofill/fido2/content/fido2-page-script.ts index 4c1761c37b..5b9ea5e5b2 100644 --- a/apps/browser/src/autofill/fido2/content/fido2-page-script.ts +++ b/apps/browser/src/autofill/fido2/content/fido2-page-script.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { WebauthnUtils } from "../utils/webauthn-utils"; -import { MessageType } from "./messaging/message"; +import { MessageTypes } from "./messaging/message"; import { Messenger } from "./messaging/messenger"; (function (globalContext) { @@ -100,13 +100,13 @@ import { Messenger } from "./messaging/messenger"; try { const response = await messenger.request( { - type: MessageType.CredentialCreationRequest, + type: MessageTypes.CredentialCreationRequest, data: WebauthnUtils.mapCredentialCreationOptions(options, fallbackSupported), }, options?.signal, ); - if (response.type !== MessageType.CredentialCreationResponse) { + if (response.type !== MessageTypes.CredentialCreationResponse) { throw new Error("Something went wrong."); } @@ -141,19 +141,19 @@ import { Messenger } from "./messaging/messenger"; try { const abortListener = () => messenger.request({ - type: MessageType.AbortRequest, + type: MessageTypes.AbortRequest, abortedRequestId: abortSignal.toString(), }); internalAbortController.signal.addEventListener("abort", abortListener); const response = await messenger.request( { - type: MessageType.CredentialGetRequest, + type: MessageTypes.CredentialGetRequest, data: WebauthnUtils.mapCredentialRequestOptions(options, fallbackSupported), }, internalAbortController.signal, ); internalAbortController.signal.removeEventListener("abort", abortListener); - if (response.type !== MessageType.CredentialGetResponse) { + if (response.type !== MessageTypes.CredentialGetResponse) { throw new Error("Something went wrong."); } @@ -182,13 +182,13 @@ import { Messenger } from "./messaging/messenger"; try { const response = await messenger.request( { - type: MessageType.CredentialGetRequest, + type: MessageTypes.CredentialGetRequest, data: WebauthnUtils.mapCredentialRequestOptions(options, fallbackSupported), }, options?.signal, ); - if (response.type !== MessageType.CredentialGetResponse) { + if (response.type !== MessageTypes.CredentialGetResponse) { throw new Error("Something went wrong."); } @@ -282,7 +282,7 @@ import { Messenger } from "./messaging/messenger"; const type = message.type; // Handle cleanup for disconnect request - if (type === MessageType.DisconnectRequest) { + if (type === MessageTypes.DisconnectRequest) { destroy(); } }; diff --git a/apps/browser/src/autofill/fido2/content/fido2-page-script.webauthn-supported.spec.ts b/apps/browser/src/autofill/fido2/content/fido2-page-script.webauthn-supported.spec.ts index f1aec69193..5e22027b58 100644 --- a/apps/browser/src/autofill/fido2/content/fido2-page-script.webauthn-supported.spec.ts +++ b/apps/browser/src/autofill/fido2/content/fido2-page-script.webauthn-supported.spec.ts @@ -7,7 +7,7 @@ import { } from "../../../autofill/spec/fido2-testing-utils"; import { WebauthnUtils } from "../utils/webauthn-utils"; -import { MessageType } from "./messaging/message"; +import { MessageTypes } from "./messaging/message"; import { Messenger } from "./messaging/messenger"; const originalGlobalThis = globalThis; @@ -71,7 +71,7 @@ describe("Fido2 page script with native WebAuthn support", () => { describe("creating WebAuthn credentials", () => { beforeEach(() => { messenger.request = jest.fn().mockResolvedValue({ - type: MessageType.CredentialCreationResponse, + type: MessageTypes.CredentialCreationResponse, result: mockCreateCredentialsResult, }); }); @@ -104,7 +104,7 @@ describe("Fido2 page script with native WebAuthn support", () => { describe("get WebAuthn credentials", () => { beforeEach(() => { messenger.request = jest.fn().mockResolvedValue({ - type: MessageType.CredentialGetResponse, + type: MessageTypes.CredentialGetResponse, result: mockCredentialAssertResult, }); }); @@ -147,7 +147,7 @@ describe("Fido2 page script with native WebAuthn support", () => { it("should destroy the message listener when receiving a disconnect request", async () => { jest.spyOn(globalThis.top, "removeEventListener"); const SENDER = "bitwarden-webauthn"; - void messenger.handler({ type: MessageType.DisconnectRequest, SENDER, senderId: "1" }); + void messenger.handler({ type: MessageTypes.DisconnectRequest, SENDER, senderId: "1" }); expect(globalThis.top.removeEventListener).toHaveBeenCalledWith("focus", undefined); expect(messenger.destroy).toHaveBeenCalled(); diff --git a/apps/browser/src/autofill/fido2/content/fido2-page-script.webauthn-unsupported.spec.ts b/apps/browser/src/autofill/fido2/content/fido2-page-script.webauthn-unsupported.spec.ts index af1838ec94..d15bc475f5 100644 --- a/apps/browser/src/autofill/fido2/content/fido2-page-script.webauthn-unsupported.spec.ts +++ b/apps/browser/src/autofill/fido2/content/fido2-page-script.webauthn-unsupported.spec.ts @@ -6,7 +6,7 @@ import { } from "../../../autofill/spec/fido2-testing-utils"; import { WebauthnUtils } from "../utils/webauthn-utils"; -import { MessageType } from "./messaging/message"; +import { MessageTypes } from "./messaging/message"; import { Messenger } from "./messaging/messenger"; const originalGlobalThis = globalThis; @@ -65,7 +65,7 @@ describe("Fido2 page script without native WebAuthn support", () => { describe("creating WebAuthn credentials", () => { beforeEach(() => { messenger.request = jest.fn().mockResolvedValue({ - type: MessageType.CredentialCreationResponse, + type: MessageTypes.CredentialCreationResponse, result: mockCreateCredentialsResult, }); }); @@ -86,7 +86,7 @@ describe("Fido2 page script without native WebAuthn support", () => { describe("get WebAuthn credentials", () => { beforeEach(() => { messenger.request = jest.fn().mockResolvedValue({ - type: MessageType.CredentialGetResponse, + type: MessageTypes.CredentialGetResponse, result: mockCredentialAssertResult, }); }); @@ -108,7 +108,7 @@ describe("Fido2 page script without native WebAuthn support", () => { it("should destroy the message listener when receiving a disconnect request", async () => { jest.spyOn(globalThis.top, "removeEventListener"); const SENDER = "bitwarden-webauthn"; - void messenger.handler({ type: MessageType.DisconnectRequest, SENDER, senderId: "1" }); + void messenger.handler({ type: MessageTypes.DisconnectRequest, SENDER, senderId: "1" }); expect(globalThis.top.removeEventListener).toHaveBeenCalledWith("focus", undefined); expect(messenger.destroy).toHaveBeenCalled(); diff --git a/apps/browser/src/autofill/fido2/content/messaging/message.ts b/apps/browser/src/autofill/fido2/content/messaging/message.ts index 640af22ab9..55dc522cea 100644 --- a/apps/browser/src/autofill/fido2/content/messaging/message.ts +++ b/apps/browser/src/autofill/fido2/content/messaging/message.ts @@ -5,19 +5,19 @@ 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, - CredentialGetRequest, - CredentialGetResponse, - AbortRequest, - DisconnectRequest, - ReconnectRequest, - AbortResponse, - ErrorResponse, -} +export const MessageTypes = { + CredentialCreationRequest: 0, + CredentialCreationResponse: 1, + CredentialGetRequest: 2, + CredentialGetResponse: 3, + AbortRequest: 4, + DisconnectRequest: 5, + ReconnectRequest: 6, + AbortResponse: 7, + ErrorResponse: 8, +} as const; + +export type MessageType = (typeof MessageTypes)[keyof typeof MessageTypes]; /** * The params provided by the page-script are created in an insecure environment and @@ -30,12 +30,12 @@ export type InsecureCreateCredentialParams = Omit< >; export type CredentialCreationRequest = { - type: MessageType.CredentialCreationRequest; + type: typeof MessageTypes.CredentialCreationRequest; data: InsecureCreateCredentialParams; }; export type CredentialCreationResponse = { - type: MessageType.CredentialCreationResponse; + type: typeof MessageTypes.CredentialCreationResponse; result?: CreateCredentialResult; }; @@ -50,35 +50,35 @@ export type InsecureAssertCredentialParams = Omit< >; export type CredentialGetRequest = { - type: MessageType.CredentialGetRequest; + type: typeof MessageTypes.CredentialGetRequest; data: InsecureAssertCredentialParams; }; export type CredentialGetResponse = { - type: MessageType.CredentialGetResponse; + type: typeof MessageTypes.CredentialGetResponse; result?: AssertCredentialResult; }; export type AbortRequest = { - type: MessageType.AbortRequest; + type: typeof MessageTypes.AbortRequest; abortedRequestId: string; }; export type DisconnectRequest = { - type: MessageType.DisconnectRequest; + type: typeof MessageTypes.DisconnectRequest; }; export type ReconnectRequest = { - type: MessageType.ReconnectRequest; + type: typeof MessageTypes.ReconnectRequest; }; export type ErrorResponse = { - type: MessageType.ErrorResponse; + type: typeof MessageTypes.ErrorResponse; error: string; }; export type AbortResponse = { - type: MessageType.AbortResponse; + type: typeof MessageTypes.AbortResponse; abortedRequestId: string; }; diff --git a/apps/browser/src/autofill/fido2/content/messaging/messenger.ts b/apps/browser/src/autofill/fido2/content/messaging/messenger.ts index ec7ff3bb7a..257f7e9efd 100644 --- a/apps/browser/src/autofill/fido2/content/messaging/messenger.ts +++ b/apps/browser/src/autofill/fido2/content/messaging/messenger.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Message, MessageType } from "./message"; +import { Message, MessageTypes } from "./message"; const SENDER = "bitwarden-webauthn"; @@ -80,7 +80,7 @@ export class Messenger { const abortListener = () => localPort.postMessage({ metadata: { SENDER }, - type: MessageType.AbortRequest, + type: MessageTypes.AbortRequest, }); abortSignal?.addEventListener("abort", abortListener); @@ -92,7 +92,7 @@ export class Messenger { abortSignal?.removeEventListener("abort", abortListener); - if (response.type === MessageType.ErrorResponse) { + if (response.type === MessageTypes.ErrorResponse) { const error = new Error(); Object.assign(error, JSON.parse(response.error)); throw error; @@ -119,7 +119,7 @@ export class Messenger { const abortController = new AbortController(); port.onmessage = (event: MessageEvent) => { - if (event.data.type === MessageType.AbortRequest) { + if (event.data.type === MessageTypes.AbortRequest) { abortController.abort(); } }; @@ -133,7 +133,7 @@ export class Messenger { } catch (error) { port.postMessage({ SENDER, - type: MessageType.ErrorResponse, + type: MessageTypes.ErrorResponse, error: JSON.stringify(error, Object.getOwnPropertyNames(error)), }); } finally { @@ -157,7 +157,7 @@ export class Messenger { } private async sendDisconnectCommand() { - await this.request({ type: MessageType.DisconnectRequest }); + await this.request({ type: MessageTypes.DisconnectRequest }); } private generateUniqueId() { diff --git a/apps/browser/src/autofill/models/autofill-field.ts b/apps/browser/src/autofill/models/autofill-field.ts index c0be60f1cd..1a8c3bb875 100644 --- a/apps/browser/src/autofill/models/autofill-field.ts +++ b/apps/browser/src/autofill/models/autofill-field.ts @@ -4,7 +4,7 @@ import { FieldRect } from "../background/abstractions/overlay.background"; import { AutofillFieldQualifierType } from "../enums/autofill-field.enums"; import { InlineMenuAccountCreationFieldTypes, - InlineMenuFillTypes, + InlineMenuFillType, } from "../enums/autofill-overlay.enum"; /** @@ -118,7 +118,7 @@ export default class AutofillField { checked?: boolean; - inlineMenuFillType?: InlineMenuFillTypes; + inlineMenuFillType?: InlineMenuFillType; showPasskeys?: boolean; diff --git a/apps/browser/src/autofill/overlay/inline-menu/abstractions/autofill-inline-menu-list.ts b/apps/browser/src/autofill/overlay/inline-menu/abstractions/autofill-inline-menu-list.ts index a20bd3c531..f5e1fe0885 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/abstractions/autofill-inline-menu-list.ts +++ b/apps/browser/src/autofill/overlay/inline-menu/abstractions/autofill-inline-menu-list.ts @@ -1,7 +1,7 @@ import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { InlineMenuCipherData } from "../../../background/abstractions/overlay.background"; -import { InlineMenuFillTypes } from "../../../enums/autofill-overlay.enum"; +import { InlineMenuFillType } from "../../../enums/autofill-overlay.enum"; type AutofillInlineMenuListMessage = { command: string }; @@ -23,7 +23,7 @@ export type InitAutofillInlineMenuListMessage = AutofillInlineMenuListMessage & theme: string; translations: Record; ciphers?: InlineMenuCipherData[]; - inlineMenuFillType?: InlineMenuFillTypes; + inlineMenuFillType?: InlineMenuFillType; showInlineMenuAccountCreation?: boolean; showPasskeysLabels?: boolean; portKey: string; diff --git a/apps/browser/src/autofill/overlay/inline-menu/pages/list/autofill-inline-menu-list.ts b/apps/browser/src/autofill/overlay/inline-menu/pages/list/autofill-inline-menu-list.ts index e0db93b6b4..c680fe4745 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/pages/list/autofill-inline-menu-list.ts +++ b/apps/browser/src/autofill/overlay/inline-menu/pages/list/autofill-inline-menu-list.ts @@ -10,7 +10,7 @@ import { EVENTS, UPDATE_PASSKEYS_HEADINGS_ON_SCROLL } from "@bitwarden/common/au import { CipherRepromptType, CipherType } from "@bitwarden/common/vault/enums"; import { InlineMenuCipherData } from "../../../../background/abstractions/overlay.background"; -import { InlineMenuFillTypes } from "../../../../enums/autofill-overlay.enum"; +import { InlineMenuFillType } from "../../../../enums/autofill-overlay.enum"; import { buildSvgDomElement, specialCharacterToKeyMap, throttle } from "../../../../utils"; import { creditCardIcon, @@ -42,7 +42,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { private cipherListScrollIsDebounced = false; private cipherListScrollDebounceTimeout: number | NodeJS.Timeout; private currentCipherIndex = 0; - private inlineMenuFillType: InlineMenuFillTypes; + private inlineMenuFillType: InlineMenuFillType; private showInlineMenuAccountCreation: boolean; private showPasskeysLabels: boolean; private newItemButtonElement: HTMLButtonElement; @@ -1105,8 +1105,8 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement { const svgElement = buildSvgDomElement(` - diff --git a/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts b/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts index 48bc7ceafd..730b002953 100644 --- a/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts +++ b/apps/browser/src/autofill/services/autofill-overlay-content.service.spec.ts @@ -6,7 +6,7 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import AutofillInit from "../content/autofill-init"; import { AutofillOverlayElement, - InlineMenuFillType, + InlineMenuFillTypes, MAX_SUB_FRAME_DEPTH, RedirectFocusDirection, } from "../enums/autofill-overlay.enum"; @@ -1383,7 +1383,7 @@ describe("AutofillOverlayContentService", () => { ); expect(autofillFieldElement.removeEventListener).toHaveBeenCalled(); expect(inputAccountFieldData.inlineMenuFillType).toEqual( - InlineMenuFillType.AccountCreationUsername, + InlineMenuFillTypes.AccountCreationUsername, ); }); @@ -1420,7 +1420,7 @@ describe("AutofillOverlayContentService", () => { await flushPromises(); expect(currentPasswordFieldData.inlineMenuFillType).toEqual( - InlineMenuFillType.CurrentPasswordUpdate, + InlineMenuFillTypes.CurrentPasswordUpdate, ); }); }); diff --git a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts index dc8f45d104..1a972e0eaa 100644 --- a/apps/browser/src/autofill/services/autofill-overlay-content.service.ts +++ b/apps/browser/src/autofill/services/autofill-overlay-content.service.ts @@ -24,7 +24,7 @@ import { AutofillFieldQualifier, AutofillFieldQualifierType } from "../enums/aut import { AutofillOverlayElement, InlineMenuAccountCreationFieldType, - InlineMenuFillType, + InlineMenuFillTypes, MAX_SUB_FRAME_DEPTH, RedirectFocusDirection, } from "../enums/autofill-overlay.enum"; @@ -789,11 +789,11 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ if (!autofillFieldData.fieldQualifier) { switch (autofillFieldData.inlineMenuFillType) { case CipherType.Login: - case InlineMenuFillType.CurrentPasswordUpdate: + case InlineMenuFillTypes.CurrentPasswordUpdate: this.qualifyUserFilledField(autofillFieldData, this.loginFieldQualifiers); break; - case InlineMenuFillType.AccountCreationUsername: - case InlineMenuFillType.PasswordGeneration: + case InlineMenuFillTypes.AccountCreationUsername: + case InlineMenuFillTypes.PasswordGeneration: this.qualifyUserFilledField(autofillFieldData, this.accountCreationFieldQualifiers); break; case CipherType.Card: @@ -1106,18 +1106,18 @@ export class AutofillOverlayContentService implements AutofillOverlayContentServ */ private setQualifiedAccountCreationFillType(autofillFieldData: AutofillField) { if (this.inlineMenuFieldQualificationService.isNewPasswordField(autofillFieldData)) { - autofillFieldData.inlineMenuFillType = InlineMenuFillType.PasswordGeneration; + autofillFieldData.inlineMenuFillType = InlineMenuFillTypes.PasswordGeneration; this.qualifyAccountCreationFieldType(autofillFieldData); return; } if (this.inlineMenuFieldQualificationService.isUpdateCurrentPasswordField(autofillFieldData)) { - autofillFieldData.inlineMenuFillType = InlineMenuFillType.CurrentPasswordUpdate; + autofillFieldData.inlineMenuFillType = InlineMenuFillTypes.CurrentPasswordUpdate; return; } if (this.inlineMenuFieldQualificationService.isUsernameField(autofillFieldData)) { - autofillFieldData.inlineMenuFillType = InlineMenuFillType.AccountCreationUsername; + autofillFieldData.inlineMenuFillType = InlineMenuFillTypes.AccountCreationUsername; this.qualifyAccountCreationFieldType(autofillFieldData); } }