From d28ab919bbc3cb10115cf9c1baba9600d55cc754 Mon Sep 17 00:00:00 2001 From: RMidhunSuresh Date: Sun, 26 Dec 2021 17:59:04 +0530 Subject: [PATCH] Implement dummy registration logic --- src/matrix/registration/Registration.ts | 85 +++++++++++++++++++ .../registration/registrationStageFromType.ts | 24 ++++++ .../stages/BaseRegistrationStage.ts | 64 ++++++++++++++ src/matrix/registration/stages/DummyAuth.ts | 33 +++++++ 4 files changed, 206 insertions(+) create mode 100644 src/matrix/registration/Registration.ts create mode 100644 src/matrix/registration/registrationStageFromType.ts create mode 100644 src/matrix/registration/stages/BaseRegistrationStage.ts create mode 100644 src/matrix/registration/stages/DummyAuth.ts diff --git a/src/matrix/registration/Registration.ts b/src/matrix/registration/Registration.ts new file mode 100644 index 00000000..9dcfdbe2 --- /dev/null +++ b/src/matrix/registration/Registration.ts @@ -0,0 +1,85 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import type {HomeServerApi} from "../net/HomeServerApi"; +import { registrationStageFromType } from "./registrationStageFromType"; +import type {BaseRegistrationStage} from "./stages/BaseRegistrationStage"; + +export type RegistrationParameters = { + username: string; + password: string; + initialDeviceDisplayName: string; + inhibitLogin: boolean; +} + +// todo: type this later +export type RegistrationResponse = { + [key: string]: any; +} + +export class Registration { + private _hsApi: HomeServerApi; + private _data: RegistrationParameters; + private _firstStage: BaseRegistrationStage; + private _session: string; + + constructor(hsApi: HomeServerApi, data: RegistrationParameters) { + this._hsApi = hsApi; + this._data = data; + } + + private async _fetchFlows(): Promise { + const response = await this._hsApi.register( + this._username, + this._password, + this._initialDeviceDisplayName, + undefined, + this._inhibitLogin).response(); + return response; + } + + async start(): Promise { + const response = await this._fetchFlows(); + this.parseStagesFromResponse(response); + await new Promise(r => setTimeout(r, 2000)); + return this._firstStage; + } + + parseStagesFromResponse(response: RegistrationResponse) { + this._session = response.session; + const flow = response.flows.pop(); + let lastStage: BaseRegistrationStage; + for (const stage of flow.stages) { + const stageClass = registrationStageFromType(stage); + if (!stageClass) { + throw new Error("Unknown stage"); + } + const registrationStage = new stageClass(this._hsApi, this._data, this._session); + if (!this._firstStage) { + this._firstStage = registrationStage; + lastStage = registrationStage; + } else { + lastStage!.setNextStage(registrationStage); + lastStage = registrationStage; + } + } + } + + private get _username() { return this._data.username; } + private get _password() { return this._data.password; } + private get _initialDeviceDisplayName() { return this._data.initialDeviceDisplayName; } + private get _inhibitLogin() { return this._data.inhibitLogin; } +} diff --git a/src/matrix/registration/registrationStageFromType.ts b/src/matrix/registration/registrationStageFromType.ts new file mode 100644 index 00000000..3a9950fd --- /dev/null +++ b/src/matrix/registration/registrationStageFromType.ts @@ -0,0 +1,24 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import {DummyAuth} from "./stages/DummyAuth"; + +export function registrationStageFromType(type: string): typeof DummyAuth | undefined { + switch (type) { + case "m.login.dummy": + return DummyAuth; + } +} diff --git a/src/matrix/registration/stages/BaseRegistrationStage.ts b/src/matrix/registration/stages/BaseRegistrationStage.ts new file mode 100644 index 00000000..6c5ae256 --- /dev/null +++ b/src/matrix/registration/stages/BaseRegistrationStage.ts @@ -0,0 +1,64 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +export type Auth = { + [key: string]: any; +} + +import type {HomeServerApi} from "../../net/HomeServerApi"; +import type {RegistrationParameters, RegistrationResponse} from "../Registration"; + +export abstract class BaseRegistrationStage { + protected _hsApi: HomeServerApi; + protected _registrationData: RegistrationParameters; + protected _session: string; + protected _nextStage: BaseRegistrationStage; + + constructor(hsApi: HomeServerApi, registrationData: RegistrationParameters, session: string) { + this._hsApi = hsApi; + this._registrationData = registrationData; + this._session = session; + } + + /** + * eg: m.login.recaptcha or m.login.dummy + */ + abstract get type(): string; + + /** + * Finish a registration stage, return value is: + * - the next stage if this stage was completed successfully + * - true if registration is completed + * - an error if something went wrong + */ + abstract complete(auth?: Auth): Promise; + + setNextStage(stage: BaseRegistrationStage) { + this._nextStage = stage; + } + + parseResponse(response: RegistrationResponse) { + if (response.user_id) { + // registration completed successfully + return true; + } + else if (response.completed?.forEach(c => c === this.type)) { + return this._nextStage; + } + const error = response.error ?? "Could not parse response"; + return new Error(error); + } +} diff --git a/src/matrix/registration/stages/DummyAuth.ts b/src/matrix/registration/stages/DummyAuth.ts new file mode 100644 index 00000000..4a5d9bd8 --- /dev/null +++ b/src/matrix/registration/stages/DummyAuth.ts @@ -0,0 +1,33 @@ +/* +Copyright 2021 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import {BaseRegistrationStage} from "./BaseRegistrationStage"; + +export class DummyAuth extends BaseRegistrationStage { + + async complete() { + const { username, password, initialDeviceDisplayName, inhibitLogin } = this._registrationData; + const response = await this._hsApi.register(username, password, initialDeviceDisplayName, { + session: this._session, + type: this.type + }, inhibitLogin).response(); + return this.parseResponse(response); + } + + get type(): string { + return "m.login.dummy"; + } +}