diff options
Diffstat (limited to 'webclient/components')
-rw-r--r-- | webclient/components/matrix/matrix-service.js | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/webclient/components/matrix/matrix-service.js b/webclient/components/matrix/matrix-service.js new file mode 100644 index 0000000000..bbfffe75e7 --- /dev/null +++ b/webclient/components/matrix/matrix-service.js @@ -0,0 +1,307 @@ +'use strict'; + +angular.module('matrixService', []) +.factory('matrixService', ['$http', '$q', function($http, $q) { + + /* + * Permanent storage of user information + * The config contains: + * - homeserver url + * - Identity server url + * - user_id + * - access_token + * - version: the version of this cache + */ + var config; + + // Current version of permanent storage + var configVersion = 0; + var prefixPath = "/matrix/client/api/v1"; + var MAPPING_PREFIX = "alias_for_"; + + var doRequest = function(method, path, params, data) { + // Inject the access token + if (!params) { + params = {}; + } + params.access_token = config.access_token; + + return doBaseRequest(config.homeserver, method, path, params, data, undefined); + }; + + var doBaseRequest = function(baseUrl, method, path, params, data, headers) { + if (path.indexOf(prefixPath) !== 0) { + path = prefixPath + path; + } + // Do not directly return the $http instance but return a promise + // with enriched or cleaned information + var deferred = $q.defer(); + $http({ + method: method, + url: baseUrl + path, + params: params, + data: data, + headers: headers + }) + .success(function(data, status, headers, config) { + // @TODO: We could detect a bad access token here and make an automatic logout + deferred.resolve(data, status, headers, config); + }) + .error(function(data, status, headers, config) { + // Enrich the error callback with an human readable error reason + var reason = data.error; + if (!data.error) { + reason = JSON.stringify(data); + } + deferred.reject(reason, data, status, headers, config); + }); + + return deferred.promise; + }; + + + return { + /****** Home server API ******/ + prefix: prefixPath, + + // Register an user + register: function(user_name, password) { + // The REST path spec + var path = "/register"; + + return doRequest("POST", path, undefined, { + user_id: user_name, + password: password + }); + }, + + // Create a room + create: function(room_id, visibility) { + // The REST path spec + var path = "/rooms"; + + return doRequest("POST", path, undefined, { + visibility: visibility, + room_alias_name: room_id + }); + }, + + // List all rooms joined or been invited to + rooms: function(from, to, limit) { + // The REST path spec + var path = "/im/sync"; + + return doRequest("GET", path); + }, + + // Joins a room + join: function(room_id) { + // The REST path spec + var path = "/rooms/$room_id/members/$user_id/state"; + + // Like the cmd client, escape room ids + room_id = encodeURIComponent(room_id); + + // Customize it + path = path.replace("$room_id", room_id); + path = path.replace("$user_id", config.user_id); + + return doRequest("PUT", path, undefined, { + membership: "join" + }); + }, + + // Invite a user to a room + invite: function(room_id, user_id) { + // The REST path spec + var path = "/rooms/$room_id/members/$user_id/state"; + + // Like the cmd client, escape room ids + room_id = encodeURIComponent(room_id); + + // Customize it + path = path.replace("$room_id", room_id); + path = path.replace("$user_id", user_id); + + return doRequest("PUT", path, undefined, { + membership: "invite" + }); + }, + + // Leaves a room + leave: function(room_id) { + // The REST path spec + var path = "/rooms/$room_id/members/$user_id/state"; + + // Like the cmd client, escape room ids + room_id = encodeURIComponent(room_id); + + // Customize it + path = path.replace("$room_id", room_id); + path = path.replace("$user_id", config.user_id); + + return doRequest("DELETE", path, undefined, undefined); + }, + + sendMessage: function(room_id, msg_id, content) { + // The REST path spec + var path = "/rooms/$room_id/messages/$from/$msg_id"; + + if (!msg_id) { + msg_id = "m" + new Date().getTime(); + } + + // Like the cmd client, escape room ids + room_id = encodeURIComponent(room_id); + + // Customize it + path = path.replace("$room_id", room_id); + path = path.replace("$from", config.user_id); + path = path.replace("$msg_id", msg_id); + + return doRequest("PUT", path, undefined, content); + }, + + // Send a text message + sendTextMessage: function(room_id, body, msg_id) { + var content = { + msgtype: "m.text", + body: body + }; + + return this.sendMessage(room_id, msg_id, content); + }, + + // Send an emote message + sendEmoteMessage: function(room_id, body, msg_id) { + var content = { + msgtype: "m.emote", + body: body + }; + + return this.sendMessage(room_id, msg_id, content); + }, + + // get a snapshot of the members in a room. + getMemberList: function(room_id) { + // Like the cmd client, escape room ids + room_id = encodeURIComponent(room_id); + + var path = "/rooms/$room_id/members/list"; + path = path.replace("$room_id", room_id); + return doRequest("GET", path); + }, + + // get a list of public rooms on your home server + publicRooms: function() { + var path = "/public/rooms" + return doRequest("GET", path); + }, + + // get a display name for this user ID + getDisplayName: function(userId) { + return this.getProfileInfo(userId, "displayname"); + }, + + // get the profile picture url for this user ID + getProfilePictureUrl: function(userId) { + return this.getProfileInfo(userId, "avatar_url"); + }, + + // update your display name + setDisplayName: function(newName) { + var content = { + displayname: newName + }; + return this.setProfileInfo(content, "displayname"); + }, + + // update your profile picture url + setProfilePictureUrl: function(newUrl) { + var content = { + avatar_url: newUrl + }; + return this.setProfileInfo(content, "avatar_url"); + }, + + setProfileInfo: function(data, info_segment) { + var path = "/profile/$user/" + info_segment; + path = path.replace("$user", config.user_id); + return doRequest("PUT", path, undefined, data); + }, + + getProfileInfo: function(userId, info_segment) { + var path = "/profile/$user_id/" + info_segment; + path = path.replace("$user_id", userId); + return doRequest("GET", path); + }, + + login: function(userId, password) { + // TODO We should be checking to make sure the client can support + // logging in to this HS, else use the fallback. + var path = "/login"; + var data = { + "type": "m.login.password", + "user": userId, + "password": password + }; + return doRequest("POST", path, undefined, data); + }, + + // hit the Identity Server for a 3PID request. + linkEmail: function(email) { + var path = "/matrix/identity/api/v1/validate/email/requestToken" + var data = "clientSecret=abc123&email=" + encodeURIComponent(email); + var headers = {}; + headers["Content-Type"] = "application/x-www-form-urlencoded"; + return doBaseRequest(config.identityServer, "POST", path, {}, data, headers); + }, + + authEmail: function(userId, tokenId, code) { + var path = "/matrix/identity/api/v1/validate/email/submitToken"; + var data = "token="+code+"&mxId="+encodeURIComponent(userId)+"&tokenId="+tokenId; + var headers = {}; + headers["Content-Type"] = "application/x-www-form-urlencoded"; + return doBaseRequest(config.identityServer, "POST", path, {}, data, headers); + }, + + /****** Permanent storage of user information ******/ + + // Returns the current config + config: function() { + if (!config) { + config = localStorage.getItem("config"); + if (config) { + config = JSON.parse(config); + + // Reset the cache if the version loaded is not the expected one + if (configVersion !== config.version) { + config = undefined; + this.saveConfig(); + } + } + } + return config; + }, + + // Set a new config (Use saveConfig to actually store it permanently) + setConfig: function(newConfig) { + config = newConfig; + }, + + // Commits config into permanent storage + saveConfig: function() { + config.version = configVersion; + localStorage.setItem("config", JSON.stringify(config)); + }, + + createRoomIdToAliasMapping: function(roomId, alias) { + localStorage.setItem(MAPPING_PREFIX+roomId, alias); + }, + + getRoomIdToAliasMapping: function(roomId) { + return localStorage.getItem(MAPPING_PREFIX+roomId); + } + + }; +}]); |