You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-09 10:22:46 +03:00
Fix up more types & Sonar warnings (#2363)
* Fix up more types & Sonar warnings * Fix test * Add first test for callEventHandler
This commit is contained in:
committed by
GitHub
parent
4d4d6e1411
commit
4721aa1d24
@@ -526,8 +526,7 @@ describe("MatrixClient event timelines", function() {
|
|||||||
return {
|
return {
|
||||||
original_event: THREAD_ROOT,
|
original_event: THREAD_ROOT,
|
||||||
chunk: [THREAD_REPLY],
|
chunk: [THREAD_REPLY],
|
||||||
next_batch: "next_batch_token0",
|
// no next batch as this is the oldest end of the timeline
|
||||||
prev_batch: "prev_batch_token0",
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -536,8 +535,8 @@ describe("MatrixClient event timelines", function() {
|
|||||||
|
|
||||||
const timeline = await timelinePromise;
|
const timeline = await timelinePromise;
|
||||||
|
|
||||||
expect(timeline.getEvents().find(e => e.getId() === THREAD_ROOT.event_id));
|
expect(timeline.getEvents().find(e => e.getId() === THREAD_ROOT.event_id)).toBeTruthy();
|
||||||
expect(timeline.getEvents().find(e => e.getId() === THREAD_REPLY.event_id));
|
expect(timeline.getEvents().find(e => e.getId() === THREAD_REPLY.event_id)).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
54
spec/unit/webrtc/callEventHandler.spec.ts
Normal file
54
spec/unit/webrtc/callEventHandler.spec.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { TestClient } from '../../TestClient';
|
||||||
|
import { ClientEvent, EventType, MatrixEvent, RoomEvent } from "../../../src";
|
||||||
|
import { CallEventHandler, CallEventHandlerEvent } from "../../../src/webrtc/callEventHandler";
|
||||||
|
import { SyncState } from "../../../src/sync";
|
||||||
|
|
||||||
|
describe("callEventHandler", () => {
|
||||||
|
it("should ignore a call if invite & hangup come within a single sync", () => {
|
||||||
|
const testClient = new TestClient();
|
||||||
|
const client = testClient.client;
|
||||||
|
client.callEventHandler = new CallEventHandler(client);
|
||||||
|
client.callEventHandler.start();
|
||||||
|
|
||||||
|
// Fire off call invite then hangup within a single sync
|
||||||
|
const callInvite = new MatrixEvent({
|
||||||
|
type: EventType.CallInvite,
|
||||||
|
content: {
|
||||||
|
call_id: "123",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
client.emit(RoomEvent.Timeline, callInvite);
|
||||||
|
|
||||||
|
const callHangup = new MatrixEvent({
|
||||||
|
type: EventType.CallHangup,
|
||||||
|
content: {
|
||||||
|
call_id: "123",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
client.emit(RoomEvent.Timeline, callHangup);
|
||||||
|
|
||||||
|
const incomingCallEmitted = jest.fn();
|
||||||
|
client.on(CallEventHandlerEvent.Incoming, incomingCallEmitted);
|
||||||
|
|
||||||
|
client.getSyncState = jest.fn().mockReturnValue(SyncState.Syncing);
|
||||||
|
client.emit(ClientEvent.Sync);
|
||||||
|
|
||||||
|
expect(incomingCallEmitted).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
@@ -17,9 +17,11 @@ limitations under the License.
|
|||||||
import { Callback } from "../client";
|
import { Callback } from "../client";
|
||||||
import { IContent, IEvent } from "../models/event";
|
import { IContent, IEvent } from "../models/event";
|
||||||
import { Preset, Visibility } from "./partials";
|
import { Preset, Visibility } from "./partials";
|
||||||
import { SearchKey } from "./search";
|
import { IEventWithRoomId, SearchKey } from "./search";
|
||||||
import { IRoomEventFilter } from "../filter";
|
import { IRoomEventFilter } from "../filter";
|
||||||
import { Direction } from "../models/event-timeline";
|
import { Direction } from "../models/event-timeline";
|
||||||
|
import { PushRuleAction } from "./PushRules";
|
||||||
|
import { IRoomEvent } from "../sync-accumulator";
|
||||||
|
|
||||||
// allow camelcase as these are things that go onto the wire
|
// allow camelcase as these are things that go onto the wire
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
@@ -155,4 +157,37 @@ export interface IRelationsResponse {
|
|||||||
prev_batch?: string;
|
prev_batch?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IContextResponse {
|
||||||
|
end: string;
|
||||||
|
start: string;
|
||||||
|
state: IEventWithRoomId[];
|
||||||
|
events_before: IEventWithRoomId[];
|
||||||
|
events_after: IEventWithRoomId[];
|
||||||
|
event: IEventWithRoomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IEventsResponse {
|
||||||
|
chunk: IEventWithRoomId[];
|
||||||
|
end: string;
|
||||||
|
start: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface INotification {
|
||||||
|
actions: PushRuleAction[];
|
||||||
|
event: IRoomEvent;
|
||||||
|
profile_tag?: string;
|
||||||
|
read: boolean;
|
||||||
|
room_id: string;
|
||||||
|
ts: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface INotificationsResponse {
|
||||||
|
next_token: string;
|
||||||
|
notifications: INotification[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IFilterResponse {
|
||||||
|
filter_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
/* eslint-enable camelcase */
|
/* eslint-enable camelcase */
|
||||||
|
@@ -113,6 +113,8 @@ import {
|
|||||||
RoomMemberEventHandlerMap,
|
RoomMemberEventHandlerMap,
|
||||||
RoomStateEvent,
|
RoomStateEvent,
|
||||||
RoomStateEventHandlerMap,
|
RoomStateEventHandlerMap,
|
||||||
|
INotificationsResponse,
|
||||||
|
IFilterResponse,
|
||||||
} from "./matrix";
|
} from "./matrix";
|
||||||
import {
|
import {
|
||||||
CrossSigningKey,
|
CrossSigningKey,
|
||||||
@@ -132,6 +134,7 @@ import { Room } from "./models/room";
|
|||||||
import {
|
import {
|
||||||
IAddThreePidOnlyBody,
|
IAddThreePidOnlyBody,
|
||||||
IBindThreePidBody,
|
IBindThreePidBody,
|
||||||
|
IContextResponse,
|
||||||
ICreateRoomOpts,
|
ICreateRoomOpts,
|
||||||
IEventSearchOpts,
|
IEventSearchOpts,
|
||||||
IGuestAccessOpts,
|
IGuestAccessOpts,
|
||||||
@@ -5245,7 +5248,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we should implement a backoff (as per scrollback()) to deal more nicely with HTTP errors.
|
// TODO: we should implement a backoff (as per scrollback()) to deal more nicely with HTTP errors.
|
||||||
const res = await this.http.authedRequest<any>(undefined, Method.Get, path, params); // TODO types
|
const res = await this.http.authedRequest<IContextResponse>(undefined, Method.Get, path, params);
|
||||||
if (!res.event) {
|
if (!res.event) {
|
||||||
throw new Error("'event' not in '/context' result - homeserver too old?");
|
throw new Error("'event' not in '/context' result - homeserver too old?");
|
||||||
}
|
}
|
||||||
@@ -5424,7 +5427,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
params.from = token;
|
params.from = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
promise = this.http.authedRequest<any>( // TODO types
|
promise = this.http.authedRequest<INotificationsResponse>(
|
||||||
undefined, Method.Get, path, params, undefined,
|
undefined, Method.Get, path, params, undefined,
|
||||||
).then(async (res) => {
|
).then(async (res) => {
|
||||||
const token = res.next_token;
|
const token = res.next_token;
|
||||||
@@ -6101,15 +6104,13 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
|||||||
const path = utils.encodeUri("/user/$userId/filter", {
|
const path = utils.encodeUri("/user/$userId/filter", {
|
||||||
$userId: this.credentials.userId,
|
$userId: this.credentials.userId,
|
||||||
});
|
});
|
||||||
// TODO types
|
return this.http.authedRequest<IFilterResponse>(undefined, Method.Post, path, undefined, content)
|
||||||
return this.http.authedRequest<any>(undefined, Method.Post, path, undefined, content).then((response) => {
|
.then((response) => {
|
||||||
// persist the filter
|
// persist the filter
|
||||||
const filter = Filter.fromJson(
|
const filter = Filter.fromJson(this.credentials.userId, response.filter_id, content);
|
||||||
this.credentials.userId, response.filter_id, content,
|
this.store.storeFilter(filter);
|
||||||
);
|
return filter;
|
||||||
this.store.storeFilter(filter);
|
});
|
||||||
return filter;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -942,7 +942,7 @@ async function updateStoredDeviceKeysForUser(
|
|||||||
async function storeDeviceKeys(
|
async function storeDeviceKeys(
|
||||||
olmDevice: OlmDevice,
|
olmDevice: OlmDevice,
|
||||||
userStore: Record<string, DeviceInfo>,
|
userStore: Record<string, DeviceInfo>,
|
||||||
deviceResult: any, // TODO types
|
deviceResult: IDownloadKeyResult["device_keys"]["user_id"]["device_id"],
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!deviceResult.keys) {
|
if (!deviceResult.keys) {
|
||||||
// no keys?
|
// no keys?
|
||||||
|
@@ -58,7 +58,7 @@ import { keyFromPassphrase } from './key_passphrase';
|
|||||||
import { decodeRecoveryKey, encodeRecoveryKey } from './recoverykey';
|
import { decodeRecoveryKey, encodeRecoveryKey } from './recoverykey';
|
||||||
import { VerificationRequest } from "./verification/request/VerificationRequest";
|
import { VerificationRequest } from "./verification/request/VerificationRequest";
|
||||||
import { InRoomChannel, InRoomRequests } from "./verification/request/InRoomChannel";
|
import { InRoomChannel, InRoomRequests } from "./verification/request/InRoomChannel";
|
||||||
import { ToDeviceChannel, ToDeviceRequests } from "./verification/request/ToDeviceChannel";
|
import { ToDeviceChannel, ToDeviceRequests, Request } from "./verification/request/ToDeviceChannel";
|
||||||
import { IllegalMethod } from "./verification/IllegalMethod";
|
import { IllegalMethod } from "./verification/IllegalMethod";
|
||||||
import { KeySignatureUploadError } from "../errors";
|
import { KeySignatureUploadError } from "../errors";
|
||||||
import { calculateKeyCheck, decryptAES, encryptAES } from './aes';
|
import { calculateKeyCheck, decryptAES, encryptAES } from './aes';
|
||||||
@@ -2318,8 +2318,8 @@ export class Crypto extends TypedEventEmitter<CryptoEvent, CryptoEventHandlerMap
|
|||||||
userId: string,
|
userId: string,
|
||||||
deviceId: string,
|
deviceId: string,
|
||||||
transactionId: string = null,
|
transactionId: string = null,
|
||||||
): any { // TODO types
|
): VerificationBase<any, any> {
|
||||||
let request;
|
let request: Request;
|
||||||
if (transactionId) {
|
if (transactionId) {
|
||||||
request = this.toDeviceVerificationRequests.getRequestBySenderAndTxnId(userId, transactionId);
|
request = this.toDeviceVerificationRequests.getRequestBySenderAndTxnId(userId, transactionId);
|
||||||
if (!request) {
|
if (!request) {
|
||||||
|
@@ -1043,7 +1043,7 @@ export class MatrixEvent extends TypedEventEmitter<EmittedEvents, MatrixEventHan
|
|||||||
* caused a change in the actual visibility of this event, either by making it
|
* caused a change in the actual visibility of this event, either by making it
|
||||||
* visible (if it was hidden), by making it hidden (if it was visible) or by
|
* visible (if it was hidden), by making it hidden (if it was visible) or by
|
||||||
* changing the reason (if it was hidden).
|
* changing the reason (if it was hidden).
|
||||||
* @param visibilityEvent event holding a hide/unhide payload, or nothing
|
* @param visibilityChange event holding a hide/unhide payload, or nothing
|
||||||
* if the event is being reset to its original visibility (presumably
|
* if the event is being reset to its original visibility (presumably
|
||||||
* by a visibility event being redacted).
|
* by a visibility event being redacted).
|
||||||
*/
|
*/
|
||||||
@@ -1065,9 +1065,7 @@ export class MatrixEvent extends TypedEventEmitter<EmittedEvents, MatrixEventHan
|
|||||||
reason: reason,
|
reason: reason,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (change) {
|
this.emit(MatrixEventEvent.VisibilityChange, this, visible);
|
||||||
this.emit(MatrixEventEvent.VisibilityChange, this, visible);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,6 @@ export interface IRoomEvent extends IMinimalEvent {
|
|||||||
event_id: string;
|
event_id: string;
|
||||||
sender: string;
|
sender: string;
|
||||||
origin_server_ts: number;
|
origin_server_ts: number;
|
||||||
unsigned?: IUnsigned;
|
|
||||||
/** @deprecated - legacy field */
|
/** @deprecated - legacy field */
|
||||||
age?: number;
|
age?: number;
|
||||||
}
|
}
|
||||||
|
@@ -54,6 +54,7 @@ import { IPushRules } from "./@types/PushRules";
|
|||||||
import { RoomStateEvent } from "./models/room-state";
|
import { RoomStateEvent } from "./models/room-state";
|
||||||
import { RoomMemberEvent } from "./models/room-member";
|
import { RoomMemberEvent } from "./models/room-member";
|
||||||
import { BeaconEvent } from "./models/beacon";
|
import { BeaconEvent } from "./models/beacon";
|
||||||
|
import { IEventsResponse } from "./@types/requests";
|
||||||
|
|
||||||
const DEBUG = true;
|
const DEBUG = true;
|
||||||
|
|
||||||
@@ -274,7 +275,7 @@ export class SyncApi {
|
|||||||
getFilterName(client.credentials.userId, "LEFT_ROOMS"), filter,
|
getFilterName(client.credentials.userId, "LEFT_ROOMS"), filter,
|
||||||
).then(function(filterId) {
|
).then(function(filterId) {
|
||||||
qps.filter = filterId;
|
qps.filter = filterId;
|
||||||
return client.http.authedRequest<any>( // TODO types
|
return client.http.authedRequest<ISyncResponse>(
|
||||||
undefined, Method.Get, "/sync", qps as any, undefined, localTimeoutMs,
|
undefined, Method.Get, "/sync", qps as any, undefined, localTimeoutMs,
|
||||||
);
|
);
|
||||||
}).then(async (data) => {
|
}).then(async (data) => {
|
||||||
@@ -409,8 +410,7 @@ export class SyncApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: gut wrenching; hard-coded timeout values
|
// FIXME: gut wrenching; hard-coded timeout values
|
||||||
// TODO types
|
this.client.http.authedRequest<IEventsResponse>(undefined, Method.Get, "/events", {
|
||||||
this.client.http.authedRequest<any>(undefined, Method.Get, "/events", {
|
|
||||||
room_id: peekRoom.roomId,
|
room_id: peekRoom.roomId,
|
||||||
timeout: String(30 * 1000),
|
timeout: String(30 * 1000),
|
||||||
from: token,
|
from: token,
|
||||||
@@ -874,7 +874,7 @@ export class SyncApi {
|
|||||||
|
|
||||||
private doSyncRequest(syncOptions: ISyncOptions, syncToken: string): IRequestPromise<ISyncResponse> {
|
private doSyncRequest(syncOptions: ISyncOptions, syncToken: string): IRequestPromise<ISyncResponse> {
|
||||||
const qps = this.getSyncParams(syncOptions, syncToken);
|
const qps = this.getSyncParams(syncOptions, syncToken);
|
||||||
return this.client.http.authedRequest( // TODO types
|
return this.client.http.authedRequest<ISyncResponse>(
|
||||||
undefined, Method.Get, "/sync", qps as any, undefined,
|
undefined, Method.Get, "/sync", qps as any, undefined,
|
||||||
qps.timeout + BUFFER_PERIOD_MS,
|
qps.timeout + BUFFER_PERIOD_MS,
|
||||||
);
|
);
|
||||||
|
@@ -72,21 +72,17 @@ export class CallEventHandler {
|
|||||||
this.client.decryptEventIfNeeded(event);
|
this.client.decryptEventIfNeeded(event);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const ignoreCallIds = new Set<String>();
|
const ignoreCallIds = new Set<string>();
|
||||||
// inspect the buffer and mark all calls which have been answered
|
// inspect the buffer and mark all calls which have been answered
|
||||||
// or hung up before passing them to the call event handler.
|
// or hung up before passing them to the call event handler.
|
||||||
for (const ev of this.callEventBuffer) {
|
for (const ev of this.callEventBuffer) {
|
||||||
if (ev.getType() === EventType.CallAnswer ||
|
if (ev.getType() === EventType.CallAnswer || ev.getType() === EventType.CallHangup) {
|
||||||
ev.getType() === EventType.CallHangup) {
|
|
||||||
ignoreCallIds.add(ev.getContent().call_id);
|
ignoreCallIds.add(ev.getContent().call_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now loop through the buffer chronologically and inject them
|
// now loop through the buffer chronologically and inject them
|
||||||
for (const e of this.callEventBuffer) {
|
for (const e of this.callEventBuffer) {
|
||||||
if (
|
if (e.getType() === EventType.CallInvite && ignoreCallIds.has(e.getContent().call_id)) {
|
||||||
e.getType() === EventType.CallInvite &&
|
|
||||||
ignoreCallIds.has(e.getContent().call_id)
|
|
||||||
) {
|
|
||||||
// This call has previously been answered or hung up: ignore it
|
// This call has previously been answered or hung up: ignore it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -191,7 +187,7 @@ export class CallEventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Were we trying to call that user (room)?
|
// Were we trying to call that user (room)?
|
||||||
let existingCall;
|
let existingCall: MatrixCall;
|
||||||
for (const thisCall of this.calls.values()) {
|
for (const thisCall of this.calls.values()) {
|
||||||
const isCalling = [CallState.WaitLocalMedia, CallState.CreateOffer, CallState.InviteSent].includes(
|
const isCalling = [CallState.WaitLocalMedia, CallState.CreateOffer, CallState.InviteSent].includes(
|
||||||
thisCall.state,
|
thisCall.state,
|
||||||
|
Reference in New Issue
Block a user