mirror of https://github.com/vector-im/riot-web
migrate SetupEncryptionStore to TypeScript
parent
68db2438ea
commit
5f2ab50a90
|
@ -44,6 +44,7 @@ import { EventIndexPeg } from "../indexing/EventIndexPeg";
|
||||||
import {VoiceRecordingStore} from "../stores/VoiceRecordingStore";
|
import {VoiceRecordingStore} from "../stores/VoiceRecordingStore";
|
||||||
import PerformanceMonitor from "../performance";
|
import PerformanceMonitor from "../performance";
|
||||||
import UIStore from "../stores/UIStore";
|
import UIStore from "../stores/UIStore";
|
||||||
|
import { SetupEncryptionStore } from "../stores/SetupEncryptionStore";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -84,6 +85,7 @@ declare global {
|
||||||
mxPerformanceMonitor: PerformanceMonitor;
|
mxPerformanceMonitor: PerformanceMonitor;
|
||||||
mxPerformanceEntryNames: any;
|
mxPerformanceEntryNames: any;
|
||||||
mxUIStore: UIStore;
|
mxUIStore: UIStore;
|
||||||
|
mxSetupEncryptionStore?: SetupEncryptionStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Document {
|
interface Document {
|
||||||
|
|
|
@ -18,11 +18,11 @@ import React from 'react';
|
||||||
import SetupEncryptionBody from '../../../structures/auth/SetupEncryptionBody';
|
import SetupEncryptionBody from '../../../structures/auth/SetupEncryptionBody';
|
||||||
import BaseDialog from '../BaseDialog';
|
import BaseDialog from '../BaseDialog';
|
||||||
import { _t } from '../../../../languageHandler';
|
import { _t } from '../../../../languageHandler';
|
||||||
import { SetupEncryptionStore, PHASE_DONE } from '../../../../stores/SetupEncryptionStore';
|
import { SetupEncryptionStore, PHASE } from '../../../../stores/SetupEncryptionStore';
|
||||||
import {replaceableComponent} from "../../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../../utils/replaceableComponent";
|
||||||
|
|
||||||
function iconFromPhase(phase: string) {
|
function iconFromPhase(phase: PHASE) {
|
||||||
if (phase === PHASE_DONE) {
|
if (phase === PHASE.DONE) {
|
||||||
return require("../../../../../res/img/e2e/verified.svg");
|
return require("../../../../../res/img/e2e/verified.svg");
|
||||||
} else {
|
} else {
|
||||||
return require("../../../../../res/img/e2e/warning.svg");
|
return require("../../../../../res/img/e2e/warning.svg");
|
||||||
|
@ -34,7 +34,7 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
icon: any;
|
icon: PHASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.dialogs.security.SetupEncryptionDialog")
|
@replaceableComponent("views.dialogs.security.SetupEncryptionDialog")
|
||||||
|
|
|
@ -15,29 +15,42 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import EventEmitter from 'events';
|
import EventEmitter from 'events';
|
||||||
|
import { VerificationRequest } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
|
||||||
|
import { IKeyBackupVersion } from "matrix-js-sdk/src/crypto/keybackup";
|
||||||
|
import { ISecretStorageKeyInfo } from "matrix-js-sdk/src/matrix";
|
||||||
import { MatrixClientPeg } from '../MatrixClientPeg';
|
import { MatrixClientPeg } from '../MatrixClientPeg';
|
||||||
import { accessSecretStorage, AccessCancelledError } from '../SecurityManager';
|
import { accessSecretStorage, AccessCancelledError } from '../SecurityManager';
|
||||||
import { PHASE_DONE as VERIF_PHASE_DONE } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
|
import { PHASE_DONE as VERIF_PHASE_DONE } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest";
|
||||||
|
|
||||||
export const PHASE_LOADING = 0;
|
export enum PHASE {
|
||||||
export const PHASE_INTRO = 1;
|
LOADING = 0,
|
||||||
export const PHASE_BUSY = 2;
|
INTRO = 1,
|
||||||
export const PHASE_DONE = 3; //final done stage, but still showing UX
|
BUSY = 2,
|
||||||
export const PHASE_CONFIRM_SKIP = 4;
|
DONE = 3, // final done stage, but still showing UX
|
||||||
export const PHASE_FINISHED = 5; //UX can be closed
|
CONFIRM_SKIP = 4,
|
||||||
|
FINISHED = 5, // UX can be closed
|
||||||
|
}
|
||||||
|
|
||||||
export class SetupEncryptionStore extends EventEmitter {
|
export class SetupEncryptionStore extends EventEmitter {
|
||||||
static sharedInstance() {
|
private started: boolean;
|
||||||
if (!global.mx_SetupEncryptionStore) global.mx_SetupEncryptionStore = new SetupEncryptionStore();
|
public phase: PHASE;
|
||||||
return global.mx_SetupEncryptionStore;
|
public verificationRequest: VerificationRequest;
|
||||||
|
public backupInfo: IKeyBackupVersion;
|
||||||
|
public keyId: string;
|
||||||
|
public keyInfo: ISecretStorageKeyInfo;
|
||||||
|
public hasDevicesToVerifyAgainst: boolean;
|
||||||
|
|
||||||
|
public static sharedInstance() {
|
||||||
|
if (!window.mxSetupEncryptionStore) window.mxSetupEncryptionStore = new SetupEncryptionStore();
|
||||||
|
return window.mxSetupEncryptionStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
public start(): void {
|
||||||
if (this._started) {
|
if (this.started) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._started = true;
|
this.started = true;
|
||||||
this.phase = PHASE_LOADING;
|
this.phase = PHASE.LOADING;
|
||||||
this.verificationRequest = null;
|
this.verificationRequest = null;
|
||||||
this.backupInfo = null;
|
this.backupInfo = null;
|
||||||
|
|
||||||
|
@ -48,34 +61,34 @@ export class SetupEncryptionStore extends EventEmitter {
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
cli.on("crypto.verification.request", this.onVerificationRequest);
|
cli.on("crypto.verification.request", this.onVerificationRequest);
|
||||||
cli.on('userTrustStatusChanged', this._onUserTrustStatusChanged);
|
cli.on('userTrustStatusChanged', this.onUserTrustStatusChanged);
|
||||||
|
|
||||||
const requestsInProgress = cli.getVerificationRequestsToDeviceInProgress(cli.getUserId());
|
const requestsInProgress = cli.getVerificationRequestsToDeviceInProgress(cli.getUserId());
|
||||||
if (requestsInProgress.length) {
|
if (requestsInProgress.length) {
|
||||||
// If there are multiple, we take the most recent. Equally if the user sends another request from
|
// If there are multiple, we take the most recent. Equally if the user sends another request from
|
||||||
// another device after this screen has been shown, we'll switch to the new one, so this
|
// another device after this screen has been shown, we'll switch to the new one, so this
|
||||||
// generally doesn't support multiple requests.
|
// generally doesn't support multiple requests.
|
||||||
this._setActiveVerificationRequest(requestsInProgress[requestsInProgress.length - 1]);
|
this.setActiveVerificationRequest(requestsInProgress[requestsInProgress.length - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.fetchKeyInfo();
|
this.fetchKeyInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() {
|
public stop(): void {
|
||||||
if (!this._started) {
|
if (!this.started) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._started = false;
|
this.started = false;
|
||||||
if (this.verificationRequest) {
|
if (this.verificationRequest) {
|
||||||
this.verificationRequest.off("change", this.onVerificationRequestChange);
|
this.verificationRequest.off("change", this.onVerificationRequestChange);
|
||||||
}
|
}
|
||||||
if (MatrixClientPeg.get()) {
|
if (MatrixClientPeg.get()) {
|
||||||
MatrixClientPeg.get().removeListener("crypto.verification.request", this.onVerificationRequest);
|
MatrixClientPeg.get().removeListener("crypto.verification.request", this.onVerificationRequest);
|
||||||
MatrixClientPeg.get().removeListener('userTrustStatusChanged', this._onUserTrustStatusChanged);
|
MatrixClientPeg.get().removeListener('userTrustStatusChanged', this.onUserTrustStatusChanged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchKeyInfo() {
|
public async fetchKeyInfo(): Promise<void> {
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const keys = await cli.isSecretStored('m.cross_signing.master', false);
|
const keys = await cli.isSecretStored('m.cross_signing.master', false);
|
||||||
if (keys === null || Object.keys(keys).length === 0) {
|
if (keys === null || Object.keys(keys).length === 0) {
|
||||||
|
@ -97,15 +110,15 @@ export class SetupEncryptionStore extends EventEmitter {
|
||||||
|
|
||||||
if (!this.hasDevicesToVerifyAgainst && !this.keyInfo) {
|
if (!this.hasDevicesToVerifyAgainst && !this.keyInfo) {
|
||||||
// skip before we can even render anything.
|
// skip before we can even render anything.
|
||||||
this.phase = PHASE_FINISHED;
|
this.phase = PHASE.FINISHED;
|
||||||
} else {
|
} else {
|
||||||
this.phase = PHASE_INTRO;
|
this.phase = PHASE.INTRO;
|
||||||
}
|
}
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
}
|
}
|
||||||
|
|
||||||
async usePassPhrase() {
|
public async usePassPhrase(): Promise<void> {
|
||||||
this.phase = PHASE_BUSY;
|
this.phase = PHASE.BUSY;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
try {
|
try {
|
||||||
|
@ -120,7 +133,7 @@ export class SetupEncryptionStore extends EventEmitter {
|
||||||
// passphase cached for that work. This dialog itself will only wait
|
// passphase cached for that work. This dialog itself will only wait
|
||||||
// on the first trust check, and the key backup restore will happen
|
// on the first trust check, and the key backup restore will happen
|
||||||
// in the background.
|
// in the background.
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve: (value?: unknown) => void, reject: (reason?: any) => void) => {
|
||||||
accessSecretStorage(async () => {
|
accessSecretStorage(async () => {
|
||||||
await cli.checkOwnCrossSigningTrust();
|
await cli.checkOwnCrossSigningTrust();
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -134,7 +147,7 @@ export class SetupEncryptionStore extends EventEmitter {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (cli.getCrossSigningId()) {
|
if (cli.getCrossSigningId()) {
|
||||||
this.phase = PHASE_DONE;
|
this.phase = PHASE.DONE;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -142,25 +155,25 @@ export class SetupEncryptionStore extends EventEmitter {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
}
|
}
|
||||||
// this will throw if the user hits cancel, so ignore
|
// this will throw if the user hits cancel, so ignore
|
||||||
this.phase = PHASE_INTRO;
|
this.phase = PHASE.INTRO;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onUserTrustStatusChanged = (userId) => {
|
private onUserTrustStatusChanged = (userId: string) => {
|
||||||
if (userId !== MatrixClientPeg.get().getUserId()) return;
|
if (userId !== MatrixClientPeg.get().getUserId()) return;
|
||||||
const publicKeysTrusted = MatrixClientPeg.get().getCrossSigningId();
|
const publicKeysTrusted = MatrixClientPeg.get().getCrossSigningId();
|
||||||
if (publicKeysTrusted) {
|
if (publicKeysTrusted) {
|
||||||
this.phase = PHASE_DONE;
|
this.phase = PHASE.DONE;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onVerificationRequest = (request) => {
|
public onVerificationRequest = (request: VerificationRequest): void => {
|
||||||
this._setActiveVerificationRequest(request);
|
this.setActiveVerificationRequest(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
onVerificationRequestChange = () => {
|
public onVerificationRequestChange = (): void => {
|
||||||
if (this.verificationRequest.cancelled) {
|
if (this.verificationRequest.cancelled) {
|
||||||
this.verificationRequest.off("change", this.onVerificationRequestChange);
|
this.verificationRequest.off("change", this.onVerificationRequestChange);
|
||||||
this.verificationRequest = null;
|
this.verificationRequest = null;
|
||||||
|
@ -172,34 +185,34 @@ export class SetupEncryptionStore extends EventEmitter {
|
||||||
// cross signing to be ready to use, so wait for the user trust status to
|
// cross signing to be ready to use, so wait for the user trust status to
|
||||||
// change (or change to DONE if it's already ready).
|
// change (or change to DONE if it's already ready).
|
||||||
const publicKeysTrusted = MatrixClientPeg.get().getCrossSigningId();
|
const publicKeysTrusted = MatrixClientPeg.get().getCrossSigningId();
|
||||||
this.phase = publicKeysTrusted ? PHASE_DONE : PHASE_BUSY;
|
this.phase = publicKeysTrusted ? PHASE.DONE : PHASE.BUSY;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip() {
|
public skip(): void {
|
||||||
this.phase = PHASE_CONFIRM_SKIP;
|
this.phase = PHASE.CONFIRM_SKIP;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
}
|
}
|
||||||
|
|
||||||
skipConfirm() {
|
public skipConfirm(): void {
|
||||||
this.phase = PHASE_FINISHED;
|
this.phase = PHASE.FINISHED;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
}
|
}
|
||||||
|
|
||||||
returnAfterSkip() {
|
public returnAfterSkip(): void {
|
||||||
this.phase = PHASE_INTRO;
|
this.phase = PHASE.INTRO;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
}
|
}
|
||||||
|
|
||||||
done() {
|
public done(): void {
|
||||||
this.phase = PHASE_FINISHED;
|
this.phase = PHASE.FINISHED;
|
||||||
this.emit("update");
|
this.emit("update");
|
||||||
// async - ask other clients for keys, if necessary
|
// async - ask other clients for keys, if necessary
|
||||||
MatrixClientPeg.get().crypto.cancelAndResendAllOutgoingKeyRequests();
|
MatrixClientPeg.get().crypto.cancelAndResendAllOutgoingKeyRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
async _setActiveVerificationRequest(request) {
|
private async setActiveVerificationRequest(request: VerificationRequest): Promise<void> {
|
||||||
if (request.otherUserId !== MatrixClientPeg.get().getUserId()) return;
|
if (request.otherUserId !== MatrixClientPeg.get().getUserId()) return;
|
||||||
|
|
||||||
if (this.verificationRequest) {
|
if (this.verificationRequest) {
|
Loading…
Reference in New Issue