:x
This commit is contained in:
parent
f275a03b93
commit
fcbb561d62
3 changed files with 150 additions and 77 deletions
11
index.html
11
index.html
|
@ -3,9 +3,18 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Battermost</title>
|
||||
<title>Bettermost</title>
|
||||
</head>
|
||||
<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>
|
||||
</body>
|
||||
</html>
|
||||
|
|
125
main.js
125
main.js
|
@ -1,84 +1,57 @@
|
|||
//async function postJson(url, data = {}, options = {}) {
|
||||
//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;
|
||||
//}
|
||||
"use strict";
|
||||
|
||||
//var endpoint = "https://mattermost.zeus.gent/api/v4"; // Must not end with slash
|
||||
var endpoint = "http://localhost:8080"; // Must not end with slash
|
||||
var username = "fill me in";
|
||||
var password = "fill me in";
|
||||
function byId(id, nullOk=false) {
|
||||
const el = document.getElementById(id);
|
||||
if (!el && !nullOk) {
|
||||
console.error(`No element #${id}`);
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
class MattermostApi {
|
||||
constructor(endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
function scopeToArg(f) {
|
||||
return function(...rest) {
|
||||
return f(this, ...rest);
|
||||
async validateToken(token) {
|
||||
const response = await ajax.getJson(`${this.endpoint}/users/me`, {
|
||||
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={}) {
|
||||
const prom = new Promise((resolve, reject) => {
|
||||
let oReq = new XMLHttpRequest();
|
||||
oReq.addEventListener("load", scopeToArg(resolve));
|
||||
oReq.addEventListener("abort", scopeToArg(reject));
|
||||
oReq.addEventListener("error", scopeToArg(reject));
|
||||
oReq.addEventListener("timeout", scopeToArg(reject));
|
||||
oReq.open("POST", url);
|
||||
oReq.send(JSON.stringify(data));
|
||||
function logIn() {
|
||||
let endpoint = byId("server").value;
|
||||
if (!endpoint.endsWith("/")) endpoint += "/";
|
||||
endpoint += "api/v4";
|
||||
|
||||
});
|
||||
return prom;
|
||||
let api = new MattermostApi(endpoint);
|
||||
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
91
xhr.js
Normal 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
|
||||
};
|
||||
|
||||
})();
|
Loading…
Reference in a new issue