You've already forked matrix-react-sdk
							
							
				mirror of
				https://github.com/matrix-org/matrix-react-sdk.git
				synced 2025-11-03 00:33:22 +03:00 
			
		
		
		
	Invoke Secure Backup flow inside the app when requested by HS
If the Secure Backup required mode is set the client `.well-known` file, then this will ensure that everyone already inside the app is required to complete setup matching that policy. Fixes https://github.com/vector-im/element-web/issues/14954
This commit is contained in:
		
							
								
								
									
										2
									
								
								src/@types/global.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								src/@types/global.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -27,10 +27,12 @@ import {ModalManager} from "../Modal";
 | 
				
			|||||||
import SettingsStore from "../settings/SettingsStore";
 | 
					import SettingsStore from "../settings/SettingsStore";
 | 
				
			||||||
import {ActiveRoomObserver} from "../ActiveRoomObserver";
 | 
					import {ActiveRoomObserver} from "../ActiveRoomObserver";
 | 
				
			||||||
import {Notifier} from "../Notifier";
 | 
					import {Notifier} from "../Notifier";
 | 
				
			||||||
 | 
					import type {Renderer} from "react-dom";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
declare global {
 | 
					declare global {
 | 
				
			||||||
    interface Window {
 | 
					    interface Window {
 | 
				
			||||||
        Modernizr: ModernizrStatic;
 | 
					        Modernizr: ModernizrStatic;
 | 
				
			||||||
 | 
					        matrixChat: ReturnType<Renderer>;
 | 
				
			||||||
        mxMatrixClientPeg: IMatrixClientPeg;
 | 
					        mxMatrixClientPeg: IMatrixClientPeg;
 | 
				
			||||||
        Olm: {
 | 
					        Olm: {
 | 
				
			||||||
            init: () => Promise<void>;
 | 
					            init: () => Promise<void>;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@ limitations under the License.
 | 
				
			|||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {MatrixClientPeg} from './MatrixClientPeg';
 | 
					import {MatrixClientPeg} from './MatrixClientPeg';
 | 
				
			||||||
 | 
					import dis from "./dispatcher/dispatcher";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    hideToast as hideBulkUnverifiedSessionsToast,
 | 
					    hideToast as hideBulkUnverifiedSessionsToast,
 | 
				
			||||||
    showToast as showBulkUnverifiedSessionsToast,
 | 
					    showToast as showBulkUnverifiedSessionsToast,
 | 
				
			||||||
@@ -29,11 +30,15 @@ import {
 | 
				
			|||||||
    showToast as showUnverifiedSessionsToast,
 | 
					    showToast as showUnverifiedSessionsToast,
 | 
				
			||||||
} from "./toasts/UnverifiedSessionToast";
 | 
					} from "./toasts/UnverifiedSessionToast";
 | 
				
			||||||
import { privateShouldBeEncrypted } from "./createRoom";
 | 
					import { privateShouldBeEncrypted } from "./createRoom";
 | 
				
			||||||
import { isSecretStorageBeingAccessed } from "./CrossSigningManager";
 | 
					import { isSecretStorageBeingAccessed, accessSecretStorage } from "./CrossSigningManager";
 | 
				
			||||||
 | 
					import { ensureClientWellKnown, isSecureBackupRequired } from './utils/WellKnownUtils';
 | 
				
			||||||
 | 
					import { isLoggedIn } from './components/structures/MatrixChat';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;
 | 
					const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class DeviceListener {
 | 
					export default class DeviceListener {
 | 
				
			||||||
 | 
					    private dispatcherRef: string;
 | 
				
			||||||
    // device IDs for which the user has dismissed the verify toast ('Later')
 | 
					    // device IDs for which the user has dismissed the verify toast ('Later')
 | 
				
			||||||
    private dismissed = new Set<string>();
 | 
					    private dismissed = new Set<string>();
 | 
				
			||||||
    // has the user dismissed any of the various nag toasts to setup encryption on this device?
 | 
					    // has the user dismissed any of the various nag toasts to setup encryption on this device?
 | 
				
			||||||
@@ -61,6 +66,7 @@ export default class DeviceListener {
 | 
				
			|||||||
        MatrixClientPeg.get().on('crossSigning.keysChanged', this._onCrossSingingKeysChanged);
 | 
					        MatrixClientPeg.get().on('crossSigning.keysChanged', this._onCrossSingingKeysChanged);
 | 
				
			||||||
        MatrixClientPeg.get().on('accountData', this._onAccountData);
 | 
					        MatrixClientPeg.get().on('accountData', this._onAccountData);
 | 
				
			||||||
        MatrixClientPeg.get().on('sync', this._onSync);
 | 
					        MatrixClientPeg.get().on('sync', this._onSync);
 | 
				
			||||||
 | 
					        this.dispatcherRef = dis.register(this._onAction);
 | 
				
			||||||
        this._recheck();
 | 
					        this._recheck();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,6 +80,10 @@ export default class DeviceListener {
 | 
				
			|||||||
            MatrixClientPeg.get().removeListener('accountData', this._onAccountData);
 | 
					            MatrixClientPeg.get().removeListener('accountData', this._onAccountData);
 | 
				
			||||||
            MatrixClientPeg.get().removeListener('sync', this._onSync);
 | 
					            MatrixClientPeg.get().removeListener('sync', this._onSync);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (this.dispatcherRef) {
 | 
				
			||||||
 | 
					            dis.unregister(this.dispatcherRef);
 | 
				
			||||||
 | 
					            this.dispatcherRef = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        this.dismissed.clear();
 | 
					        this.dismissed.clear();
 | 
				
			||||||
        this.dismissedThisDeviceToast = false;
 | 
					        this.dismissedThisDeviceToast = false;
 | 
				
			||||||
        this.keyBackupInfo = null;
 | 
					        this.keyBackupInfo = null;
 | 
				
			||||||
@@ -159,6 +169,11 @@ export default class DeviceListener {
 | 
				
			|||||||
        if (state === 'PREPARED' && prevState === null) this._recheck();
 | 
					        if (state === 'PREPARED' && prevState === null) this._recheck();
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _onAction = ({ action }) => {
 | 
				
			||||||
 | 
					        if (action !== "on_logged_in") return;
 | 
				
			||||||
 | 
					        this._recheck();
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The server doesn't tell us when key backup is set up, so we poll
 | 
					    // The server doesn't tell us when key backup is set up, so we poll
 | 
				
			||||||
    // & cache the result
 | 
					    // & cache the result
 | 
				
			||||||
    async _getKeyBackupInfo() {
 | 
					    async _getKeyBackupInfo() {
 | 
				
			||||||
@@ -211,7 +226,15 @@ export default class DeviceListener {
 | 
				
			|||||||
                    showSetupEncryptionToast(SetupKind.UPGRADE_ENCRYPTION);
 | 
					                    showSetupEncryptionToast(SetupKind.UPGRADE_ENCRYPTION);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    // No cross-signing or key backup on account (set up encryption)
 | 
					                    // No cross-signing or key backup on account (set up encryption)
 | 
				
			||||||
                    showSetupEncryptionToast(SetupKind.SET_UP_ENCRYPTION);
 | 
					                    await ensureClientWellKnown();
 | 
				
			||||||
 | 
					                    if (isSecureBackupRequired() && isLoggedIn()) {
 | 
				
			||||||
 | 
					                        // If we're meant to set up, and Secure Backup is required,
 | 
				
			||||||
 | 
					                        // trigger the flow directly without a toast once logged in.
 | 
				
			||||||
 | 
					                        hideSetupEncryptionToast();
 | 
				
			||||||
 | 
					                        accessSecretStorage();
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        showSetupEncryptionToast(SetupKind.SET_UP_ENCRYPTION);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2085,3 +2085,10 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
 | 
				
			|||||||
        </ErrorBoundary>;
 | 
					        </ErrorBoundary>;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isLoggedIn(): boolean {
 | 
				
			||||||
 | 
					    // JRS: Maybe we should move the step that writes this to the window out of
 | 
				
			||||||
 | 
					    // `element-web` and into this file?
 | 
				
			||||||
 | 
					    const app = window.matrixChat;
 | 
				
			||||||
 | 
					    return app && (app as MatrixChat).state.view === Views.LOGGED_IN;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,14 @@ export interface IE2EEWellKnown {
 | 
				
			|||||||
    default?: boolean;
 | 
					    default?: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function ensureClientWellKnown() {
 | 
				
			||||||
 | 
					    const cli = MatrixClientPeg.get();
 | 
				
			||||||
 | 
					    if (cli.haveAttemptedFetchingClientWellKnown()) return;
 | 
				
			||||||
 | 
					    return new Promise(resolve => {
 | 
				
			||||||
 | 
					        cli.once("WellKnown.attempted", resolve);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function getE2EEWellKnown(): IE2EEWellKnown {
 | 
					export function getE2EEWellKnown(): IE2EEWellKnown {
 | 
				
			||||||
    const clientWellKnown = MatrixClientPeg.get().getClientWellKnown();
 | 
					    const clientWellKnown = MatrixClientPeg.get().getClientWellKnown();
 | 
				
			||||||
    if (clientWellKnown && clientWellKnown[E2EE_WK_KEY]) {
 | 
					    if (clientWellKnown && clientWellKnown[E2EE_WK_KEY]) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user