You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-06 12:02:40 +03:00
Allow applications to specify their own logger instance (#3792)
* Support MatrixClient-specific loggers. Signed-off-by: Patrick Cloke <clokep@patrick.cloke.us> * Use client-specific logger in client.ts. Signed-off-by: Patrick Cloke <clokep@patrick.cloke.us> * Log `fetch` requests to the per-client logger * Use client-specific logger in rust-crypto
This commit is contained in:
committed by
GitHub
parent
7c2a12085c
commit
42be793a56
@@ -14,14 +14,14 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { mocked } from "jest-mock";
|
import { Mocked } from "jest-mock";
|
||||||
|
|
||||||
import { FetchHttpApi } from "../../../src/http-api/fetch";
|
import { FetchHttpApi } from "../../../src/http-api/fetch";
|
||||||
import { TypedEventEmitter } from "../../../src/models/typed-event-emitter";
|
import { TypedEventEmitter } from "../../../src/models/typed-event-emitter";
|
||||||
import { ClientPrefix, HttpApiEvent, HttpApiEventHandlerMap, IdentityPrefix, IHttpOpts, Method } from "../../../src";
|
import { ClientPrefix, HttpApiEvent, HttpApiEventHandlerMap, IdentityPrefix, IHttpOpts, Method } from "../../../src";
|
||||||
import { emitPromise } from "../../test-utils/test-utils";
|
import { emitPromise } from "../../test-utils/test-utils";
|
||||||
import { defer, QueryDict } from "../../../src/utils";
|
import { defer, QueryDict } from "../../../src/utils";
|
||||||
import { logger } from "../../../src/logger";
|
import { Logger } from "../../../src/logger";
|
||||||
|
|
||||||
describe("FetchHttpApi", () => {
|
describe("FetchHttpApi", () => {
|
||||||
const baseUrl = "http://baseUrl";
|
const baseUrl = "http://baseUrl";
|
||||||
@@ -300,22 +300,29 @@ describe("FetchHttpApi", () => {
|
|||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
const deferred = defer<Response>();
|
const deferred = defer<Response>();
|
||||||
const fetchFn = jest.fn().mockReturnValue(deferred.promise);
|
const fetchFn = jest.fn().mockReturnValue(deferred.promise);
|
||||||
jest.spyOn(logger, "debug").mockImplementation(() => {});
|
const mockLogger = {
|
||||||
const api = new FetchHttpApi(new TypedEventEmitter<any, any>(), { baseUrl, prefix, fetchFn });
|
debug: jest.fn(),
|
||||||
|
} as unknown as Mocked<Logger>;
|
||||||
|
const api = new FetchHttpApi(new TypedEventEmitter<any, any>(), {
|
||||||
|
baseUrl,
|
||||||
|
prefix,
|
||||||
|
fetchFn,
|
||||||
|
logger: mockLogger,
|
||||||
|
});
|
||||||
const prom = api.requestOtherUrl(Method.Get, "https://server:8448/some/path?query=param#fragment");
|
const prom = api.requestOtherUrl(Method.Get, "https://server:8448/some/path?query=param#fragment");
|
||||||
jest.advanceTimersByTime(1234);
|
jest.advanceTimersByTime(1234);
|
||||||
deferred.resolve({ ok: true, status: 200, text: () => Promise.resolve("RESPONSE") } as Response);
|
deferred.resolve({ ok: true, status: 200, text: () => Promise.resolve("RESPONSE") } as Response);
|
||||||
await prom;
|
await prom;
|
||||||
expect(logger.debug).not.toHaveBeenCalledWith("fragment");
|
expect(mockLogger.debug).not.toHaveBeenCalledWith("fragment");
|
||||||
expect(logger.debug).not.toHaveBeenCalledWith("query");
|
expect(mockLogger.debug).not.toHaveBeenCalledWith("query");
|
||||||
expect(logger.debug).not.toHaveBeenCalledWith("param");
|
expect(mockLogger.debug).not.toHaveBeenCalledWith("param");
|
||||||
expect(logger.debug).toHaveBeenCalledTimes(2);
|
expect(mockLogger.debug).toHaveBeenCalledTimes(2);
|
||||||
expect(mocked(logger.debug).mock.calls[0]).toMatchInlineSnapshot(`
|
expect(mockLogger.debug.mock.calls[0]).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
"FetchHttpApi: --> GET https://server:8448/some/path?query=xxx",
|
"FetchHttpApi: --> GET https://server:8448/some/path?query=xxx",
|
||||||
]
|
]
|
||||||
`);
|
`);
|
||||||
expect(mocked(logger.debug).mock.calls[1]).toMatchInlineSnapshot(`
|
expect(mockLogger.debug.mock.calls[1]).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
"FetchHttpApi: <-- GET https://server:8448/some/path?query=xxx [1234ms 200]",
|
"FetchHttpApi: <-- GET https://server:8448/some/path?query=xxx [1234ms 200]",
|
||||||
]
|
]
|
||||||
|
@@ -49,6 +49,7 @@ import {
|
|||||||
} from "../../../src/crypto-api";
|
} from "../../../src/crypto-api";
|
||||||
import * as testData from "../../test-utils/test-data";
|
import * as testData from "../../test-utils/test-data";
|
||||||
import { defer } from "../../../src/utils";
|
import { defer } from "../../../src/utils";
|
||||||
|
import { logger } from "../../../src/logger";
|
||||||
|
|
||||||
const TEST_USER = "@alice:example.com";
|
const TEST_USER = "@alice:example.com";
|
||||||
const TEST_DEVICE_ID = "TEST_DEVICE";
|
const TEST_DEVICE_ID = "TEST_DEVICE";
|
||||||
@@ -72,6 +73,7 @@ describe("initRustCrypto", () => {
|
|||||||
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
||||||
|
|
||||||
await initRustCrypto(
|
await initRustCrypto(
|
||||||
|
logger,
|
||||||
{} as MatrixClient["http"],
|
{} as MatrixClient["http"],
|
||||||
TEST_USER,
|
TEST_USER,
|
||||||
TEST_DEVICE_ID,
|
TEST_DEVICE_ID,
|
||||||
@@ -94,6 +96,7 @@ describe("initRustCrypto", () => {
|
|||||||
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
jest.spyOn(OlmMachine, "initialize").mockResolvedValue(testOlmMachine);
|
||||||
|
|
||||||
await initRustCrypto(
|
await initRustCrypto(
|
||||||
|
logger,
|
||||||
{} as MatrixClient["http"],
|
{} as MatrixClient["http"],
|
||||||
TEST_USER,
|
TEST_USER,
|
||||||
TEST_DEVICE_ID,
|
TEST_DEVICE_ID,
|
||||||
@@ -316,6 +319,7 @@ describe("RustCrypto", () => {
|
|||||||
} as unknown as Mocked<OutgoingRequestProcessor>;
|
} as unknown as Mocked<OutgoingRequestProcessor>;
|
||||||
|
|
||||||
rustCrypto = new RustCrypto(
|
rustCrypto = new RustCrypto(
|
||||||
|
logger,
|
||||||
olmMachine,
|
olmMachine,
|
||||||
{} as MatrixHttpApi<any>,
|
{} as MatrixHttpApi<any>,
|
||||||
TEST_USER,
|
TEST_USER,
|
||||||
@@ -445,6 +449,7 @@ describe("RustCrypto", () => {
|
|||||||
getRoomEventEncryptionInfo: jest.fn(),
|
getRoomEventEncryptionInfo: jest.fn(),
|
||||||
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
|
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
|
||||||
rustCrypto = new RustCrypto(
|
rustCrypto = new RustCrypto(
|
||||||
|
logger,
|
||||||
olmMachine,
|
olmMachine,
|
||||||
{} as MatrixClient["http"],
|
{} as MatrixClient["http"],
|
||||||
TEST_USER,
|
TEST_USER,
|
||||||
@@ -619,6 +624,7 @@ describe("RustCrypto", () => {
|
|||||||
getDevice: jest.fn(),
|
getDevice: jest.fn(),
|
||||||
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
|
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
|
||||||
rustCrypto = new RustCrypto(
|
rustCrypto = new RustCrypto(
|
||||||
|
logger,
|
||||||
olmMachine,
|
olmMachine,
|
||||||
{} as MatrixClient["http"],
|
{} as MatrixClient["http"],
|
||||||
TEST_USER,
|
TEST_USER,
|
||||||
@@ -837,6 +843,7 @@ describe("RustCrypto", () => {
|
|||||||
getIdentity: jest.fn(),
|
getIdentity: jest.fn(),
|
||||||
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
|
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
|
||||||
rustCrypto = new RustCrypto(
|
rustCrypto = new RustCrypto(
|
||||||
|
logger,
|
||||||
olmMachine,
|
olmMachine,
|
||||||
{} as MatrixClient["http"],
|
{} as MatrixClient["http"],
|
||||||
TEST_USER,
|
TEST_USER,
|
||||||
@@ -898,6 +905,7 @@ describe("RustCrypto", () => {
|
|||||||
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
|
} as unknown as Mocked<RustSdkCryptoJs.OlmMachine>;
|
||||||
|
|
||||||
const rustCrypto = new RustCrypto(
|
const rustCrypto = new RustCrypto(
|
||||||
|
logger,
|
||||||
olmMachine,
|
olmMachine,
|
||||||
mockHttpApi,
|
mockHttpApi,
|
||||||
testData.TEST_USER_ID,
|
testData.TEST_USER_ID,
|
||||||
@@ -927,5 +935,5 @@ async function makeTestRustCrypto(
|
|||||||
secretStorage: ServerSideSecretStorage = {} as ServerSideSecretStorage,
|
secretStorage: ServerSideSecretStorage = {} as ServerSideSecretStorage,
|
||||||
cryptoCallbacks: CryptoCallbacks = {} as CryptoCallbacks,
|
cryptoCallbacks: CryptoCallbacks = {} as CryptoCallbacks,
|
||||||
): Promise<RustCrypto> {
|
): Promise<RustCrypto> {
|
||||||
return await initRustCrypto(http, userId, deviceId, secretStorage, cryptoCallbacks, null, undefined);
|
return await initRustCrypto(logger, http, userId, deviceId, secretStorage, cryptoCallbacks, null, undefined);
|
||||||
}
|
}
|
||||||
|
130
src/client.ts
130
src/client.ts
@@ -52,7 +52,7 @@ import { IExportedDevice as IExportedOlmDevice } from "./crypto/OlmDevice";
|
|||||||
import { IOlmDevice } from "./crypto/algorithms/megolm";
|
import { IOlmDevice } from "./crypto/algorithms/megolm";
|
||||||
import { TypedReEmitter } from "./ReEmitter";
|
import { TypedReEmitter } from "./ReEmitter";
|
||||||
import { IRoomEncryption, RoomList } from "./crypto/RoomList";
|
import { IRoomEncryption, RoomList } from "./crypto/RoomList";
|
||||||
import { logger } from "./logger";
|
import { logger, Logger } from "./logger";
|
||||||
import { SERVICE_TYPES } from "./service-types";
|
import { SERVICE_TYPES } from "./service-types";
|
||||||
import {
|
import {
|
||||||
Body,
|
Body,
|
||||||
@@ -415,6 +415,12 @@ export interface ICreateClientOpts {
|
|||||||
* so that livekit media can be used in the application layert (js-sdk contains no livekit code).
|
* so that livekit media can be used in the application layert (js-sdk contains no livekit code).
|
||||||
*/
|
*/
|
||||||
useLivekitForGroupCalls?: boolean;
|
useLivekitForGroupCalls?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A logger to associate with this MatrixClient.
|
||||||
|
* Defaults to the built-in global logger.
|
||||||
|
*/
|
||||||
|
logger?: Logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMatrixClientCreateOpts extends ICreateClientOpts {
|
export interface IMatrixClientCreateOpts extends ICreateClientOpts {
|
||||||
@@ -1207,6 +1213,8 @@ const SSO_ACTION_PARAM = new UnstableValue("action", "org.matrix.msc3824.action"
|
|||||||
export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHandlerMap> {
|
export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHandlerMap> {
|
||||||
public static readonly RESTORE_BACKUP_ERROR_BAD_KEY = "RESTORE_BACKUP_ERROR_BAD_KEY";
|
public static readonly RESTORE_BACKUP_ERROR_BAD_KEY = "RESTORE_BACKUP_ERROR_BAD_KEY";
|
||||||
|
|
||||||
|
private readonly logger: Logger;
|
||||||
|
|
||||||
public reEmitter = new TypedReEmitter<EmittedEvents, ClientEventHandlerMap>(this);
|
public reEmitter = new TypedReEmitter<EmittedEvents, ClientEventHandlerMap>(this);
|
||||||
public olmVersion: [number, number, number] | null = null; // populated after initCrypto
|
public olmVersion: [number, number, number] | null = null; // populated after initCrypto
|
||||||
public usingExternalCrypto = false;
|
public usingExternalCrypto = false;
|
||||||
@@ -1312,6 +1320,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
public constructor(opts: IMatrixClientCreateOpts) {
|
public constructor(opts: IMatrixClientCreateOpts) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
// If a custom logger is provided, use it. Otherwise, default to the global
|
||||||
|
// one in logger.ts.
|
||||||
|
this.logger = opts.logger ?? logger;
|
||||||
|
|
||||||
opts.baseUrl = utils.ensureNoTrailingSlash(opts.baseUrl);
|
opts.baseUrl = utils.ensureNoTrailingSlash(opts.baseUrl);
|
||||||
opts.idBaseUrl = utils.ensureNoTrailingSlash(opts.idBaseUrl);
|
opts.idBaseUrl = utils.ensureNoTrailingSlash(opts.idBaseUrl);
|
||||||
|
|
||||||
@@ -1337,21 +1349,22 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
extraParams: opts.queryParams,
|
extraParams: opts.queryParams,
|
||||||
localTimeoutMs: opts.localTimeoutMs,
|
localTimeoutMs: opts.localTimeoutMs,
|
||||||
useAuthorizationHeader: opts.useAuthorizationHeader,
|
useAuthorizationHeader: opts.useAuthorizationHeader,
|
||||||
|
logger: this.logger,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (opts.deviceToImport) {
|
if (opts.deviceToImport) {
|
||||||
if (this.deviceId) {
|
if (this.deviceId) {
|
||||||
logger.warn(
|
this.logger.warn(
|
||||||
"not importing device because device ID is provided to " +
|
"not importing device because device ID is provided to " +
|
||||||
"constructor independently of exported data",
|
"constructor independently of exported data",
|
||||||
);
|
);
|
||||||
} else if (this.credentials.userId) {
|
} else if (this.credentials.userId) {
|
||||||
logger.warn(
|
this.logger.warn(
|
||||||
"not importing device because user ID is provided to " +
|
"not importing device because user ID is provided to " +
|
||||||
"constructor independently of exported data",
|
"constructor independently of exported data",
|
||||||
);
|
);
|
||||||
} else if (!opts.deviceToImport.deviceId) {
|
} else if (!opts.deviceToImport.deviceId) {
|
||||||
logger.warn("not importing device because no device ID in exported data");
|
this.logger.warn("not importing device because no device ID in exported data");
|
||||||
} else {
|
} else {
|
||||||
this.deviceId = opts.deviceToImport.deviceId;
|
this.deviceId = opts.deviceToImport.deviceId;
|
||||||
this.credentials.userId = opts.deviceToImport.userId;
|
this.credentials.userId = opts.deviceToImport.userId;
|
||||||
@@ -1523,7 +1536,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
|
|
||||||
if (this.syncApi) {
|
if (this.syncApi) {
|
||||||
// This shouldn't happen since we thought the client was not running
|
// This shouldn't happen since we thought the client was not running
|
||||||
logger.error("Still have sync object whilst not running: stopping old one");
|
this.logger.error("Still have sync object whilst not running: stopping old one");
|
||||||
this.syncApi.stop();
|
this.syncApi.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1537,7 +1550,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
Thread.setServerSideListSupport(list);
|
Thread.setServerSideListSupport(list);
|
||||||
Thread.setServerSideFwdPaginationSupport(fwdPagination);
|
Thread.setServerSideFwdPaginationSupport(fwdPagination);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error("Can't fetch server versions, continuing to initialise sync, this will be retried later", e);
|
this.logger.error(
|
||||||
|
"Can't fetch server versions, continuing to initialise sync, this will be retried later",
|
||||||
|
e,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clientOpts = opts ?? {};
|
this.clientOpts = opts ?? {};
|
||||||
@@ -1553,7 +1569,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.clientOpts.hasOwnProperty("experimentalThreadSupport")) {
|
if (this.clientOpts.hasOwnProperty("experimentalThreadSupport")) {
|
||||||
logger.warn("`experimentalThreadSupport` has been deprecated, use `threadSupport` instead");
|
this.logger.warn("`experimentalThreadSupport` has been deprecated, use `threadSupport` instead");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If `threadSupport` is omitted and the deprecated `experimentalThreadSupport` has been passed
|
// If `threadSupport` is omitted and the deprecated `experimentalThreadSupport` has been passed
|
||||||
@@ -1565,7 +1581,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
this.clientOpts.threadSupport = this.clientOpts.experimentalThreadSupport;
|
this.clientOpts.threadSupport = this.clientOpts.experimentalThreadSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.syncApi.sync().catch((e) => logger.info("Sync startup aborted with an error:", e));
|
this.syncApi.sync().catch((e) => this.logger.info("Sync startup aborted with an error:", e));
|
||||||
|
|
||||||
if (this.clientOpts.clientWellKnownPollPeriod !== undefined) {
|
if (this.clientOpts.clientWellKnownPollPeriod !== undefined) {
|
||||||
this.clientWellKnownIntervalID = setInterval(() => {
|
this.clientWellKnownIntervalID = setInterval(() => {
|
||||||
@@ -1604,7 +1620,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
|
|
||||||
if (!this.clientRunning) return; // already stopped
|
if (!this.clientRunning) return; // already stopped
|
||||||
|
|
||||||
logger.log("stopping MatrixClient");
|
this.logger.debug("stopping MatrixClient");
|
||||||
|
|
||||||
this.clientRunning = false;
|
this.clientRunning = false;
|
||||||
|
|
||||||
@@ -1654,7 +1670,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!getDeviceResult.device_data || !getDeviceResult.device_id) {
|
if (!getDeviceResult.device_data || !getDeviceResult.device_id) {
|
||||||
logger.info("no dehydrated device found");
|
this.logger.info("no dehydrated device found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1662,16 +1678,16 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
try {
|
try {
|
||||||
const deviceData = getDeviceResult.device_data;
|
const deviceData = getDeviceResult.device_data;
|
||||||
if (deviceData.algorithm !== DEHYDRATION_ALGORITHM) {
|
if (deviceData.algorithm !== DEHYDRATION_ALGORITHM) {
|
||||||
logger.warn("Wrong algorithm for dehydrated device");
|
this.logger.warn("Wrong algorithm for dehydrated device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.log("unpickling dehydrated device");
|
this.logger.debug("unpickling dehydrated device");
|
||||||
const key = await this.cryptoCallbacks.getDehydrationKey(deviceData, (k) => {
|
const key = await this.cryptoCallbacks.getDehydrationKey(deviceData, (k) => {
|
||||||
// copy the key so that it doesn't get clobbered
|
// copy the key so that it doesn't get clobbered
|
||||||
account.unpickle(new Uint8Array(k), deviceData.account);
|
account.unpickle(new Uint8Array(k), deviceData.account);
|
||||||
});
|
});
|
||||||
account.unpickle(key, deviceData.account);
|
account.unpickle(key, deviceData.account);
|
||||||
logger.log("unpickled device");
|
this.logger.debug("unpickled device");
|
||||||
|
|
||||||
const rehydrateResult = await this.http.authedRequest<{ success: boolean }>(
|
const rehydrateResult = await this.http.authedRequest<{ success: boolean }>(
|
||||||
Method.Post,
|
Method.Post,
|
||||||
@@ -1687,7 +1703,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
|
|
||||||
if (rehydrateResult.success) {
|
if (rehydrateResult.success) {
|
||||||
this.deviceId = getDeviceResult.device_id;
|
this.deviceId = getDeviceResult.device_id;
|
||||||
logger.info("using dehydrated device");
|
this.logger.info("using dehydrated device");
|
||||||
const pickleKey = this.pickleKey || "DEFAULT_KEY";
|
const pickleKey = this.pickleKey || "DEFAULT_KEY";
|
||||||
this.exportedOlmDeviceToImport = {
|
this.exportedOlmDeviceToImport = {
|
||||||
pickledAccount: account.pickle(pickleKey),
|
pickledAccount: account.pickle(pickleKey),
|
||||||
@@ -1698,12 +1714,12 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
return this.deviceId;
|
return this.deviceId;
|
||||||
} else {
|
} else {
|
||||||
account.free();
|
account.free();
|
||||||
logger.info("not using dehydrated device");
|
this.logger.info("not using dehydrated device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
account.free();
|
account.free();
|
||||||
logger.warn("could not unpickle", e);
|
this.logger.warn("could not unpickle", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1723,7 +1739,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.info("could not get dehydrated device", e);
|
this.logger.info("could not get dehydrated device", e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1745,7 +1761,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
deviceDisplayName?: string,
|
deviceDisplayName?: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!this.crypto) {
|
if (!this.crypto) {
|
||||||
logger.warn("not dehydrating device if crypto is not enabled");
|
this.logger.warn("not dehydrating device if crypto is not enabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return this.crypto.dehydrationManager.setKeyAndQueueDehydration(key, keyInfo, deviceDisplayName);
|
return this.crypto.dehydrationManager.setKeyAndQueueDehydration(key, keyInfo, deviceDisplayName);
|
||||||
@@ -1766,7 +1782,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
deviceDisplayName?: string,
|
deviceDisplayName?: string,
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
if (!this.crypto) {
|
if (!this.crypto) {
|
||||||
logger.warn("not dehydrating device if crypto is not enabled");
|
this.logger.warn("not dehydrating device if crypto is not enabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.crypto.dehydrationManager.setKey(key, keyInfo, deviceDisplayName);
|
await this.crypto.dehydrationManager.setKey(key, keyInfo, deviceDisplayName);
|
||||||
@@ -1775,7 +1791,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
|
|
||||||
public async exportDevice(): Promise<IExportedDevice | undefined> {
|
public async exportDevice(): Promise<IExportedDevice | undefined> {
|
||||||
if (!this.crypto) {
|
if (!this.crypto) {
|
||||||
logger.warn("not exporting device if crypto is not enabled");
|
this.logger.warn("not exporting device if crypto is not enabled");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -1818,10 +1834,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
`${RUST_SDK_STORE_PREFIX}::matrix-sdk-crypto-meta`,
|
`${RUST_SDK_STORE_PREFIX}::matrix-sdk-crypto-meta`,
|
||||||
]) {
|
]) {
|
||||||
const prom = new Promise((resolve, reject) => {
|
const prom = new Promise((resolve, reject) => {
|
||||||
logger.info(`Removing IndexedDB instance ${dbname}`);
|
this.logger.info(`Removing IndexedDB instance ${dbname}`);
|
||||||
const req = indexedDB.deleteDatabase(dbname);
|
const req = indexedDB.deleteDatabase(dbname);
|
||||||
req.onsuccess = (_): void => {
|
req.onsuccess = (_): void => {
|
||||||
logger.info(`Removed IndexedDB instance ${dbname}`);
|
this.logger.info(`Removed IndexedDB instance ${dbname}`);
|
||||||
resolve(0);
|
resolve(0);
|
||||||
};
|
};
|
||||||
req.onerror = (e): void => {
|
req.onerror = (e): void => {
|
||||||
@@ -1830,11 +1846,11 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
// database that did not allow mutations."
|
// database that did not allow mutations."
|
||||||
//
|
//
|
||||||
// it seems like the only thing we can really do is ignore the error.
|
// it seems like the only thing we can really do is ignore the error.
|
||||||
logger.warn(`Failed to remove IndexedDB instance ${dbname}:`, e);
|
this.logger.warn(`Failed to remove IndexedDB instance ${dbname}:`, e);
|
||||||
resolve(0);
|
resolve(0);
|
||||||
};
|
};
|
||||||
req.onblocked = (e): void => {
|
req.onblocked = (e): void => {
|
||||||
logger.info(`cannot yet remove IndexedDB instance ${dbname}`);
|
this.logger.info(`cannot yet remove IndexedDB instance ${dbname}`);
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
await prom;
|
await prom;
|
||||||
@@ -2141,7 +2157,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
|
|
||||||
if (this.cachedCapabilities && !fresh) {
|
if (this.cachedCapabilities && !fresh) {
|
||||||
if (now < this.cachedCapabilities.expiration) {
|
if (now < this.cachedCapabilities.expiration) {
|
||||||
logger.log("Returning cached capabilities");
|
this.logger.debug("Returning cached capabilities");
|
||||||
return Promise.resolve(this.cachedCapabilities.capabilities);
|
return Promise.resolve(this.cachedCapabilities.capabilities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2153,7 +2169,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
.authedRequest<Response>(Method.Get, "/capabilities")
|
.authedRequest<Response>(Method.Get, "/capabilities")
|
||||||
.catch((e: Error): Response => {
|
.catch((e: Error): Response => {
|
||||||
// We swallow errors because we need a default object anyhow
|
// We swallow errors because we need a default object anyhow
|
||||||
logger.error(e);
|
this.logger.error(e);
|
||||||
return {};
|
return {};
|
||||||
})
|
})
|
||||||
.then((r = {}) => {
|
.then((r = {}) => {
|
||||||
@@ -2168,7 +2184,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
expiration: now + cacheMs,
|
expiration: now + cacheMs,
|
||||||
};
|
};
|
||||||
|
|
||||||
logger.log("Caching capabilities: ", capabilities);
|
this.logger.debug("Caching capabilities: ", capabilities);
|
||||||
return capabilities;
|
return capabilities;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2191,7 +2207,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.cryptoBackend) {
|
if (this.cryptoBackend) {
|
||||||
logger.warn("Attempt to re-initialise e2e encryption on MatrixClient");
|
this.logger.warn("Attempt to re-initialise e2e encryption on MatrixClient");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2200,11 +2216,11 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
throw new Error(`Cannot enable encryption: no cryptoStore provided`);
|
throw new Error(`Cannot enable encryption: no cryptoStore provided`);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log("Crypto: Starting up crypto store...");
|
this.logger.debug("Crypto: Starting up crypto store...");
|
||||||
await this.cryptoStore.startup();
|
await this.cryptoStore.startup();
|
||||||
|
|
||||||
// initialise the list of encrypted rooms (whether or not crypto is enabled)
|
// initialise the list of encrypted rooms (whether or not crypto is enabled)
|
||||||
logger.log("Crypto: initialising roomlist...");
|
this.logger.debug("Crypto: initialising roomlist...");
|
||||||
await this.roomList.init();
|
await this.roomList.init();
|
||||||
|
|
||||||
const userId = this.getUserId();
|
const userId = this.getUserId();
|
||||||
@@ -2244,7 +2260,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
CryptoEvent.KeysChanged,
|
CryptoEvent.KeysChanged,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
logger.log("Crypto: initialising crypto object...");
|
this.logger.debug("Crypto: initialising crypto object...");
|
||||||
await crypto.init({
|
await crypto.init({
|
||||||
exportedOlmDevice: this.exportedOlmDeviceToImport,
|
exportedOlmDevice: this.exportedOlmDeviceToImport,
|
||||||
pickleKey: this.pickleKey,
|
pickleKey: this.pickleKey,
|
||||||
@@ -2260,7 +2276,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
// upload our keys in the background
|
// upload our keys in the background
|
||||||
this.crypto.uploadDeviceKeys().catch((e) => {
|
this.crypto.uploadDeviceKeys().catch((e) => {
|
||||||
// TODO: throwing away this error is a really bad idea.
|
// TODO: throwing away this error is a really bad idea.
|
||||||
logger.error("Error uploading device keys", e);
|
this.logger.error("Error uploading device keys", e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2281,7 +2297,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
*/
|
*/
|
||||||
public async initRustCrypto({ useIndexedDB = true }: { useIndexedDB?: boolean } = {}): Promise<void> {
|
public async initRustCrypto({ useIndexedDB = true }: { useIndexedDB?: boolean } = {}): Promise<void> {
|
||||||
if (this.cryptoBackend) {
|
if (this.cryptoBackend) {
|
||||||
logger.warn("Attempt to re-initialise e2e encryption on MatrixClient");
|
this.logger.warn("Attempt to re-initialise e2e encryption on MatrixClient");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2304,6 +2320,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
// needed.
|
// needed.
|
||||||
const RustCrypto = await import("./rust-crypto");
|
const RustCrypto = await import("./rust-crypto");
|
||||||
const rustCrypto = await RustCrypto.initRustCrypto(
|
const rustCrypto = await RustCrypto.initRustCrypto(
|
||||||
|
this.logger,
|
||||||
this.http,
|
this.http,
|
||||||
userId,
|
userId,
|
||||||
deviceId,
|
deviceId,
|
||||||
@@ -2382,7 +2399,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
* @deprecated Does nothing.
|
* @deprecated Does nothing.
|
||||||
*/
|
*/
|
||||||
public async uploadKeys(): Promise<void> {
|
public async uploadKeys(): Promise<void> {
|
||||||
logger.warn("MatrixClient.uploadKeys is deprecated");
|
this.logger.warn("MatrixClient.uploadKeys is deprecated");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -3462,7 +3479,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
|
|
||||||
if (opts.secureSecretStorage) {
|
if (opts.secureSecretStorage) {
|
||||||
await this.secretStorage.store("m.megolm_backup.v1", encodeBase64(privateKey));
|
await this.secretStorage.store("m.megolm_backup.v1", encodeBase64(privateKey));
|
||||||
logger.info("Key backup private key stored in secret storage");
|
this.logger.info("Key backup private key stored in secret storage");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -3531,7 +3548,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
// sessions.
|
// sessions.
|
||||||
await this.checkKeyBackup();
|
await this.checkKeyBackup();
|
||||||
if (!this.getKeyBackupEnabled()) {
|
if (!this.getKeyBackupEnabled()) {
|
||||||
logger.error("Key backup not usable even though we just created it");
|
this.logger.error("Key backup not usable even though we just created it");
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@@ -3887,7 +3904,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
this.cryptoBackend
|
this.cryptoBackend
|
||||||
.storeSessionBackupPrivateKey(privKey, backupInfo.version)
|
.storeSessionBackupPrivateKey(privKey, backupInfo.version)
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
logger.warn("Error caching session backup key:", e);
|
this.logger.warn("Error caching session backup key:", e);
|
||||||
})
|
})
|
||||||
.then(cacheCompleteCallback);
|
.then(cacheCompleteCallback);
|
||||||
|
|
||||||
@@ -3934,7 +3951,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
key.session_id = targetSessionId!;
|
key.session_id = targetSessionId!;
|
||||||
keys.push(key);
|
keys.push(key);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.log("Failed to decrypt megolm session from backup", e);
|
this.logger.debug("Failed to decrypt megolm session from backup", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -3980,7 +3997,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
const roomEncryption = this.roomList.getRoomEncryption(roomId);
|
const roomEncryption = this.roomList.getRoomEncryption(roomId);
|
||||||
if (!roomEncryption) {
|
if (!roomEncryption) {
|
||||||
// unknown room, or unencrypted room
|
// unknown room, or unencrypted room
|
||||||
logger.error("Unknown room. Not sharing decryption keys");
|
this.logger.error("Unknown room. Not sharing decryption keys");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3995,7 +4012,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
if (alg.sendSharedHistoryInboundSessions) {
|
if (alg.sendSharedHistoryInboundSessions) {
|
||||||
await alg.sendSharedHistoryInboundSessions(devicesByUser);
|
await alg.sendSharedHistoryInboundSessions(devicesByUser);
|
||||||
} else {
|
} else {
|
||||||
logger.warn("Algorithm does not support sharing previous keys", roomEncryption.algorithm);
|
this.logger.warn("Algorithm does not support sharing previous keys", roomEncryption.algorithm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4578,7 +4595,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
const type = localEvent.getType();
|
const type = localEvent.getType();
|
||||||
logger.log(`sendEvent of type ${type} in ${roomId} with txnId ${txnId}`);
|
this.logger.debug(`sendEvent of type ${type} in ${roomId} with txnId ${txnId}`);
|
||||||
|
|
||||||
localEvent.setTxnId(txnId);
|
localEvent.setTxnId(txnId);
|
||||||
localEvent.setStatus(EventStatus.SENDING);
|
localEvent.setStatus(EventStatus.SENDING);
|
||||||
@@ -4650,7 +4667,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
return promise;
|
return promise;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
logger.error("Error sending event", err.stack || err);
|
this.logger.error("Error sending event", err.stack || err);
|
||||||
try {
|
try {
|
||||||
// set the error on the event before we update the status:
|
// set the error on the event before we update the status:
|
||||||
// updating the status emits the event, so the state should be
|
// updating the status emits the event, so the state should be
|
||||||
@@ -4658,7 +4675,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
event.error = err;
|
event.error = err;
|
||||||
this.updatePendingEventStatus(room, event, EventStatus.NOT_SENT);
|
this.updatePendingEventStatus(room, event, EventStatus.NOT_SENT);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error("Exception in error handler!", (<Error>e).stack || err);
|
this.logger.error("Exception in error handler!", (<Error>e).stack || err);
|
||||||
}
|
}
|
||||||
if (err instanceof MatrixError) {
|
if (err instanceof MatrixError) {
|
||||||
err.event = event;
|
err.event = event;
|
||||||
@@ -4771,7 +4788,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
return this.http
|
return this.http
|
||||||
.authedRequest<ISendEventResponse>(Method.Put, path, undefined, event.getWireContent())
|
.authedRequest<ISendEventResponse>(Method.Put, path, undefined, event.getWireContent())
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
logger.log(`Event sent to ${event.getRoomId()} with event id ${res.event_id}`);
|
this.logger.debug(`Event sent to ${event.getRoomId()} with event id ${res.event_id}`);
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -5871,7 +5888,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
const mapper = this.getEventMapper();
|
const mapper = this.getEventMapper();
|
||||||
const event = mapper(res.event);
|
const event = mapper(res.event);
|
||||||
if (event.isRelation(THREAD_RELATION_TYPE.name)) {
|
if (event.isRelation(THREAD_RELATION_TYPE.name)) {
|
||||||
logger.warn("Tried loading a regular timeline at the position of a thread event");
|
this.logger.warn("Tried loading a regular timeline at the position of a thread event");
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const events = [
|
const events = [
|
||||||
@@ -7008,7 +7025,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
// cleanup locks
|
// cleanup locks
|
||||||
this.syncLeftRoomsPromise
|
this.syncLeftRoomsPromise
|
||||||
.then(() => {
|
.then(() => {
|
||||||
logger.log("Marking success of sync left room request");
|
this.logger.debug("Marking success of sync left room request");
|
||||||
this.syncedLeftRooms = true; // flip the bit on success
|
this.syncedLeftRooms = true; // flip the bit on success
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
@@ -7213,14 +7230,14 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
let credentialsGood = false;
|
let credentialsGood = false;
|
||||||
const remainingTime = this.turnServersExpiry - Date.now();
|
const remainingTime = this.turnServersExpiry - Date.now();
|
||||||
if (remainingTime > TURN_CHECK_INTERVAL) {
|
if (remainingTime > TURN_CHECK_INTERVAL) {
|
||||||
logger.debug("TURN creds are valid for another " + remainingTime + " ms: not fetching new ones.");
|
this.logger.debug("TURN creds are valid for another " + remainingTime + " ms: not fetching new ones.");
|
||||||
credentialsGood = true;
|
credentialsGood = true;
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Fetching new TURN credentials");
|
this.logger.debug("Fetching new TURN credentials");
|
||||||
try {
|
try {
|
||||||
const res = await this.turnServer();
|
const res = await this.turnServer();
|
||||||
if (res.uris) {
|
if (res.uris) {
|
||||||
logger.log("Got TURN URIs: " + res.uris + " refresh in " + res.ttl + " secs");
|
this.logger.debug("Got TURN URIs: " + res.uris + " refresh in " + res.ttl + " secs");
|
||||||
// map the response to a format that can be fed to RTCPeerConnection
|
// map the response to a format that can be fed to RTCPeerConnection
|
||||||
const servers: ITurnServer = {
|
const servers: ITurnServer = {
|
||||||
urls: res.uris,
|
urls: res.uris,
|
||||||
@@ -7234,10 +7251,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
this.emit(ClientEvent.TurnServers, this.turnServers);
|
this.emit(ClientEvent.TurnServers, this.turnServers);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error("Failed to get TURN URIs", err);
|
this.logger.error("Failed to get TURN URIs", err);
|
||||||
if ((<HTTPError>err).httpStatus === 403) {
|
if ((<HTTPError>err).httpStatus === 403) {
|
||||||
// We got a 403, so there's no point in looping forever.
|
// We got a 403, so there's no point in looping forever.
|
||||||
logger.info("TURN access unavailable for this account: stopping credentials checks");
|
this.logger.info("TURN access unavailable for this account: stopping credentials checks");
|
||||||
if (this.checkTurnServersIntervalID !== null) global.clearInterval(this.checkTurnServersIntervalID);
|
if (this.checkTurnServersIntervalID !== null) global.clearInterval(this.checkTurnServersIntervalID);
|
||||||
this.checkTurnServersIntervalID = undefined;
|
this.checkTurnServersIntervalID = undefined;
|
||||||
this.emit(ClientEvent.TurnServersError, <HTTPError>err, true); // fatal
|
this.emit(ClientEvent.TurnServersError, <HTTPError>err, true); // fatal
|
||||||
@@ -7976,7 +7993,10 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
try {
|
try {
|
||||||
while ((await this.crypto.backupManager.backupPendingKeys(200)) > 0);
|
while ((await this.crypto.backupManager.backupPendingKeys(200)) > 0);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error("Key backup request failed when logging out. Some keys may be missing from backup", err);
|
this.logger.error(
|
||||||
|
"Key backup request failed when logging out. Some keys may be missing from backup",
|
||||||
|
err,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8137,7 +8157,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
templatedUrl += "/$eventType";
|
templatedUrl += "/$eventType";
|
||||||
}
|
}
|
||||||
} else if (eventType !== null) {
|
} else if (eventType !== null) {
|
||||||
logger.warn(`eventType: ${eventType} ignored when fetching
|
this.logger.warn(`eventType: ${eventType} ignored when fetching
|
||||||
relations as relationType is null`);
|
relations as relationType is null`);
|
||||||
eventType = null;
|
eventType = null;
|
||||||
}
|
}
|
||||||
@@ -9429,7 +9449,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
targets.set(userId, Array.from(deviceMessages.keys()));
|
targets.set(userId, Array.from(deviceMessages.keys()));
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log(`PUT ${path}`, targets);
|
this.logger.debug(`PUT ${path}`, targets);
|
||||||
|
|
||||||
return this.http.authedRequest(Method.Put, path, undefined, body);
|
return this.http.authedRequest(Method.Put, path, undefined, body);
|
||||||
}
|
}
|
||||||
@@ -9688,7 +9708,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
* @deprecated use supportsThreads() instead
|
* @deprecated use supportsThreads() instead
|
||||||
*/
|
*/
|
||||||
public supportsExperimentalThreads(): boolean {
|
public supportsExperimentalThreads(): boolean {
|
||||||
logger.warn(`supportsExperimentalThreads() is deprecated, use supportThreads() instead`);
|
this.logger.warn(`supportsExperimentalThreads() is deprecated, use supportThreads() instead`);
|
||||||
return this.clientOpts?.experimentalThreadSupport || false;
|
return this.clientOpts?.experimentalThreadSupport || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,7 +25,6 @@ import { ConnectionError, MatrixError } from "./errors";
|
|||||||
import { HttpApiEvent, HttpApiEventHandlerMap, IHttpOpts, IRequestOpts, Body } from "./interface";
|
import { HttpApiEvent, HttpApiEventHandlerMap, IHttpOpts, IRequestOpts, Body } from "./interface";
|
||||||
import { anySignal, parseErrorResponse, timeoutSignal } from "./utils";
|
import { anySignal, parseErrorResponse, timeoutSignal } from "./utils";
|
||||||
import { QueryDict } from "../utils";
|
import { QueryDict } from "../utils";
|
||||||
import { logger } from "../logger";
|
|
||||||
|
|
||||||
interface TypedResponse<T> extends Response {
|
interface TypedResponse<T> extends Response {
|
||||||
json(): Promise<T>;
|
json(): Promise<T>;
|
||||||
@@ -225,7 +224,7 @@ export class FetchHttpApi<O extends IHttpOpts> {
|
|||||||
opts: Pick<IRequestOpts, "headers" | "json" | "localTimeoutMs" | "keepAlive" | "abortSignal" | "priority"> = {},
|
opts: Pick<IRequestOpts, "headers" | "json" | "localTimeoutMs" | "keepAlive" | "abortSignal" | "priority"> = {},
|
||||||
): Promise<ResponseType<T, O>> {
|
): Promise<ResponseType<T, O>> {
|
||||||
const urlForLogs = this.sanitizeUrlForLogs(url);
|
const urlForLogs = this.sanitizeUrlForLogs(url);
|
||||||
logger.debug(`FetchHttpApi: --> ${method} ${urlForLogs}`);
|
this.opts.logger?.debug(`FetchHttpApi: --> ${method} ${urlForLogs}`);
|
||||||
|
|
||||||
const headers = Object.assign({}, opts.headers || {});
|
const headers = Object.assign({}, opts.headers || {});
|
||||||
const json = opts.json ?? true;
|
const json = opts.json ?? true;
|
||||||
@@ -279,9 +278,11 @@ export class FetchHttpApi<O extends IHttpOpts> {
|
|||||||
priority: opts.priority,
|
priority: opts.priority,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.debug(`FetchHttpApi: <-- ${method} ${urlForLogs} [${Date.now() - start}ms ${res.status}]`);
|
this.opts.logger?.debug(
|
||||||
|
`FetchHttpApi: <-- ${method} ${urlForLogs} [${Date.now() - start}ms ${res.status}]`,
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.debug(`FetchHttpApi: <-- ${method} ${urlForLogs} [${Date.now() - start}ms ${e}]`);
|
this.opts.logger?.debug(`FetchHttpApi: <-- ${method} ${urlForLogs} [${Date.now() - start}ms ${e}]`);
|
||||||
if ((<Error>e).name === "AbortError") {
|
if ((<Error>e).name === "AbortError") {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { MatrixError } from "./errors";
|
import { MatrixError } from "./errors";
|
||||||
|
import { Logger } from "../logger";
|
||||||
|
|
||||||
export type Body = Record<string, any> | BodyInit;
|
export type Body = Record<string, any> | BodyInit;
|
||||||
|
|
||||||
@@ -46,6 +47,9 @@ export interface IHttpOpts {
|
|||||||
|
|
||||||
onlyData?: boolean;
|
onlyData?: boolean;
|
||||||
localTimeoutMs?: number;
|
localTimeoutMs?: number;
|
||||||
|
|
||||||
|
/** Optional logger instance. If provided, requests and responses will be logged. */
|
||||||
|
logger?: Logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRequestOpts extends Pick<RequestInit, "priority"> {
|
export interface IRequestOpts extends Pick<RequestInit, "priority"> {
|
||||||
|
@@ -17,14 +17,15 @@ limitations under the License.
|
|||||||
import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
|
import * as RustSdkCryptoJs from "@matrix-org/matrix-sdk-crypto-wasm";
|
||||||
|
|
||||||
import { RustCrypto } from "./rust-crypto";
|
import { RustCrypto } from "./rust-crypto";
|
||||||
import { logger } from "../logger";
|
|
||||||
import { IHttpOpts, MatrixHttpApi } from "../http-api";
|
import { IHttpOpts, MatrixHttpApi } from "../http-api";
|
||||||
import { ServerSideSecretStorage } from "../secret-storage";
|
import { ServerSideSecretStorage } from "../secret-storage";
|
||||||
import { ICryptoCallbacks } from "../crypto";
|
import { ICryptoCallbacks } from "../crypto";
|
||||||
|
import { Logger } from "../logger";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new `RustCrypto` implementation
|
* Create a new `RustCrypto` implementation
|
||||||
*
|
*
|
||||||
|
* @param logger - A `Logger` instance that will be used for debug output.
|
||||||
* @param http - Low-level HTTP interface: used to make outgoing requests required by the rust SDK.
|
* @param http - Low-level HTTP interface: used to make outgoing requests required by the rust SDK.
|
||||||
* We expect it to set the access token, etc.
|
* We expect it to set the access token, etc.
|
||||||
* @param userId - The local user's User ID.
|
* @param userId - The local user's User ID.
|
||||||
@@ -40,6 +41,7 @@ import { ICryptoCallbacks } from "../crypto";
|
|||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export async function initRustCrypto(
|
export async function initRustCrypto(
|
||||||
|
logger: Logger,
|
||||||
http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
|
http: MatrixHttpApi<IHttpOpts & { onlyData: true }>,
|
||||||
userId: string,
|
userId: string,
|
||||||
deviceId: string,
|
deviceId: string,
|
||||||
@@ -65,7 +67,7 @@ export async function initRustCrypto(
|
|||||||
storePrefix ?? undefined,
|
storePrefix ?? undefined,
|
||||||
(storePrefix && storePassphrase) ?? undefined,
|
(storePrefix && storePassphrase) ?? undefined,
|
||||||
);
|
);
|
||||||
const rustCrypto = new RustCrypto(olmMachine, http, userId, deviceId, secretStorage, cryptoCallbacks);
|
const rustCrypto = new RustCrypto(logger, olmMachine, http, userId, deviceId, secretStorage, cryptoCallbacks);
|
||||||
await olmMachine.registerRoomKeyUpdatedCallback((sessions: RustSdkCryptoJs.RoomKeyInfo[]) =>
|
await olmMachine.registerRoomKeyUpdatedCallback((sessions: RustSdkCryptoJs.RoomKeyInfo[]) =>
|
||||||
rustCrypto.onRoomKeysUpdated(sessions),
|
rustCrypto.onRoomKeysUpdated(sessions),
|
||||||
);
|
);
|
||||||
|
@@ -24,7 +24,7 @@ import { IContent, MatrixEvent, MatrixEventEvent } from "../models/event";
|
|||||||
import { Room } from "../models/room";
|
import { Room } from "../models/room";
|
||||||
import { RoomMember } from "../models/room-member";
|
import { RoomMember } from "../models/room-member";
|
||||||
import { BackupDecryptor, CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend";
|
import { BackupDecryptor, CryptoBackend, OnSyncCompletedData } from "../common-crypto/CryptoBackend";
|
||||||
import { logger } from "../logger";
|
import { Logger } from "../logger";
|
||||||
import { ClientPrefix, IHttpOpts, MatrixHttpApi, Method } from "../http-api";
|
import { ClientPrefix, IHttpOpts, MatrixHttpApi, Method } from "../http-api";
|
||||||
import { RoomEncryptor } from "./RoomEncryptor";
|
import { RoomEncryptor } from "./RoomEncryptor";
|
||||||
import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor";
|
import { OutgoingRequest, OutgoingRequestProcessor } from "./OutgoingRequestProcessor";
|
||||||
@@ -118,6 +118,8 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
private readonly reemitter = new TypedReEmitter<RustCryptoEvents, RustCryptoEventMap>(this);
|
private readonly reemitter = new TypedReEmitter<RustCryptoEvents, RustCryptoEventMap>(this);
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
|
private readonly logger: Logger,
|
||||||
|
|
||||||
/** The `OlmMachine` from the underlying rust crypto sdk. */
|
/** The `OlmMachine` from the underlying rust crypto sdk. */
|
||||||
private readonly olmMachine: RustSdkCryptoJs.OlmMachine,
|
private readonly olmMachine: RustSdkCryptoJs.OlmMachine,
|
||||||
|
|
||||||
@@ -143,7 +145,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
super();
|
super();
|
||||||
this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http);
|
this.outgoingRequestProcessor = new OutgoingRequestProcessor(olmMachine, http);
|
||||||
this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor);
|
this.keyClaimManager = new KeyClaimManager(olmMachine, this.outgoingRequestProcessor);
|
||||||
this.eventDecryptor = new EventDecryptor(olmMachine, this);
|
this.eventDecryptor = new EventDecryptor(this.logger, olmMachine, this);
|
||||||
|
|
||||||
this.backupManager = new RustBackupManager(olmMachine, http, this.outgoingRequestProcessor);
|
this.backupManager = new RustBackupManager(olmMachine, http, this.outgoingRequestProcessor);
|
||||||
this.reemitter.reEmit(this.backupManager, [
|
this.reemitter.reEmit(this.backupManager, [
|
||||||
@@ -1312,11 +1314,13 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
|
|
||||||
private onRoomKeyUpdated(key: RustSdkCryptoJs.RoomKeyInfo): void {
|
private onRoomKeyUpdated(key: RustSdkCryptoJs.RoomKeyInfo): void {
|
||||||
if (this.stopped) return;
|
if (this.stopped) return;
|
||||||
logger.debug(`Got update for session ${key.senderKey.toBase64()}|${key.sessionId} in ${key.roomId.toString()}`);
|
this.logger.debug(
|
||||||
|
`Got update for session ${key.senderKey.toBase64()}|${key.sessionId} in ${key.roomId.toString()}`,
|
||||||
|
);
|
||||||
const pendingList = this.eventDecryptor.getEventsPendingRoomKey(key);
|
const pendingList = this.eventDecryptor.getEventsPendingRoomKey(key);
|
||||||
if (pendingList.length === 0) return;
|
if (pendingList.length === 0) return;
|
||||||
|
|
||||||
logger.debug(
|
this.logger.debug(
|
||||||
"Retrying decryption on events:",
|
"Retrying decryption on events:",
|
||||||
pendingList.map((e) => `${e.getId()}`),
|
pendingList.map((e) => `${e.getId()}`),
|
||||||
);
|
);
|
||||||
@@ -1329,7 +1333,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
// and deduplicates repeated attempts for the same event.
|
// and deduplicates repeated attempts for the same event.
|
||||||
for (const ev of pendingList) {
|
for (const ev of pendingList) {
|
||||||
ev.attemptDecryption(this, { isRetry: true }).catch((_e) => {
|
ev.attemptDecryption(this, { isRetry: true }).catch((_e) => {
|
||||||
logger.info(`Still unable to decrypt event ${ev.getId()} after receiving key`);
|
this.logger.info(`Still unable to decrypt event ${ev.getId()} after receiving key`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1405,7 +1409,9 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
throw new Error("missing roomId in the event");
|
throw new Error("missing roomId in the event");
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug(`Incoming verification event ${event.getId()} type ${event.getType()} from ${event.getSender()}`);
|
this.logger.debug(
|
||||||
|
`Incoming verification event ${event.getId()} type ${event.getType()} from ${event.getSender()}`,
|
||||||
|
);
|
||||||
|
|
||||||
await this.olmMachine.receiveVerificationEvent(
|
await this.olmMachine.receiveVerificationEvent(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@@ -1430,7 +1436,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
|
|
||||||
if (!request) {
|
if (!request) {
|
||||||
// There are multiple reasons this can happen; probably the most likely is that the event is too old.
|
// There are multiple reasons this can happen; probably the most likely is that the event is too old.
|
||||||
logger.info(
|
this.logger.info(
|
||||||
`Ignoring just-received verification request ${event.getId()} which did not start a rust-side verification`,
|
`Ignoring just-received verification request ${event.getId()} which did not start a rust-side verification`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -1470,7 +1476,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
}
|
}
|
||||||
// fire off the loop in the background
|
// fire off the loop in the background
|
||||||
this.outgoingRequestLoopInner().catch((e) => {
|
this.outgoingRequestLoopInner().catch((e) => {
|
||||||
logger.error("Error processing outgoing-message requests from rust crypto-sdk", e);
|
this.logger.error("Error processing outgoing-message requests from rust crypto-sdk", e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1486,7 +1492,7 @@ export class RustCrypto extends TypedEventEmitter<RustCryptoEvents, RustCryptoEv
|
|||||||
// if `this.outgoingRequestLoop()` was called while `OlmMachine.outgoingRequests()` was running.
|
// if `this.outgoingRequestLoop()` was called while `OlmMachine.outgoingRequests()` was running.
|
||||||
this.outgoingRequestLoopOneMoreLoop = false;
|
this.outgoingRequestLoopOneMoreLoop = false;
|
||||||
|
|
||||||
logger.debug("Calling OlmMachine.outgoingRequests()");
|
this.logger.debug("Calling OlmMachine.outgoingRequests()");
|
||||||
const outgoingRequests: Object[] = await this.olmMachine.outgoingRequests();
|
const outgoingRequests: Object[] = await this.olmMachine.outgoingRequests();
|
||||||
|
|
||||||
if (this.stopped) {
|
if (this.stopped) {
|
||||||
@@ -1521,10 +1527,14 @@ class EventDecryptor {
|
|||||||
() => new MapWithDefault<string, Set<MatrixEvent>>(() => new Set()),
|
() => new MapWithDefault<string, Set<MatrixEvent>>(() => new Set()),
|
||||||
);
|
);
|
||||||
|
|
||||||
public constructor(private readonly olmMachine: RustSdkCryptoJs.OlmMachine, private readonly crypto: RustCrypto) {}
|
public constructor(
|
||||||
|
private readonly logger: Logger,
|
||||||
|
private readonly olmMachine: RustSdkCryptoJs.OlmMachine,
|
||||||
|
private readonly crypto: RustCrypto,
|
||||||
|
) {}
|
||||||
|
|
||||||
public async attemptEventDecryption(event: MatrixEvent): Promise<IEventDecryptionResult> {
|
public async attemptEventDecryption(event: MatrixEvent): Promise<IEventDecryptionResult> {
|
||||||
logger.info(
|
this.logger.info(
|
||||||
`Attempting decryption of event ${event.getId()} in ${event.getRoomId()} from ${event.getSender()}`,
|
`Attempting decryption of event ${event.getId()} in ${event.getRoomId()} from ${event.getSender()}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1605,7 +1615,7 @@ class EventDecryptor {
|
|||||||
new RustSdkCryptoJs.RoomId(event.getRoomId()!),
|
new RustSdkCryptoJs.RoomId(event.getRoomId()!),
|
||||||
);
|
);
|
||||||
|
|
||||||
return rustEncryptionInfoToJsEncryptionInfo(encryptionInfo);
|
return rustEncryptionInfoToJsEncryptionInfo(this.logger, encryptionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1677,6 +1687,7 @@ function stringifyEvent(event: MatrixEvent): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function rustEncryptionInfoToJsEncryptionInfo(
|
function rustEncryptionInfoToJsEncryptionInfo(
|
||||||
|
logger: Logger,
|
||||||
encryptionInfo: RustSdkCryptoJs.EncryptionInfo | undefined,
|
encryptionInfo: RustSdkCryptoJs.EncryptionInfo | undefined,
|
||||||
): EventEncryptionInfo | null {
|
): EventEncryptionInfo | null {
|
||||||
if (encryptionInfo === undefined) {
|
if (encryptionInfo === undefined) {
|
||||||
|
Reference in New Issue
Block a user