This commit is contained in:
RMidhunSuresh 2023-02-17 17:18:17 +05:30
parent d81864e901
commit e6ea003bef
No known key found for this signature in database
4 changed files with 58 additions and 48 deletions

View File

@ -17,17 +17,28 @@ import {StartVerificationStage} from "./stages/StartVerificationStage";
import type {ILogItem} from "../../../logging/types";
import type {Room} from "../../room/Room.js";
import type {BaseSASVerificationStage, UserData} from "./stages/BaseSASVerificationStage";
import {WaitForIncomingMessageStage} from "./stages/WaitForIncomingMessageStage";
export class SASVerification {
private stages: BaseSASVerificationStage[] = [];
private startStage: BaseSASVerificationStage;
constructor(private room: Room, private ourUser: UserData, otherUserId: string, log: ILogItem) {
this.stages.push(new StartVerificationStage(room, ourUser, otherUserId, log));
const options = { room, ourUser, otherUserId, log };
let stage: BaseSASVerificationStage = new StartVerificationStage(options);
this.startStage = stage;
stage.setNextStage(new WaitForIncomingMessageStage("m.key.verification.ready", options));
stage = stage.nextStage;
stage.setNextStage(new WaitForIncomingMessageStage("m.key.verification.start", options));
stage = stage.nextStage;
}
async start() {
for (const stage of this.stages) {
let stage = this.startStage;
do {
await stage.completeStage();
}
stage = stage.nextStage;
} while (stage);
}
}

View File

@ -36,6 +36,7 @@ export abstract class BaseSASVerificationStage extends Disposables {
protected log: ILogItem;
protected requestEventId: string;
protected previousResult: undefined | any;
protected _nextStage: BaseSASVerificationStage;
constructor(options: Options) {
super();
@ -55,7 +56,14 @@ export abstract class BaseSASVerificationStage extends Disposables {
this.previousResult = result;
}
abstract get type(): string;
abstract completeStage(): undefined | Record<string, any>;
abstract get nextStage(): BaseSASVerificationStage;
setNextStage(stage: BaseSASVerificationStage) {
this._nextStage = stage;
}
get nextStage(): BaseSASVerificationStage {
return this._nextStage;
}
abstract get type(): string;
abstract completeStage(): Promise<any>;
}

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import {BaseSASVerificationStage} from "./BaseSASVerificationStage";
import {FragmentBoundaryEntry} from "../../../room/timeline/entries/FragmentBoundaryEntry.js";
// From element-web
// type KeyAgreement = "curve25519-hkdf-sha256" | "curve25519";
@ -31,9 +32,6 @@ import {BaseSASVerificationStage} from "./BaseSASVerificationStage";
// const SAS_LIST = Object.keys(sasGenerators);
export class StartVerificationStage extends BaseSASVerificationStage {
private readyMessagePromise: Promise<any>;
private startMessagePromise: Promise<any>;
async completeStage() {
await this.log.wrap("StartVerificationStage.completeStage", async (log) => {
const content = {
@ -43,44 +41,38 @@ export class StartVerificationStage extends BaseSASVerificationStage {
"msgtype": "m.key.verification.request",
"to": this.otherUserId,
};
const promise = this.trackEventId();
await this.room.sendEvent("m.room.message", content, null, log);
const [readyContent, startContent] = await this.fetchMessageEventsFromTimeline();
console.log("readyContent", readyContent, "startContent", startContent);
const eventId = await promise;
console.log("eventId", eventId);
this.setRequestEventId(eventId);
this.dispose();
});
return true;
}
private fetchMessageEventsFromTimeline() {
let readyResolve, startResolve;
this.readyMessagePromise = new Promise(r => { readyResolve = r; });
this.startMessagePromise = new Promise(r => { startResolve = r; });
private trackEventId(): Promise<string> {
return new Promise(resolve => {
this.track(
this.room._timeline.entries.subscribe({
onAdd: (_, entry) => {
if (entry.eventType === "m.key.verification.ready") {
readyResolve(entry.content);
if (entry instanceof FragmentBoundaryEntry) {
return;
}
else if (entry.eventType === "m.key.verification.start") {
startResolve(entry.content);
if (!entry.isPending &&
entry.content["msgtype"] === "m.key.verification.request" &&
entry.content["from_device"] === this.ourUser.deviceId) {
console.log("found event", entry);
resolve(entry.id);
}
},
onRemove: () => {
},
onUpdate: () => {
},
onRemove: () => { /**noop*/ },
onUpdate: () => { /**noop*/ },
})
);
return Promise.all([this.readyMessagePromise, this.startMessagePromise]);
});
}
get type() {
return "m.key.verification.request";
}
get nextStage(): BaseSASVerificationStage {
return this;
}
}

View File

@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import {BaseSASVerificationStage, Options} from "./BaseSASVerificationStage";
import {FragmentBoundaryEntry} from "../../../room/timeline/entries/FragmentBoundaryEntry.js";
export class WaitForIncomingMessageStage extends BaseSASVerificationStage {
constructor(private messageType: string, options: Options) {
@ -30,7 +31,6 @@ export class WaitForIncomingMessageStage extends BaseSASVerificationStage {
});
this.dispose();
});
return true;
}
private fetchMessageEventsFromTimeline() {
@ -43,7 +43,7 @@ export class WaitForIncomingMessageStage extends BaseSASVerificationStage {
// We only care about incoming / remote message events
return;
}
if (entry.eventType === this.messageType &&
if (entry.type === this.messageType &&
entry.content["m.relates_to"]["event_id"] === this.requestEventId) {
resolve(entry.content);
}
@ -55,7 +55,10 @@ export class WaitForIncomingMessageStage extends BaseSASVerificationStage {
const remoteEntries = this.room._timeline.remoteEntries;
// In case we were slow and the event is already added to the timeline,
for (const entry of remoteEntries) {
if (entry.eventType === this.messageType &&
if (entry instanceof FragmentBoundaryEntry) {
return;
}
if (entry.type === this.messageType &&
entry.content["m.relates_to"]["event_id"] === this.requestEventId) {
resolve(entry.content);
}
@ -66,9 +69,5 @@ export class WaitForIncomingMessageStage extends BaseSASVerificationStage {
get type() {
return this.messageType;
}
get nextStage(): BaseSASVerificationStage {
return this;
}
}