Remove dead & duplicated code (#11405)

* Remove dead code

* Make dead code happier

* DRY pickle additional data calculation

* Iterate
This commit is contained in:
Michael Telatynski 2023-08-15 09:43:15 +01:00 committed by GitHub
parent 672ad98ec7
commit 27d79458da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 50 additions and 201 deletions

View file

@ -281,16 +281,15 @@ export default class AddThreepid {
): Promise<[success?: boolean, result?: IAuthData | Error | null] | undefined> {
const authClient = new IdentityAuthClient();
let result: { success: boolean } | MatrixError;
if (this.submitUrl) {
result = await this.matrixClient.submitMsisdnTokenOtherUrl(
await this.matrixClient.submitMsisdnTokenOtherUrl(
this.submitUrl,
this.sessionId!,
this.clientSecret,
msisdnToken,
);
} else if (this.bind) {
result = await this.matrixClient.submitMsisdnToken(
await this.matrixClient.submitMsisdnToken(
this.sessionId!,
this.clientSecret,
msisdnToken,
@ -299,9 +298,6 @@ export default class AddThreepid {
} else {
throw new UserFriendlyError("The add / bind with MSISDN flow is misconfigured");
}
if (result instanceof Error) {
throw result;
}
if (this.bind) {
await this.matrixClient.bindThreePid({

View file

@ -67,7 +67,7 @@ export default abstract class BasePlatform {
protected notificationCount = 0;
protected errorDidOccur = false;
public constructor() {
protected constructor() {
dis.register(this.onAction);
this.startUpdateCheck = this.startUpdateCheck.bind(this);
}
@ -365,14 +365,7 @@ export default abstract class BasePlatform {
return null;
}
const additionalData = new Uint8Array(userId.length + deviceId.length + 1);
for (let i = 0; i < userId.length; i++) {
additionalData[i] = userId.charCodeAt(i);
}
additionalData[userId.length] = 124; // "|"
for (let i = 0; i < deviceId.length; i++) {
additionalData[userId.length + 1 + i] = deviceId.charCodeAt(i);
}
const additionalData = this.getPickleAdditionalData(userId, deviceId);
try {
const key = await crypto.subtle.decrypt(
@ -387,6 +380,18 @@ export default abstract class BasePlatform {
}
}
private getPickleAdditionalData(userId: string, deviceId: string): Uint8Array {
const additionalData = new Uint8Array(userId.length + deviceId.length + 1);
for (let i = 0; i < userId.length; i++) {
additionalData[i] = userId.charCodeAt(i);
}
additionalData[userId.length] = 124; // "|"
for (let i = 0; i < deviceId.length; i++) {
additionalData[userId.length + 1 + i] = deviceId.charCodeAt(i);
}
return additionalData;
}
/**
* Create and store a pickle key for encrypting libolm objects.
* @param {string} userId the user ID for the user that the pickle key is for.
@ -408,15 +413,7 @@ export default abstract class BasePlatform {
const iv = new Uint8Array(32);
crypto.getRandomValues(iv);
const additionalData = new Uint8Array(userId.length + deviceId.length + 1);
for (let i = 0; i < userId.length; i++) {
additionalData[i] = userId.charCodeAt(i);
}
additionalData[userId.length] = 124; // "|"
for (let i = 0; i < deviceId.length; i++) {
additionalData[userId.length + 1 + i] = deviceId.charCodeAt(i);
}
const additionalData = this.getPickleAdditionalData(userId, deviceId);
const encrypted = await crypto.subtle.encrypt({ name: "AES-GCM", iv, additionalData }, cryptoKey, randomArray);
try {

View file

@ -75,10 +75,6 @@ export default class IdentityAuthClient {
return window.localStorage.getItem("mx_is_access_token");
}
public hasCredentials(): boolean {
return Boolean(this.accessToken);
}
// Returns a promise that resolves to the access_token string from the IS
public async getAccessToken({ check = true } = {}): Promise<string | null> {
if (!this.authEnabled) {

View file

@ -429,15 +429,6 @@ export default class LegacyCallHandler extends EventEmitter {
return this.calls.get(roomId) || null;
}
public getAnyActiveCall(): MatrixCall | null {
for (const call of this.calls.values()) {
if (call.state !== CallState.Ended) {
return call;
}
}
return null;
}
public getAllActiveCalls(): MatrixCall[] {
const activeCalls: MatrixCall[] = [];

View file

@ -47,41 +47,6 @@ export default class PasswordReset {
this.clientSecret = this.client.generateClientSecret();
}
/**
* Attempt to reset the user's password. This will trigger a side-effect of
* sending an email to the provided email address.
* @param {string} emailAddress The email address
* @param {string} newPassword The new password for the account.
* @param {boolean} logoutDevices Should all devices be signed out after the reset? Defaults to `true`.
* @return {Promise} Resolves when the email has been sent. Then call checkEmailLinkClicked().
*/
public async resetPassword(
emailAddress: string,
newPassword: string,
logoutDevices = true,
): Promise<IRequestTokenResponse> {
this.password = newPassword;
this.logoutDevices = logoutDevices;
this.sendAttempt++;
try {
const result = await this.client.requestPasswordEmailToken(
emailAddress,
this.clientSecret,
this.sendAttempt,
);
this.sessionId = result.sid;
return result;
} catch (err: any) {
if (err.errcode === "M_THREEPID_NOT_FOUND") {
err.message = _t("This email address was not found");
} else if (err.httpStatus) {
err.message = err.message + ` (Status ${err.httpStatus})`;
}
throw err;
}
}
/**
* Request a password reset token.
* This will trigger a side-effect of sending an email to the provided email address.

View file

@ -256,9 +256,8 @@ export function determineUnreadState(
return { symbol: null, count: trueCount, color: NotificationColor.Grey };
}
// We don't have any notified messages, but we might have unread messages. Let's
// find out.
let hasUnread = false;
// We don't have any notified messages, but we might have unread messages. Let's find out.
let hasUnread: boolean;
if (threadId) hasUnread = doesRoomOrThreadHaveUnreadMessages(room.getThread(threadId)!);
else hasUnread = doesRoomHaveUnreadMessages(room);

View file

@ -679,7 +679,7 @@ function canSendEvent(event: MessageEvent<any>, roomId: string): void {
}
const me = client.credentials.userId!;
let canSend = false;
let canSend: boolean;
if (isState) {
canSend = room.currentState.maySendStateEvent(evType, me);
} else {

View file

@ -117,7 +117,7 @@ const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
return (
<QuestionDialog
className="mx_FeedbackDialog"
hasCancelButton={!!hasFeedback}
hasCancelButton={hasFeedback}
title={_t("Feedback")}
description={
<React.Fragment>

View file

@ -461,7 +461,7 @@ export default class EditorModel {
*/
public transform(callback: ManualTransformCallback): Promise<void> {
const pos = callback();
let acPromise: Promise<void> | null = null;
let acPromise: Promise<void> | null;
if (!(pos instanceof Range)) {
acPromise = this.setActivePart(pos, true);
} else {

View file

@ -112,13 +112,6 @@ export default abstract class BaseEventIndexManager {
throw new Error("Unimplemented");
}
/**
* Check if our event index is empty.
*/
public indexIsEmpty(): Promise<boolean> {
throw new Error("Unimplemented");
}
/**
* Check if the room with the given id is already indexed.
*

View file

@ -26,7 +26,6 @@ import IntegrationsImpossibleDialog from "../components/views/dialogs/Integratio
import IntegrationsDisabledDialog from "../components/views/dialogs/IntegrationsDisabledDialog";
import WidgetUtils from "../utils/WidgetUtils";
import { MatrixClientPeg } from "../MatrixClientPeg";
import { parseUrl } from "../utils/UrlUtils";
const KIND_PREFERENCE = [
// Ordered: first is most preferred, last is least preferred.
@ -179,52 +178,6 @@ export class IntegrationManagers {
public showDisabledDialog(): void {
Modal.createDialog(IntegrationsDisabledDialog);
}
/**
* Attempts to discover an integration manager using only its name. This will not validate that
* the integration manager is functional - that is the caller's responsibility.
* @param {string} domainName The domain name to look up.
* @returns {Promise<IntegrationManagerInstance>} Resolves to an integration manager instance,
* or null if none was found.
*/
public async tryDiscoverManager(domainName: string): Promise<IntegrationManagerInstance | null> {
logger.log("Looking up integration manager via .well-known");
if (domainName.startsWith("http:") || domainName.startsWith("https:")) {
// trim off the scheme and just use the domain
domainName = parseUrl(domainName).host;
}
let wkConfig: IClientWellKnown;
try {
const result = await fetch(`https://${domainName}/.well-known/matrix/integrations`);
wkConfig = await result.json();
} catch (e) {
logger.error(e);
logger.warn("Failed to locate integration manager");
return null;
}
if (!wkConfig || !wkConfig["m.integrations_widget"]) {
logger.warn("Missing integrations widget on .well-known response");
return null;
}
const widget = wkConfig["m.integrations_widget"];
if (!widget["url"] || !widget["data"] || !widget["data"]["api_url"]) {
logger.warn("Malformed .well-known response for integrations widget");
return null;
}
// All discovered managers are per-user managers
const manager = new IntegrationManagerInstance(Kind.Account, widget["data"]["api_url"], widget["url"]);
logger.log("Got an integration manager (untested)");
// We don't test the manager because the caller may need to do extra
// checks or similar with it. For instance, they may need to deal with
// terms of service or want to call something particular.
return manager;
}
}
// For debugging

View file

@ -63,10 +63,6 @@ export class BanList {
return this._rules.filter((r) => r.kind === RULE_USER);
}
public get roomRules(): ListRule[] {
return this._rules.filter((r) => r.kind === RULE_ROOM);
}
public async banEntity(kind: string, entity: string, reason: string): Promise<any> {
const type = ruleTypeToStable(kind);
if (!type) return; // unknown rule type

View file

@ -157,7 +157,7 @@ export abstract class Call extends TypedEventEmitter<CallEvent, CallEventHandler
this.emit(CallEvent.Participants, value, prevValue);
}
public constructor(
protected constructor(
/**
* The widget used to access this call.
*/

View file

@ -117,7 +117,7 @@ async function collectBugReport(opts: IOpts = {}, gzipLogs = true): Promise<Form
);
body.append("secret_storage_ready", String(await client.isSecretStorageReady()));
body.append("secret_storage_key_in_account", String(!!(await secretStorage.hasKey())));
body.append("secret_storage_key_in_account", String(await secretStorage.hasKey()));
body.append("session_backup_key_in_secret_storage", String(!!(await client.isKeyBackupKeyStored())));
const sessionBackupKeyFromCache = await client.crypto.getSessionBackupPrivateKey();

View file

@ -139,7 +139,7 @@ async function getCryptoContext(client: MatrixClient): Promise<CryptoContext> {
!!(pkCache && (await pkCache.getCrossSigningKeyCache?.("user_signing"))),
),
secret_storage_ready: String(await client.isSecretStorageReady()),
secret_storage_key_in_account: String(!!(await secretStorage.hasKey())),
secret_storage_key_in_account: String(await secretStorage.hasKey()),
session_backup_key_in_secret_storage: String(!!(await client.isKeyBackupKeyStored())),
session_backup_key_cached: String(!!sessionBackupKeyFromCache),
session_backup_key_well_formed: String(sessionBackupKeyFromCache instanceof Uint8Array),

View file

@ -577,10 +577,9 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> implements
* @param {IFilterCondition} filter The filter condition to add.
*/
public async addFilter(filter: IFilterCondition): Promise<void> {
let promise = Promise.resolve();
filter.on(FILTER_CHANGED, this.onPrefilterUpdated);
this.prefilterConditions.push(filter);
promise = this.recalculatePrefiltering();
const promise = this.recalculatePrefiltering();
promise.then(() => this.updateFn.trigger());
}

View file

@ -399,6 +399,4 @@ export class SlidingRoomListStoreClass extends AsyncStoreWithClient<IState> impl
}
protected async onAction(payload: ActionPayload): Promise<void> {}
protected async onDispatchAsync(payload: ActionPayload): Promise<void> {}
}

View file

@ -90,10 +90,6 @@ export class Algorithm extends EventEmitter {
return this._stickyRoom ? this._stickyRoom.room : null;
}
public get knownRooms(): Room[] {
return this.rooms;
}
public get hasTagSortingMap(): boolean {
return !!this.sortAlgorithms;
}

View file

@ -242,10 +242,6 @@ export class StopGapWidget extends EventEmitter {
return parsed.toString().replace(/%24/g, "$");
}
public get isManagedByManager(): boolean {
return !!this.scalarToken;
}
public get started(): boolean {
return !!this.messaging;
}

View file

@ -245,7 +245,7 @@ export class StopGapWidgetDriver extends WidgetDriver {
if (!client || !roomId) throw new Error("Not in a room or not attached to a client");
let r: { event_id: string } | null = null; // eslint-disable-line camelcase
let r: { event_id: string } | null;
if (stateKey !== null) {
// state event
r = await client.sendStateEvent(roomId, eventType, content, stateKey);

View file

@ -411,45 +411,6 @@ export default class WidgetUtils {
return widgets.filter((w) => w.content?.type === "m.integration_manager");
}
public static getRoomWidgetsOfType(room: Room, type: WidgetType): MatrixEvent[] {
const widgets = WidgetUtils.getRoomWidgets(room) || [];
return widgets.filter((w) => {
const content = w.getContent();
return content.url && type.matches(content.type);
});
}
public static async removeIntegrationManagerWidgets(client: MatrixClient | undefined): Promise<void> {
if (!client) {
throw new Error("User not logged in");
}
const widgets = client.getAccountData("m.widgets");
if (!widgets) return;
const userWidgets: Record<string, IWidgetEvent> = widgets.getContent() || {};
Object.entries(userWidgets).forEach(([key, widget]) => {
if (widget.content && widget.content.type === "m.integration_manager") {
delete userWidgets[key];
}
});
await client.setAccountData("m.widgets", userWidgets);
}
public static addIntegrationManagerWidget(
client: MatrixClient,
name: string,
uiUrl: string,
apiUrl: string,
): Promise<void> {
return WidgetUtils.setUserWidget(
client,
"integration_manager_" + new Date().getTime(),
WidgetType.INTEGRATION_MANAGER,
uiUrl,
"Integration manager: " + name,
{ api_url: apiUrl },
);
}
/**
* Remove all stickerpicker widgets (stickerpickers are user widgets by nature)
* @param client The matrix client of the logged-in user

View file

@ -69,8 +69,4 @@ export class PermalinkParts {
public get primaryEntityId(): string | null {
return this.roomIdOrAlias || this.userId;
}
public get sigil(): string {
return this.primaryEntityId?.[0] || "?";
}
}

View file

@ -114,6 +114,7 @@ export class RoomPermalinkCreator {
}
public start(): void {
if (this.started) return;
this.load();
this.room?.currentState.on(RoomStateEvent.Update, this.onRoomStateUpdate);
this.started = true;
@ -128,10 +129,6 @@ export class RoomPermalinkCreator {
return this._serverCandidates;
}
public isStarted(): boolean {
return this.started;
}
public forEvent(eventId: string): string {
return getPermalinkConstructor().forEvent(this.roomId, eventId, this._serverCandidates);
}

View file

@ -31,7 +31,6 @@ describe("transforming search term", () => {
eventId: "",
userId: "",
viaServers: [],
sigil: "",
});
expect(transformSearchTerm(roomLink)).toBe(parsedPermalink);
@ -46,7 +45,6 @@ describe("transforming search term", () => {
eventId: null,
userId: null,
viaServers: null,
sigil: "?",
});
expect(transformSearchTerm(searchTerm)).toBe(searchTerm);

View file

@ -12,6 +12,8 @@ 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 { EventEmitter } from "events";
import { Room, RoomMember, EventType, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../../../src/MatrixClientPeg";
@ -87,6 +89,26 @@ describe("Permalinks", function () {
jest.spyOn(MatrixClientPeg, "get").mockRestore();
});
it("should not clean up listeners even if start was called multiple times", () => {
const room = mockRoom("!fake:example.org", []);
const getListenerCount = (emitter: EventEmitter) =>
emitter
.eventNames()
.map((e) => emitter.listenerCount(e))
.reduce((a, b) => a + b, 0);
const listenerCountBefore = getListenerCount(room.currentState);
const creator = new RoomPermalinkCreator(room);
creator.start();
creator.start();
creator.start();
creator.start();
expect(getListenerCount(room.currentState)).toBeGreaterThan(listenerCountBefore);
creator.stop();
expect(getListenerCount(room.currentState)).toBe(listenerCountBefore);
});
it("should pick no candidate servers when the room has no members", function () {
const room = mockRoom("!fake:example.org", []);
const creator = new RoomPermalinkCreator(room);