diff --git a/src/js/login.js b/src/js/login.js index 4754bef..55caa66 100644 --- a/src/js/login.js +++ b/src/js/login.js @@ -77,16 +77,40 @@ class Form extends ElemJS { if (!username.isValid()) return this.cancel("Username is not valid.") // Resolve homeserver address - let domain - try { - domain = await this.findHomeserver(homeserver.value) - } catch(e) { - return this.cancel(e.message) + let currentAddress = homeserver.value + let ok = false + while (!ok) { + if (!currentAddress.match(/^https?:\/\//)) { + console.warn(`${currentAddress} doesn't specify the protocol, assuming https`) + currentAddress = "https://" + currentAddress + } + currentAddress = currentAddress.replace(/\/*$/, "") + this.status(`Looking up homeserver... trying ${currentAddress}`) + try { + // check if we found the actual matrix server + try { + const versions = await fetch(`${currentAddress}/_matrix/client/versions`).then(res => res.json()) + if (Array.isArray(versions.versions)) { + ok = true + break + } + } catch (e) {} + // find the next matrix server in the chain + const root = await fetch(`${currentAddress}/.well-known/matrix/client`).then(res => res.json()) + let nextAddress = root["m.homeserver"].base_url + nextAddress = nextAddress.replace(/\/*$/, "") + if (currentAddress === nextAddress) { + ok = true + } + currentAddress = nextAddress + } catch (e) { + return this.cancel(`Failed to look up server ${currentAddress}`) + } } // Request access token this.status("Logging in...") - const root = await fetch(`${domain}/_matrix/client/r0/login`, { + const root = await fetch(`${currentAddress}/_matrix/client/r0/login`, { method: "POST", body: JSON.stringify({ type: "m.login.password", @@ -106,52 +130,12 @@ class Form extends ElemJS { } localStorage.setItem("mx_user_id", root.user_id) - localStorage.setItem("domain", domain) + localStorage.setItem("domain", currentAddress) localStorage.setItem("access_token", root.access_token) location.assign("../") } - async findHomeserver(address, maxDepth = 5) { - - //Protects from servers sending us on a redirect loop - maxDepth-- - if (maxDepth <= 0) throw new Error(`Failed to look up homeserver, maximum search depth reached`) - - //Normalise the address - if (!address.match(/^https?:\/\//)) { - console.warn(`${address} doesn't specify the protocol, assuming https`) - address = "https://" + address - } - address = address.replace(/\/*$/, "") - - this.status(`Looking up homeserver... trying ${address}`) - - // Check if we found the actual matrix server - try { - const versionsReq = await fetch(`${address}/_matrix/client/versions`) - if (versionsReq.ok) { - const versions = await versionsReq.json() - if (Array.isArray(versions.versions)) return address - } - } catch(e) {} - - // Find the next matrix server in the chain - const root = await fetch(`${address}/.well-known/matrix/client`).then(res => res.json()).catch(e => { - console.error(e) - throw new Error(`Failed to look up server ${address}`) - }) - - let nextAddress = root["m.homeserver"].base_url - nextAddress = nextAddress.replace(/\/*$/, "") - - if (address === nextAddress) { - throw new Error(`Failed to look up server ${address}, /.well-known/matrix/client found a redirect loop`); - } - - return this.findHomeserver(nextAddress, maxDepth) - } - status(message) { feedback.setLoading(true) feedback.message(message)