diff --git a/app.js b/app.js
index 0a548e2..5d515c0 100644
--- a/app.js
+++ b/app.js
@@ -9,6 +9,7 @@ const Matrix = require('./backends/matrix.js')
const Sidebar = require('./components/sidebar.js')
+const Login = require('./components/Login.js')
const Info = require('./components/info.js')
const Chat = require('./components/chat.js')
const Input = require('./components/input.js')
@@ -40,60 +41,18 @@ let App = create({
}, 100)
},
- login: function() {
- let user = document.getElementById("user").value
- let pass = document.getElementById("pass").value
- let hs = document.getElementById("hs").value
- this.setState({apiUrl: hs})
- hs = urllib.parse(hs)
-
- let data = {
- user: user,
- password: pass,
- type: "m.login.password",
- initial_device_display_name: "Neo v4",
- };
-
- let url = urllib.format(Object.assign(hs, {
- pathname: "/_matrix/client/r0/login"
- }));
-
- fetch(url, {
- body: JSON.stringify(data),
- headers: {
- 'content-type': 'application/json'
- },
- method: 'POST',
- }).then((response) => response.json())
- .then((responseJson) => {
- this.setState({json: responseJson});
- if(responseJson.access_token != undefined) {
- let backend = new Matrix(responseJson.user_id, responseJson.access_token, this.state.apiUrl)
- this.setState({
- backend: backend
- })
- this.checkBackend()
- }
- })
- .catch((error) => {
- console.error(error);
- });
+ loginCallback: function(userId, accessToken, apiUrl) {
+ let backend = new Matrix(userId, accessToken, apiUrl)
+ this.setState({
+ backend: backend
+ })
+ this.checkBackend()
},
render: function() {
if (this.state.backend == undefined) {
//Login screen
- return (
-
- )
+ return
}
return (
<>
diff --git a/components/Login.js b/components/Login.js
new file mode 100644
index 0000000..81194e6
--- /dev/null
+++ b/components/Login.js
@@ -0,0 +1,158 @@
+'use strict'
+const React = require('react')
+const ReactDOM = require('react-dom')
+const create = require('create-react-class')
+const Promise = require('bluebird')
+const urllib = require('url')
+const debounce = require('debounce')
+const defaultValue = require('default-value')
+
+let login = create({
+ displayName: "Login",
+
+ getInitialState: function() {
+ return {error: null}
+ },
+
+ login: function() {
+ let user = document.getElementById("user").value
+ let pass = document.getElementById("pass").value
+
+ let parts = user.split(':')
+ if (parts.length != 2) {
+ return this.setState({error: "Please enter a full mxid, like @username:homeserver.tld"})
+ }
+
+ let hostname = urllib.parse("https://" + parts[1])
+ getApiServer(hostname).then((hostname) => {
+ hostname.pathname = ""
+ let hs = urllib.format(hostname)
+ console.log("Using API server", hs)
+ this.setState({apiUrl: hs})
+ //this.login()
+ })
+ },
+
+ login: function() {
+ let data = {
+ user: this.state.user,
+ password: this.state.password,
+ type: "m.login.password",
+ initial_device_display_name: "Neo v4",
+ };
+
+ let url = urllib.format(Object.assign(this.state.apiUrl, {
+ pathname: "/_matrix/client/r0/login"
+ }));
+
+ fetch(url, {
+ body: JSON.stringify(data),
+ headers: {
+ 'content-type': 'application/json'
+ },
+ method: 'POST',
+ }).then((response) => response.json())
+ .then((responseJson) => {
+ this.setState({json: responseJson});
+ if(responseJson.access_token != undefined) {
+ this.props.loginCallback()
+ }
+ })
+ .catch((error) => {
+ console.error(error);
+ });
+ },
+
+ render: function() {
+ return (
+
+ )
+ }
+})
+
+function getApiServer(hostname) {
+ return new Promise((resolve, reject) => {
+ console.log("Checking for api server from mxid", urllib.format(hostname))
+ checkApi(hostname).then(() => {
+ // Hostname is a valid api server
+ resolve(hostname)
+ }).catch(() => {
+ console.log("trying .well-known")
+ tryWellKnown(hostname).then((hostname) => {
+ console.log("got .well-known host", hostname)
+ }).catch((err) => {
+ console.log("Fatal error trying to get API host", err)
+ })
+ })
+ })
+}
+
+function checkApi(host) {
+ let versionUrl = buildUrl(host, "/_matrix/client/versions")
+ return new Promise((resolve, reject) => {
+ fetch(versionUrl).then((response) => {
+ if (response.status != 200) {
+ console.log("Invalid homeserver url", versionUrl)
+ return reject()
+ }
+ resolve()
+ }).catch((err) => {
+ reject(err)
+ })
+ })
+}
+
+function tryWellKnown(host) {
+ let wellKnownUrl = urllib.format(Object.assign(host, {
+ pathname: "/.well-known/matrix/client"
+ }))
+ console.log("Trying", wellKnownUrl, "for .well-known")
+ return new Promise((resolve, reject) => {
+ return fetch(wellKnownUrl)
+ .then((response) => {
+ if (response.status != 200) {
+ console.log("no well-known in use")
+ reject()
+ }
+ return response
+ })
+ .then((response) => response.json())
+ .then((json) => {
+ console.log("Parsed json", json)
+ if (json['m.homeserver'] != undefined && json['m.homeserver'].base_url != undefined) {
+ resolve(json['m.homeserver'].base_url)
+ }
+ })
+ .catch((err) => {
+ console.log("Error in json", err)
+ reject()
+ })
+ })
+}
+
+function buildUrl(host, path) {
+ return urllib.format(Object.assign(host, {
+ pathname: path
+ }))
+}
+
+module.exports = login
diff --git a/public/scss/style.scss b/public/scss/style.scss
index a5a5304..dcaad54 100644
--- a/public/scss/style.scss
+++ b/public/scss/style.scss
@@ -57,6 +57,10 @@ body {
justify-content: center;
flex-direction: column;
+ input, label, button {
+ font-size: 140%;
+ }
+
img {
height: 15rem;
width: 15rem;
@@ -65,6 +69,10 @@ body {
}
}
+.error {
+ color: $red;
+}
+
.login {
align-self: center;
display: inline-grid;
@@ -73,8 +81,8 @@ body {
$blue: #5294e2;
label, input, button {
- margin: 0.3rem;
- padding: 0.3rem;
+ margin: 0.3em;
+ padding: 0.3em;
}
label {