From c8d13a77821bff4de8aac3aab276e46f307141c5 Mon Sep 17 00:00:00 2001
From: Midhun Suresh <midhunr@element.io>
Date: Thu, 27 Jan 2022 11:49:29 +0530
Subject: [PATCH] Generate random username, fetch prefix from config

---
 config.json                             |  5 +++--
 src/random.ts                           | 21 +++++++++++++--------
 src/types/IChatterboxConfig.ts          |  3 ++-
 src/viewmodels/AccountSetupViewModel.ts | 10 ++++++----
 4 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/config.json b/config.json
index 1ce3069..5290951 100644
--- a/config.json
+++ b/config.json
@@ -1,4 +1,5 @@
 {
     "homeserver": "http://localhost:8008",
-    "auto_join_room": "!KiuRShFqxJLSoshNKa:localhost:8008"
-}
\ No newline at end of file
+    "auto_join_room": "!KiuRShFqxJLSoshNKa:localhost:8008",
+    "username_prefix": "testcorp"
+}
diff --git a/src/random.ts b/src/random.ts
index b3f2412..1b668e8 100644
--- a/src/random.ts
+++ b/src/random.ts
@@ -1,13 +1,18 @@
-// todo: do we need something better than this?
-// todo: usernames can't start with _
-// todo: lookup grammar for mxids
-
-export function generateRandomString(length: number): string {
+function generateRandomString(length: number, allowedCharacters: string): string {
     let result = "";
-    const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
-    var charactersLength = characters.length;
+    const l = allowedCharacters.length;
     for (let i = 0; i < length; i++) {
-        result += characters.charAt(Math.floor(Math.random() * charactersLength));
+        result += allowedCharacters.charAt(Math.floor(Math.random() * l));
     }
     return result;
 }
+
+export function generatePassword(length: number) {
+    const characters = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
+    return generateRandomString(length, characters);
+}
+
+export function generateUsername(length: number) {
+    const characters = 'abcdefghijklmnopqrstuvwxyz0123456789_-.=/';
+    return generateRandomString(length, characters);
+}
diff --git a/src/types/IChatterboxConfig.ts b/src/types/IChatterboxConfig.ts
index 80f9722..bf0bd8e 100644
--- a/src/types/IChatterboxConfig.ts
+++ b/src/types/IChatterboxConfig.ts
@@ -1,4 +1,5 @@
 export interface IChatterboxConfig {
 	homeserver: string;
 	auto_join_room: string;
-}
\ No newline at end of file
+    username_prefix: string;
+}
diff --git a/src/viewmodels/AccountSetupViewModel.ts b/src/viewmodels/AccountSetupViewModel.ts
index 3e2bc30..03bb256 100644
--- a/src/viewmodels/AccountSetupViewModel.ts
+++ b/src/viewmodels/AccountSetupViewModel.ts
@@ -1,6 +1,6 @@
 import { ViewModel, Client, LoadStatus } from "hydrogen-view-sdk";
 import { IChatterboxConfig } from "../types/IChatterboxConfig";
-import { generateRandomString } from "../random";
+import { generatePassword, generateUsername } from "../random";
 import "hydrogen-view-sdk/style.css";
 
 
@@ -9,6 +9,7 @@ export class AccountSetupViewModel extends ViewModel {
     private _client: typeof Client;
     private _termsStage?: any;
     private _password: string;
+    private _username: string;
 
     constructor(options) {
         super(options);
@@ -18,8 +19,9 @@ export class AccountSetupViewModel extends ViewModel {
     }
 
     private async _startRegistration(): Promise<void> {
-        this._password = generateRandomString(10);
-        let stage = await this._client.startRegistration(this._homeserver, null, this._password, "Chatterbox");
+        this._password = generatePassword(10);
+        this._username = `${this._config.username_prefix}-${generateUsername(10)}`;
+        let stage = await this._client.startRegistration(this._homeserver, this._username, this._password, "Chatterbox");
         if (stage.type === "m.login.terms") {
             this._termsStage = stage;
             this.emitChange("termsStage");
@@ -32,7 +34,7 @@ export class AccountSetupViewModel extends ViewModel {
             stage = await stage.complete();
         }
         // stage is username when registration is completed
-        const loginPromise = this.login(stage, this._password);
+        const loginPromise = this.login(this._username, this._password);
         this.navigation.push("timeline", loginPromise);
     }
 
-- 
GitLab