From 3265c49528e9b8e1e28052a8914ccc6dc2a41d16 Mon Sep 17 00:00:00 2001 From: Giuseppe Stelluto Date: Fri, 19 Jan 2024 22:20:30 +0100 Subject: [PATCH 1/8] Fix first .well-known bug (server not returning .well-known file) Also slightly improved organization by adding a tryWellKnown function --- src/Login.tsx | 62 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/Login.tsx b/src/Login.tsx index 5ce6583..7f51c8d 100644 --- a/src/Login.tsx +++ b/src/Login.tsx @@ -100,35 +100,45 @@ class Login extends Component<{}, LoginState> { } }; + tryWellKnown = () => { + this.homeserverName = this.homeserverName.replace("https://", ""); + this.homeserverName = this.homeserverName.replace("http://", ""); + let url = `https://${this.homeserverName}/.well-known/matrix/client`; + return fetch(url) + .then((r: Response) => { + if (r.ok) { + r.json().then((j: WellKnown) => { + this.homeserverUrl = j["m.homeserver"].base_url; + }); + } else { + console.log(`.well-known not found at ${url}`); + } + }) + .catch((e) => { + // This can fail for a number of reasons, such as CORS, and still not be a problem yet + console.log(`.well-known not found at ${url}`); + }); + }; + rightCb = () => { switch (this.state.stage) { case 0: - this.homeserverName = this.homeserverName.replace("https://", ""); - this.homeserverName = this.homeserverName.replace("http://", ""); - fetch(`https://${this.homeserverName}/.well-known/matrix/client`) - .then((r: Response) => { - if (r.ok) { - r.json().then((j: WellKnown) => { - this.homeserverUrl = j["m.homeserver"].base_url; - shared.mClient = createClient({ - baseUrl: this.homeserverUrl, - fetchFn: customFetch, - }); - shared.mClient - .loginFlows() - .then((result) => { - this.loginFlows = result.flows; - this.setState({ cursor: 0, stage: 1 }); - }) - .catch((e: any) => console.log(e)); - }); - } else { - alert( - "Cannot connect to homeserver. Are you sure the address valid?" - ); - } - }) - .catch((e) => console.log(e)); + this.tryWellKnown().then(() => { + if (!this.homeserverUrl) { + this.homeserverUrl = "https://" + this.homeserverName; + } + shared.mClient = createClient({ + baseUrl: this.homeserverUrl, + fetchFn: customFetch, + }); + shared.mClient + .loginFlows() + .then((result) => { + this.loginFlows = result.flows; + this.setState({ cursor: 0, stage: 1 }); + }) + .catch((e: any) => console.log(e)); + }); break; case 1: this.selectedLoginFlow = this.loginFlows[this.state.cursor]; From 5fa7c8db29876a303b68d672d4c6d1d6498dd896 Mon Sep 17 00:00:00 2001 From: Giuseppe Stelluto Date: Fri, 19 Jan 2024 23:14:05 +0100 Subject: [PATCH 2/8] Fix: login fails when client does not supply well-known property If the server does not supply a .well-known file, generate a fake one and save that in the localstorage. --- src/App.tsx | 9 +++++++-- src/Login.tsx | 4 ++++ src/Matrix.tsx | 7 ++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index e5d7869..a6b5400 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,7 @@ import * as localforage from "localforage"; import Matrix from "./Matrix"; import Login from "./Login"; import Guide from "./Guide"; -import { LoginData } from "./types"; +import { LoginData, WellKnown } from "./types"; interface AppState { state: string | null; @@ -15,12 +15,14 @@ interface AppState { class App extends Component<{}, AppState> { private loginData: null | LoginData; + private well_known: null | WellKnown; private timeout: null | number; public state: AppState; constructor(props: {}) { super(props); this.loginData = null; + this.well_known = null; this.timeout = null; this.state = { state: null, @@ -35,6 +37,9 @@ class App extends Component<{}, AppState> { this.setState({ state: "login" }); } }); + localforage.getItem("well_known").then((well_known: unknown) => { + this.well_known = well_known as WellKnown; + }); localforage.getItem("guide").then((value: unknown) => { this.setState({ guide: Boolean(value) }); }); @@ -78,7 +83,7 @@ class App extends Component<{}, AppState> { } if (state === "matrix") { - return ; + return ; } alert("Some error occured. This must not happen"); window.close(); diff --git a/src/Login.tsx b/src/Login.tsx index 7f51c8d..b3ffb74 100644 --- a/src/Login.tsx +++ b/src/Login.tsx @@ -127,6 +127,10 @@ class Login extends Component<{}, LoginState> { if (!this.homeserverUrl) { this.homeserverUrl = "https://" + this.homeserverName; } + localforage.setItem("well_known", { + "m.homeserver": {"base_url": this.homeserverUrl}, + "m.identity_server": {"base_url": "https://vector.im"}, // TODO Where to infer this outside of actual .well-known? + }) shared.mClient = createClient({ baseUrl: this.homeserverUrl, fetchFn: customFetch, diff --git a/src/Matrix.tsx b/src/Matrix.tsx index 8348008..8790e5f 100644 --- a/src/Matrix.tsx +++ b/src/Matrix.tsx @@ -27,6 +27,7 @@ const vapidPublicKey = interface MatrixProps { data: any; + well_known: any; } interface Call { @@ -321,10 +322,10 @@ class Matrix extends Component { userId: props.data.user_id, accessToken: props.data.access_token, deviceId: props.data.device_id, - baseUrl: props.data.well_known["m.homeserver"].base_url, + baseUrl: props.well_known["m.homeserver"].base_url, identityServer: - props.data.well_known["m.identity_server"] && - props.data.well_known["m.identity_server"].base_url, + props.well_known["m.identity_server"] && + props.well_known["m.identity_server"].base_url, // store: new matrixcs.IndexedDBStore({ indexedDB: window.indexedDB, localStorage: window.localStorage }), }); const client = shared.mClient; From 738e3466667137e7cf48c07247b4833267ff19d9 Mon Sep 17 00:00:00 2001 From: Giuseppe Stelluto Date: Fri, 19 Jan 2024 23:24:01 +0100 Subject: [PATCH 3/8] Update well_known if client login property returns well_known information --- src/Login.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Login.tsx b/src/Login.tsx index b3ffb74..61a85bf 100644 --- a/src/Login.tsx +++ b/src/Login.tsx @@ -71,6 +71,11 @@ class Login extends Component<{}, LoginState> { this.password ) .then((result: any) => { + if (result.well_known) { + localforage.setItem("well_known", result.well_known).then(() => { + console.log("Received a well_known from client login property. Updating previous settings.") + }); + } localforage.setItem("login", result).then(() => { alert("Logged in as " + this.username); window.location = window.location; From c0ea6d2592683ef7ae5acb53bb4bae70b232c42a Mon Sep 17 00:00:00 2001 From: Giuseppe Stelluto Date: Sat, 20 Jan 2024 19:17:14 +0100 Subject: [PATCH 4/8] Create LoginHandler and move well-known logic there --- src/Login.tsx | 67 ++++++++++----------------------------------- src/LoginHandler.ts | 53 +++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 52 deletions(-) create mode 100644 src/LoginHandler.ts diff --git a/src/Login.tsx b/src/Login.tsx index 61a85bf..b2400e4 100644 --- a/src/Login.tsx +++ b/src/Login.tsx @@ -1,11 +1,10 @@ import { Component } from "inferno"; -import { createClient } from "matrix-js-sdk"; import * as localforage from "localforage"; import { TextListItem, TextInput, Header, SoftKey, ListViewKeyed } from "KaiUI"; import shared from "./shared"; -import { fetch as customFetch } from "./fetch"; import { WellKnown } from "./types"; import LoginWithQR from "./LoginWithQR"; +import LoginHandler from "./LoginHandler"; import { LoginFlow } from "matrix-js-sdk/lib/@types/auth"; interface LoginState { @@ -15,14 +14,13 @@ interface LoginState { } class Login extends Component<{}, LoginState> { - private homeserverUrl: string; - private homeserverName: string; - private loginFlows: LoginFlow[]; private readonly stageNames: string[]; private selectedLoginFlow?: LoginFlow; + public state: LoginState; + private loginHandler: LoginHandler; + private homeserverName: string; private username: string; private password: string; - public state: LoginState; cursorChangeCb = (cursor: number) => { this.setState({ cursor: cursor }); @@ -105,52 +103,18 @@ class Login extends Component<{}, LoginState> { } }; - tryWellKnown = () => { - this.homeserverName = this.homeserverName.replace("https://", ""); - this.homeserverName = this.homeserverName.replace("http://", ""); - let url = `https://${this.homeserverName}/.well-known/matrix/client`; - return fetch(url) - .then((r: Response) => { - if (r.ok) { - r.json().then((j: WellKnown) => { - this.homeserverUrl = j["m.homeserver"].base_url; - }); - } else { - console.log(`.well-known not found at ${url}`); - } - }) - .catch((e) => { - // This can fail for a number of reasons, such as CORS, and still not be a problem yet - console.log(`.well-known not found at ${url}`); - }); - }; - rightCb = () => { switch (this.state.stage) { case 0: - this.tryWellKnown().then(() => { - if (!this.homeserverUrl) { - this.homeserverUrl = "https://" + this.homeserverName; - } - localforage.setItem("well_known", { - "m.homeserver": {"base_url": this.homeserverUrl}, - "m.identity_server": {"base_url": "https://vector.im"}, // TODO Where to infer this outside of actual .well-known? - }) - shared.mClient = createClient({ - baseUrl: this.homeserverUrl, - fetchFn: customFetch, - }); - shared.mClient - .loginFlows() - .then((result) => { - this.loginFlows = result.flows; - this.setState({ cursor: 0, stage: 1 }); - }) - .catch((e: any) => console.log(e)); - }); + this.loginHandler.findHomeserver(this.homeserverName).then( () => { + this.setState({ cursor: 0, stage: 1}) + }).catch((e: any) => { + window.alert("Could not connect to homeserver"); + console.log(e); + }); break; case 1: - this.selectedLoginFlow = this.loginFlows[this.state.cursor]; + this.selectedLoginFlow = this.loginHandler.loginFlows[this.state.cursor]; if (this.selectedLoginFlow.type !== "m.login.password") { window.alert("The selected login method is not implemented, yet."); } else { @@ -174,12 +138,11 @@ class Login extends Component<{}, LoginState> { constructor(props: any) { super(props); - this.stageNames = ["Login Info", "Login method", "Login"]; - this.loginFlows = []; + this.homeserverName = ""; this.username = ""; this.password = ""; - this.homeserverName = ""; - this.homeserverUrl = ""; + this.stageNames = ["Login Info", "Login method", "Login"]; + this.loginHandler = new LoginHandler() this.state = { stage: 0, cursor: 0, @@ -233,7 +196,7 @@ class Login extends Component<{}, LoginState> { }); break; case 1: - listViewChildren = this.loginFlows.map((flow: LoginFlow) => { + listViewChildren = this.loginHandler.loginFlows.map((flow: LoginFlow) => { return ; }); break; diff --git a/src/LoginHandler.ts b/src/LoginHandler.ts new file mode 100644 index 0000000..062e968 --- /dev/null +++ b/src/LoginHandler.ts @@ -0,0 +1,53 @@ +import { fetch as customFetch } from "./fetch"; +import { WellKnown } from "./types"; +import { LoginFlow } from "matrix-js-sdk/lib/@types/auth"; +import * as localforage from "localforage"; +import { createClient } from "matrix-js-sdk"; +import shared from "./shared"; + +export default class LoginHandler { + public base_url: string; + public homeserverName: string; + public username: string; + public password: string; + public loginFlows: LoginFlow[]; + + constructor() { + this.homeserverName = ""; + this.username = ""; + this.password = ""; + this.loginFlows = []; + this.base_url = ""; + } + + public async findHomeserver(name: string) { + name = name.replace("https://", ""); + name = name.replace("http://", ""); + let base_url: string = ""; + let well_known_url = `https://${name}/.well-known/matrix/client`; + try { + let r: Response = await fetch(well_known_url); + if (!r.ok) { + throw new Error("404"); + + } + let well_known: WellKnown = await r.json(); + base_url = well_known["m.homeserver"].base_url; + } catch (e: any) { + console.log(`.well-known not found or malformed at ${well_known_url}`); + base_url = "https://" + name; + } finally { + this.base_url = base_url; + localforage.setItem("well_known", { + "m.homeserver": {"base_url": base_url}, + "m.identity_server": {"base_url": "https://vector.im"}, // TODO Where to infer this outside of actual .well-known? + }) + shared.mClient = createClient({ + baseUrl: base_url, + fetchFn: customFetch, + }); + let result = await shared.mClient.loginFlows() + this.loginFlows = result.flows; + } + } +} From e92ce41edf33b08deed2376b3d1e11fa32b6487d Mon Sep 17 00:00:00 2001 From: Giuseppe Stelluto Date: Sun, 21 Jan 2024 00:12:51 +0100 Subject: [PATCH 5/8] Move doLogin into LoginHandler --- src/Login.tsx | 55 ++++++------------------------------------ src/LoginHandler.ts | 59 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 48 deletions(-) diff --git a/src/Login.tsx b/src/Login.tsx index b2400e4..7f51b94 100644 --- a/src/Login.tsx +++ b/src/Login.tsx @@ -57,52 +57,6 @@ class Login extends Component<{}, LoginState> { } }; - doLogin = () => { - if (!this.selectedLoginFlow) { - throw new Error("selectedLoginFlow is not defined"); - } - switch (this.selectedLoginFlow.type) { - case "m.login.password": - shared.mClient - .loginWithPassword( - `@${this.username}:${this.homeserverName}`, - this.password - ) - .then((result: any) => { - if (result.well_known) { - localforage.setItem("well_known", result.well_known).then(() => { - console.log("Received a well_known from client login property. Updating previous settings.") - }); - } - localforage.setItem("login", result).then(() => { - alert("Logged in as " + this.username); - window.location = window.location; - }); - }) - .catch((err: any) => { - switch (err.errcode) { - case "M_FORBIDDEN": - alert("Incorrect login credentials"); - break; - case "M_USER_DEACTIVATED": - alert("This account has been deactivated"); - break; - case "M_LIMIT_EXCEEDED": - const retry = Math.ceil(err.retry_after_ms / 1000); - alert("Too many requests! Retry after" + retry.toString()); - break; - default: - alert("Login failed for some unknown reason"); - break; - } - }); - break; - default: - alert("Invalid/unsupported login method. This is likely a bug"); - break; - } - }; - rightCb = () => { switch (this.state.stage) { case 0: @@ -122,7 +76,14 @@ class Login extends Component<{}, LoginState> { } break; case 2: - this.doLogin(); + let loginData = {'username': this.username, 'password': this.password}; + if (this.selectedLoginFlow !== undefined) { + this.loginHandler.doLogin(this.selectedLoginFlow, loginData).then(() => { + window.location = window.location; + }).catch((e) => alert(e.message)); + } else { + throw new Error("Undefined selectedLoginFlow") + } break; default: alert("Invalid stage!"); diff --git a/src/LoginHandler.ts b/src/LoginHandler.ts index 062e968..a493b50 100644 --- a/src/LoginHandler.ts +++ b/src/LoginHandler.ts @@ -20,9 +20,66 @@ export default class LoginHandler { this.base_url = ""; } + private setWellKnown(well_known: WellKnown) { + return localforage.setItem("well_known", well_known); + } + + public async doLogin(loginFlow: LoginFlow, loginData: any) { + // TODO implement more login flows + // Instead of implementing them one by one, consider using mClient.login + // and passing loginData (which needs to be properly formed according to their spec) + // (may or may not be a bad idea) + try { + let loginResult: any; + let username: string = `@${loginData.username}:${this.homeserverName}`; + switch (loginFlow.type) { + case "m.login.password": + let password: string = loginData.password; + loginResult = await shared.mClient + .loginWithPassword(username, password); + break; + default: + throw new Error("Unsupported"); + break; + } + if (loginResult.well_known) { + this.setWellKnown(loginResult.well_known) + console.log("Received a well_known from client login property. Updating previous settings.") + console.log(loginResult.well_known) + } + await localforage.setItem("login", loginResult); + alert("Logged in as " + username); + } catch (e: any) { + let message: string; + switch (e.errcode) { + case "M_FORBIDDEN": + message = "Incorrect login credentials"; + break; + case "M_USER_DEACTIVATED": + message = "This account has been deactivated"; + break; + case "M_LIMIT_EXCEEDED": + const retry = Math.ceil(e.retry_after_ms / 1000); + message = `Too many requests! Retry after ${retry.toString()}`; + break; + default: + if (e.message === "Unsupported") { + message = "Login flow selected is unsupported" + } else if (e.errcode) { + message = e.errcode; + } else { + message = `Login failed for some unknown reason: ${e.message}`; + } + break; + } + throw new Error(message) + } + } + public async findHomeserver(name: string) { name = name.replace("https://", ""); name = name.replace("http://", ""); + this.homeserverName = name; let base_url: string = ""; let well_known_url = `https://${name}/.well-known/matrix/client`; try { @@ -38,7 +95,7 @@ export default class LoginHandler { base_url = "https://" + name; } finally { this.base_url = base_url; - localforage.setItem("well_known", { + this.setWellKnown({ "m.homeserver": {"base_url": base_url}, "m.identity_server": {"base_url": "https://vector.im"}, // TODO Where to infer this outside of actual .well-known? }) From a4756007a5bc897203972db579485ddb17830320 Mon Sep 17 00:00:00 2001 From: Giuseppe Stelluto Date: Sun, 21 Jan 2024 17:10:19 +0100 Subject: [PATCH 6/8] Refactor LoginWithQR to use LoginHandler --- src/Login.tsx | 5 +- src/LoginWithQR/LoginWithQR.tsx | 136 ++++++++++---------------------- 2 files changed, 46 insertions(+), 95 deletions(-) diff --git a/src/Login.tsx b/src/Login.tsx index 7f51b94..b14c063 100644 --- a/src/Login.tsx +++ b/src/Login.tsx @@ -121,7 +121,8 @@ class Login extends Component<{}, LoginState> { render() { if (this.state.loginWithQr) { - return ; + return ; + // return ; } let listViewChildren; switch (this.state.stage) { @@ -147,7 +148,7 @@ class Login extends Component<{}, LoginState> { }, { tertiary: - "Press Call button and scan a QR in the following format to login with QR code instead of typing all these(PASS = password authentication): PASS server_name username password", + "Press Call button and scan a QR in the following format to login with QR code instead of typing all these (PASS = password authentication): PASS server_name username password", type: "text", key: "qrHint", }, diff --git a/src/LoginWithQR/LoginWithQR.tsx b/src/LoginWithQR/LoginWithQR.tsx index b7ba8eb..f6ea2ae 100644 --- a/src/LoginWithQR/LoginWithQR.tsx +++ b/src/LoginWithQR/LoginWithQR.tsx @@ -1,16 +1,18 @@ import { Component } from "inferno"; import QrScanner from "qr-scanner"; -import { createClient } from "matrix-js-sdk"; -import * as localforage from "localforage"; +import { LoginFlow } from "matrix-js-sdk/lib/@types/auth"; import "./LoginWithQR.css"; import { SoftKey } from "KaiUI"; -import shared from "../shared"; -import { fetch as customFetch } from "../fetch"; -import { WellKnown } from "../types"; +import LoginHandler from "../LoginHandler"; -class LoginWithQR extends Component<{}, {}> { +interface LoginWithQRProps { + loginHandler: LoginHandler; +} + +class LoginWithQR extends Component { private video?: HTMLVideoElement; + private loginHandler: LoginHandler; startScanning = () => { if (!this.video) { @@ -27,104 +29,52 @@ class LoginWithQR extends Component<{}, {}> { scanner.start(); }; - doLogin = (data: string) => { + private login_flows_short: {[key: string]: string} = { + "PASS": "m.login.password" + } + + private async doLogin (data: string) { let decodedParts: string[] = data.split(" ", 4); - const flow = decodedParts[0]; + let flow = decodedParts[0]; const server_name = decodedParts[1]; const username = decodedParts[2]; - let password: string; - if ( - window.confirm( - `Do you confirm? Flow: ${flow} | Server name: ${server_name} | Username: ${username}` - ) - ) { - const start: number = - flow.length + server_name.length + username.length + 3; - password = data.substring(start); - fetch(`https://${server_name}/.well-known/matrix/client`).then( - (r: Response) => { - if (r.ok) { - r.json() - .then((j: WellKnown) => { - const server_url: string = j["m.homeserver"].base_url; - shared.mClient = createClient({ - baseUrl: server_url, - fetchFn: customFetch, - }); - shared.mClient - .loginFlows() - .then((result) => { - let gotPasswordLogin = false; - for (let flow of result.flows) { - if ("m.login.password" === flow.type) { - gotPasswordLogin = true; - break; - } - } - if (gotPasswordLogin) { - shared.mClient - .loginWithPassword( - `@${username}:${server_name}`, - password - ) - .then((result: any) => { - localforage.setItem("login", result).then(() => { - window.alert("Logged in as " + username); - window.location = window.location; - }); - }) - .catch((err: any) => { - switch (err.errcode) { - case "M_FORBIDDEN": - alert("Incorrect login credentials"); - break; - case "M_USER_DEACTIVATED": - alert("This account has been deactivated"); - break; - case "M_LIMIT_EXCEEDED": - const retry = Math.ceil( - err.retry_after_ms / 1000 - ); - alert( - "Too many requests! Retry after" + - retry.toString() - ); - break; - default: - alert("Login failed! Unknown reason"); - break; - } - // eslint-disable-next-line no-self-assign - window.location = window.location; - }); - } else { - window.alert( - "This homeserver does not support authentication with password" - ); - } - }) - .catch((e) => { - window.alert("Error getting login flows from the server"); - console.log(e); - }); - }) - .catch((e) => { - window.alert("Error getting information about the server"); - console.log("REPORT", e); - }); - } else { - alert( - "Cannot connect to homeserver. Are you sure the address is correct?" - ); + const start = flow.length + server_name.length + username.length + 3; + let password: string = data.substring(start); + // TODO implement more flows + if (window.confirm( + `Do you confirm? Flow: ${flow} | Server name: ${server_name} | Username: ${username}`)) { + // users can either write the full m.login.password (or whatever other flow) or use a shorthand + // This maps the shorthand to the actual flow identificator + if (!flow.startsWith("m.login")) { + flow = this.login_flows_short[flow]; + } + if (flow !== "m.login.password") { + alert("Password authentication is the only supported flow currently") + return; + } + try { + await this.loginHandler.findHomeserver(server_name); + let selected_flow: LoginFlow | undefined; + for (let available_flow of this.loginHandler.loginFlows) { + if (available_flow.type === flow) { + selected_flow = available_flow; } } - ); + if (selected_flow !== undefined) { + let loginData = {'username': username, 'password': password}; + await this.loginHandler.doLogin(selected_flow, loginData); + window.location = window.location; + } + } catch (e) { + alert(e) + } } }; constructor(props: any) { super(props); this.state = null; + this.loginHandler = props.loginHandler; } componentDidMount() { From 6e535f4fc405871446711212e69a5a99ffa16113 Mon Sep 17 00:00:00 2001 From: Giuseppe Stelluto Date: Sun, 21 Jan 2024 17:59:08 +0100 Subject: [PATCH 7/8] Throw exception if no login flows found --- src/LoginHandler.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/LoginHandler.ts b/src/LoginHandler.ts index a493b50..38fb6c8 100644 --- a/src/LoginHandler.ts +++ b/src/LoginHandler.ts @@ -95,16 +95,24 @@ export default class LoginHandler { base_url = "https://" + name; } finally { this.base_url = base_url; + try { + shared.mClient = createClient({ + baseUrl: base_url, + fetchFn: customFetch, + }); + let result = await shared.mClient.loginFlows() + if (! result.flows) { + throw new Error("Got no flows"); + } + this.loginFlows = result.flows; + } catch (e) { + alert(`No server found at ${base_url}`) + console.log(e); + } this.setWellKnown({ "m.homeserver": {"base_url": base_url}, "m.identity_server": {"base_url": "https://vector.im"}, // TODO Where to infer this outside of actual .well-known? }) - shared.mClient = createClient({ - baseUrl: base_url, - fetchFn: customFetch, - }); - let result = await shared.mClient.loginFlows() - this.loginFlows = result.flows; } } } From c91edc5c96cf9910ced9ddd2c4967f7b0ca2566b Mon Sep 17 00:00:00 2001 From: Giuseppe Stelluto Date: Sun, 21 Jan 2024 18:04:13 +0100 Subject: [PATCH 8/8] Remove unused imports --- src/Login.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Login.tsx b/src/Login.tsx index b14c063..933b06b 100644 --- a/src/Login.tsx +++ b/src/Login.tsx @@ -1,8 +1,5 @@ import { Component } from "inferno"; -import * as localforage from "localforage"; import { TextListItem, TextInput, Header, SoftKey, ListViewKeyed } from "KaiUI"; -import shared from "./shared"; -import { WellKnown } from "./types"; import LoginWithQR from "./LoginWithQR"; import LoginHandler from "./LoginHandler"; import { LoginFlow } from "matrix-js-sdk/lib/@types/auth";