From 7801fd312356d27a1d09040e66cb2f6f12ee94f3 Mon Sep 17 00:00:00 2001 From: neuronull <9162534+neuronull@users.noreply.github.com> Date: Tue, 4 Nov 2025 08:13:08 -0800 Subject: [PATCH 1/7] Desktop Autotype use managed object for IPC vault data payload (#17105) * Desktop Autotype use managed object for IPC vault data payload * claude feedback 1 * check for falsey values * add unit test * remove unecessary async * helper result type * dear claude --- .../main/main-desktop-autotype.service.ts | 20 +++----- .../autofill/models/autotype-vault-data.ts | 8 +++ apps/desktop/src/autofill/preload.ts | 17 +++---- .../services/desktop-autotype.service.spec.ts | 50 +++++++++++++++++++ .../services/desktop-autotype.service.ts | 31 ++++++++++-- 5 files changed, 99 insertions(+), 27 deletions(-) create mode 100644 apps/desktop/src/autofill/models/autotype-vault-data.ts create mode 100644 apps/desktop/src/autofill/services/desktop-autotype.service.spec.ts diff --git a/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts b/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts index 09f03d2ef8e..e33ab0d4c3b 100644 --- a/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts +++ b/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts @@ -5,6 +5,7 @@ import { LogService } from "@bitwarden/logging"; import { WindowMain } from "../../main/window.main"; import { stringIsNotUndefinedNullAndEmpty } from "../../utils"; +import { AutotypeVaultData } from "../models/autotype-vault-data"; import { AutotypeKeyboardShortcut } from "../models/main-autotype-keyboard-shortcut"; export class MainDesktopAutotypeService { @@ -47,18 +48,12 @@ export class MainDesktopAutotypeService { } }); - ipcMain.on("autofill.completeAutotypeRequest", (event, data) => { - const { response } = data; - + ipcMain.on("autofill.completeAutotypeRequest", (_event, vaultData: AutotypeVaultData) => { if ( - stringIsNotUndefinedNullAndEmpty(response.username) && - stringIsNotUndefinedNullAndEmpty(response.password) + stringIsNotUndefinedNullAndEmpty(vaultData.username) && + stringIsNotUndefinedNullAndEmpty(vaultData.password) ) { - this.doAutotype( - response.username, - response.password, - this.autotypeKeyboardShortcut.getArrayFormat(), - ); + this.doAutotype(vaultData, this.autotypeKeyboardShortcut.getArrayFormat()); } }); } @@ -89,8 +84,9 @@ export class MainDesktopAutotypeService { : this.logService.info("Enabling autotype failed."); } - private doAutotype(username: string, password: string, keyboardShortcut: string[]) { - const inputPattern = username + "\t" + password; + private doAutotype(vaultData: AutotypeVaultData, keyboardShortcut: string[]) { + const TAB = "\t"; + const inputPattern = vaultData.username + TAB + vaultData.password; const inputArray = new Array(inputPattern.length); for (let i = 0; i < inputPattern.length; i++) { diff --git a/apps/desktop/src/autofill/models/autotype-vault-data.ts b/apps/desktop/src/autofill/models/autotype-vault-data.ts new file mode 100644 index 00000000000..ee3db98c334 --- /dev/null +++ b/apps/desktop/src/autofill/models/autotype-vault-data.ts @@ -0,0 +1,8 @@ +/** + * Vault data used in autotype operations. + * `username` and `password` are guaranteed to be not null/undefined. + */ +export interface AutotypeVaultData { + username: string; + password: string; +} diff --git a/apps/desktop/src/autofill/preload.ts b/apps/desktop/src/autofill/preload.ts index fcb2f646743..22b5cdf9463 100644 --- a/apps/desktop/src/autofill/preload.ts +++ b/apps/desktop/src/autofill/preload.ts @@ -5,6 +5,8 @@ import type { autofill } from "@bitwarden/desktop-napi"; import { Command } from "../platform/main/autofill/command"; import { RunCommandParams, RunCommandResult } from "../platform/main/autofill/native-autofill.main"; +import { AutotypeVaultData } from "./models/autotype-vault-data"; + export default { runCommand: (params: RunCommandParams): Promise> => ipcRenderer.invoke("autofill.runCommand", params), @@ -133,10 +135,7 @@ export default { listenAutotypeRequest: ( fn: ( windowTitle: string, - completeCallback: ( - error: Error | null, - response: { username?: string; password?: string }, - ) => void, + completeCallback: (error: Error | null, response: AutotypeVaultData | null) => void, ) => void, ) => { ipcRenderer.on( @@ -149,7 +148,7 @@ export default { ) => { const { windowTitle } = data; - fn(windowTitle, (error, response) => { + fn(windowTitle, (error, vaultData) => { if (error) { ipcRenderer.send("autofill.completeError", { windowTitle, @@ -157,11 +156,9 @@ export default { }); return; } - - ipcRenderer.send("autofill.completeAutotypeRequest", { - windowTitle, - response, - }); + if (vaultData !== null) { + ipcRenderer.send("autofill.completeAutotypeRequest", vaultData); + } }); }, ); diff --git a/apps/desktop/src/autofill/services/desktop-autotype.service.spec.ts b/apps/desktop/src/autofill/services/desktop-autotype.service.spec.ts new file mode 100644 index 00000000000..30cc800dd28 --- /dev/null +++ b/apps/desktop/src/autofill/services/desktop-autotype.service.spec.ts @@ -0,0 +1,50 @@ +import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; + +import { getAutotypeVaultData } from "./desktop-autotype.service"; + +describe("getAutotypeVaultData", () => { + it("should return vault data when cipher has username and password", () => { + const cipherView = new CipherView(); + cipherView.login.username = "foo"; + cipherView.login.password = "bar"; + + const [error, vaultData] = getAutotypeVaultData(cipherView); + + expect(error).toBeNull(); + expect(vaultData?.username).toEqual("foo"); + expect(vaultData?.password).toEqual("bar"); + }); + + it("should return error when firstCipher is undefined", () => { + const cipherView = undefined; + const [error, vaultData] = getAutotypeVaultData(cipherView); + + expect(vaultData).toBeNull(); + expect(error).toBeDefined(); + expect(error?.message).toEqual("No matching vault item."); + }); + + it("should return error when username is undefined", () => { + const cipherView = new CipherView(); + cipherView.login.username = undefined; + cipherView.login.password = "bar"; + + const [error, vaultData] = getAutotypeVaultData(cipherView); + + expect(vaultData).toBeNull(); + expect(error).toBeDefined(); + expect(error?.message).toEqual("Vault item is undefined."); + }); + + it("should return error when password is undefined", () => { + const cipherView = new CipherView(); + cipherView.login.username = "foo"; + cipherView.login.password = undefined; + + const [error, vaultData] = getAutotypeVaultData(cipherView); + + expect(vaultData).toBeNull(); + expect(error).toBeDefined(); + expect(error?.message).toEqual("Vault item is undefined."); + }); +}); diff --git a/apps/desktop/src/autofill/services/desktop-autotype.service.ts b/apps/desktop/src/autofill/services/desktop-autotype.service.ts index 24ec3907a62..7ee889e7b81 100644 --- a/apps/desktop/src/autofill/services/desktop-autotype.service.ts +++ b/apps/desktop/src/autofill/services/desktop-autotype.service.ts @@ -17,6 +17,8 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { UserId } from "@bitwarden/user-core"; +import { AutotypeVaultData } from "../models/autotype-vault-data"; + import { DesktopAutotypeDefaultSettingPolicy } from "./desktop-autotype-policy.service"; export const defaultWindowsAutotypeKeyboardShortcut: string[] = ["Control", "Shift", "B"]; @@ -27,6 +29,8 @@ export const AUTOTYPE_ENABLED = new KeyDefinition( { deserializer: (b) => b }, ); +export type Result = [E, null] | [null, T]; + /* Valid windows shortcut keys: Control, Alt, Super, Shift, letters A - Z Valid macOS shortcut keys: Control, Alt, Command, Shift, letters A - Z @@ -63,11 +67,8 @@ export class DesktopAutotypeService { ipc.autofill.listenAutotypeRequest(async (windowTitle, callback) => { const possibleCiphers = await this.matchCiphersToWindowTitle(windowTitle); const firstCipher = possibleCiphers?.at(0); - - return callback(null, { - username: firstCipher?.login?.username, - password: firstCipher?.login?.password, - }); + const [error, vaultData] = getAutotypeVaultData(firstCipher); + callback(error, vaultData); }); } @@ -176,3 +177,23 @@ export class DesktopAutotypeService { return possibleCiphers; } } + +/** + * @return an `AutotypeVaultData` object or an `Error` if the + * cipher or vault data within are undefined. + */ +export function getAutotypeVaultData( + cipherView: CipherView | undefined, +): Result { + if (!cipherView) { + return [Error("No matching vault item."), null]; + } else if (cipherView.login.username === undefined || cipherView.login.password === undefined) { + return [Error("Vault item is undefined."), null]; + } else { + const vaultData: AutotypeVaultData = { + username: cipherView.login.username, + password: cipherView.login.password, + }; + return [null, vaultData]; + } +} From a71ab020c4f4ed6825d1983c44aadc5b02dacaff Mon Sep 17 00:00:00 2001 From: Daniel Riera Date: Tue, 4 Nov 2025 12:47:26 -0500 Subject: [PATCH 2/7] PM-27807 remove unused es-lint disable (#17212) --- apps/browser/src/autofill/notification/bar.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/browser/src/autofill/notification/bar.html b/apps/browser/src/autofill/notification/bar.html index c0b57de612e..8934fe6a031 100644 --- a/apps/browser/src/autofill/notification/bar.html +++ b/apps/browser/src/autofill/notification/bar.html @@ -1,5 +1,4 @@ - - + Bitwarden From cef503ee9a0de7a81d5c15cef527effd4e43df19 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 18:13:10 +0000 Subject: [PATCH 3/7] [deps] SM: Update jest-diff to v30 (#15293) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: cd-bitwarden <106776772+cd-bitwarden@users.noreply.github.com> --- package-lock.json | 160 ++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 76 insertions(+), 86 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9636184c5ee..e456e257ca4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -152,7 +152,7 @@ "html-webpack-injector": "1.1.4", "html-webpack-plugin": "5.6.3", "husky": "9.1.7", - "jest-diff": "29.7.0", + "jest-diff": "30.2.0", "jest-junit": "16.0.0", "jest-mock-extended": "3.0.7", "jest-preset-angular": "14.6.1", @@ -26136,26 +26136,51 @@ "license": "MIT" }, "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", + "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/jest-diff/node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/@sinclair/typebox": { + "version": "0.34.41", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", + "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "license": "MIT" + }, "node_modules/jest-diff/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -26165,25 +26190,23 @@ } }, "node_modules/jest-diff/node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-diff/node_modules/react-is": { "version": "18.3.1", "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-docblock": { @@ -26658,6 +26681,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/jest-matcher-utils/node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/jest-matcher-utils/node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -27225,6 +27264,22 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/jest-snapshot/node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -32171,36 +32226,6 @@ } } }, - "node_modules/nx/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/nx/node_modules/@sinclair/typebox": { - "version": "0.34.38", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.38.tgz", - "integrity": "sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA==", - "license": "MIT" - }, - "node_modules/nx/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/nx/node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -32258,21 +32283,6 @@ "node": ">=8" } }, - "node_modules/nx/node_modules/jest-diff": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.0.5.tgz", - "integrity": "sha512-1UIqE9PoEKaHcIKvq2vbibrCog4Y8G0zmOxgQUVEiTqwR5hJVMCoDsN1vFvI5JvwD37hjueZ1C4l2FyGnfpE0A==", - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.0.1", - "@jest/get-type": "30.0.1", - "chalk": "^4.1.2", - "pretty-format": "30.0.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, "node_modules/nx/node_modules/jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", @@ -32318,26 +32328,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nx/node_modules/pretty-format": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", - "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", - "license": "MIT", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/nx/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, "node_modules/nx/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", diff --git a/package.json b/package.json index c1becca3a31..e224fd00213 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "html-webpack-injector": "1.1.4", "html-webpack-plugin": "5.6.3", "husky": "9.1.7", - "jest-diff": "29.7.0", + "jest-diff": "30.2.0", "jest-junit": "16.0.0", "jest-mock-extended": "3.0.7", "jest-preset-angular": "14.6.1", From f556f3b00043da081328929ee987370c5a79642b Mon Sep 17 00:00:00 2001 From: Tom <144813356+ttalty@users.noreply.github.com> Date: Tue, 4 Nov 2025 13:22:57 -0500 Subject: [PATCH 4/7] Adding the removal from the access intelligence routing canActivate (#17216) --- .../access-intelligence/access-intelligence-routing.module.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/access-intelligence-routing.module.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/access-intelligence-routing.module.ts index 2e3c53d8d9f..4a37bea8872 100644 --- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/access-intelligence-routing.module.ts +++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/access-intelligence-routing.module.ts @@ -9,9 +9,7 @@ const routes: Routes = [ { path: "", pathMatch: "full", redirectTo: "risk-insights" }, { path: "risk-insights", - canActivate: [ - organizationPermissionsGuard((org) => org.useRiskInsights && org.canAccessReports), - ], + canActivate: [organizationPermissionsGuard((org) => org.canAccessReports)], component: RiskInsightsComponent, data: { titleId: "RiskInsights", From 409dbc4c449c2bdf6ce8813465cdaf718cf2a12d Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:41:00 -0800 Subject: [PATCH 5/7] fix(sso-login): [PM-27674] (Auth) Make 'enter' press start sso process if ssoRequired (#17186) If user's email is NOT in the ssoRequiredCache, pressing "enter" takes them to the MP login screen. If the user's email is in the ssoRequiredCache, pressing "enter" starts the SSO login process. Feature Flags enabled: pm-22110-disable-alternate-login-methods --- libs/auth/src/angular/login/login.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/auth/src/angular/login/login.component.html b/libs/auth/src/angular/login/login.component.html index 4e1689b1054..9faa582c071 100644 --- a/libs/auth/src/angular/login/login.component.html +++ b/libs/auth/src/angular/login/login.component.html @@ -21,7 +21,7 @@ bitInput appAutofocus (input)="onEmailInput($event)" - (keyup.enter)="continuePressed()" + (keyup.enter)="ssoRequired ? handleSsoClick() : continuePressed()" /> From 92118e525d1b76d7cc646de90aaf37ca6804446f Mon Sep 17 00:00:00 2001 From: Vicki League Date: Tue, 4 Nov 2025 13:56:01 -0500 Subject: [PATCH 6/7] [PM-26984] Use medium instead of semibold or bold (#17185) --- .../src/autofill/content/components/buttons/action-button.ts | 2 +- .../content/components/notification/confirmation/message.ts | 2 +- .../content/components/notification/header-message.ts | 2 +- .../content/components/option-selection/option-items.ts | 2 +- .../src/autofill/content/components/rows/action-row.ts | 2 +- .../src/autofill/overlay/inline-menu/pages/list/list.scss | 4 ++-- .../src/autofill/components/autotype-shortcut.component.html | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/browser/src/autofill/content/components/buttons/action-button.ts b/apps/browser/src/autofill/content/components/buttons/action-button.ts index b43bed7f96b..73fc1e79ec5 100644 --- a/apps/browser/src/autofill/content/components/buttons/action-button.ts +++ b/apps/browser/src/autofill/content/components/buttons/action-button.ts @@ -68,7 +68,7 @@ const actionButtonStyles = ({ overflow: hidden; text-align: center; text-overflow: ellipsis; - font-weight: 700; + font-weight: 500; ${disabled || isLoading ? ` 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 01a2b783eda..36ea9c1f9d6 100644 --- a/apps/browser/src/autofill/content/components/notification/confirmation/message.ts +++ b/apps/browser/src/autofill/content/components/notification/confirmation/message.ts @@ -115,7 +115,7 @@ const notificationConfirmationButtonTextStyles = (theme: Theme) => css` ${baseTextStyles} color: ${themes[theme].primary[600]}; - font-weight: 700; + font-weight: 500; cursor: pointer; `; diff --git a/apps/browser/src/autofill/content/components/notification/header-message.ts b/apps/browser/src/autofill/content/components/notification/header-message.ts index 4b6e4722a83..2e51d82dd07 100644 --- a/apps/browser/src/autofill/content/components/notification/header-message.ts +++ b/apps/browser/src/autofill/content/components/notification/header-message.ts @@ -21,5 +21,5 @@ const notificationHeaderMessageStyles = (theme: Theme) => css` color: ${themes[theme].text.main}; font-family: Inter, sans-serif; font-size: 18px; - font-weight: 600; + font-weight: 500; `; diff --git a/apps/browser/src/autofill/content/components/option-selection/option-items.ts b/apps/browser/src/autofill/content/components/option-selection/option-items.ts index ceb72905357..58216b6c1b2 100644 --- a/apps/browser/src/autofill/content/components/option-selection/option-items.ts +++ b/apps/browser/src/autofill/content/components/option-selection/option-items.ts @@ -94,7 +94,7 @@ const optionsLabelStyles = ({ theme }: { theme: Theme }) => css` user-select: none; padding: 0.375rem ${spacing["3"]}; color: ${themes[theme].text.muted}; - font-weight: 600; + font-weight: 500; `; export const optionsMenuItemMaxWidth = 260; diff --git a/apps/browser/src/autofill/content/components/rows/action-row.ts b/apps/browser/src/autofill/content/components/rows/action-row.ts index 0380f91012a..8f13b166156 100644 --- a/apps/browser/src/autofill/content/components/rows/action-row.ts +++ b/apps/browser/src/autofill/content/components/rows/action-row.ts @@ -34,7 +34,7 @@ const actionRowStyles = (theme: Theme) => css` min-height: 40px; text-align: left; color: ${themes[theme].primary["600"]}; - font-weight: 700; + font-weight: 500; > span { display: block; diff --git a/apps/browser/src/autofill/overlay/inline-menu/pages/list/list.scss b/apps/browser/src/autofill/overlay/inline-menu/pages/list/list.scss index 93f5f647ffe..ee9c68ee603 100644 --- a/apps/browser/src/autofill/overlay/inline-menu/pages/list/list.scss +++ b/apps/browser/src/autofill/overlay/inline-menu/pages/list/list.scss @@ -82,7 +82,7 @@ body * { width: 100%; font-family: $font-family-sans-serif; font-size: 1.6rem; - font-weight: 700; + font-weight: 500; text-align: left; background: transparent; border: none; @@ -187,7 +187,7 @@ body * { top: 0; z-index: 1; font-family: $font-family-sans-serif; - font-weight: 600; + font-weight: 500; font-size: 1rem; line-height: 1.3; letter-spacing: 0.025rem; diff --git a/apps/desktop/src/autofill/components/autotype-shortcut.component.html b/apps/desktop/src/autofill/components/autotype-shortcut.component.html index 774c299e0b6..6f73d4006ac 100644 --- a/apps/desktop/src/autofill/components/autotype-shortcut.component.html +++ b/apps/desktop/src/autofill/components/autotype-shortcut.component.html @@ -1,6 +1,6 @@
-
+
{{ "typeShortcut" | i18n }}
From d364dfdda07dbba6561a0ee446d938fe2ea78c52 Mon Sep 17 00:00:00 2001 From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com> Date: Tue, 4 Nov 2025 10:59:00 -0800 Subject: [PATCH 7/7] [PM-26182] - [Defect] [Browser] Safari - Autofill on page load default setting is missing yes or no (#16605) * handle parenthesis translation * add whitespace around placeholder with parentheses * fix test * fix label * fix spec --- apps/browser/src/_locales/en/messages.json | 10 ++++++++++ .../autofill-options.component.spec.ts | 4 ++-- .../autofill-options/autofill-options.component.ts | 5 ++++- .../autofill-options/uri-option.component.spec.ts | 6 +++--- .../autofill-options/uri-option.component.ts | 2 +- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index a7fe29e85d4..a8743b0db68 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -4974,6 +4974,16 @@ } } }, + "defaultLabelWithValue": { + "message": "Default ( $VALUE$ )", + "description": "A label that indicates the default value for a field with the current default value in parentheses.", + "placeholders": { + "value": { + "content": "$1", + "example": "Base domain" + } + } + }, "showMatchDetection": { "message": "Show match detection $WEBSITE$", "placeholders": { diff --git a/libs/vault/src/cipher-form/components/autofill-options/autofill-options.component.spec.ts b/libs/vault/src/cipher-form/components/autofill-options/autofill-options.component.spec.ts index 3aeeac6ca92..f1bb1ef942b 100644 --- a/libs/vault/src/cipher-form/components/autofill-options/autofill-options.component.spec.ts +++ b/libs/vault/src/cipher-form/components/autofill-options/autofill-options.component.spec.ts @@ -201,12 +201,12 @@ describe("AutofillOptionsComponent", () => { it("updates the default autofill on page load label", () => { fixture.detectChanges(); - expect(component["autofillOptions"][0].label).toEqual("defaultLabel no"); + expect(component["autofillOptions"][0].label).toEqual("defaultLabelWithValue no"); (autofillSettingsService.autofillOnPageLoadDefault$ as BehaviorSubject).next(true); fixture.detectChanges(); - expect(component["autofillOptions"][0].label).toEqual("defaultLabel yes"); + expect(component["autofillOptions"][0].label).toEqual("defaultLabelWithValue yes"); }); it("hides the autofill on page load field when the setting is disabled", () => { diff --git a/libs/vault/src/cipher-form/components/autofill-options/autofill-options.component.ts b/libs/vault/src/cipher-form/components/autofill-options/autofill-options.component.ts index e6b8b5c9aca..7215b1d6c67 100644 --- a/libs/vault/src/cipher-form/components/autofill-options/autofill-options.component.ts +++ b/libs/vault/src/cipher-form/components/autofill-options/autofill-options.component.ts @@ -218,7 +218,10 @@ export class AutofillOptionsComponent implements OnInit { return; } - this.autofillOptions[0].label = this.i18nService.t("defaultLabel", defaultOption.label); + this.autofillOptions[0].label = this.i18nService.t( + "defaultLabelWithValue", + defaultOption.label, + ); // Trigger change detection to update the label in the template this.autofillOptions = [...this.autofillOptions]; }); diff --git a/libs/vault/src/cipher-form/components/autofill-options/uri-option.component.spec.ts b/libs/vault/src/cipher-form/components/autofill-options/uri-option.component.spec.ts index 2d06f5dcc29..ed70b4381d2 100644 --- a/libs/vault/src/cipher-form/components/autofill-options/uri-option.component.spec.ts +++ b/libs/vault/src/cipher-form/components/autofill-options/uri-option.component.spec.ts @@ -77,19 +77,19 @@ describe("UriOptionComponent", () => { component.defaultMatchDetection = UriMatchStrategy.Domain; fixture.detectChanges(); - expect(component["uriMatchOptions"][0].label).toBe("defaultLabel baseDomain"); + expect(component["uriMatchOptions"][0].label).toBe("defaultLabelWithValue baseDomain"); }); it("should update the default uri match strategy label", () => { component.defaultMatchDetection = UriMatchStrategy.Exact; fixture.detectChanges(); - expect(component["uriMatchOptions"][0].label).toBe("defaultLabel exact"); + expect(component["uriMatchOptions"][0].label).toBe("defaultLabelWithValue exact"); component.defaultMatchDetection = UriMatchStrategy.StartsWith; fixture.detectChanges(); - expect(component["uriMatchOptions"][0].label).toBe("defaultLabel startsWith"); + expect(component["uriMatchOptions"][0].label).toBe("defaultLabelWithValue startsWith"); }); it("should focus the uri input when focusInput is called", () => { diff --git a/libs/vault/src/cipher-form/components/autofill-options/uri-option.component.ts b/libs/vault/src/cipher-form/components/autofill-options/uri-option.component.ts index b61109a45bb..34ac284c3f3 100644 --- a/libs/vault/src/cipher-form/components/autofill-options/uri-option.component.ts +++ b/libs/vault/src/cipher-form/components/autofill-options/uri-option.component.ts @@ -124,7 +124,7 @@ export class UriOptionComponent implements ControlValueAccessor { } this.uriMatchOptions[0].label = this.i18nService.t( - "defaultLabel", + "defaultLabelWithValue", this.uriMatchOptions.find((o) => o.value === value)?.label, ); }