Skip to content

Commit 00cc112

Browse files
committed
wip
1 parent f56a272 commit 00cc112

2 files changed

Lines changed: 65 additions & 86 deletions

File tree

src/components/structures/MatrixChat.tsx

Lines changed: 57 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ import Markdown from "../../Markdown";
141141
import { sanitizeHtmlParams } from "../../Linkify";
142142
import { isOnlyAdmin } from "../../utils/membership";
143143
import { ModuleApi } from "../../modules/Api.ts";
144+
import { logErrorAndShowErrorDialog } from "../../utils/ErrorUtils.tsx";
144145

145146
// legacy export
146147
export { default as Views } from "../../Views";
@@ -411,61 +412,13 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
411412
*
412413
* {@link onWillStartClient} and {@link onClientStarted} will already have been called (but not necessarily
413414
* completed).
414-
*
415-
* This method either calls {@link onLiggedIn} directly, or switches to {@link Views.E2E_SETUP} or
416-
* {@link Views.COMPLETE_SECURITY}, which will later call {@link onCompleteSecurityE2eSetupFinished}.
417415
*/
418416
private async postLoginSetup(): Promise<void> {
419-
const cli = MatrixClientPeg.safeGet();
420-
const cryptoEnabled = Boolean(cli.getCrypto());
421-
if (!cryptoEnabled) {
422-
this.onLoggedIn();
423-
}
424-
425-
const promisesList: Promise<any>[] = [this.firstSyncPromise.promise];
426-
let crossSigningIsSetUp = false;
427-
if (cryptoEnabled) {
428-
// check if the user has previously published public cross-signing keys,
429-
// as a proxy to figure out if it's worth prompting the user to verify
430-
// from another device.
431-
promisesList.push(
432-
(async (): Promise<void> => {
433-
crossSigningIsSetUp = Boolean(await cli.getCrypto()?.userHasCrossSigningKeys());
434-
})(),
435-
);
436-
}
437-
417+
// TODO: move to onUserCompletedLoginFlow?
438418
// Now update the state to say we're waiting for the first sync to complete rather
439419
// than for the login to finish.
440420
this.setState({ pendingInitialSync: true });
441-
442-
await Promise.all(promisesList);
443-
444-
if (!cryptoEnabled) {
445-
this.setState({ pendingInitialSync: false });
446-
return;
447-
}
448-
449-
if (crossSigningIsSetUp) {
450-
// if the user has previously set up cross-signing, verify this device so we can fetch the
451-
// private keys.
452-
453-
const cryptoExtension = ModuleRunner.instance.extensions.cryptoSetup;
454-
if (cryptoExtension.SHOW_ENCRYPTION_SETUP_UI == false) {
455-
this.onLoggedIn();
456-
} else {
457-
this.setStateForNewView({ view: Views.COMPLETE_SECURITY });
458-
}
459-
} else if (!(await shouldSkipSetupEncryption(cli))) {
460-
// if cross-signing is not yet set up, do so now if possible.
461-
InitialCryptoSetupStore.sharedInstance().startInitialCryptoSetup(
462-
cli,
463-
this.onCompleteSecurityE2eSetupFinished,
464-
);
465-
this.setStateForNewView({ view: Views.E2E_SETUP });
466-
} else {
467-
this.onLoggedIn();
468-
}
421+
await this.firstSyncPromise.promise;
469422
this.setState({ pendingInitialSync: false });
470423
}
471424

