This commit is contained in:
Midgard 2020-03-25 17:05:25 +01:00
parent f275a03b93
commit fcbb561d62
Signed by: midgard
GPG key ID: 511C112F1331BBB4
3 changed files with 150 additions and 77 deletions

View file

@ -3,9 +3,18 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<title>Battermost</title> <title>Bettermost</title>
</head> </head>
<body> <body>
<form>
<table>
<tr><th>Server</th><td><input type="text" id="server" value="http://localhost:8080"/></td></tr>
<tr><th>Username</th><td><input type="text" id="username"/></td></tr>
<tr><th>Password</th><td><input type="password" id="password"/></td></tr>
</table>
<input type="submit" onclick="this.disabled = true; this.value = 'Logging in...'; logIn(); return false" value="Log in"/>
</form>
<script type="text/javascript" src="xhr.js"></script>
<script type="text/javascript" src="main.js"></script> <script type="text/javascript" src="main.js"></script>
</body> </body>
</html> </html>

125
main.js
View file

@ -1,84 +1,57 @@
//async function postJson(url, data = {}, options = {}) { "use strict";
//const response = await fetch(url, {
//method: "POST",
//mode: "no-cors",
//credentials: "include",
//headers: { "Content-Type": "application/json" },
//redirect: "follow",
//referrerPolicy: "no-referrer",
//body: JSON.stringify(data),
//...options
//});
////return await response.json();
//return response;
//}
//var endpoint = "https://mattermost.zeus.gent/api/v4"; // Must not end with slash function byId(id, nullOk=false) {
var endpoint = "http://localhost:8080"; // Must not end with slash const el = document.getElementById(id);
var username = "fill me in"; if (!el && !nullOk) {
var password = "fill me in"; console.error(`No element #${id}`);
}
return el;
}
class MattermostApi {
constructor(endpoint) {
this.endpoint = endpoint;
}
function scopeToArg(f) { async validateToken(token) {
return function(...rest) { const response = await ajax.getJson(`${this.endpoint}/users/me`, {
return f(this, ...rest); headers: {
"Token": `Authorization: Bearer ${token}`
}
});
return response.ok;
}
logIn(username, password) {
return ajax.postJson(`${this.endpoint}/users/login`, {
"login_id": username,
"password": password
})
.then(response => {
let token = response.getHeader("Token");
window.localStorage.setItem("token", token);
return response;
})
.then(response => {
document.body.innerHTML = "";
const pre = document.createElement("pre");
pre.innerText = JSON.stringify(response.json, null, 2);
document.body.appendChild(pre);
return response;
})
.catch(error => {
console.error(error);
document.body.innerText = `An error occurred: ${error}`;
});
} }
} }
function postJson(url, data={}, options={}) { function logIn() {
const prom = new Promise((resolve, reject) => { let endpoint = byId("server").value;
let oReq = new XMLHttpRequest(); if (!endpoint.endsWith("/")) endpoint += "/";
oReq.addEventListener("load", scopeToArg(resolve)); endpoint += "api/v4";
oReq.addEventListener("abort", scopeToArg(reject));
oReq.addEventListener("error", scopeToArg(reject));
oReq.addEventListener("timeout", scopeToArg(reject));
oReq.open("POST", url);
oReq.send(JSON.stringify(data));
}); let api = new MattermostApi(endpoint);
return prom; api.logIn(byId("username").value, byId("password").value);
} }
var token = null;
function printIt(response) {
console.log(response);
if (response.status == 0) {
document.body.innerText = "Network error";
return;
}
if (200 <= response.status && response.status < 300) {
try {
const json = JSON.parse(response.response);
document.body.innerHTML = "";
const pre = document.createElement("pre");
pre.innerText = "Received " + JSON.stringify(json, null, 2);
document.body.appendChild(pre);
token = response.getResponseHeader("token");
window.localStorage.setItem("token", token);
return token;
} catch(e) {
document.body.innerText = "The server did not reply with a valid JSON object. Make sure the server URL points to a Mattermost instance that is working correctly.";
}
} else {
console.log(response.getAllResponseHeaders());
try {
const json = JSON.parse(response.response);
document.body.innerText = "Failed to log in: " + json.message;
} catch(e) {
document.body.innerText = "Error: " + response.statusText;
}
}
}
postJson(`${endpoint}/api/v4/users/login`, {
"login_id": username,
"password": password
})
.then(printIt, printIt)
.then(token => console.log(token));

91
xhr.js Normal file
View file

@ -0,0 +1,91 @@
const ajax = (function() { "use strict";
class NetworkError extends Error {}
class UnexpectedMimeError extends Error {}
class InvalidJsonError extends Error {}
const MIME_JSON = "application/json";
/**
* Wrap a function so that it receives `this` as first argument.
*/
function thisToArg(f) {
return function(...rest) {
return f(this, ...rest);
}
}
function xhrInitForPromise(resolve, reject, url, method, headers) {
const t_resolve = thisToArg(resolve),
t_reject = thisToArg(reject);
let xhr = new XMLHttpRequest();
xhr.addEventListener("load", t_resolve);
xhr.addEventListener("error", t_resolve);
xhr.addEventListener("abort", t_reject);
xhr.addEventListener("timeout", t_reject);
xhr.open(method, url);
for (let header of Object.getOwnPropertyNames(headers)) {
xhr.setRequestHeader(header, headers[header]);
}
return xhr;
}
function xhrParseJsonResponse(xhr) {
if (xhr.status == 0) {
console.error(xhr);
throw new NetworkError("Failed to connect to server");
}
if (!xhr.responseText) {
const json = null;
} else {
const contentType = xhr.getResponseHeader("Content-Type");
if (contentType != MIME_JSON) {
throw new UnexpectedMimeError(`Server did not reply with JSON but with ${contentType}`);
}
try {
const json = JSON.parse(xhr.responseText);
} catch(e) {
throw new InvalidJsonError();
}
}
return {
ok: 200 <= xhr.status && xhr.status < 300,
status: xhr.status,
statusText: xhr.statusText,
getHeader: xhr.getResponseHeader,
json,
xhr,
};
}
function getJson(url, options={}) {
if (!options.headers) options.headers = {};
options.headers["Accept"] = MIME_JSON;
return new Promise((resolve, reject) => {
let xhr = xhrInitForPromise(resolve, reject, url, "GET", options.headers);
xhr.send();
}).then(xhrParseJsonResponse);
}
function postJson(url, data={}, options={}) {
if (!options.headers) options.headers = {};
options.headers["Content-Type"] = MIME_JSON;
options.headers["Accept"] = MIME_JSON;
return new Promise((resolve, reject) => {
let xhr = xhrInitForPromise(resolve, reject, url, "POST", options.headers);
xhr.send(JSON.stringify(data));
}).then(xhrParseJsonResponse);
}
return {
NetworkError, UnexpectedMimeError, InvalidJsonError,
getJson, postJson
};
})();