1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-26 17:03:12 +03:00

Moar typescriptification

This commit is contained in:
Michael Telatynski
2021-06-24 17:41:52 +01:00
parent 3effeb7dc4
commit b4dc1e1555
8 changed files with 74 additions and 78 deletions

View File

@@ -114,7 +114,7 @@ import url from "url";
import { randomString } from "./randomstring"; import { randomString } from "./randomstring";
import { ReadStream } from "fs"; import { ReadStream } from "fs";
import { WebStorageSessionStore } from "./store/session/webstorage"; import { WebStorageSessionStore } from "./store/session/webstorage";
import { BackupManager, IKeyBackupCheck, TrustInfo } from "./crypto/backup"; import { BackupManager, IKeyBackupCheck, IPreparedKeyBackupVersion, TrustInfo } from "./crypto/backup";
import { DEFAULT_TREE_POWER_LEVELS_TEMPLATE, MSC3089TreeSpace } from "./models/MSC3089TreeSpace"; import { DEFAULT_TREE_POWER_LEVELS_TEMPLATE, MSC3089TreeSpace } from "./models/MSC3089TreeSpace";
export type Store = StubStore | MemoryStore | LocalIndexedDBStoreBackend | RemoteIndexedDBStoreBackend; export type Store = StubStore | MemoryStore | LocalIndexedDBStoreBackend | RemoteIndexedDBStoreBackend;
@@ -2180,7 +2180,7 @@ export class MatrixClient extends EventEmitter {
public async prepareKeyBackupVersion( public async prepareKeyBackupVersion(
password: string, password: string,
opts: IKeyBackupPrepareOpts = { secureSecretStorage: false }, opts: IKeyBackupPrepareOpts = { secureSecretStorage: false },
): Promise<IKeyBackupVersion> { ): Promise<Pick<IPreparedKeyBackupVersion, "algorithm" | "auth_data" | "recovery_key">> {
if (!this.crypto) { if (!this.crypto) {
throw new Error("End-to-end encryption disabled"); throw new Error("End-to-end encryption disabled");
} }
@@ -2198,7 +2198,7 @@ export class MatrixClient extends EventEmitter {
algorithm, algorithm,
auth_data, auth_data,
recovery_key, recovery_key,
} as any; // TODO: Types };
} }
/** /**
@@ -2313,7 +2313,7 @@ export class MatrixClient extends EventEmitter {
* Back up session keys to the homeserver. * Back up session keys to the homeserver.
* @param {string} roomId ID of the room that the keys are for Optional. * @param {string} roomId ID of the room that the keys are for Optional.
* @param {string} sessionId ID of the session that the keys are for Optional. * @param {string} sessionId ID of the session that the keys are for Optional.
* @param {integer} version backup version Optional. * @param {number} version backup version Optional.
* @param {object} data Object keys to send * @param {object} data Object keys to send
* @return {Promise} a promise that will resolve when the keys * @return {Promise} a promise that will resolve when the keys
* are uploaded * are uploaded
@@ -2388,7 +2388,7 @@ export class MatrixClient extends EventEmitter {
* @param {string} recoveryKey The recovery key * @param {string} recoveryKey The recovery key
* @return {Uint8Array} key backup key * @return {Uint8Array} key backup key
*/ */
public keyBackupKeyFromRecoveryKey(recoveryKey: string): Uint8Array { public keyBackupKeyFromRecoveryKey(recoveryKey: string): ArrayLike<number> {
return decodeRecoveryKey(recoveryKey); return decodeRecoveryKey(recoveryKey);
} }
@@ -2478,9 +2478,7 @@ export class MatrixClient extends EventEmitter {
opts: IKeyBackupRestoreOpts, opts: IKeyBackupRestoreOpts,
): Promise<IKeyBackupRestoreResult> { ): Promise<IKeyBackupRestoreResult> {
const privKey = decodeRecoveryKey(recoveryKey); const privKey = decodeRecoveryKey(recoveryKey);
return this.restoreKeyBackup( return this.restoreKeyBackup(privKey, targetRoomId, targetSessionId, backupInfo, opts);
privKey, targetRoomId, targetSessionId, backupInfo, opts,
);
} }
// TODO: Types // TODO: Types
@@ -2498,7 +2496,7 @@ export class MatrixClient extends EventEmitter {
} }
private async restoreKeyBackup( private async restoreKeyBackup(
privKey: Uint8Array, privKey: ArrayLike<number>,
targetRoomId: string, targetRoomId: string,
targetSessionId: string, targetSessionId: string,
backupInfo: IKeyBackupVersion, backupInfo: IKeyBackupVersion,

View File

@@ -296,7 +296,7 @@ export class CrossSigningInfo extends EventEmitter {
} }
const privateKeys: Record<string, Uint8Array> = {}; const privateKeys: Record<string, Uint8Array> = {};
const keys: Record<string, object> = {}; const keys: Record<string, any> = {}; // TODO types
let masterSigning; let masterSigning;
let masterPub; let masterPub;
@@ -719,12 +719,12 @@ export function createCryptoStoreCacheCallbacks(store: CryptoStore, olmDevice: O
); );
} }
const pickleKey = Buffer.from(olmDevice._pickleKey); const pickleKey = Buffer.from(olmDevice._pickleKey);
key = await encryptAES(encodeBase64(key), pickleKey, type); const encryptedKey = await encryptAES(encodeBase64(key), pickleKey, type);
return store.doTxn( return store.doTxn(
'readwrite', 'readwrite',
[IndexedDBCryptoStore.STORE_ACCOUNT], [IndexedDBCryptoStore.STORE_ACCOUNT],
(txn) => { (txn) => {
store.storeSecretStorePrivateKey(txn, type, key); store.storeSecretStorePrivateKey(txn, type, encryptedKey);
}, },
); );
}, },

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2020 The Matrix.org Foundation C.I.C. Copyright 2020 - 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import type { BinaryLike } from "crypto";
import { getCrypto } from '../utils'; import { getCrypto } from '../utils';
import { decodeBase64, encodeBase64 } from './olmlib'; import { decodeBase64, encodeBase64 } from './olmlib';
@@ -23,6 +25,12 @@ const subtleCrypto = (typeof window !== "undefined" && window.crypto) ?
// salt for HKDF, with 8 bytes of zeros // salt for HKDF, with 8 bytes of zeros
const zeroSalt = new Uint8Array(8); const zeroSalt = new Uint8Array(8);
interface IEncryptedPayload {
iv: string;
ciphertext: string;
mac: string;
}
/** /**
* encrypt a string in Node.js * encrypt a string in Node.js
* *
@@ -31,7 +39,7 @@ const zeroSalt = new Uint8Array(8);
* @param {string} name the name of the secret * @param {string} name the name of the secret
* @param {string} ivStr the initialization vector to use * @param {string} ivStr the initialization vector to use
*/ */
async function encryptNode(data: string, key: Uint8Array, name: string, ivStr?: string) { async function encryptNode(data: string, key: Uint8Array, name: string, ivStr?: string): Promise<IEncryptedPayload> {
const crypto = getCrypto(); const crypto = getCrypto();
if (!crypto) { if (!crypto) {
throw new Error("No usable crypto implementation"); throw new Error("No usable crypto implementation");
@@ -77,7 +85,7 @@ async function encryptNode(data: string, key: Uint8Array, name: string, ivStr?:
* @param {Uint8Array} key the encryption key to use * @param {Uint8Array} key the encryption key to use
* @param {string} name the name of the secret * @param {string} name the name of the secret
*/ */
async function decryptNode(data: IData, key: Uint8Array, name: string) { async function decryptNode(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string> {
const crypto = getCrypto(); const crypto = getCrypto();
if (!crypto) { if (!crypto) {
throw new Error("No usable crypto implementation"); throw new Error("No usable crypto implementation");
@@ -100,10 +108,9 @@ async function decryptNode(data: IData, key: Uint8Array, name: string) {
+ decipher.final("utf8"); + decipher.final("utf8");
} }
function deriveKeysNode(key, name) { function deriveKeysNode(key: BinaryLike, name: string): [Buffer, Buffer] {
const crypto = getCrypto(); const crypto = getCrypto();
const prk = crypto.createHmac("sha256", zeroSalt) const prk = crypto.createHmac("sha256", zeroSalt).update(key).digest();
.update(key).digest();
const b = Buffer.alloc(1, 1); const b = Buffer.alloc(1, 1);
const aesKey = crypto.createHmac("sha256", prk) const aesKey = crypto.createHmac("sha256", prk)
@@ -123,7 +130,7 @@ function deriveKeysNode(key, name) {
* @param {string} name the name of the secret * @param {string} name the name of the secret
* @param {string} ivStr the initialization vector to use * @param {string} ivStr the initialization vector to use
*/ */
async function encryptBrowser(data: string, key: Uint8Array, name: string, ivStr?: string) { async function encryptBrowser(data: string, key: Uint8Array, name: string, ivStr?: string): Promise<IEncryptedPayload> {
let iv; let iv;
if (ivStr) { if (ivStr) {
iv = decodeBase64(ivStr); iv = decodeBase64(ivStr);
@@ -163,12 +170,6 @@ async function encryptBrowser(data: string, key: Uint8Array, name: string, ivStr
}; };
} }
interface IData {
ciphertext: string;
iv: string;
mac: string;
}
/** /**
* decrypt a string in the browser * decrypt a string in the browser
* *
@@ -179,7 +180,7 @@ interface IData {
* @param {Uint8Array} key the encryption key to use * @param {Uint8Array} key the encryption key to use
* @param {string} name the name of the secret * @param {string} name the name of the secret
*/ */
async function decryptBrowser(data: IData, key: Uint8Array, name: string) { async function decryptBrowser(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string> {
const [aesKey, hmacKey] = await deriveKeysBrowser(key, name); const [aesKey, hmacKey] = await deriveKeysBrowser(key, name);
const ciphertext = decodeBase64(data.ciphertext); const ciphertext = decodeBase64(data.ciphertext);
@@ -206,7 +207,7 @@ async function decryptBrowser(data: IData, key: Uint8Array, name: string) {
return new TextDecoder().decode(new Uint8Array(plaintext)); return new TextDecoder().decode(new Uint8Array(plaintext));
} }
async function deriveKeysBrowser(key, name) { async function deriveKeysBrowser(key: Uint8Array, name: string): Promise<[CryptoKey, CryptoKey]> {
const hkdfkey = await subtleCrypto.importKey( const hkdfkey = await subtleCrypto.importKey(
'raw', 'raw',
key, key,
@@ -252,11 +253,11 @@ async function deriveKeysBrowser(key, name) {
return await Promise.all([aesProm, hmacProm]); return await Promise.all([aesProm, hmacProm]);
} }
export function encryptAES(data: string, key: Uint8Array, name: string, ivStr?: string) { export function encryptAES(data: string, key: Uint8Array, name: string, ivStr?: string): Promise<IEncryptedPayload> {
return subtleCrypto ? encryptBrowser(data, key, name, ivStr) : encryptNode(data, key, name, ivStr); return subtleCrypto ? encryptBrowser(data, key, name, ivStr) : encryptNode(data, key, name, ivStr);
} }
export function decryptAES(data: IData, key: Uint8Array, name: string) { export function decryptAES(data: IEncryptedPayload, key: Uint8Array, name: string): Promise<string> {
return subtleCrypto ? decryptBrowser(data, key, name) : decryptNode(data, key, name); return subtleCrypto ? decryptBrowser(data, key, name) : decryptNode(data, key, name);
} }

View File

@@ -29,16 +29,11 @@ import { keyFromPassphrase } from './key_passphrase';
import { sleep } from "../utils"; import { sleep } from "../utils";
import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store'; import { IndexedDBCryptoStore } from './store/indexeddb-crypto-store';
import { encodeRecoveryKey } from './recoverykey'; import { encodeRecoveryKey } from './recoverykey';
import { IKeyBackupVersion } from "./keybackup";
const KEY_BACKUP_KEYS_PER_REQUEST = 200; const KEY_BACKUP_KEYS_PER_REQUEST = 200;
type AuthData = Record<string, any>; type AuthData = IKeyBackupVersion["auth_data"];
type BackupInfo = {
algorithm: string,
auth_data: AuthData, // eslint-disable-line camelcase
[properties: string]: any,
};
type SigInfo = { type SigInfo = {
deviceId: string, deviceId: string,
@@ -54,13 +49,22 @@ export type TrustInfo = {
}; };
export interface IKeyBackupCheck { export interface IKeyBackupCheck {
backupInfo: BackupInfo; backupInfo: IKeyBackupVersion;
trustInfo: TrustInfo; trustInfo: TrustInfo;
} }
/* eslint-disable camelcase */
export interface IPreparedKeyBackupVersion {
algorithm: string;
auth_data: AuthData;
recovery_key: string;
privateKey: Uint8Array;
}
/* eslint-enable camelcase */
/** A function used to get the secret key for a backup. /** A function used to get the secret key for a backup.
*/ */
type GetKey = () => Promise<Uint8Array>; type GetKey = () => Promise<ArrayLike<number>>;
interface BackupAlgorithmClass { interface BackupAlgorithmClass {
algorithmName: string; algorithmName: string;
@@ -77,7 +81,7 @@ interface BackupAlgorithm {
encryptSession(data: Record<string, any>): Promise<any>; encryptSession(data: Record<string, any>): Promise<any>;
decryptSessions(ciphertexts: Record<string, any>): Promise<Record<string, any>[]>; decryptSessions(ciphertexts: Record<string, any>): Promise<Record<string, any>[]>;
authData: AuthData; authData: AuthData;
keyMatches(key: Uint8Array): Promise<boolean>; keyMatches(key: ArrayLike<number>): Promise<boolean>;
free(): void; free(): void;
} }
@@ -86,7 +90,7 @@ interface BackupAlgorithm {
*/ */
export class BackupManager { export class BackupManager {
private algorithm: BackupAlgorithm | undefined; private algorithm: BackupAlgorithm | undefined;
public backupInfo: BackupInfo | undefined; // The info dict from /room_keys/version public backupInfo: IKeyBackupVersion | undefined; // The info dict from /room_keys/version
public checkedForBackup: boolean; // Have we checked the server for a backup we can use? public checkedForBackup: boolean; // Have we checked the server for a backup we can use?
private sendingBackups: boolean; // Are we currently sending backups? private sendingBackups: boolean; // Are we currently sending backups?
constructor(private readonly baseApis: MatrixClient, public readonly getKey: GetKey) { constructor(private readonly baseApis: MatrixClient, public readonly getKey: GetKey) {
@@ -98,7 +102,7 @@ export class BackupManager {
return this.backupInfo && this.backupInfo.version; return this.backupInfo && this.backupInfo.version;
} }
public static async makeAlgorithm(info: BackupInfo, getKey: GetKey): Promise<BackupAlgorithm> { public static async makeAlgorithm(info: IKeyBackupVersion, getKey: GetKey): Promise<BackupAlgorithm> {
const Algorithm = algorithmsByName[info.algorithm]; const Algorithm = algorithmsByName[info.algorithm];
if (!Algorithm) { if (!Algorithm) {
throw new Error("Unknown backup algorithm"); throw new Error("Unknown backup algorithm");
@@ -106,7 +110,7 @@ export class BackupManager {
return await Algorithm.init(info.auth_data, getKey); return await Algorithm.init(info.auth_data, getKey);
} }
public async enableKeyBackup(info: BackupInfo): Promise<void> { public async enableKeyBackup(info: IKeyBackupVersion): Promise<void> {
this.backupInfo = info; this.backupInfo = info;
if (this.algorithm) { if (this.algorithm) {
this.algorithm.free(); this.algorithm.free();
@@ -145,7 +149,8 @@ export class BackupManager {
public async prepareKeyBackupVersion( public async prepareKeyBackupVersion(
key?: string | Uint8Array | null, key?: string | Uint8Array | null,
algorithm?: string | undefined, algorithm?: string | undefined,
): Promise<BackupInfo> { // eslint-disable-next-line camelcase
): Promise<IPreparedKeyBackupVersion> {
const Algorithm = algorithm ? algorithmsByName[algorithm] : DefaultAlgorithm; const Algorithm = algorithm ? algorithmsByName[algorithm] : DefaultAlgorithm;
if (!Algorithm) { if (!Algorithm) {
throw new Error("Unknown backup algorithm"); throw new Error("Unknown backup algorithm");
@@ -161,7 +166,7 @@ export class BackupManager {
}; };
} }
public async createKeyBackupVersion(info: BackupInfo): Promise<void> { public async createKeyBackupVersion(info: IKeyBackupVersion): Promise<void> {
this.algorithm = await BackupManager.makeAlgorithm(info, this.getKey); this.algorithm = await BackupManager.makeAlgorithm(info, this.getKey);
} }
@@ -171,14 +176,14 @@ export class BackupManager {
* one of the user's verified devices, start backing up * one of the user's verified devices, start backing up
* to it. * to it.
*/ */
public async checkAndStart(): Promise<{backupInfo: BackupInfo, trustInfo: TrustInfo}> { public async checkAndStart(): Promise<IKeyBackupCheck> {
logger.log("Checking key backup status..."); logger.log("Checking key backup status...");
if (this.baseApis.isGuest()) { if (this.baseApis.isGuest()) {
logger.log("Skipping key backup check since user is guest"); logger.log("Skipping key backup check since user is guest");
this.checkedForBackup = true; this.checkedForBackup = true;
return null; return null;
} }
let backupInfo: BackupInfo; let backupInfo: IKeyBackupVersion;
try { try {
backupInfo = await this.baseApis.getKeyBackupVersion(); backupInfo = await this.baseApis.getKeyBackupVersion();
} catch (e) { } catch (e) {
@@ -255,7 +260,7 @@ export class BackupManager {
* ] * ]
* } * }
*/ */
public async isKeyBackupTrusted(backupInfo: BackupInfo): Promise<TrustInfo> { public async isKeyBackupTrusted(backupInfo: IKeyBackupVersion): Promise<TrustInfo> {
const ret = { const ret = {
usable: false, usable: false,
trusted_locally: false, trusted_locally: false,
@@ -569,7 +574,7 @@ export class Curve25519 implements BackupAlgorithm {
): Promise<[Uint8Array, AuthData]> { ): Promise<[Uint8Array, AuthData]> {
const decryption = new global.Olm.PkDecryption(); const decryption = new global.Olm.PkDecryption();
try { try {
const authData: AuthData = {}; const authData: Partial<AuthData> = {};
if (!key) { if (!key) {
authData.public_key = decryption.generate_key(); authData.public_key = decryption.generate_key();
} else if (key instanceof Uint8Array) { } else if (key instanceof Uint8Array) {
@@ -585,7 +590,7 @@ export class Curve25519 implements BackupAlgorithm {
return [ return [
decryption.get_private_key(), decryption.get_private_key(),
authData, authData as AuthData,
]; ];
} finally { } finally {
decryption.free(); decryption.free();

View File

@@ -138,11 +138,6 @@ interface IDeviceVerificationUpgrade {
* could be established * could be established
*/ */
interface IOlmSessionResult {
device: DeviceInfo;
sessionId?: string;
}
interface IUserOlmSession { interface IUserOlmSession {
deviceIdKey: string; deviceIdKey: string;
sessions: { sessions: {
@@ -1079,17 +1074,17 @@ export class Crypto extends EventEmitter {
* @param {Uint8Array} key the private key * @param {Uint8Array} key the private key
* @returns {Promise} so you can catch failures * @returns {Promise} so you can catch failures
*/ */
public async storeSessionBackupPrivateKey(key: Uint8Array): Promise<void> { public async storeSessionBackupPrivateKey(key: ArrayLike<number>): Promise<void> {
if (!(key instanceof Uint8Array)) { if (!(key instanceof Uint8Array)) {
throw new Error(`storeSessionBackupPrivateKey expects Uint8Array, got ${key}`); throw new Error(`storeSessionBackupPrivateKey expects Uint8Array, got ${key}`);
} }
const pickleKey = Buffer.from(this.olmDevice._pickleKey); const pickleKey = Buffer.from(this.olmDevice._pickleKey);
key = await encryptAES(olmlib.encodeBase64(key), pickleKey, "m.megolm_backup.v1"); const encryptedKey = await encryptAES(olmlib.encodeBase64(key), pickleKey, "m.megolm_backup.v1");
return this.cryptoStore.doTxn( return this.cryptoStore.doTxn(
'readwrite', 'readwrite',
[IndexedDBCryptoStore.STORE_ACCOUNT], [IndexedDBCryptoStore.STORE_ACCOUNT],
(txn) => { (txn) => {
this.cryptoStore.storeSecretStorePrivateKey(txn, "m.megolm_backup.v1", key); this.cryptoStore.storeSecretStorePrivateKey(txn, "m.megolm_backup.v1", encryptedKey);
}, },
); );
} }
@@ -2573,7 +2568,7 @@ export class Crypto extends EventEmitter {
* an Object mapping from userId to deviceId to * an Object mapping from userId to deviceId to
* {@link module:crypto~OlmSessionResult} * {@link module:crypto~OlmSessionResult}
*/ */
ensureOlmSessionsForUsers(users: string[]): Promise<IOlmSessionResult> { ensureOlmSessionsForUsers(users: string[]): Promise<Record<string, Record<string, olmlib.IOlmSessionResult>>> {
const devicesByUser = {}; const devicesByUser = {};
for (let i = 0; i < users.length; ++i) { for (let i = 0; i < users.length; ++i) {
@@ -2598,9 +2593,7 @@ export class Crypto extends EventEmitter {
} }
} }
return olmlib.ensureOlmSessionsForDevices( return olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser);
this.olmDevice, this.baseApis, devicesByUser,
);
} }
/** /**
@@ -3259,9 +3252,7 @@ export class Crypto extends EventEmitter {
} }
const devicesByUser = {}; const devicesByUser = {};
devicesByUser[sender] = [device]; devicesByUser[sender] = [device];
await olmlib.ensureOlmSessionsForDevices( await olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser, true);
this.olmDevice, this.baseApis, devicesByUser, true,
);
this.lastNewSessionForced[sender][deviceKey] = Date.now(); this.lastNewSessionForced[sender][deviceKey] = Date.now();

View File

@@ -44,7 +44,6 @@ export interface IKeyBackupVersion {
count: number; count: number;
etag: string; etag: string;
version: string; // number contained within version: string; // number contained within
recovery_key: string;
} }
/* eslint-enable camelcase */ /* eslint-enable camelcase */

View File

@@ -52,6 +52,11 @@ export const MEGOLM_ALGORITHM = Algorithm.Megolm;
*/ */
export const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup; export const MEGOLM_BACKUP_ALGORITHM = Algorithm.MegolmBackup;
export interface IOlmSessionResult {
device: DeviceInfo;
sessionId?: string;
}
/** /**
* Encrypt an event payload for an Olm device * Encrypt an event payload for an Olm device
* *
@@ -209,11 +214,11 @@ export async function ensureOlmSessionsForDevices(
olmDevice: OlmDevice, olmDevice: OlmDevice,
baseApis: MatrixClient, baseApis: MatrixClient,
devicesByUser: Record<string, DeviceInfo[]>, devicesByUser: Record<string, DeviceInfo[]>,
force: boolean, force = false,
otkTimeout: number, otkTimeout?: number,
failedServers: string[], failedServers?: string[],
log: Logger, log: Logger = logger,
) { ): Promise<Record<string, Record<string, IOlmSessionResult>>> {
if (typeof force === "number") { if (typeof force === "number") {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - backwards compatibility // @ts-ignore - backwards compatibility
@@ -224,9 +229,6 @@ export async function ensureOlmSessionsForDevices(
otkTimeout = force; otkTimeout = force;
force = false; force = false;
} }
if (!log) {
log = logger;
}
const devicesWithoutSession = [ const devicesWithoutSession = [
// [userId, deviceId], ... // [userId, deviceId], ...
@@ -439,9 +441,9 @@ async function _verifyKeyAndStartSession(
return sid; return sid;
} }
interface IObject { export interface IObject {
unsigned: object; unsigned?: object;
signatures: object; signatures?: object;
} }
/** /**
@@ -555,7 +557,7 @@ export function pkVerify(obj: IObject, pubKey: string, userId: string) {
* @param {Uint8Array} uint8Array The data to encode. * @param {Uint8Array} uint8Array The data to encode.
* @return {string} The base64. * @return {string} The base64.
*/ */
export function encodeBase64(uint8Array: ArrayBuffer): string { export function encodeBase64(uint8Array: ArrayBuffer | Uint8Array): string {
return Buffer.from(uint8Array).toString("base64"); return Buffer.from(uint8Array).toString("base64");
} }

View File

@@ -35,7 +35,7 @@ export function encodeRecoveryKey(key: ArrayLike<number>): string {
return base58key.match(/.{1,4}/g).join(" "); return base58key.match(/.{1,4}/g).join(" ");
} }
export function decodeRecoveryKey(recoveryKey: string): ArrayLike<number> { export function decodeRecoveryKey(recoveryKey: string): Uint8Array {
const result = bs58.decode(recoveryKey.replace(/ /g, '')); const result = bs58.decode(recoveryKey.replace(/ /g, ''));
let parity = 0; let parity = 0;