@@ -1385,10 +1338,10 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
13851338
/**
13861339
* Returns true if the user must go through the device verification process before they
13871340
* can use the app.
1388-
* @returns true if the user must verify
1341+
*
1342+
* @returns true if the device is unverified, but crypto is enabled.
13891343
*/
1390-
private async shouldForceVerification(): Promise<boolean> {
1391-
if (!SdkConfig.get("force_verification")) return false;
1344+
private async deviceNeedsVerification(): Promise<boolean> {
13921345
const mustVerifyFlag = localStorage.getItem("must_verify_device");
13931346
if (!mustVerifyFlag) return false;
13941347

@@ -1416,8 +1369,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
14161369
ThemeController.isLogin = false;
14171370
this.themeWatcher?.recheck();
14181371
StorageManager.tryPersistStorage();
1419-
1420-
await this.onShowPostLoginScreen();
14211372
}
14221373

14231374
/**
@@ -1429,15 +1380,55 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
14291380
* - by {@link onCompleteSecurityE2eSetupFinished}
14301381
*
14311382
* In other words, whenever we think we have completed the login and E2E setup tasks.
1383+
*
1384+
* TODO: fix docs
14321385
*/
1433-
private async onShowPostLoginScreen(): Promise<void> {
1434-
logger.debug("onShowPostLoginScreen: Transitioning to logged in view.");
1386+
private async showNextView(): Promise<void> {
1387+
const cli = MatrixClientPeg.safeGet();
1388+
1389+
const forceVerification = SdkConfig.get("force_verification");
1390+
logger.debug(`showNextView: current view=${this.state.view}; force_verification=${forceVerification}`);
1391+
1392+
// First of all, figure out if we need to do some cross-signing setup.
1393+
// Traditionally, we would only do that just after logging in, but with the advent of `force_verification`,
1394+
// we may need to do it on every restart.
1395+
if (
1396+
(this.state.view == Views.LOGIN || this.state.view == Views.REGISTER || forceVerification) &&
1397+
!(await shouldSkipSetupEncryption(cli))
1398+
) {
1399+
const crypto = cli.getCrypto()!;
1400+
1401+
// Check if we need to create cross-signing keys for this user.
1402+
if (!(await crypto!.userHasCrossSigningKeys())) {
1403+
logger.debug("showNextView: user lacks cross-signing keys, starting setup");
1404+
InitialCryptoSetupStore.sharedInstance().startInitialCryptoSetup(
1405+
cli,
1406+
this.onCompleteSecurityE2eSetupFinished,
1407+
);
1408+
this.setStateForNewView({ view: Views.E2E_SETUP });
1409+
return;
1410+
}
1411+
1412+
// We have cross-signing keys, so see if we need to verify this device.
1413+
if (
1414+
ModuleRunner.instance.extensions.cryptoSetup.SHOW_ENCRYPTION_SETUP_UI &&
1415+
(await this.deviceNeedsVerification())
1416+
) {
1417+
logger.debug("showNextView: user must verify device, starting verification");
1418+
this.setStateForNewView({ view: Views.COMPLETE_SECURITY });
1419+
return;
1420+
}
1421+
}
1422+
1423+
// We've done the E2E setup stuff, so we can transition to the regular application, with
1424+
// an appropriate screen.
1425+
logger.debug("showNextView: E2E setup done, transitioning to logged in view.");
14351426

14361427
this.setStateForNewView({ view: Views.LOGGED_IN });
14371428
// If a specific screen is set to be shown after login, show that above
14381429
// all else, as it probably means the user clicked on something already.
14391430
if (this.screenAfterLogin?.screen) {
1440-
logger.debug(`onShowPostLoginScreen: showing screen ${this.screenAfterLogin.screen}`);
1431+
logger.debug(`showNextView: showing screen ${this.screenAfterLogin.screen}`);
14411432
this.showScreen(this.screenAfterLogin.screen, this.screenAfterLogin.params);
14421433
this.screenAfterLogin = undefined;
14431434
} else if (MatrixClientPeg.currentUserIsJustRegistered()) {
@@ -1446,7 +1437,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
14461437
if (ThreepidInviteStore.instance.pickBestInvite()) {
14471438
// The user has a 3pid invite pending - show them that
14481439
const threepidInvite = ThreepidInviteStore.instance.pickBestInvite();
1449-
logger.debug(`onShowPostLoginScreen: showing room ${threepidInvite.roomId} after registration`);
1440+
logger.debug(`showNextView: showing room ${threepidInvite.roomId} after registration`);
14501441

14511442
// HACK: This is a pretty brutal way of threading the invite back through
14521443
// our systems, but it's the safest we have for now.
@@ -1455,11 +1446,11 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
14551446
} else {
14561447
// The user has just logged in after registering,
14571448
// so show the homepage.
1458-
logger.debug("onShowPostLoginScreen: Showing home page after registration");
1449+
logger.debug("showNextView: Showing home page after registration");
14591450
dis.dispatch<ViewHomePagePayload>({ action: Action.ViewHomePage, justRegistered: true });
14601451
}
14611452
} else {
1462-
logger.debug("onShowPostLoginScreen: showScreenAfterLogin");
1453+
logger.debug("showNextView: showScreenAfterLogin");
14631454
this.showScreenAfterLogin();
14641455
}
14651456

@@ -1776,18 +1767,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
17761767
*/
17771768
private async onClientStarted(): Promise<void> {
17781769
const cli = MatrixClientPeg.safeGet();
1779-
1780-
const shouldForceVerification = await this.shouldForceVerification();
1781-
// XXX: Don't replace the screen if it's already one of these: postLoginSetup
1782-
// changes to these screens in certain circumstances so we shouldn't clobber it.
1783-
// We should probably have one place where we decide what the next screen is after
1784-
// login.
1785-
if (![Views.COMPLETE_SECURITY, Views.E2E_SETUP].includes(this.state.view)) {
1786-
if (shouldForceVerification) {
1787-
this.setStateForNewView({ view: Views.COMPLETE_SECURITY });
1788-
}
1789-
}
1790-
17911770
const crypto = cli.getCrypto();
17921771
if (crypto) {
17931772
const blacklistEnabled = SettingsStore.getValueAt(SettingLevel.DEVICE, "blacklistUnverifiedDevices");
@@ -1803,6 +1782,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
18031782
this.setState({
18041783
ready: true,
18051784
});
1785+
1786+
await this.showNextView();
18061787
}
18071788

18081789
public showScreen(screen: string, params?: { [key: string]: any }): void {
@@ -2110,18 +2091,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
21102091
};
21112092

21122093
/** Called when {@link Views.E2E_SETUP} or {@link Views.COMPLETE_SECURITY} have completed. */
2113-
private onCompleteSecurityE2eSetupFinished = async (): Promise<void> => {
2114-
const forceVerify = await this.shouldForceVerification();
2115-
if (forceVerify) {
2116-
const isVerified = await MatrixClientPeg.safeGet().getCrypto()?.isCrossSigningReady();
2117-
if (!isVerified) {
2118-
// We must verify but we haven't yet verified - don't continue logging in
2119-
return;
2120-
}
2121-
}
2122-
2123-
await this.onShowPostLoginScreen().catch((e) => {
2124-
logger.error("Exception showing post-login screen", e);
2094+
private onCompleteSecurityE2eSetupFinished = (): void => {
2095+
this.showNextView().catch((e) => {
2096+
logErrorAndShowErrorDialog("Exception showing post-login screen", e);
21252097
});
21262098
};
21272099

src/dispatcher/dispatcher.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
88
Please see LICENSE files in the repository root for full details.
99
*/
1010

11-
import { type Action } from "./actions";
11+
import { logger } from "matrix-js-sdk/src/logger";
12+
13+
import { Action } from "./actions";
1214
import { type ActionPayload, AsyncActionPayload } from "./payloads";
1315

1416
type DispatchToken = string;
@@ -82,6 +84,11 @@ export class MatrixDispatcher {
8284
*/
8385
// eslint-disable-next-line @typescript-eslint/naming-convention
8486
private _dispatch = (payload: ActionPayload): void => {
87+
// Log all actions, except a few spammy ones
88+
if (payload.action !== Action.UserActivity) {
89+
logger.info(`Dispatch action ${payload.action}`, payload);
90+
}
91+
8592
invariant(!this.isDispatching(), "Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.");
8693
this.startDispatching(payload);
8794
try {

0 commit comments

Comments
 (0)