Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Conform more of the codebase to strictNullChecks (#10518 #10518

Merged
merged 3 commits into from
Apr 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 19 additions & 20 deletions src/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export async function loadSession(opts: ILoadSessionOpts = {}): Promise<boolean>
enableGuest = false;
}

if (enableGuest && fragmentQueryParams.guest_user_id && fragmentQueryParams.guest_access_token) {
if (enableGuest && guestHsUrl && fragmentQueryParams.guest_user_id && fragmentQueryParams.guest_access_token) {
logger.log("Using guest access credentials");
return doSetLoggedIn(
{
Expand All @@ -150,7 +150,7 @@ export async function loadSession(opts: ILoadSessionOpts = {}): Promise<boolean>
return true;
}

if (enableGuest) {
if (enableGuest && guestHsUrl) {
return registerAsGuest(guestHsUrl, guestIsUrl, defaultDeviceDisplayName);
}

Expand All @@ -174,7 +174,7 @@ export async function loadSession(opts: ILoadSessionOpts = {}): Promise<boolean>
* session is for a guest user, if an owner exists. If there is no stored session,
* return [null, null].
*/
export async function getStoredSessionOwner(): Promise<[string, boolean]> {
export async function getStoredSessionOwner(): Promise<[string, boolean] | [null, null]> {
const { hsUrl, userId, hasAccessToken, isGuest } = await getStoredSessionVars();
return hsUrl && userId && hasAccessToken ? [userId, isGuest] : [null, null];
}
Expand Down Expand Up @@ -259,7 +259,7 @@ export function attemptTokenLogin(
});
}

export function handleInvalidStoreError(e: InvalidStoreError): Promise<void> {
export function handleInvalidStoreError(e: InvalidStoreError): Promise<void> | void {
if (e.reason === InvalidStoreError.TOGGLED_LAZY_LOADING) {
return Promise.resolve()
.then(() => {
Expand Down Expand Up @@ -292,7 +292,7 @@ export function handleInvalidStoreError(e: InvalidStoreError): Promise<void> {
}
}

function registerAsGuest(hsUrl: string, isUrl: string, defaultDeviceDisplayName: string): Promise<boolean> {
function registerAsGuest(hsUrl: string, isUrl?: string, defaultDeviceDisplayName?: string): Promise<boolean> {
logger.log(`Doing guest login on ${hsUrl}`);

// create a temporary MatrixClient to do the login
Expand Down Expand Up @@ -346,14 +346,14 @@ export interface IStoredSession {
export async function getStoredSessionVars(): Promise<IStoredSession> {
const hsUrl = localStorage.getItem(HOMESERVER_URL_KEY);
const isUrl = localStorage.getItem(ID_SERVER_URL_KEY);
let accessToken;
let accessToken: string | undefined;
try {
accessToken = await StorageManager.idbLoad("account", "mx_access_token");
} catch (e) {
logger.error("StorageManager.idbLoad failed for account:mx_access_token", e);
}
if (!accessToken) {
accessToken = localStorage.getItem("mx_access_token");
accessToken = localStorage.getItem("mx_access_token") ?? undefined;
if (accessToken) {
try {
// try to migrate access token to IndexedDB if we can
Expand All @@ -370,7 +370,7 @@ export async function getStoredSessionVars(): Promise<IStoredSession> {
const userId = localStorage.getItem("mx_user_id");
const deviceId = localStorage.getItem("mx_device_id");

let isGuest;
let isGuest: boolean;
if (localStorage.getItem("mx_is_guest") !== null) {
isGuest = localStorage.getItem("mx_is_guest") === "true";
} else {
Expand Down Expand Up @@ -447,7 +447,7 @@ export async function restoreFromLocalStorage(opts?: { ignoreGuest?: boolean }):
}

let decryptedAccessToken = accessToken;
const pickleKey = await PlatformPeg.get().getPickleKey(userId, deviceId);
const pickleKey = await PlatformPeg.get()?.getPickleKey(userId, deviceId);
if (pickleKey) {
logger.log("Got pickle key");
if (typeof accessToken !== "string") {
Expand All @@ -471,7 +471,7 @@ export async function restoreFromLocalStorage(opts?: { ignoreGuest?: boolean }):
homeserverUrl: hsUrl,
identityServerUrl: isUrl,
guest: isGuest,
pickleKey: pickleKey,
pickleKey: pickleKey ?? undefined,
freshLogin: freshLogin,
},
false,
Expand Down Expand Up @@ -561,7 +561,8 @@ export async function hydrateSession(credentials: IMatrixClientCreds): Promise<M

if (!credentials.pickleKey) {
logger.info("Lifecycle#hydrateSession: Pickle key not provided - trying to get one");
credentials.pickleKey = await PlatformPeg.get().getPickleKey(credentials.userId, credentials.deviceId);
credentials.pickleKey =
(await PlatformPeg.get()?.getPickleKey(credentials.userId, credentials.deviceId)) ?? undefined;
}

return doSetLoggedIn(credentials, overwrite);
Expand Down Expand Up @@ -646,12 +647,10 @@ async function doSetLoggedIn(credentials: IMatrixClientCreds, clearStorageEnable
return client;
}

function showStorageEvictedDialog(): Promise<boolean> {
return new Promise((resolve) => {
Modal.createDialog(StorageEvictedDialog, {
onFinished: resolve,
});
});
async function showStorageEvictedDialog(): Promise<boolean> {
const { finished } = Modal.createDialog(StorageEvictedDialog);
const [ok] = await finished;
return !!ok;
}

// Note: Babel 6 requires the `transform-builtin-extend` plugin for this to satisfy
Expand All @@ -675,7 +674,7 @@ async function persistCredentials(credentials: IMatrixClientCreds): Promise<void
}

if (credentials.pickleKey) {
let encryptedAccessToken: IEncryptedPayload;
let encryptedAccessToken: IEncryptedPayload | undefined;
try {
// try to encrypt the access token using the pickle key
const encrKey = await pickleKeyToAesKey(credentials.pickleKey);
Expand Down Expand Up @@ -741,7 +740,7 @@ export function logout(): void {

_isLoggingOut = true;
const client = MatrixClientPeg.get();
PlatformPeg.get().destroyPickleKey(client.getUserId(), client.getDeviceId());
PlatformPeg.get()?.destroyPickleKey(client.getSafeUserId(), client.getDeviceId());
client.logout(true).then(onLoggedOut, (err) => {
// Just throwing an error here is going to be very unhelpful
// if you're trying to log out because your server's down and
Expand Down Expand Up @@ -870,7 +869,7 @@ export async function onLoggedOut(): Promise<void> {
logger.log("Redirecting to external provider to finish logout");
// XXX: Defer this so that it doesn't race with MatrixChat unmounting the world by going to /#/login
window.setTimeout(() => {
window.location.href = SdkConfig.get().logout_redirect_url;
window.location.href = SdkConfig.get().logout_redirect_url!;
}, 100);
}
// Do this last to prevent racing `stopMatrixClient` and `on_logged_out` with MatrixChat handling Session.logged_out
Expand Down
2 changes: 1 addition & 1 deletion src/MatrixClientPeg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class MatrixClientPegClass implements IMatrixClientPeg {
}

public currentUserIsJustRegistered(): boolean {
return this.matrixClient && this.matrixClient.credentials.userId === this.justRegisteredUserId;
return !!this.matrixClient && this.matrixClient.credentials.userId === this.justRegisteredUserId;
}

public userRegisteredWithinLastHours(hours: number): boolean {
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/messages/EditHistoryMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default class EditHistoryMessage extends React.PureComponent<IProps, ISta
ConfirmAndWaitRedactDialog,
{
redact: async () => {
await cli.redactEvent(event.getRoomId()!, event.getId());
await cli.redactEvent(event.getRoomId()!, event.getId()!);
},
},
"mx_Dialog_confirmredact",
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/messages/ReactionsRowButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default class ReactionsRowButton extends React.PureComponent<IProps, ISta
public onClick = (): void => {
const { mxEvent, myReactionEvent, content } = this.props;
if (myReactionEvent) {
this.context.redactEvent(mxEvent.getRoomId()!, myReactionEvent.getId());
this.context.redactEvent(mxEvent.getRoomId()!, myReactionEvent.getId()!);
} else {
this.context.sendEvent(mxEvent.getRoomId()!, "m.reaction", {
"m.relates_to": {
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/settings/account/PhoneNumbers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export default class PhoneNumbers extends React.Component<IProps, IState> {
const address = this.state.verifyMsisdn;
this.state.addTask
?.haveMsisdnToken(token)
.then(([finished]) => {
.then(([finished] = []) => {
let newPhoneNumber = this.state.newPhoneNumber;
if (finished) {
const msisdns = [...this.props.msisdns, { address, medium: ThreepidMedium.Phone }];
Expand Down
2 changes: 1 addition & 1 deletion src/createRoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ export default async function createRoom(opts: IOpts): Promise<string | null> {
return SpaceStore.instance.addRoomToSpace(
opts.parentSpace,
roomId,
[client.getDomain()],
[client.getDomain()!],
opts.suggested,
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/stores/AsyncStoreWithClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export abstract class AsyncStoreWithClient<T extends Object> extends AsyncStore<
// Create an anonymous class to avoid code duplication
const asyncStore = this; // eslint-disable-line @typescript-eslint/no-this-alias
this.readyStore = new (class extends ReadyWatchingStore {
public get mxClient(): MatrixClient {
public get mxClient(): MatrixClient | null {
return this.matrixClient;
}

Expand All @@ -48,7 +48,7 @@ export abstract class AsyncStoreWithClient<T extends Object> extends AsyncStore<
await this.readyStore.start();
}

public get matrixClient(): MatrixClient {
public get matrixClient(): MatrixClient | null {
return this.readyStore.mxClient;
}

Expand Down
2 changes: 1 addition & 1 deletion src/stores/AutoRageshakeStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export default class AutoRageshakeStore extends AsyncStoreWithClient<IState> {
...eventInfo,
recipient_rageshake: rageshakeURL,
};
this.matrixClient.sendToDevice(
this.matrixClient?.sendToDevice(
AUTO_RS_REQUEST,
new Map([["messageContent.user_id", new Map([[messageContent.device_id, messageContent]])]]),
);
Expand Down
22 changes: 13 additions & 9 deletions src/stores/BreadcrumbsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { ClientEvent } from "matrix-js-sdk/src/client";
import SettingsStore from "../settings/SettingsStore";
import { AsyncStoreWithClient } from "./AsyncStoreWithClient";
import defaultDispatcher from "../dispatcher/dispatcher";
import { arrayHasDiff } from "../utils/arrays";
import { arrayHasDiff, filterBoolean } from "../utils/arrays";
import { SettingLevel } from "../settings/SettingLevel";
import { Action } from "../dispatcher/actions";
import { SettingUpdatedPayload } from "../dispatcher/payloads/SettingUpdatedPayload";
Expand Down Expand Up @@ -75,7 +75,7 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> {
public get meetsRoomRequirement(): boolean {
if (SettingsStore.getValue("feature_breadcrumbs_v2")) return true;
const msc3946ProcessDynamicPredecessor = SettingsStore.getValue("feature_dynamic_room_predecessors");
return this.matrixClient?.getVisibleRooms(msc3946ProcessDynamicPredecessor).length >= 20;
return !!this.matrixClient && this.matrixClient.getVisibleRooms(msc3946ProcessDynamicPredecessor).length >= 20;
}

protected async onAction(payload: SettingUpdatedPayload | ViewRoomPayload | JoinRoomPayload): Promise<void> {
Expand Down Expand Up @@ -107,13 +107,17 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> {
await this.updateRooms();
await this.updateState({ enabled: SettingsStore.getValue("breadcrumbs", null) });

this.matrixClient.on(RoomEvent.MyMembership, this.onMyMembership);
this.matrixClient.on(ClientEvent.Room, this.onRoom);
if (this.matrixClient) {
this.matrixClient.on(RoomEvent.MyMembership, this.onMyMembership);
this.matrixClient.on(ClientEvent.Room, this.onRoom);
}
}

protected async onNotReady(): Promise<void> {
this.matrixClient.removeListener(RoomEvent.MyMembership, this.onMyMembership);
this.matrixClient.removeListener(ClientEvent.Room, this.onRoom);
if (this.matrixClient) {
this.matrixClient.removeListener(RoomEvent.MyMembership, this.onMyMembership);
this.matrixClient.removeListener(ClientEvent.Room, this.onRoom);
}
}

private onMyMembership = async (room: Room): Promise<void> => {
Expand All @@ -137,7 +141,7 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> {
let roomIds = SettingsStore.getValue<string[]>("breadcrumb_rooms");
if (!roomIds || roomIds.length === 0) roomIds = [];

const rooms = roomIds.map((r) => this.matrixClient.getRoom(r)).filter((r) => !!r);
const rooms = filterBoolean(roomIds.map((r) => this.matrixClient?.getRoom(r)));
const currentRooms = this.state.rooms || [];
if (!arrayHasDiff(rooms, currentRooms)) return; // no change (probably echo)
await this.updateState({ rooms });
Expand All @@ -150,8 +154,8 @@ export class BreadcrumbsStore extends AsyncStoreWithClient<IState> {

// If the room is upgraded, use that room instead. We'll also splice out
// any children of the room.
const history = this.matrixClient.getRoomUpgradeHistory(room.roomId, false, msc3946ProcessDynamicPredecessor);
if (history.length > 1) {
const history = this.matrixClient?.getRoomUpgradeHistory(room.roomId, false, msc3946ProcessDynamicPredecessor);
if (history && history.length > 1) {
room = history[history.length - 1]; // Last room is most recent in history

// Take out any room that isn't the most recent room
Expand Down
10 changes: 7 additions & 3 deletions src/stores/CallStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class CallStore extends AsyncStoreWithClient<{}> {
}

protected async onReady(): Promise<any> {
if (!this.matrixClient) return;
// We assume that the calls present in a room are a function of room
// widgets and group calls, so we initialize the room map here and then
// update it whenever those change
Expand Down Expand Up @@ -90,9 +91,11 @@ export class CallStore extends AsyncStoreWithClient<{}> {
this.calls.clear();
this._activeCalls.clear();

this.matrixClient.off(GroupCallEventHandlerEvent.Incoming, this.onGroupCall);
this.matrixClient.off(GroupCallEventHandlerEvent.Outgoing, this.onGroupCall);
this.matrixClient.off(GroupCallEventHandlerEvent.Ended, this.onGroupCall);
if (this.matrixClient) {
this.matrixClient.off(GroupCallEventHandlerEvent.Incoming, this.onGroupCall);
this.matrixClient.off(GroupCallEventHandlerEvent.Outgoing, this.onGroupCall);
this.matrixClient.off(GroupCallEventHandlerEvent.Ended, this.onGroupCall);
}
WidgetStore.instance.off(UPDATE_EVENT, this.onWidgets);
}

Expand Down Expand Up @@ -174,6 +177,7 @@ export class CallStore extends AsyncStoreWithClient<{}> {
}

private onWidgets = (roomId: string | null): void => {
if (!this.matrixClient) return;
if (roomId === null) {
// This store happened to start before the widget store was done
// loading all rooms, so we need to initialize each room again
Expand Down
40 changes: 25 additions & 15 deletions src/stores/OwnBeaconStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,13 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
}

protected async onNotReady(): Promise<void> {
this.matrixClient.removeListener(BeaconEvent.LivenessChange, this.onBeaconLiveness);
this.matrixClient.removeListener(BeaconEvent.New, this.onNewBeacon);
this.matrixClient.removeListener(BeaconEvent.Update, this.onUpdateBeacon);
this.matrixClient.removeListener(BeaconEvent.Destroy, this.onDestroyBeacon);
this.matrixClient.removeListener(RoomStateEvent.Members, this.onRoomStateMembers);
if (this.matrixClient) {
this.matrixClient.removeListener(BeaconEvent.LivenessChange, this.onBeaconLiveness);
this.matrixClient.removeListener(BeaconEvent.New, this.onNewBeacon);
this.matrixClient.removeListener(BeaconEvent.Update, this.onUpdateBeacon);
this.matrixClient.removeListener(BeaconEvent.Destroy, this.onDestroyBeacon);
this.matrixClient.removeListener(RoomStateEvent.Members, this.onRoomStateMembers);
}
SettingsStore.unwatchSetting(this.dynamicWatcherRef ?? "");

this.clearBeacons();
Expand All @@ -164,11 +166,13 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
}

protected async onReady(): Promise<void> {
this.matrixClient.on(BeaconEvent.LivenessChange, this.onBeaconLiveness);
this.matrixClient.on(BeaconEvent.New, this.onNewBeacon);
this.matrixClient.on(BeaconEvent.Update, this.onUpdateBeacon);
this.matrixClient.on(BeaconEvent.Destroy, this.onDestroyBeacon);
this.matrixClient.on(RoomStateEvent.Members, this.onRoomStateMembers);
if (this.matrixClient) {
this.matrixClient.on(BeaconEvent.LivenessChange, this.onBeaconLiveness);
this.matrixClient.on(BeaconEvent.New, this.onNewBeacon);
this.matrixClient.on(BeaconEvent.Update, this.onUpdateBeacon);
this.matrixClient.on(BeaconEvent.Destroy, this.onDestroyBeacon);
this.matrixClient.on(RoomStateEvent.Members, this.onRoomStateMembers);
}
this.dynamicWatcherRef = SettingsStore.watchSetting(
"feature_dynamic_room_predecessors",
null,
Expand Down Expand Up @@ -200,7 +204,8 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
* Then consider it to have an error
*/
public beaconHasLocationPublishError = (beaconId: string): boolean => {
return this.beaconLocationPublishErrorCounts.get(beaconId) >= BAIL_AFTER_CONSECUTIVE_ERROR_COUNT;
const counts = this.beaconLocationPublishErrorCounts.get(beaconId);
return counts !== undefined && counts >= BAIL_AFTER_CONSECUTIVE_ERROR_COUNT;
};

public resetLocationPublishError = (beaconId: string): void => {
Expand Down Expand Up @@ -246,7 +251,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
*/

private onNewBeacon = (_event: MatrixEvent, beacon: Beacon): void => {
if (!isOwnBeacon(beacon, this.matrixClient.getUserId()!)) {
if (!this.matrixClient || !isOwnBeacon(beacon, this.matrixClient.getUserId()!)) {
return;
}
this.addBeacon(beacon);
Expand All @@ -257,7 +262,7 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
* This will be called when a beacon is replaced
*/
private onUpdateBeacon = (_event: MatrixEvent, beacon: Beacon): void => {
if (!isOwnBeacon(beacon, this.matrixClient.getUserId()!)) {
if (!this.matrixClient || !isOwnBeacon(beacon, this.matrixClient.getUserId()!)) {
return;
}

Expand Down Expand Up @@ -296,7 +301,11 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
*/
private onRoomStateMembers = (_event: MatrixEvent, roomState: RoomState, member: RoomMember): void => {
// no beacons for this room, ignore
if (!this.beaconsByRoomId.has(roomState.roomId) || member.userId !== this.matrixClient.getUserId()) {
if (
!this.matrixClient ||
!this.beaconsByRoomId.has(roomState.roomId) ||
member.userId !== this.matrixClient.getUserId()
) {
return;
}

Expand Down Expand Up @@ -332,7 +341,8 @@ export class OwnBeaconStore extends AsyncStoreWithClient<OwnBeaconStoreState> {
};

private initialiseBeaconState = (): void => {
const userId = this.matrixClient.getUserId()!;
if (!this.matrixClient) return;
const userId = this.matrixClient.getSafeUserId();
const visibleRooms = this.matrixClient.getVisibleRooms(
SettingsStore.getValue("feature_dynamic_room_predecessors"),
);
Expand Down
Loading