const mm_client = (function() { "use strict"; class MattermostClient { constructor (endpoint, credentials_provider) { this.endpoint = endpoint; this.credentials = credentials_provider; const creds = this.credentials.get(this.endpoint); this.token = creds ? creds.token : null; console.info(`Created MattermostClient for ${this.endpoint}, ${this.token ? "found token" : "did not find token"}`); } async get(path, token, queryParams) { const headers = token ? {"Authorization": `Bearer ${token}`} : {}; const response = await ajax.getJson(`${this.endpoint}${path}`, {headers, queryParams}); if (!response.ok) { throw response; } return response; } async post(path, token, data) { const headers = token ? {"Authorization": `Bearer ${token}`} : {}; const response = await ajax.postJson(`${this.endpoint}${path}`, data, {headers}); if (!response.ok) { throw response; } return response; } async authedGet(url, queryParams) { assert(this.token, "logged in"); const response = await this.get(url, this.token, queryParams); return response.responseJson; } async authedPaginatedGet(url, queryParams, perPage=200) { assert(this.token, "logged in"); let data = []; let params = {page: 0, per_page: perPage}; if (queryParams) { extend(params, queryParams); } let loadMore = true; while (loadMore) { if (params.page > 100) { throw new Error("Requesting more than 100 pages, something looks wrong"); } const response = await this.get(url, this.token, params); data = data.concat(response.responseJson); loadMore = response.responseJson.length > 0; params.page++; } return data; } async loggedIn() { if (!this.token) { return false; } try { const meResponse = await this.userMe(); return true; } catch (e) { if (e instanceof ajax.NotOkError && e.xhr.status == 401) { return false; } else { throw e; } } } async logIn(login_id, password) { if (await this.loggedIn()) { throw Error("Already logged in on this server"); } const response = await this.post("/users/login", undefined, {login_id, password}); const token = response.getResponseHeader("Token"); if (!token) { throw Error("No Token header in response to log in request"); } this.credentials.store(this.endpoint, login_id, token); this.token = token; let _ = this.getUsers(); return response.responseJson; } async logOut() { assert(this.token, "logged in"); const response = await this.post("/users/logout", this.token); // Verify that the token is now invalidated if (await this.loggedIn()) { throw new Error("Failed to log out: token still works after trying to log out"); } this.credentials.clear(this.endpoint); this.token = null; return response.responseJson; } user(user_id) { assertIsMattermostId(user_id); return this.authedGet(`/users/${user_id}`); } userMe() { return this.authedGet("/users/me"); } myTeams() { return this.authedGet("/users/me/teams"); } myChannels(team_id) { assertIsMattermostId(team_id); return this.authedGet(`/users/me/teams/${team_id}/channels`); } channelPosts(channel_id, beforePost=null, afterPost=null, since=null) { assertIsMattermostId(channel_id); assertIsNullOrMattermostId(beforePost); assertIsNullOrMattermostId(afterPost); return this.authedGet(`/channels/${channel_id}/posts`, { before: beforePost, after: afterPost, since }); } getUsers() { if (!this.users) { this.users = this.authedPaginatedGet("/users", {}).then(users => { const newUsers = Object.create(null); for (let user_data of users) { const user = user_data; newUsers[user.id] = user; } return newUsers; }); } return this.users; } async filePublicLink(file_id) { const response = await this.authedGet(`/files/${file_id}/link`, {}); return response.link; } } let clients = Object.create(null); function get(endpoint) { if (!clients[endpoint]) { clients[endpoint] = new MattermostClient(endpoint, localstorage_credentials); } return clients[endpoint]; } function getMultiple(endpoints) { return endpoints.map(get); } function drop(endpoint) { delete clients[endpoint]; } return {get, getMultiple, drop}; })();