diff --git a/index.html b/index.html
index 70cf1f3..967d483 100644
--- a/index.html
+++ b/index.html
@@ -12,7 +12,8 @@
Username | |
Password | |
-
+ (ignores username and password)
+
diff --git a/main.js b/main.js
index 9533e46..12ae4e6 100644
--- a/main.js
+++ b/main.js
@@ -1,5 +1,7 @@
"use strict";
+const LOCALSTORAGE_KEY_SERVERS = "mattermostServers";
+
function byId(id, nullOk=false) {
const el = document.getElementById(id);
if (!el && !nullOk) {
@@ -8,6 +10,18 @@ function byId(id, nullOk=false) {
return el;
}
+function storeCredentials(endpoint, login_id, token) {
+ let storedServers = JSON.parse(window.localStorage.getItem(LOCALSTORAGE_KEY_SERVERS) || "[]");
+ if (!(endpoint in storedServers)) storedServers.push(endpoint);
+ window.localStorage.setItem(LOCALSTORAGE_KEY_SERVERS, JSON.stringify(storedServers));
+
+ window.localStorage.setItem(`${LOCALSTORAGE_KEY_SERVERS}_${endpoint}`, JSON.stringify({login_id, token}));
+}
+
+function getCredentials(endpoint) {
+ return JSON.parse(window.localStorage.getItem(`${LOCALSTORAGE_KEY_SERVERS}_${endpoint}`) || "null");
+}
+
class MattermostApi {
constructor(endpoint) {
this.endpoint = endpoint;
@@ -19,17 +33,17 @@ class MattermostApi {
"Token": `Authorization: Bearer ${token}`
}
});
- return response.ok;
+ if (!response.ok) {
+ throw response;
+ }
+ return response;
}
- logIn(username, password) {
- return ajax.postJson(`${this.endpoint}/users/login`, {
- "login_id": username,
- "password": password
- })
+ logIn(login_id, password) {
+ return ajax.postJson(`${this.endpoint}/users/login`, {login_id, password})
.then(response => {
let token = response.getHeader("Token");
- window.localStorage.setItem("token", token);
+ storeCredentials(this.endpoint, login_id, token);
return response;
})
.then(response => {
@@ -47,11 +61,38 @@ class MattermostApi {
}
}
+/**
+ * Return an endpoint URL that has a protocol, domain and path
+ */
+function normalizedEndpoint(endpoint) {
+ let matches = endpoint.match(/^(https?:\/\/)?([^\/]+)(\/.*)?$/i);
+ if (!matches) throw Error("Invalid endpoint URL");
+
+ let protocol = matches[1] || "https://";
+ let domain = matches[2];
+ let path = matches[3] || "/api/v4";
+
+ return `${protocol}${domain}${path}`;
+}
+
function logIn() {
- let endpoint = byId("server").value;
- if (!endpoint.endsWith("/")) endpoint += "/";
- endpoint += "api/v4";
+ let endpoint = normalizedEndpoint(byId("server").value);
let api = new MattermostApi(endpoint);
api.logIn(byId("username").value, byId("password").value);
}
+
+function validateToken() {
+ let endpoint = normalizedEndpoint(byId("server").value);
+
+ let api = new MattermostApi(endpoint);
+ api.validateToken(getCredentials(endpoint))
+ .then(() => {
+ byId("validate").value = "Validation succeeded";
+ byId("validate").disabled = false;
+ })
+ .catch(() => {
+ byId("validate").value = "Validation failed";
+ byId("validate").disabled = false;
+ });
+}
diff --git a/xhr.js b/xhr.js
index a8e36e3..02c866d 100644
--- a/xhr.js
+++ b/xhr.js
@@ -33,20 +33,21 @@ function xhrInitForPromise(resolve, reject, url, method, headers) {
}
function xhrParseJsonResponse(xhr) {
- if (xhr.status == 0) {
+ if (xhr.status === 0) {
console.error(xhr);
throw new NetworkError("Failed to connect to server");
}
+ let json;
if (!xhr.responseText) {
- const json = null;
+ 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);
+ json = JSON.parse(xhr.responseText);
} catch(e) {
throw new InvalidJsonError();
}
@@ -56,7 +57,7 @@ function xhrParseJsonResponse(xhr) {
ok: 200 <= xhr.status && xhr.status < 300,
status: xhr.status,
statusText: xhr.statusText,
- getHeader: xhr.getResponseHeader,
+ getHeader: header => xhr.getResponseHeader(header),
json,
xhr,
};
@@ -74,8 +75,9 @@ function getJson(url, options={}) {
function postJson(url, data={}, options={}) {
if (!options.headers) options.headers = {};
- options.headers["Content-Type"] = MIME_JSON;
- options.headers["Accept"] = MIME_JSON;
+ // This triggers CORS, which is not acceptable
+ //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);