From 795780da66c29453d935d0acc3f04fb474bfc96b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 19:23:40 +0000 Subject: [PATCH] Update dependency typescript to v5.9.3 (#30492) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- package.json | 2 +- ...atrix-org+react-sdk-module-api+2.5.0.patch | 47 +++++++++++++++++++ playwright/pages/bot.ts | 22 ++------- src/SecurityManager.ts | 10 ++-- .../security/CreateSecretStorageDialog.tsx | 2 +- src/audio/VoiceMessageRecording.ts | 2 +- src/utils/MegolmExportEncryption.ts | 10 ++-- src/utils/arrays.ts | 4 +- src/utils/tokens/pickling.ts | 4 +- src/utils/tokens/tokens.ts | 2 +- test/setup/setupManualMocks.ts | 3 +- .../audio/VoiceMessageRecording-test.ts | 2 +- .../utils/MegolmExportEncryption-test.ts | 4 +- yarn.lock | 8 ++-- 14 files changed, 81 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index f38df33e4e..ca45e3c015 100644 --- a/package.json +++ b/package.json @@ -294,7 +294,7 @@ "stylelint-value-no-unknown-custom-properties": "^6.0.1", "terser-webpack-plugin": "^5.3.9", "testcontainers": "^11.0.0", - "typescript": "5.8.3", + "typescript": "5.9.3", "util": "^0.12.5", "web-streams-polyfill": "^4.0.0", "webpack": "^5.89.0", diff --git a/patches/@matrix-org+react-sdk-module-api+2.5.0.patch b/patches/@matrix-org+react-sdk-module-api+2.5.0.patch index 89cbca457f..17943f892d 100644 --- a/patches/@matrix-org+react-sdk-module-api+2.5.0.patch +++ b/patches/@matrix-org+react-sdk-module-api+2.5.0.patch @@ -11,6 +11,53 @@ index 917a7fc..a2710c6 100644 didOkOrSubmit: boolean; model: M; }>; +diff --git a/node_modules/@matrix-org/react-sdk-module-api/lib/lifecycles/CryptoSetupExtensions.d.ts b/node_modules/@matrix-org/react-sdk-module-api/lib/lifecycles/CryptoSetupExtensions.d.ts +index cb5f2e5..51daa51 100644 +--- a/node_modules/@matrix-org/react-sdk-module-api/lib/lifecycles/CryptoSetupExtensions.d.ts ++++ b/node_modules/@matrix-org/react-sdk-module-api/lib/lifecycles/CryptoSetupExtensions.d.ts +@@ -66,23 +66,23 @@ export interface SetupEncryptionStoreProjection { + export interface ProvideCryptoSetupExtensions { + examineLoginResponse(response: any, credentials: ExtendedMatrixClientCreds): void; + persistCredentials(credentials: ExtendedMatrixClientCreds): void; +- getSecretStorageKey(): Uint8Array | null; +- createSecretStorageKey(): Uint8Array | null; ++ getSecretStorageKey(): Uint8Array | null; ++ createSecretStorageKey(): Uint8Array | null; + catchAccessSecretStorageError(e: Error): void; + setupEncryptionNeeded: (args: CryptoSetupArgs) => boolean; + /** @deprecated This callback is no longer used by matrix-react-sdk */ +- getDehydrationKeyCallback(): ((keyInfo: SecretStorageKeyDescription, checkFunc: (key: Uint8Array) => void) => Promise) | null; ++ getDehydrationKeyCallback(): ((keyInfo: SecretStorageKeyDescription, checkFunc: (key: Uint8Array) => void) => Promise>) | null; + SHOW_ENCRYPTION_SETUP_UI: boolean; + } + export declare abstract class CryptoSetupExtensionsBase implements ProvideCryptoSetupExtensions { + abstract examineLoginResponse(response: any, credentials: ExtendedMatrixClientCreds): void; + abstract persistCredentials(credentials: ExtendedMatrixClientCreds): void; +- abstract getSecretStorageKey(): Uint8Array | null; +- abstract createSecretStorageKey(): Uint8Array | null; ++ abstract getSecretStorageKey(): Uint8Array | null; ++ abstract createSecretStorageKey(): Uint8Array | null; + abstract catchAccessSecretStorageError(e: Error): void; + abstract setupEncryptionNeeded(args: CryptoSetupArgs): boolean; + /** `getDehydrationKeyCallback` is no longer used; we provide an empty impl for type compatibility. */ +- getDehydrationKeyCallback(): ((keyInfo: SecretStorageKeyDescription, checkFunc: (key: Uint8Array) => void) => Promise) | null; ++ getDehydrationKeyCallback(): ((keyInfo: SecretStorageKeyDescription, checkFunc: (key: Uint8Array) => void) => Promise>) | null; + abstract SHOW_ENCRYPTION_SETUP_UI: boolean; + } + export interface CryptoSetupArgs { +@@ -98,9 +98,9 @@ export declare class DefaultCryptoSetupExtensions extends CryptoSetupExtensionsB + SHOW_ENCRYPTION_SETUP_UI: boolean; + examineLoginResponse(response: any, credentials: ExtendedMatrixClientCreds): void; + persistCredentials(credentials: ExtendedMatrixClientCreds): void; +- getSecretStorageKey(): Uint8Array | null; +- createSecretStorageKey(): Uint8Array | null; ++ getSecretStorageKey(): Uint8Array | null; ++ createSecretStorageKey(): Uint8Array | null; + catchAccessSecretStorageError(e: Error): void; + setupEncryptionNeeded(args: CryptoSetupArgs): boolean; +- getDehydrationKeyCallback(): ((keyInfo: SecretStorageKeyDescription, checkFunc: (key: Uint8Array) => void) => Promise) | null; ++ getDehydrationKeyCallback(): ((keyInfo: SecretStorageKeyDescription, checkFunc: (key: Uint8Array) => void) => Promise>) | null; + } diff --git a/node_modules/@matrix-org/react-sdk-module-api/lib/lifecycles/CryptoSetupExtensions.js b/node_modules/@matrix-org/react-sdk-module-api/lib/lifecycles/CryptoSetupExtensions.js index 5d422ed..b823add 100644 --- a/node_modules/@matrix-org/react-sdk-module-api/lib/lifecycles/CryptoSetupExtensions.js diff --git a/playwright/pages/bot.ts b/playwright/pages/bot.ts index c3168a89ac..300721d0ec 100644 --- a/playwright/pages/bot.ts +++ b/playwright/pages/bot.ts @@ -13,7 +13,7 @@ import { type MatrixClient } from "matrix-js-sdk/src/matrix"; import type { Logger } from "matrix-js-sdk/src/logger"; import type { SecretStorageKeyDescription } from "matrix-js-sdk/src/secret-storage"; import type { Credentials, HomeserverInstance } from "../plugins/homeserver"; -import type { GeneratedSecretStorageKey } from "matrix-js-sdk/src/crypto-api"; +import type { CryptoCallbacks, GeneratedSecretStorageKey } from "matrix-js-sdk/src/crypto-api"; import { bootstrapCrossSigningForClient, Client } from "./client"; export interface CredentialsOptionalAccessToken extends Omit { @@ -141,22 +141,12 @@ export class Bot extends Client { const logger = getLogger(`bot ${credentials.userId}`); - const keys = {}; - - const getCrossSigningKey = (type: string) => { - return keys[type]; - }; - - const saveCrossSigningKeys = (k: Record) => { - Object.assign(keys, k); - }; - // Store the cached secret storage key and return it when `getSecretStorageKey` is called - let cachedKey: { keyId: string; key: Uint8Array }; + let cachedKey: { keyId: string; key: Uint8Array }; const cacheSecretStorageKey = ( keyId: string, keyInfo: SecretStorageKeyDescription, - key: Uint8Array, + key: Uint8Array, ) => { cachedKey = { keyId, @@ -165,11 +155,9 @@ export class Bot extends Client { }; const getSecretStorageKey = () => - Promise.resolve<[string, Uint8Array]>([cachedKey.keyId, cachedKey.key]); + Promise.resolve<[string, Uint8Array]>([cachedKey.keyId, cachedKey.key]); - const cryptoCallbacks = { - getCrossSigningKey, - saveCrossSigningKeys, + const cryptoCallbacks: CryptoCallbacks = { cacheSecretStorageKey, getSecretStorageKey, }; diff --git a/src/SecurityManager.ts b/src/SecurityManager.ts index a5be789c8a..84642626e8 100644 --- a/src/SecurityManager.ts +++ b/src/SecurityManager.ts @@ -25,7 +25,7 @@ import InteractiveAuthDialog from "./components/views/dialogs/InteractiveAuthDia // during the same single operation. Use `accessSecretStorage` below to scope a // single secret storage operation, as it will clear the cached keys once the // operation ends. -let secretStorageKeys: Record = {}; +let secretStorageKeys: Record> = {}; let secretStorageKeyInfo: Record = {}; let secretStorageBeingAccessed = false; @@ -50,8 +50,8 @@ export class AccessCancelledError extends Error { function makeInputToKey( keyInfo: SecretStorage.SecretStorageKeyDescription, -): (keyParams: KeyParams) => Promise { - return async ({ passphrase, recoveryKey }): Promise => { +): (keyParams: KeyParams) => Promise> { + return async ({ passphrase, recoveryKey }): Promise> => { if (passphrase) { return deriveRecoveryKeyFromPassphrase(passphrase, keyInfo.passphrase.salt, keyInfo.passphrase.iterations); } else if (recoveryKey) { @@ -68,7 +68,7 @@ async function getSecretStorageKey( keys: Record; }, secretName: string, -): Promise<[string, Uint8Array]> { +): Promise<[string, Uint8Array]> { const cli = MatrixClientPeg.safeGet(); const defaultKeyId = await cli.secretStorage.getDefaultKeyId(); @@ -138,7 +138,7 @@ async function getSecretStorageKey( function cacheSecretStorageKey( keyId: string, keyInfo: SecretStorage.SecretStorageKeyDescription, - key: Uint8Array, + key: Uint8Array, ): void { if (secretStorageBeingAccessed) { logger.debug(`Caching 4S key ${keyId}`); diff --git a/src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx b/src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx index 902bf4d780..9abb4d147d 100644 --- a/src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx +++ b/src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx @@ -112,7 +112,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent): void { logger.log("CryptoSetupExtension: Created key via extension, jumping to bootstrap step"); this.recoveryKey = { privateKey: keyFromCustomisations, diff --git a/src/audio/VoiceMessageRecording.ts b/src/audio/VoiceMessageRecording.ts index 1b15896e97..c9d7a71f6e 100644 --- a/src/audio/VoiceMessageRecording.ts +++ b/src/audio/VoiceMessageRecording.ts @@ -142,7 +142,7 @@ export class VoiceMessageRecording implements IDestroyable { this.buffer = concat(this.buffer, buf); }; - private get audioBuffer(): Uint8Array { + private get audioBuffer(): Uint8Array { // We need a clone of the buffer to avoid accidentally changing the position // on the real thing. return this.buffer.slice(0); diff --git a/src/utils/MegolmExportEncryption.ts b/src/utils/MegolmExportEncryption.ts index 60d4a687cf..818f20b532 100644 --- a/src/utils/MegolmExportEncryption.ts +++ b/src/utils/MegolmExportEncryption.ts @@ -180,7 +180,11 @@ export async function encryptMegolmKeyFile( * @param {String} password password * @return {Promise<[CryptoKey, CryptoKey]>} promise for [aes key, hmac key] */ -async function deriveKeys(salt: Uint8Array, iterations: number, password: string): Promise<[CryptoKey, CryptoKey]> { +async function deriveKeys( + salt: Uint8Array, + iterations: number, + password: string, +): Promise<[CryptoKey, CryptoKey]> { const start = new Date(); let key; @@ -249,7 +253,7 @@ const TRAILER_LINE = "-----END MEGOLM SESSION DATA-----"; * @param {ArrayBuffer} data input file * @return {Uint8Array} unbase64ed content */ -function unpackMegolmKeyFile(data: ArrayBuffer): Uint8Array { +function unpackMegolmKeyFile(data: ArrayBuffer): Uint8Array { // parse the file as a great big String. This should be safe, because there // should be no non-ASCII characters, and it means that we can do string // comparisons to find the header and footer, and feed it into window.atob. @@ -340,7 +344,7 @@ function encodeBase64(uint8Array: Uint8Array): string { * @param {string} base64 The base64 to decode. * @return {Uint8Array} The decoded data. */ -function decodeBase64(base64: string): Uint8Array { +function decodeBase64(base64: string): Uint8Array { // window.atob returns a unicode string with codepoints in the range 0-255. const latin1String = window.atob(base64); // Encode the string as a Uint8Array diff --git a/src/utils/arrays.ts b/src/utils/arrays.ts index 392436eee8..63b16a6f72 100644 --- a/src/utils/arrays.ts +++ b/src/utils/arrays.ts @@ -297,8 +297,8 @@ export class GroupedArray { } } -export const concat = (...arrays: Uint8Array[]): Uint8Array => { - return arrays.reduce((concatenatedSoFar: Uint8Array, toBeConcatenated: Uint8Array) => { +export const concat = (...arrays: Uint8Array[]): Uint8Array => { + return arrays.reduce((concatenatedSoFar: Uint8Array, toBeConcatenated: Uint8Array) => { const concatenated = new Uint8Array(concatenatedSoFar.length + toBeConcatenated.length); concatenated.set(concatenatedSoFar, 0); concatenated.set(toBeConcatenated, concatenatedSoFar.length); diff --git a/src/utils/tokens/pickling.ts b/src/utils/tokens/pickling.ts index 3284d3f9cf..3415624e64 100644 --- a/src/utils/tokens/pickling.ts +++ b/src/utils/tokens/pickling.ts @@ -48,7 +48,7 @@ export interface EncryptedPickleKey { * @param {string} deviceId The device ID which owns the pickle key. * @return {Uint8Array} The additional data as a Uint8Array. */ -export function getPickleAdditionalData(userId: string, deviceId: string): Uint8Array { +export function getPickleAdditionalData(userId: string, deviceId: string): Uint8Array { const additionalData = new Uint8Array(userId.length + deviceId.length + 1); for (let i = 0; i < userId.length; i++) { additionalData[i] = userId.charCodeAt(i); @@ -70,7 +70,7 @@ export function getPickleAdditionalData(userId: string, deviceId: string): Uint8 * @returns Data object ready for storing in indexeddb. */ export async function encryptPickleKey( - pickleKey: Uint8Array, + pickleKey: Uint8Array, userId: string, deviceId: string, ): Promise { diff --git a/src/utils/tokens/tokens.ts b/src/utils/tokens/tokens.ts index 9716e5af8a..ec01ca199e 100644 --- a/src/utils/tokens/tokens.ts +++ b/src/utils/tokens/tokens.ts @@ -39,7 +39,7 @@ export const HAS_REFRESH_TOKEN_STORAGE_KEY = "mx_has_refresh_token"; * @param pickleKey * @returns AES key */ -async function pickleKeyToAesKey(pickleKey: string): Promise { +async function pickleKeyToAesKey(pickleKey: string): Promise> { const pickleKeyBuffer = new Uint8Array(pickleKey.length); for (let i = 0; i < pickleKey.length; i++) { pickleKeyBuffer[i] = pickleKey.charCodeAt(i); diff --git a/test/setup/setupManualMocks.ts b/test/setup/setupManualMocks.ts index 7c49b33e03..ff386a8a0a 100644 --- a/test/setup/setupManualMocks.ts +++ b/test/setup/setupManualMocks.ts @@ -64,7 +64,8 @@ global.URL.revokeObjectURL = jest.fn(); // polyfilling TextEncoder as it is not available on JSDOM // view https://github.com/facebook/jest/issues/9983 -global.TextEncoder = TextEncoder; +// XXX: Node's implementation has marginally different types, so we fudge it +(globalThis as any).TextEncoder = TextEncoder; // @ts-ignore global.TextDecoder = TextDecoder; diff --git a/test/unit-tests/audio/VoiceMessageRecording-test.ts b/test/unit-tests/audio/VoiceMessageRecording-test.ts index aec34fa236..6694f861a6 100644 --- a/test/unit-tests/audio/VoiceMessageRecording-test.ts +++ b/test/unit-tests/audio/VoiceMessageRecording-test.ts @@ -118,7 +118,7 @@ describe("VoiceMessageRecording", () => { const encryptedFile = {} as unknown as EncryptedFile; beforeEach(() => { - voiceRecording.onDataAvailable!(testBuf); + voiceRecording.onDataAvailable!(testBuf.buffer); }); it("contentLength should return the buffer length", () => { diff --git a/test/unit-tests/utils/MegolmExportEncryption-test.ts b/test/unit-tests/utils/MegolmExportEncryption-test.ts index 0d963ec11a..1719313795 100644 --- a/test/unit-tests/utils/MegolmExportEncryption-test.ts +++ b/test/unit-tests/utils/MegolmExportEncryption-test.ts @@ -59,8 +59,8 @@ const TEST_VECTORS = [ ], ]; -function stringToArray(s: string): ArrayBufferLike { - return new TextEncoder().encode(s).buffer; +function stringToArray(s: string): ArrayBuffer { + return new TextEncoder().encode(s).buffer as ArrayBuffer; } describe("MegolmExportEncryption", function () { diff --git a/yarn.lock b/yarn.lock index 5e64107fd4..a684a5532e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13330,10 +13330,10 @@ typed-array-length@^1.0.7: possible-typed-array-names "^1.0.0" reflect.getprototypeof "^1.0.6" -typescript@5.8.3: - version "5.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" - integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== +typescript@5.9.3: + version "5.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== ua-parser-js@1.0.40: version "1.0.40"