Skip to content
Snippets Groups Projects
AccountSetupViewModel.ts 4.46 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { ViewModel, Client, LoadStatus } from "hydrogen-view-sdk";
    
    Midhun Suresh's avatar
    Midhun Suresh committed
    import { IChatterboxConfig } from "../types/IChatterboxConfig";
    
    import { generatePassword, generateUsername } from "../random";
    
    Midhun Suresh's avatar
    Midhun Suresh committed
    import "hydrogen-view-sdk/style.css";
    
    
    export class AccountSetupViewModel extends ViewModel {
        private _config: IChatterboxConfig;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        private _client: typeof Client;
    
        private _startStage?: any;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        private _password: string;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        private _registration: any;
    
        private _privacyPolicyLink: string;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
    
        constructor(options) {
            super(options);
            this._client = options.client;
            this._config = options.config;
            this._startRegistration();
        }
    
        private async _startRegistration(): Promise<void> {
    
            this._password = generatePassword(10);
    
            const maxAttempts = 10;
            for (let i = 0; i < maxAttempts; ++i) {
                try {
    
                    const username = `${this._config.username_prefix}-${generateUsername(10)}`;
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
                    const flowSelector = (flows) => {
                        const allowedStages = [
                            "m.login.registration_token",
                            "org.matrix.msc3231.login.registration_token",
                            "m.login.terms",
                            "m.login.dummy"
                        ];
                        for (const flow of flows) {
    
                            // Find the first flow that does not contain any unsupported stages but contains Token registration stage.
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
                            const containsUnsupportedStage = flow.stages.some(stage => !allowedStages.includes(stage));
    
                            const containsTokenStage = flow.stages.includes("m.login.registration_token") ||
                                flow.stages.includes("org.matrix.msc3231.login.registration_token");
                            if (!containsUnsupportedStage && containsTokenStage) {
    
    RMidhunSuresh's avatar
    RMidhunSuresh committed
                                return flow;
                            }
                        }
                    }
                    this._registration = await this._client.startRegistration(this._homeserver, username, this._password, "Chatterbox", flowSelector);
    
                    this._startStage = await this._registration.start();
                    let stage = this._startStage;
    
                    while (stage && stage.type !== "m.login.terms") {
    
                        stage = stage.nextStage;
    
                    }
                    if (!stage) {
                        // If terms login stage is not found, go straight to completeRegistration()
                        this.completeRegistration();
                        return;
    
                    this._privacyPolicyLink = stage.privacyPolicy.en?.url;
                    this.emitChange("privacyPolicyLink");
    
                    break;
                }
                catch (e) {
                    if (e.errcode !== "M_USER_IN_USE") {
                        throw e;
                    }
                }
    
    Midhun Suresh's avatar
    Midhun Suresh committed
            }
        }
    
        async completeRegistration() {
    
            let stage = this._startStage;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
            while (stage) {
    
                if (
                    stage.type === "m.login.registration_token" ||
                    stage.type === "org.matrix.msc3231.login.registration_token"
                ) {
                    stage.setToken(this._config.token);
                }
    
    Midhun Suresh's avatar
    Midhun Suresh committed
                stage = await this._registration.submitStage(stage);
    
    Midhun Suresh's avatar
    Midhun Suresh committed
            }
    
            const loginPromise = this.login(this._password);
    
            this.navigation.push("timeline", loginPromise);
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        }
    
    
        async login(password: string): Promise<void> {
    
    Midhun Suresh's avatar
    Midhun Suresh committed
            const loginOptions = await this._client.queryLogin(this._homeserver).result;
    
            const username = this._registration.sessionInfo.user_id;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
            this._client.startWithLogin(loginOptions.password(username, password));
            await this._client.loadStatus.waitFor((status: string) => {
                return status === LoadStatus.Ready ||
                    status === LoadStatus.Error ||
                    status === LoadStatus.LoginFailed;
            }).promise;
    
            if (this._client.loginFailure) {
                throw new Error("login failed: " + this._client.loginFailure);
            } else if (this._client.loadError) {
                throw new Error("load failed: " + this._client.loadError.message);
            }
        }
    
    
        minimize(): void {
            (window as any).sendMinimizeToParent();
            this.navigation.push("minimize");
        }
    
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        private get _homeserver(): string {
            return this._config.homeserver;
        }
    
        get privacyPolicyLink() {
    
            return this._privacyPolicyLink;
    
    Midhun Suresh's avatar
    Midhun Suresh committed
        }
    
    
        get footerViewModel() {
            return this.options.footerVM;
        }
    
    Midhun Suresh's avatar
    Midhun Suresh committed
    }