From e64f4ad7b2021bd9f340ff8f123daca9d7ab9fa9 Mon Sep 17 00:00:00 2001 From: RMidhunSuresh Date: Thu, 3 Feb 2022 15:10:56 +0530 Subject: [PATCH] Refactor code - Move all code that does /register to Registration.ts - RegistrationStage only deals with the generation of auth data - Change API so that undefined is returned instead of string when registration is over --- src/matrix/Client.js | 3 +- src/matrix/registration/Registration.ts | 38 ++++++++++++++++++- .../stages/BaseRegistrationStage.ts | 21 +++------- src/matrix/registration/stages/DummyAuth.ts | 11 +++--- src/matrix/registration/stages/TermsAuth.ts | 12 +++--- src/matrix/registration/types.ts | 2 +- 6 files changed, 56 insertions(+), 31 deletions(-) diff --git a/src/matrix/Client.js b/src/matrix/Client.js index 22e686d0..b24c1ec9 100644 --- a/src/matrix/Client.js +++ b/src/matrix/Client.js @@ -140,8 +140,7 @@ export class Client { password, initialDeviceDisplayName, }); - let stage = await registration.start(); - return stage; + return registration; } async startWithLogin(loginMethod, {inspectAccountSetup} = {}) { diff --git a/src/matrix/registration/Registration.ts b/src/matrix/registration/Registration.ts index 9c7ef11b..0d408c2a 100644 --- a/src/matrix/registration/Registration.ts +++ b/src/matrix/registration/Registration.ts @@ -17,7 +17,13 @@ limitations under the License. import type {HomeServerApi} from "../net/HomeServerApi"; import {registrationStageFromType} from "./registrationStageFromType"; import type {BaseRegistrationStage} from "./stages/BaseRegistrationStage"; -import type {AccountDetails, RegistrationFlow, RegistrationResponseMoreDataNeeded} from "./types"; +import type { + AccountDetails, + RegistrationFlow, + RegistrationResponseMoreDataNeeded, + RegistrationResponse, + RegistrationResponseSuccess, +} from "./types"; type FlowSelector = (flows: RegistrationFlow[]) => RegistrationFlow | void; @@ -25,6 +31,7 @@ export class Registration { private _hsApi: HomeServerApi; private _accountDetails: AccountDetails; private _flowSelector: FlowSelector; + private _sessionInfo?: RegistrationResponseSuccess constructor(hsApi: HomeServerApi, accountDetails: AccountDetails, flowSelector?: FlowSelector) { this._hsApi = hsApi; @@ -42,6 +49,18 @@ export class Registration { return this.parseStagesFromResponse(response); } + /** + * Finish a registration stage, return value is: + * - the next stage if this stage was completed successfully + * - undefined if registration is completed + */ + async submitStage(stage: BaseRegistrationStage): Promise { + const auth = stage.generateAuthenticationData(); + const { username, password, initialDeviceDisplayName, inhibitLogin } = this._accountDetails; + const response = await this._hsApi.register(username, password, initialDeviceDisplayName, auth, inhibitLogin).response(); + return this.parseRegistrationResponse(response, stage); + } + parseStagesFromResponse(response: RegistrationResponseMoreDataNeeded): BaseRegistrationStage { const { session, params } = response; const flow = this._flowSelector(response.flows); @@ -66,4 +85,21 @@ export class Registration { } return firstStage!; } + + parseRegistrationResponse(response: RegistrationResponse, currentStage: BaseRegistrationStage) { + if ("user_id" in response) { + // registration completed successfully + this._sessionInfo = response; + return undefined; + } + else if ("completed" in response && response.completed.find(c => c === currentStage.type)) { + return currentStage.nextStage; + } + const error = "error" in response? response.error: "Could not parse response"; + throw new Error(error); + } + + get sessionInfo(): RegistrationResponseSuccess | undefined { + return this._sessionInfo; + } } diff --git a/src/matrix/registration/stages/BaseRegistrationStage.ts b/src/matrix/registration/stages/BaseRegistrationStage.ts index 74fe66c7..dfe71fa5 100644 --- a/src/matrix/registration/stages/BaseRegistrationStage.ts +++ b/src/matrix/registration/stages/BaseRegistrationStage.ts @@ -15,7 +15,7 @@ limitations under the License. */ import type {HomeServerApi} from "../../net/HomeServerApi"; -import type {AccountDetails, RegistrationResponse, AuthenticationData, RegistrationParams} from "../types"; +import type {AccountDetails, AuthenticationData, RegistrationParams} from "../types"; export abstract class BaseRegistrationStage { protected _hsApi: HomeServerApi; @@ -37,25 +37,16 @@ export abstract class BaseRegistrationStage { abstract get type(): string; /** - * Finish a registration stage, return value is: - * - the next stage if this stage was completed successfully - * - user-id (string) if registration is completed + * This method should return auth part that must be provided to + * /register endpoint to successfully complete this stage */ - abstract complete(auth?: AuthenticationData): Promise; + abstract generateAuthenticationData(): AuthenticationData; setNextStage(stage: BaseRegistrationStage) { this._nextStage = stage; } - parseResponse(response: RegistrationResponse) { - if ("user_id" in response) { - // registration completed successfully - return response.user_id; - } - else if ("completed" in response && response.completed.find(c => c === this.type)) { - return this._nextStage; - } - const error = "error" in response? response.error: "Could not parse response"; - throw new Error(error); + get nextStage(): BaseRegistrationStage { + return this._nextStage; } } diff --git a/src/matrix/registration/stages/DummyAuth.ts b/src/matrix/registration/stages/DummyAuth.ts index e22409db..b7f0a6ff 100644 --- a/src/matrix/registration/stages/DummyAuth.ts +++ b/src/matrix/registration/stages/DummyAuth.ts @@ -14,16 +14,15 @@ See the License for the specific language governing permissions and limitations under the License. */ +import {AuthenticationData} from "../types"; import {BaseRegistrationStage} from "./BaseRegistrationStage"; export class DummyAuth extends BaseRegistrationStage { - async complete() { - const { username, password, initialDeviceDisplayName, inhibitLogin } = this._accountDetails; - const response = await this._hsApi.register(username, password, initialDeviceDisplayName, { + generateAuthenticationData(): AuthenticationData { + return { session: this._session, - type: this.type - }, inhibitLogin).response(); - return this.parseResponse(response); + type: this.type, + }; } get type(): string { diff --git a/src/matrix/registration/stages/TermsAuth.ts b/src/matrix/registration/stages/TermsAuth.ts index e770b13b..bf54dd4d 100644 --- a/src/matrix/registration/stages/TermsAuth.ts +++ b/src/matrix/registration/stages/TermsAuth.ts @@ -14,16 +14,16 @@ See the License for the specific language governing permissions and limitations under the License. */ +import {AuthenticationData} from "../types"; import {BaseRegistrationStage} from "./BaseRegistrationStage"; export class TermsAuth extends BaseRegistrationStage { - async complete() { - const { username, password, initialDeviceDisplayName, inhibitLogin } = this._accountDetails; - const response = await this._hsApi.register(username, password, initialDeviceDisplayName, { + generateAuthenticationData(): AuthenticationData { + return { session: this._session, - type: this.type - }, inhibitLogin).response(); - return this.parseResponse(response); + type: this.type, + // No other auth data needed for m.login.terms + }; } get type(): string { diff --git a/src/matrix/registration/types.ts b/src/matrix/registration/types.ts index 08fc0fc4..aa319d43 100644 --- a/src/matrix/registration/types.ts +++ b/src/matrix/registration/types.ts @@ -35,7 +35,7 @@ type RegistrationResponseError = { error: string; } -type RegistrationResponseSuccess = { +export type RegistrationResponseSuccess = { user_id: string; device_id: string; access_token?: string;