Update zxcvbn-ts monorepo to v4 (#33880)

* Update zxcvbn-ts monorepo to v4

* Handle breaking changes

* Improve coverage

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
renovate[bot]
2026-06-18 11:17:50 +00:00
committed by GitHub
co-authored by renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Michael Telatynski
parent 659eab8965
commit 90fb221a8e
4 changed files with 77 additions and 24 deletions
+3 -3
View File
@@ -53,9 +53,9 @@
"@vector-im/compound-design-tokens": "catalog:",
"@vector-im/compound-web": "catalog:",
"@vector-im/matrix-wysiwyg": "2.40.0",
"@zxcvbn-ts/core": "^3.0.4",
"@zxcvbn-ts/language-common": "^3.0.4",
"@zxcvbn-ts/language-en": "^3.0.2",
"@zxcvbn-ts/core": "^4.0.0",
"@zxcvbn-ts/language-common": "^4.0.0",
"@zxcvbn-ts/language-en": "^4.0.0",
"await-lock": "^3.0.0",
"bloom-filters": "^3.0.3",
"blurhash": "^2.0.3",
+37
View File
@@ -0,0 +1,37 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { vi, describe, it, expect } from "vitest";
import { ZxcvbnFactory } from "@zxcvbn-ts/core";
import { scorePassword, baseOptions } from "./PasswordScorer.ts";
vi.mock("../languageHandler", () => ({
getCurrentLanguage: vi.fn().mockReturnValue("en"),
_t: vi.fn((k) => k),
}));
vi.mock("../SdkConfig", () => ({
default: {
get: vi.fn().mockReturnValue({
brand: "BRAND",
}),
},
}));
describe("scorePassword", () => {
const baseZxcvbn = new ZxcvbnFactory(baseOptions);
it("should handle inputs with spaces by removing them", () => {
const input = "apple banana cherry";
const baseResult = baseZxcvbn.check(input);
const output = scorePassword(null, input);
expect(output).toBeDefined();
expect(output!.score).toBe(3);
expect(output!.score).toBeLessThan(baseResult.score);
});
});
+13 -6
View File
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
Please see LICENSE files in the repository root for full details.
*/
import { zxcvbn, zxcvbnOptions, type ZxcvbnResult, type TranslationKeys } from "@zxcvbn-ts/core";
import { ZxcvbnFactory, type ZxcvbnResult, type TranslationKeys } from "@zxcvbn-ts/core";
import * as zxcvbnCommonPackage from "@zxcvbn-ts/language-common";
import * as zxcvbnEnPackage from "@zxcvbn-ts/language-en";
import { type MatrixClient } from "matrix-js-sdk/src/matrix";
@@ -13,7 +13,11 @@ import { type MatrixClient } from "matrix-js-sdk/src/matrix";
import { _t } from "../languageHandler";
import SdkConfig from "../SdkConfig";
zxcvbnOptions.setOptions({
/**
* Base zxcvbn options
* @knipignore - exported for tests
*/
export const baseOptions = {
dictionary: {
...zxcvbnCommonPackage.dictionary,
...zxcvbnEnPackage.dictionary,
@@ -21,7 +25,7 @@ zxcvbnOptions.setOptions({
},
graphs: zxcvbnCommonPackage.adjacencyGraphs,
useLevenshteinDistance: true,
});
};
function getTranslations(): TranslationKeys {
return {
@@ -95,12 +99,15 @@ export function scorePassword(
}
}
zxcvbnOptions.setTranslations(getTranslations());
const zxcvbn = new ZxcvbnFactory({
...baseOptions,
translations: getTranslations(),
});
let zxcvbnResult = zxcvbn(password, inputs);
let zxcvbnResult = zxcvbn.check(password, inputs);
// Work around https://github.com/dropbox/zxcvbn/issues/216
if (password.includes(" ")) {
const resultNoSpaces = zxcvbn(password.replace(/ /g, ""), inputs);
const resultNoSpaces = zxcvbn.check(password.replace(/ /g, ""), inputs);
if (resultNoSpaces.score < zxcvbnResult.score) zxcvbnResult = resultNoSpaces;
}
+24 -15
View File
@@ -544,14 +544,14 @@ importers:
specifier: 2.40.0
version: 2.40.0(patch_hash=7bdf6150f2905bc2f055a6bcaa7b9d78fa7ffde82e800bcc454ac7b0096bd65e)(react@19.2.7)
'@zxcvbn-ts/core':
specifier: ^3.0.4
version: 3.0.4
specifier: ^4.0.0
version: 4.1.2
'@zxcvbn-ts/language-common':
specifier: ^3.0.4
version: 3.0.4
specifier: ^4.0.0
version: 4.1.2
'@zxcvbn-ts/language-en':
specifier: ^3.0.2
version: 3.0.2
specifier: ^4.0.0
version: 4.1.1
await-lock:
specifier: ^3.0.0
version: 3.0.0(patch_hash=b767a571946a4f8710ac54b1a7bec8a7c1570f9b85d75922392fae20d0578964)
@@ -6784,14 +6784,17 @@ packages:
resolution: {integrity: sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==}
hasBin: true
'@zxcvbn-ts/core@3.0.4':
resolution: {integrity: sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw==}
'@zxcvbn-ts/core@4.1.2':
resolution: {integrity: sha512-RQmxWB3AMI+HGQErQdUv6Aq32aQhp6xOxrfgCP0+T9MsLZoP3xtLHuT8O8VojsUxdmQVZfJlYkYb1A0wOwIS+Q==}
'@zxcvbn-ts/language-common@3.0.4':
resolution: {integrity: sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw==}
'@zxcvbn-ts/dictionary-compression@3.0.1':
resolution: {integrity: sha512-p3KyPzxGc3vWSap5hHA6SllbUCmh7s+NtpGyC3qEWrxYJT9t9TUAzjPm48Okipo+UUyPQfDlIvTcs9JRShBFiQ==}
'@zxcvbn-ts/language-en@3.0.2':
resolution: {integrity: sha512-Zp+zL+I6Un2Bj0tRXNs6VUBq3Djt+hwTwUz4dkt2qgsQz47U0/XthZ4ULrT/RxjwJRl5LwiaKOOZeOtmixHnjg==}
'@zxcvbn-ts/language-common@4.1.2':
resolution: {integrity: sha512-uJlBzhC9/KjPImqdnc1/lPxmdn4xKbkruN5p1mASWkXA0gli+GZ5LrVL+dqscA8Pcf4OfudE56TtCWeHljJOvA==}
'@zxcvbn-ts/language-en@4.1.1':
resolution: {integrity: sha512-6UdzuBd3Uex8TKubohcn+uXRVAH34Zjs2eCfT4hQVo9zeTy7AkQRQfdV4OnHR5hQfW/XBrK/AGTZk7VBWh7wwQ==}
abbrev@4.0.0:
resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==}
@@ -19801,13 +19804,19 @@ snapshots:
dependencies:
argparse: 2.0.1
'@zxcvbn-ts/core@3.0.4':
'@zxcvbn-ts/core@4.1.2':
dependencies:
fastest-levenshtein: 1.0.16
'@zxcvbn-ts/language-common@3.0.4': {}
'@zxcvbn-ts/dictionary-compression@3.0.1': {}
'@zxcvbn-ts/language-en@3.0.2': {}
'@zxcvbn-ts/language-common@4.1.2':
dependencies:
'@zxcvbn-ts/dictionary-compression': 3.0.1
'@zxcvbn-ts/language-en@4.1.1':
dependencies:
'@zxcvbn-ts/dictionary-compression': 3.0.1
abbrev@4.0.0: {}