[Labs] Sign in with QR on new EW using generated QR for MSC4108 v2024 (#33184)
* PoC Sign in with QR on new EW using generated QR for MSC4108 v2024 * Revert package.json changes * Prettier * Fix i18n * Tidy up * Remove unused state variable * Iterate tests * Partial revert * Iterate * Wire up qr_login route * Iterate UI * Fix React dev mode double rendering issue * Fix react key warning * Hide flow header on login * Re-roll qr code on channel expiry * Switch to AbortSignal * Improve auto-retry QR UX * Ensure we only show sign in with QR button if enabled * XXX: enable labs flag on Netlify builds * Tweak QR code sizing * Move qr login flow into a dialog to match designs * Fix null deviceId * Remove duplicate log * Iterate * Fix tests * Fix types * Fix tests * Fix tests * Make Netlify more useful * Make Netlify more useful v2 * Update copy * Refactor QR link flow to use new SDK methods Requires https://github.com/matrix-org/matrix-js-sdk/pull/5283 For element-hq/wat-internal#188 Split out from https://github.com/element-hq/element-web/pull/33184 * Link to js-sdk branch * Update tests * Simplify * Revert js-sdk linking * Iterate * Iterate * Refactor to handle most of the TODOs * Remove unused code * Remove unused code * Use js-sdk isSignInWithQRAvailable API to simplify code * Restore app-test.ts * Improve coverage * Improve coverage * Remove unused prop/state * Iterate * Fix tests * Iterate * Tests * Handle TODOs * Docs * Remove redundant call to crossSignDevice() * Workaround to remove training slash on the serverName before auto-discovery * Revert "Workaround to remove training slash on the serverName before auto-discovery" This reverts commit 0335a8fdd1b8e8d949ab7fca17c76f8fab335b58. * setLoggedIn not to be used with OIDC flows as it clears storage as per docs on setLoggedIn we should use restoreSessionFromStorage * Don't show the security_code_prompt unconditionally(i.e. for the web logging in mobile flow) * Update LoginWithQRFlow-test.tsx.snap * Update MatrixChat-test from setLoggedInSpy to restoreSessionSpy * Add todo for server switch * Add todo about handling base URL or server name * Handle server name or base URL being returned * Format * Fix loading state height * Handle the homeserver URL differing during QR code login * Comments * Comments * Register OIDC client ID after homeserver swap * Make QrLoginDialog async to minimise the impact on bundle size * Handle unsupported HS earlier in the flow * Iterate * Delint * Fix test * Discard changes to apps/web/element.io/develop/config.json --------- Co-authored-by: Hugh Nimmo-Smith <hughns@element.io> Co-authored-by: David Langley <langley.dave@gmail.com>
This commit is contained in:
co-authored by
Hugh Nimmo-Smith
David Langley
parent
d1a6137c90
commit
486fa57b68
@@ -142,6 +142,8 @@ import { isOnlyAdmin } from "../../utils/membership";
|
||||
import { ModuleApi } from "../../modules/Api.ts";
|
||||
import { type IScreen } from "../../vector/routing.ts";
|
||||
import { type URLParams } from "../../vector/url_utils.ts";
|
||||
import { type QrLoginCredentials } from "../views/auth/LoginWithQR.tsx";
|
||||
import { configureFromCompletedOAuthLogin } from "../../Lifecycle";
|
||||
|
||||
// legacy export
|
||||
export { default as Views } from "../../Views";
|
||||
@@ -827,6 +829,26 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
this.viewSomethingBehindModal();
|
||||
break;
|
||||
}
|
||||
case Action.ViewQrLogin: {
|
||||
if (this.isLoggedInViewPageDisplayed()) {
|
||||
logger.warn("Ignoring payload due to unexpected call outside auth flows", payload);
|
||||
} else {
|
||||
Modal.createDialog(
|
||||
lazy(() => import("../../async-components/views/dialogs/QrLoginDialog")),
|
||||
{
|
||||
serverConfig: this.getServerProperties().serverConfig,
|
||||
onLoggedIn: this.onUserCompletedQrLoginFlow,
|
||||
},
|
||||
"mx_LoginWithQR_dialog",
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
// View the welcome or home page if we need something to look at
|
||||
this.viewSomethingBehindModal();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "view_welcome_page":
|
||||
this.viewWelcome();
|
||||
break;
|
||||
@@ -1858,6 +1880,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
params: params,
|
||||
});
|
||||
PerformanceMonitor.instance.start(PerformanceEntryNames.LOGIN);
|
||||
} else if (screen === "qr_login") {
|
||||
dis.fire(Action.ViewQrLogin);
|
||||
} else if (screen === "forgot_password") {
|
||||
dis.dispatch({
|
||||
action: "start_password_recovery",
|
||||
@@ -2131,6 +2155,36 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
PerformanceMonitor.instance.stop(PerformanceEntryNames.REGISTER);
|
||||
};
|
||||
|
||||
/**
|
||||
* After successful qr login, load & persist the credentials, as well as the secrets bundle.
|
||||
*/
|
||||
private onUserCompletedQrLoginFlow = async ({
|
||||
secrets,
|
||||
deviceId,
|
||||
...tokenResponse
|
||||
}: QrLoginCredentials): Promise<void> => {
|
||||
// Persist credentials + OIDC settings, then hydrate the client from storage.
|
||||
// setLoggedIn would clear storage and drop the OIDC settings; see its docstring.
|
||||
await configureFromCompletedOAuthLogin(tokenResponse);
|
||||
await Lifecycle.restoreSessionFromStorage();
|
||||
|
||||
if (secrets) {
|
||||
const crypto = MatrixClientPeg.safeGet().getCrypto();
|
||||
if (crypto?.importSecretsBundle) {
|
||||
// This imports the secrets and cross-signs the device in one go
|
||||
await crypto.importSecretsBundle(secrets);
|
||||
} else {
|
||||
logger.warn(
|
||||
"Crypto not initialised or no importSecretsBundle() method, cannot import secrets from QR login",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
logger.warn("No secrets received from QR login");
|
||||
}
|
||||
|
||||
this.onShowPostLoginScreen();
|
||||
};
|
||||
|
||||
/** Called when {@link Views.E2E_SETUP} or {@link Views.COMPLETE_SECURITY} have completed. */
|
||||
private onCompleteSecurityE2eSetupFinished = async (): Promise<void> => {
|
||||
const forceVerify = await this.shouldForceVerification();
|
||||
@@ -2220,7 +2274,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
);
|
||||
}
|
||||
} else if (this.state.view === Views.WELCOME) {
|
||||
view = <Welcome />;
|
||||
view = <Welcome {...this.getServerProperties()} />;
|
||||
} else if (this.state.view === Views.REGISTER && SettingsStore.getValue(UIFeature.Registration)) {
|
||||
const email = ThreepidInviteStore.instance.pickBestInvite()?.toEmail;
|
||||
view = (
|
||||
|
||||
Reference in New Issue
Block a user