From a367ccdc9ebc71ecd70e0197d5bc9757f16b7d2e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Aug 2025 12:16:03 +0000 Subject: [PATCH 1/3] Update dependency typescript to v5.9.2 --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index af98445abf..eb91686eaa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6729,9 +6729,9 @@ typedoc@^0.28.1: yaml "^2.8.0" typescript@^5.4.2: - version "5.8.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e" - integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ== + version "5.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" + integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== uc.micro@^2.0.0, uc.micro@^2.1.0: version "2.1.0" From 029fb28f29a6ee393778b63de3580b4c70e6374e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 21 Aug 2025 15:41:42 +0100 Subject: [PATCH 2/3] Fix up types Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- package.json | 2 +- spec/integ/crypto/cross-signing.spec.ts | 2 +- spec/integ/crypto/crypto.spec.ts | 11 +++++++--- spec/unit/oidc/authorize.spec.ts | 3 ++- src/@types/global.d.ts | 20 ------------------ src/base64.ts | 26 ++++++++++++++++++++++-- src/crypto-api/index.ts | 16 +++++++-------- src/crypto-api/key-passphrase.ts | 2 +- src/rust-crypto/libolm_migration.ts | 4 ++-- src/rust-crypto/rust-crypto.ts | 3 ++- src/secret-storage.ts | 11 ++++++---- src/utils/decryptAESSecretStorageItem.ts | 2 +- src/utils/encryptAESSecretStorageItem.ts | 4 ++-- src/utils/internal/deriveKeys.ts | 2 +- src/webrtc/callFeed.ts | 2 +- yarn.lock | 15 +++++++++----- 16 files changed, 71 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 32cdc551a0..3baf1a85ec 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "@types/content-type": "^1.1.5", "@types/debug": "^4.1.7", "@types/jest": "^29.0.0", - "@types/node": "18", + "@types/node": "^22", "@types/sdp-transform": "^2.4.5", "@typescript-eslint/eslint-plugin": "^8.0.0", "@typescript-eslint/parser": "^8.0.0", diff --git a/spec/integ/crypto/cross-signing.spec.ts b/spec/integ/crypto/cross-signing.spec.ts index 64b5d53ab4..9f79ba66e7 100644 --- a/spec/integ/crypto/cross-signing.spec.ts +++ b/spec/integ/crypto/cross-signing.spec.ts @@ -74,7 +74,7 @@ describe("cross-signing", () => { function createCryptoCallbacks(): CryptoCallbacks { return { getSecretStorageKey: (keys, name) => { - return Promise.resolve<[string, Uint8Array]>(["key_id", encryptionKey]); + return Promise.resolve<[string, Uint8Array]>(["key_id", encryptionKey]); }, }; } diff --git a/spec/integ/crypto/crypto.spec.ts b/spec/integ/crypto/crypto.spec.ts index e1f541a92b..64007fe871 100644 --- a/spec/integ/crypto/crypto.spec.ts +++ b/spec/integ/crypto/crypto.spec.ts @@ -321,15 +321,20 @@ describe("crypto", () => { */ function createCryptoCallbacks(): CryptoCallbacks { // Store the cached secret storage key and return it when `getSecretStorageKey` is called - let cachedKey: { keyId: string; key: Uint8Array }; - const cacheSecretStorageKey = (keyId: string, keyInfo: SecretStorageKeyDescription, key: Uint8Array) => { + let cachedKey: { keyId: string; key: Uint8Array }; + const cacheSecretStorageKey = ( + keyId: string, + keyInfo: SecretStorageKeyDescription, + key: Uint8Array, + ) => { cachedKey = { keyId, key, }; }; - const getSecretStorageKey = () => Promise.resolve<[string, Uint8Array]>([cachedKey.keyId, cachedKey.key]); + const getSecretStorageKey = () => + Promise.resolve<[string, Uint8Array]>([cachedKey.keyId, cachedKey.key]); return { cacheSecretStorageKey, diff --git a/spec/unit/oidc/authorize.spec.ts b/spec/unit/oidc/authorize.spec.ts index e313778602..11bc0fb838 100644 --- a/spec/unit/oidc/authorize.spec.ts +++ b/spec/unit/oidc/authorize.spec.ts @@ -53,7 +53,8 @@ describe("oidc authorization", () => { jest.setSystemTime(now); fetchMock.get(delegatedAuthConfig.issuer + ".well-known/openid-configuration", mockOpenIdConfiguration()); - globalThis.TextEncoder = TextEncoder; + // XXX: jsdom lacks a TextEncoder and Node's implementation has marginally different types, so we fudge it + (globalThis as any).TextEncoder = TextEncoder; }); beforeEach(() => { diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index b89aefa995..2f18b74d01 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -44,24 +44,4 @@ declare global { // on webkit: we should check if we still need to do this webkitGetUserMedia?: unknown; } - - export interface Uint8ArrayToBase64Options { - alphabet?: "base64" | "base64url"; - omitPadding?: boolean; - } - - interface Uint8Array { - // https://tc39.es/proposal-arraybuffer-base64/spec/#sec-uint8array.prototype.tobase64 - toBase64?(options?: Uint8ArrayToBase64Options): string; - } - - export interface Uint8ArrayFromBase64Options { - alphabet?: "base64"; // Our fallback code only handles base64. - lastChunkHandling?: "loose"; // Our fallback code doesn't support other handling at this time. - } - - interface Uint8ArrayConstructor { - // https://tc39.es/proposal-arraybuffer-base64/spec/#sec-uint8array.frombase64 - fromBase64?(base64: string, options?: Uint8ArrayFromBase64Options): Uint8Array; - } } diff --git a/src/base64.ts b/src/base64.ts index 4cb876b876..978e4e9703 100644 --- a/src/base64.ts +++ b/src/base64.ts @@ -18,6 +18,28 @@ limitations under the License. * Base64 encoding and decoding utilities */ +declare global { + export interface Uint8ArrayToBase64Options { + alphabet?: "base64" | "base64url"; + omitPadding?: boolean; + } + + interface Uint8Array { + // https://tc39.es/proposal-arraybuffer-base64/spec/#sec-uint8array.prototype.tobase64 + toBase64?(options?: Uint8ArrayToBase64Options): string; + } + + export interface Uint8ArrayFromBase64Options { + alphabet?: "base64"; // Our fallback code only handles base64. + lastChunkHandling?: "loose"; // Our fallback code doesn't support other handling at this time. + } + + interface Uint8ArrayConstructor { + // https://tc39.es/proposal-arraybuffer-base64/spec/#sec-uint8array.frombase64 + fromBase64?(base64: string, options?: Uint8ArrayFromBase64Options): Uint8Array; + } +} + function toBase64(uint8Array: Uint8Array, options: Uint8ArrayToBase64Options): string { if (typeof uint8Array.toBase64 === "function") { // Currently this is only supported in Firefox, @@ -64,7 +86,7 @@ export function encodeUnpaddedBase64Url(uint8Array: Uint8Array): string { return toBase64(uint8Array, { alphabet: "base64url", omitPadding: true }); } -function fromBase64(base64: string, options: Uint8ArrayFromBase64Options): Uint8Array { +function fromBase64(base64: string, options: Uint8ArrayFromBase64Options): Uint8Array { if (typeof Uint8Array.fromBase64 === "function") { // Currently this is only supported in Firefox, // but we match the options in the hope in the future we can rely on it for all environments. @@ -80,7 +102,7 @@ function fromBase64(base64: string, options: Uint8ArrayFromBase64Options): Uint8 * @param base64 - The base64 to decode. * @returns The decoded data. */ -export function decodeBase64(base64: string): Uint8Array { +export function decodeBase64(base64: string): Uint8Array { // The function requires us to select an alphabet, but we don't know if base64url was used so we convert. return fromBase64(base64.replace(/-/g, "+").replace(/_/g, "/"), { alphabet: "base64", lastChunkHandling: "loose" }); } diff --git a/src/crypto-api/index.ts b/src/crypto-api/index.ts index 518c646ddc..aacafc7ffb 100644 --- a/src/crypto-api/index.ts +++ b/src/crypto-api/index.ts @@ -1191,12 +1191,12 @@ export interface CryptoCallbacks { keys: Record; }, name: string, - ) => Promise<[string, Uint8Array] | null>; + ) => Promise<[string, Uint8Array] | null>; /** @deprecated: unused with the Rust crypto stack. */ - getCrossSigningKey?: (keyType: string, pubKey: string) => Promise; + getCrossSigningKey?: (keyType: string, pubKey: string) => Promise | null>; /** @deprecated: unused with the Rust crypto stack. */ - saveCrossSigningKeys?: (keys: Record) => void; + saveCrossSigningKeys?: (keys: Record>) => void; /** @deprecated: unused with the Rust crypto stack. */ shouldUpgradeDeviceVerifications?: (users: Record) => Promise; @@ -1210,7 +1210,7 @@ export interface CryptoCallbacks { * @param keyInfo - secret storage key info * @param key - private key to store */ - cacheSecretStorageKey?: (keyId: string, keyInfo: SecretStorageKeyDescription, key: Uint8Array) => void; + cacheSecretStorageKey?: (keyId: string, keyInfo: SecretStorageKeyDescription, key: Uint8Array) => void; /** @deprecated: unused with the Rust crypto stack. */ onSecretRequested?: ( @@ -1224,11 +1224,11 @@ export interface CryptoCallbacks { /** @deprecated: unused with the Rust crypto stack. */ getDehydrationKey?: ( keyInfo: SecretStorageKeyDescription, - checkFunc: (key: Uint8Array) => void, - ) => Promise; + checkFunc: (key: Uint8Array) => void, + ) => Promise>; /** @deprecated: unused with the Rust crypto stack. */ - getBackupKey?: () => Promise; + getBackupKey?: () => Promise>; } /** @@ -1304,7 +1304,7 @@ export interface GeneratedSecretStorageKey { name?: string; }; /** The raw generated private key. */ - privateKey: Uint8Array; + privateKey: Uint8Array; /** The generated key, encoded for display to the user per https://spec.matrix.org/v1.7/client-server-api/#key-representation. */ encodedPrivateKey?: string; } diff --git a/src/crypto-api/key-passphrase.ts b/src/crypto-api/key-passphrase.ts index 1bd8745017..056c35f397 100644 --- a/src/crypto-api/key-passphrase.ts +++ b/src/crypto-api/key-passphrase.ts @@ -30,7 +30,7 @@ export async function deriveRecoveryKeyFromPassphrase( salt: string, iterations: number, numBits = DEFAULT_BIT_SIZE, -): Promise { +): Promise> { if (!globalThis.crypto.subtle || !TextEncoder) { throw new Error("Password-based backup is not available on this platform"); } diff --git a/src/rust-crypto/libolm_migration.ts b/src/rust-crypto/libolm_migration.ts index 016f7e15d3..9418afaa19 100644 --- a/src/rust-crypto/libolm_migration.ts +++ b/src/rust-crypto/libolm_migration.ts @@ -161,7 +161,7 @@ async function migrateBaseData( userId: string, deviceId: string, legacyStore: CryptoStore, - pickleKey: Uint8Array, + pickleKey: Uint8Array, storeHandle: RustSdkCryptoJs.StoreHandle, logger: Logger, ): Promise { @@ -414,7 +414,7 @@ export async function migrateRoomSettingsFromLegacyCrypto({ async function getAndDecryptCachedSecretKey( legacyStore: CryptoStore, - legacyPickleKey: Uint8Array, + legacyPickleKey: Uint8Array, name: string, ): Promise { const key = await new Promise((resolve) => { diff --git a/src/rust-crypto/rust-crypto.ts b/src/rust-crypto/rust-crypto.ts index 3feed3abf9..a4eafc6a5a 100644 --- a/src/rust-crypto/rust-crypto.ts +++ b/src/rust-crypto/rust-crypto.ts @@ -1556,7 +1556,8 @@ export class RustCrypto extends TypedEventEmitter; } /** @@ -202,7 +202,7 @@ export interface SecretStorageCallbacks { keys: Record; }, name: string, - ) => Promise<[string, Uint8Array] | null>; + ) => Promise<[string, Uint8Array] | null>; } /** @@ -493,7 +493,7 @@ export class ServerSideSecretStorageImpl implements ServerSideSecretStorage { * * @returns whether or not the key matches */ - public async checkKey(key: Uint8Array, info: SecretStorageKeyDescriptionAesV1): Promise { + public async checkKey(key: Uint8Array, info: SecretStorageKeyDescriptionAesV1): Promise { if (info.algorithm === SECRET_STORAGE_ALGORITHM_V1_AES) { if (info.mac) { const { mac } = await calculateKeyCheck(key, info.iv); @@ -706,6 +706,9 @@ const ZERO_STR = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 * If omitted, a random initialization vector will be created. * @returns An object that contains, `mac` and `iv` properties. */ -export function calculateKeyCheck(key: Uint8Array, iv?: string): Promise { +export function calculateKeyCheck( + key: Uint8Array, + iv?: string, +): Promise { return encryptAESSecretStorageItem(ZERO_STR, key, "", iv); } diff --git a/src/utils/decryptAESSecretStorageItem.ts b/src/utils/decryptAESSecretStorageItem.ts index 25937ef8f5..0dc4e94c92 100644 --- a/src/utils/decryptAESSecretStorageItem.ts +++ b/src/utils/decryptAESSecretStorageItem.ts @@ -29,7 +29,7 @@ import { type AESEncryptedSecretStoragePayload } from "../@types/AESEncryptedSec */ export default async function decryptAESSecretStorageItem( data: AESEncryptedSecretStoragePayload, - key: Uint8Array, + key: Uint8Array, name: string, ): Promise { const [aesKey, hmacKey] = await deriveKeys(key, name); diff --git a/src/utils/encryptAESSecretStorageItem.ts b/src/utils/encryptAESSecretStorageItem.ts index 2035c5c791..3dac3494ce 100644 --- a/src/utils/encryptAESSecretStorageItem.ts +++ b/src/utils/encryptAESSecretStorageItem.ts @@ -33,11 +33,11 @@ import { type AESEncryptedSecretStoragePayload } from "../@types/AESEncryptedSec */ export default async function encryptAESSecretStorageItem( data: string, - key: Uint8Array, + key: Uint8Array, name: string, ivStr?: string, ): Promise { - let iv: Uint8Array; + let iv: Uint8Array; if (ivStr) { iv = decodeBase64(ivStr); } else { diff --git a/src/utils/internal/deriveKeys.ts b/src/utils/internal/deriveKeys.ts index 13249f846a..b2534345a6 100644 --- a/src/utils/internal/deriveKeys.ts +++ b/src/utils/internal/deriveKeys.ts @@ -25,7 +25,7 @@ const zeroSalt = new Uint8Array(8); * @param key * @param name */ -export async function deriveKeys(key: Uint8Array, name: string): Promise<[CryptoKey, CryptoKey]> { +export async function deriveKeys(key: Uint8Array, name: string): Promise<[CryptoKey, CryptoKey]> { const hkdfkey = await globalThis.crypto.subtle.importKey("raw", key, { name: "HKDF" }, false, ["deriveBits"]); const keybits = await globalThis.crypto.subtle.deriveBits( { diff --git a/src/webrtc/callFeed.ts b/src/webrtc/callFeed.ts index 991b5a2b42..886d6972a0 100644 --- a/src/webrtc/callFeed.ts +++ b/src/webrtc/callFeed.ts @@ -84,7 +84,7 @@ export class CallFeed extends TypedEventEmitter private measuringVolumeActivity = false; private audioContext?: AudioContext; private analyser?: AnalyserNode; - private frequencyBinCount?: Float32Array; + private frequencyBinCount?: Float32Array; private speakingThreshold = SPEAKING_THRESHOLD; private speaking = false; private volumeLooperTimeout?: ReturnType; diff --git a/yarn.lock b/yarn.lock index a5b1cea19e..9aa73e4f91 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2155,12 +2155,12 @@ dependencies: undici-types "~5.26.4" -"@types/node@18": - version "18.19.123" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.123.tgz#08a3e4f5e0c73b8840c677b7635ce59d5dc1f76d" - integrity sha512-K7DIaHnh0mzVxreCR9qwgNxp3MH9dltPNIEddW9MYUlcKAzm+3grKNSTe2vCJHI1FaLpvpL5JGJrz1UZDKYvDg== +"@types/node@^22": + version "22.17.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.17.2.tgz#47a93d6f4b79327da63af727e7c54e8cab8c4d33" + integrity sha512-gL6z5N9Jm9mhY+U2KXZpteb+09zyffliRkZyZOHODGATyC5B1Jt/7TzuuiLkFsSUMLbS1OLmlj/E+/3KF4Q/4w== dependencies: - undici-types "~5.26.4" + undici-types "~6.21.0" "@types/normalize-package-data@^2.4.0": version "2.4.4" @@ -6776,6 +6776,11 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@~6.21.0: + version "6.21.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" + integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== + unhomoglyph@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/unhomoglyph/-/unhomoglyph-1.0.6.tgz#ea41f926d0fcf598e3b8bb2980c2ddac66b081d3" From de163d5c87643c3efbf28fe833641c2fc3c067ec Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 21 Aug 2025 16:09:17 +0100 Subject: [PATCH 3/3] Type fixes Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/crypto-api/recovery-key.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto-api/recovery-key.ts b/src/crypto-api/recovery-key.ts index 2c4abdfdfb..e63e280121 100644 --- a/src/crypto-api/recovery-key.ts +++ b/src/crypto-api/recovery-key.ts @@ -44,7 +44,7 @@ export function encodeRecoveryKey(key: ArrayLike): string | undefined { * Decode a recovery key encoded with the Matrix {@link https://spec.matrix.org/v1.11/appendices/#cryptographic-key-representation | Cryptographic key representation} encoding. * @param recoveryKey */ -export function decodeRecoveryKey(recoveryKey: string): Uint8Array { +export function decodeRecoveryKey(recoveryKey: string): Uint8Array { const result = bs58.decode(recoveryKey.replace(/ /g, "")); let parity = 0;