1 | /*
|
2 | Copyright 2015, 2016 OpenMarket Ltd
|
3 | Copyright 2017 Vector Creations Ltd
|
4 | Copyright 2019 The Matrix.org Foundation C.I.C.
|
5 | Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
6 |
|
7 | Licensed under the Apache License, Version 2.0 (the "License");
|
8 | you may not use this file except in compliance with the License.
|
9 | You may obtain a copy of the License at
|
10 |
|
11 | http://www.apache.org/licenses/LICENSE-2.0
|
12 |
|
13 | Unless required by applicable law or agreed to in writing, software
|
14 | distributed under the License is distributed on an "AS IS" BASIS,
|
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16 | See the License for the specific language governing permissions and
|
17 | limitations under the License.
|
18 | */
|
19 |
|
20 | /**
|
21 | * This is an internal module. MatrixBaseApis is currently only meant to be used
|
22 | * by {@link client~MatrixClient}.
|
23 | *
|
24 | * @module base-apis
|
25 | */
|
26 |
|
27 | import {SERVICE_TYPES} from './service-types';
|
28 | import {logger} from './logger';
|
29 | import {PushProcessor} from "./pushprocessor";
|
30 | import * as utils from "./utils";
|
31 | import {MatrixHttpApi, PREFIX_IDENTITY_V2, PREFIX_R0, PREFIX_UNSTABLE} from "./http-api";
|
32 |
|
33 | function termsUrlForService(serviceType, baseUrl) {
|
34 | switch (serviceType) {
|
35 | case SERVICE_TYPES.IS:
|
36 | return baseUrl + PREFIX_IDENTITY_V2 + '/terms';
|
37 | case SERVICE_TYPES.IM:
|
38 | return baseUrl + '/_matrix/integrations/v1/terms';
|
39 | default:
|
40 | throw new Error('Unsupported service type');
|
41 | }
|
42 | }
|
43 |
|
44 | /**
|
45 | * Low-level wrappers for the Matrix APIs
|
46 | *
|
47 | * @constructor
|
48 | *
|
49 | * @param {Object} opts Configuration options
|
50 | *
|
51 | * @param {string} opts.baseUrl Required. The base URL to the client-server
|
52 | * HTTP API.
|
53 | *
|
54 | * @param {string} opts.idBaseUrl Optional. The base identity server URL for
|
55 | * identity server requests.
|
56 | *
|
57 | * @param {Function} opts.request Required. The function to invoke for HTTP
|
58 | * requests. The value of this property is typically <code>require("request")
|
59 | * </code> as it returns a function which meets the required interface. See
|
60 | * {@link requestFunction} for more information.
|
61 | *
|
62 | * @param {string} opts.accessToken The access_token for this user.
|
63 | *
|
64 | * @param {IdentityServerProvider} [opts.identityServer]
|
65 | * Optional. A provider object with one function `getAccessToken`, which is a
|
66 | * callback that returns a Promise<String> of an identity access token to supply
|
67 | * with identity requests. If the object is unset, no access token will be
|
68 | * supplied.
|
69 | * See also https://github.com/vector-im/riot-web/issues/10615 which seeks to
|
70 | * replace the previous approach of manual access tokens params with this
|
71 | * callback throughout the SDK.
|
72 | *
|
73 | * @param {Number=} opts.localTimeoutMs Optional. The default maximum amount of
|
74 | * time to wait before timing out HTTP requests. If not specified, there is no
|
75 | * timeout.
|
76 | *
|
77 | * @param {Object} opts.queryParams Optional. Extra query parameters to append
|
78 | * to all requests with this client. Useful for application services which require
|
79 | * <code>?user_id=</code>.
|
80 | *
|
81 | * @param {boolean} [opts.useAuthorizationHeader = false] Set to true to use
|
82 | * Authorization header instead of query param to send the access token to the server.
|
83 | */
|
84 | export function MatrixBaseApis(opts) {
|
85 | utils.checkObjectHasKeys(opts, ["baseUrl", "request"]);
|
86 |
|
87 | this.baseUrl = opts.baseUrl;
|
88 | this.idBaseUrl = opts.idBaseUrl;
|
89 | this.identityServer = opts.identityServer;
|
90 |
|
91 | const httpOpts = {
|
92 | baseUrl: opts.baseUrl,
|
93 | idBaseUrl: opts.idBaseUrl,
|
94 | accessToken: opts.accessToken,
|
95 | request: opts.request,
|
96 | prefix: PREFIX_R0,
|
97 | onlyData: true,
|
98 | extraParams: opts.queryParams,
|
99 | localTimeoutMs: opts.localTimeoutMs,
|
100 | useAuthorizationHeader: opts.useAuthorizationHeader,
|
101 | };
|
102 | this._http = new MatrixHttpApi(this, httpOpts);
|
103 |
|
104 | this._txnCtr = 0;
|
105 | }
|
106 |
|
107 | /**
|
108 | * Get the Homeserver URL of this client
|
109 | * @return {string} Homeserver URL of this client
|
110 | */
|
111 | MatrixBaseApis.prototype.getHomeserverUrl = function() {
|
112 | return this.baseUrl;
|
113 | };
|
114 |
|
115 | /**
|
116 | * Get the Identity Server URL of this client
|
117 | * @param {boolean} stripProto whether or not to strip the protocol from the URL
|
118 | * @return {string} Identity Server URL of this client
|
119 | */
|
120 | MatrixBaseApis.prototype.getIdentityServerUrl = function(stripProto=false) {
|
121 | if (stripProto && (this.idBaseUrl.startsWith("http://") ||
|
122 | this.idBaseUrl.startsWith("https://"))) {
|
123 | return this.idBaseUrl.split("://")[1];
|
124 | }
|
125 | return this.idBaseUrl;
|
126 | };
|
127 |
|
128 | /**
|
129 | * Set the Identity Server URL of this client
|
130 | * @param {string} url New Identity Server URL
|
131 | */
|
132 | MatrixBaseApis.prototype.setIdentityServerUrl = function(url) {
|
133 | this.idBaseUrl = utils.ensureNoTrailingSlash(url);
|
134 | this._http.setIdBaseUrl(this.idBaseUrl);
|
135 | };
|
136 |
|
137 | /**
|
138 | * Get the access token associated with this account.
|
139 | * @return {?String} The access_token or null
|
140 | */
|
141 | MatrixBaseApis.prototype.getAccessToken = function() {
|
142 | return this._http.opts.accessToken || null;
|
143 | };
|
144 |
|
145 | /**
|
146 | * @return {boolean} true if there is a valid access_token for this client.
|
147 | */
|
148 | MatrixBaseApis.prototype.isLoggedIn = function() {
|
149 | return this._http.opts.accessToken !== undefined;
|
150 | };
|
151 |
|
152 | /**
|
153 | * Make up a new transaction id
|
154 | *
|
155 | * @return {string} a new, unique, transaction id
|
156 | */
|
157 | MatrixBaseApis.prototype.makeTxnId = function() {
|
158 | return "m" + new Date().getTime() + "." + (this._txnCtr++);
|
159 | };
|
160 |
|
161 |
|
162 | // Registration/Login operations
|
163 | // =============================
|
164 |
|
165 | /**
|
166 | * Check whether a username is available prior to registration. An error response
|
167 | * indicates an invalid/unavailable username.
|
168 | * @param {string} username The username to check the availability of.
|
169 | * @return {Promise} Resolves: to `true`.
|
170 | */
|
171 | MatrixBaseApis.prototype.isUsernameAvailable = function(username) {
|
172 | return this._http.authedRequest(
|
173 | undefined, "GET", '/register/available', { username: username },
|
174 | ).then((response) => {
|
175 | return response.available;
|
176 | });
|
177 | };
|
178 |
|
179 | /**
|
180 | * @param {string} username
|
181 | * @param {string} password
|
182 | * @param {string} sessionId
|
183 | * @param {Object} auth
|
184 | * @param {Object} bindThreepids Set key 'email' to true to bind any email
|
185 | * threepid uses during registration in the ID server. Set 'msisdn' to
|
186 | * true to bind msisdn.
|
187 | * @param {string} guestAccessToken
|
188 | * @param {string} inhibitLogin
|
189 | * @param {module:client.callback} callback Optional.
|
190 | * @return {Promise} Resolves: TODO
|
191 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
192 | */
|
193 | MatrixBaseApis.prototype.register = function(
|
194 | username, password,
|
195 | sessionId, auth, bindThreepids, guestAccessToken, inhibitLogin,
|
196 | callback,
|
197 | ) {
|
198 | // backwards compat
|
199 | if (bindThreepids === true) {
|
200 | bindThreepids = {email: true};
|
201 | } else if (bindThreepids === null || bindThreepids === undefined) {
|
202 | bindThreepids = {};
|
203 | }
|
204 | if (typeof inhibitLogin === 'function') {
|
205 | callback = inhibitLogin;
|
206 | inhibitLogin = undefined;
|
207 | }
|
208 |
|
209 | if (auth === undefined || auth === null) {
|
210 | auth = {};
|
211 | }
|
212 | if (sessionId) {
|
213 | auth.session = sessionId;
|
214 | }
|
215 |
|
216 | const params = {
|
217 | auth: auth,
|
218 | };
|
219 | if (username !== undefined && username !== null) {
|
220 | params.username = username;
|
221 | }
|
222 | if (password !== undefined && password !== null) {
|
223 | params.password = password;
|
224 | }
|
225 | if (bindThreepids.email) {
|
226 | params.bind_email = true;
|
227 | }
|
228 | if (bindThreepids.msisdn) {
|
229 | params.bind_msisdn = true;
|
230 | }
|
231 | if (guestAccessToken !== undefined && guestAccessToken !== null) {
|
232 | params.guest_access_token = guestAccessToken;
|
233 | }
|
234 | if (inhibitLogin !== undefined && inhibitLogin !== null) {
|
235 | params.inhibit_login = inhibitLogin;
|
236 | }
|
237 | // Temporary parameter added to make the register endpoint advertise
|
238 | // msisdn flows. This exists because there are clients that break
|
239 | // when given stages they don't recognise. This parameter will cease
|
240 | // to be necessary once these old clients are gone.
|
241 | // Only send it if we send any params at all (the password param is
|
242 | // mandatory, so if we send any params, we'll send the password param)
|
243 | if (password !== undefined && password !== null) {
|
244 | params.x_show_msisdn = true;
|
245 | }
|
246 |
|
247 | return this.registerRequest(params, undefined, callback);
|
248 | };
|
249 |
|
250 | /**
|
251 | * Register a guest account.
|
252 | * @param {Object=} opts Registration options
|
253 | * @param {Object} opts.body JSON HTTP body to provide.
|
254 | * @param {module:client.callback} callback Optional.
|
255 | * @return {Promise} Resolves: TODO
|
256 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
257 | */
|
258 | MatrixBaseApis.prototype.registerGuest = function(opts, callback) {
|
259 | opts = opts || {};
|
260 | opts.body = opts.body || {};
|
261 | return this.registerRequest(opts.body, "guest", callback);
|
262 | };
|
263 |
|
264 | /**
|
265 | * @param {Object} data parameters for registration request
|
266 | * @param {string=} kind type of user to register. may be "guest"
|
267 | * @param {module:client.callback=} callback
|
268 | * @return {Promise} Resolves: to the /register response
|
269 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
270 | */
|
271 | MatrixBaseApis.prototype.registerRequest = function(data, kind, callback) {
|
272 | const params = {};
|
273 | if (kind) {
|
274 | params.kind = kind;
|
275 | }
|
276 |
|
277 | return this._http.request(
|
278 | callback, "POST", "/register", params, data,
|
279 | );
|
280 | };
|
281 |
|
282 | /**
|
283 | * @param {module:client.callback} callback Optional.
|
284 | * @return {Promise} Resolves: TODO
|
285 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
286 | */
|
287 | MatrixBaseApis.prototype.loginFlows = function(callback) {
|
288 | return this._http.request(callback, "GET", "/login");
|
289 | };
|
290 |
|
291 | /**
|
292 | * @param {string} loginType
|
293 | * @param {Object} data
|
294 | * @param {module:client.callback} callback Optional.
|
295 | * @return {Promise} Resolves: TODO
|
296 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
297 | */
|
298 | MatrixBaseApis.prototype.login = function(loginType, data, callback) {
|
299 | const login_data = {
|
300 | type: loginType,
|
301 | };
|
302 |
|
303 | // merge data into login_data
|
304 | utils.extend(login_data, data);
|
305 |
|
306 | return this._http.authedRequest(
|
307 | (error, response) => {
|
308 | if (response && response.access_token && response.user_id) {
|
309 | this._http.opts.accessToken = response.access_token;
|
310 | this.credentials = {
|
311 | userId: response.user_id,
|
312 | };
|
313 | }
|
314 |
|
315 | if (callback) {
|
316 | callback(error, response);
|
317 | }
|
318 | }, "POST", "/login", undefined, login_data,
|
319 | );
|
320 | };
|
321 |
|
322 | /**
|
323 | * @param {string} user
|
324 | * @param {string} password
|
325 | * @param {module:client.callback} callback Optional.
|
326 | * @return {Promise} Resolves: TODO
|
327 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
328 | */
|
329 | MatrixBaseApis.prototype.loginWithPassword = function(user, password, callback) {
|
330 | return this.login("m.login.password", {
|
331 | user: user,
|
332 | password: password,
|
333 | }, callback);
|
334 | };
|
335 |
|
336 | /**
|
337 | * @param {string} relayState URL Callback after SAML2 Authentication
|
338 | * @param {module:client.callback} callback Optional.
|
339 | * @return {Promise} Resolves: TODO
|
340 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
341 | */
|
342 | MatrixBaseApis.prototype.loginWithSAML2 = function(relayState, callback) {
|
343 | return this.login("m.login.saml2", {
|
344 | relay_state: relayState,
|
345 | }, callback);
|
346 | };
|
347 |
|
348 | /**
|
349 | * @param {string} redirectUrl The URL to redirect to after the HS
|
350 | * authenticates with CAS.
|
351 | * @return {string} The HS URL to hit to begin the CAS login process.
|
352 | */
|
353 | MatrixBaseApis.prototype.getCasLoginUrl = function(redirectUrl) {
|
354 | return this.getSsoLoginUrl(redirectUrl, "cas");
|
355 | };
|
356 |
|
357 | /**
|
358 | * @param {string} redirectUrl The URL to redirect to after the HS
|
359 | * authenticates with the SSO.
|
360 | * @param {string} loginType The type of SSO login we are doing (sso or cas).
|
361 | * Defaults to 'sso'.
|
362 | * @return {string} The HS URL to hit to begin the SSO login process.
|
363 | */
|
364 | MatrixBaseApis.prototype.getSsoLoginUrl = function(redirectUrl, loginType) {
|
365 | if (loginType === undefined) {
|
366 | loginType = "sso";
|
367 | }
|
368 | return this._http.getUrl("/login/"+loginType+"/redirect", {
|
369 | "redirectUrl": redirectUrl,
|
370 | }, PREFIX_R0);
|
371 | };
|
372 |
|
373 | /**
|
374 | * @param {string} token Login token previously received from homeserver
|
375 | * @param {module:client.callback} callback Optional.
|
376 | * @return {Promise} Resolves: TODO
|
377 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
378 | */
|
379 | MatrixBaseApis.prototype.loginWithToken = function(token, callback) {
|
380 | return this.login("m.login.token", {
|
381 | token: token,
|
382 | }, callback);
|
383 | };
|
384 |
|
385 |
|
386 | /**
|
387 | * Logs out the current session.
|
388 | * Obviously, further calls that require authorisation should fail after this
|
389 | * method is called. The state of the MatrixClient object is not affected:
|
390 | * it is up to the caller to either reset or destroy the MatrixClient after
|
391 | * this method succeeds.
|
392 | * @param {module:client.callback} callback Optional.
|
393 | * @return {Promise} Resolves: On success, the empty object
|
394 | */
|
395 | MatrixBaseApis.prototype.logout = function(callback) {
|
396 | return this._http.authedRequest(
|
397 | callback, "POST", '/logout',
|
398 | );
|
399 | };
|
400 |
|
401 | /**
|
402 | * Deactivates the logged-in account.
|
403 | * Obviously, further calls that require authorisation should fail after this
|
404 | * method is called. The state of the MatrixClient object is not affected:
|
405 | * it is up to the caller to either reset or destroy the MatrixClient after
|
406 | * this method succeeds.
|
407 | * @param {object} auth Optional. Auth data to supply for User-Interactive auth.
|
408 | * @param {boolean} erase Optional. If set, send as `erase` attribute in the
|
409 | * JSON request body, indicating whether the account should be erased. Defaults
|
410 | * to false.
|
411 | * @return {Promise} Resolves: On success, the empty object
|
412 | */
|
413 | MatrixBaseApis.prototype.deactivateAccount = function(auth, erase) {
|
414 | if (typeof(erase) === 'function') {
|
415 | throw new Error(
|
416 | 'deactivateAccount no longer accepts a callback parameter',
|
417 | );
|
418 | }
|
419 |
|
420 | const body = {};
|
421 | if (auth) {
|
422 | body.auth = auth;
|
423 | }
|
424 | if (erase !== undefined) {
|
425 | body.erase = erase;
|
426 | }
|
427 |
|
428 | return this._http.authedRequest(
|
429 | undefined, "POST", '/account/deactivate', undefined, body,
|
430 | );
|
431 | };
|
432 |
|
433 | /**
|
434 | * Get the fallback URL to use for unknown interactive-auth stages.
|
435 | *
|
436 | * @param {string} loginType the type of stage being attempted
|
437 | * @param {string} authSessionId the auth session ID provided by the homeserver
|
438 | *
|
439 | * @return {string} HS URL to hit to for the fallback interface
|
440 | */
|
441 | MatrixBaseApis.prototype.getFallbackAuthUrl = function(loginType, authSessionId) {
|
442 | const path = utils.encodeUri("/auth/$loginType/fallback/web", {
|
443 | $loginType: loginType,
|
444 | });
|
445 |
|
446 | return this._http.getUrl(path, {
|
447 | session: authSessionId,
|
448 | }, PREFIX_R0);
|
449 | };
|
450 |
|
451 | // Room operations
|
452 | // ===============
|
453 |
|
454 | /**
|
455 | * Create a new room.
|
456 | * @param {Object} options a list of options to pass to the /createRoom API.
|
457 | * @param {string} options.room_alias_name The alias localpart to assign to
|
458 | * this room.
|
459 | * @param {string} options.visibility Either 'public' or 'private'.
|
460 | * @param {string[]} options.invite A list of user IDs to invite to this room.
|
461 | * @param {string} options.name The name to give this room.
|
462 | * @param {string} options.topic The topic to give this room.
|
463 | * @param {module:client.callback} callback Optional.
|
464 | * @return {Promise} Resolves: <code>{room_id: {string},
|
465 | * room_alias: {string(opt)}}</code>
|
466 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
467 | */
|
468 | MatrixBaseApis.prototype.createRoom = function(options, callback) {
|
469 | // valid options include: room_alias_name, visibility, invite
|
470 | return this._http.authedRequest(
|
471 | callback, "POST", "/createRoom", undefined, options,
|
472 | );
|
473 | };
|
474 | /**
|
475 | * Fetches relations for a given event
|
476 | * @param {string} roomId the room of the event
|
477 | * @param {string} eventId the id of the event
|
478 | * @param {string} relationType the rel_type of the relations requested
|
479 | * @param {string} eventType the event type of the relations requested
|
480 | * @param {Object} opts options with optional values for the request.
|
481 | * @param {Object} opts.from the pagination token returned from a previous request as `next_batch` to return following relations.
|
482 | * @return {Object} the response, with chunk and next_batch.
|
483 | */
|
484 | MatrixBaseApis.prototype.fetchRelations =
|
485 | async function(roomId, eventId, relationType, eventType, opts) {
|
486 | const queryParams = {};
|
487 | if (opts.from) {
|
488 | queryParams.from = opts.from;
|
489 | }
|
490 | const queryString = utils.encodeParams(queryParams);
|
491 | const path = utils.encodeUri(
|
492 | "/rooms/$roomId/relations/$eventId/$relationType/$eventType?" + queryString, {
|
493 | $roomId: roomId,
|
494 | $eventId: eventId,
|
495 | $relationType: relationType,
|
496 | $eventType: eventType,
|
497 | });
|
498 | const response = await this._http.authedRequest(
|
499 | undefined, "GET", path, null, null, {
|
500 | prefix: PREFIX_UNSTABLE,
|
501 | },
|
502 | );
|
503 | return response;
|
504 | };
|
505 |
|
506 | /**
|
507 | * @param {string} roomId
|
508 | * @param {module:client.callback} callback Optional.
|
509 | * @return {Promise} Resolves: TODO
|
510 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
511 | */
|
512 | MatrixBaseApis.prototype.roomState = function(roomId, callback) {
|
513 | const path = utils.encodeUri("/rooms/$roomId/state", {$roomId: roomId});
|
514 | return this._http.authedRequest(callback, "GET", path);
|
515 | };
|
516 |
|
517 | /**
|
518 | * Get an event in a room by its event id.
|
519 | * @param {string} roomId
|
520 | * @param {string} eventId
|
521 | * @param {module:client.callback} callback Optional.
|
522 | *
|
523 | * @return {Promise} Resolves to an object containing the event.
|
524 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
525 | */
|
526 | MatrixBaseApis.prototype.fetchRoomEvent = function(roomId, eventId, callback) {
|
527 | const path = utils.encodeUri(
|
528 | "/rooms/$roomId/event/$eventId", {
|
529 | $roomId: roomId,
|
530 | $eventId: eventId,
|
531 | },
|
532 | );
|
533 | return this._http.authedRequest(callback, "GET", path);
|
534 | };
|
535 |
|
536 | /**
|
537 | * @param {string} roomId
|
538 | * @param {string} includeMembership the membership type to include in the response
|
539 | * @param {string} excludeMembership the membership type to exclude from the response
|
540 | * @param {string} atEventId the id of the event for which moment in the timeline the members should be returned for
|
541 | * @param {module:client.callback} callback Optional.
|
542 | * @return {Promise} Resolves: dictionary of userid to profile information
|
543 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
544 | */
|
545 | MatrixBaseApis.prototype.members =
|
546 | function(roomId, includeMembership, excludeMembership, atEventId, callback) {
|
547 | const queryParams = {};
|
548 | if (includeMembership) {
|
549 | queryParams.membership = includeMembership;
|
550 | }
|
551 | if (excludeMembership) {
|
552 | queryParams.not_membership = excludeMembership;
|
553 | }
|
554 | if (atEventId) {
|
555 | queryParams.at = atEventId;
|
556 | }
|
557 |
|
558 | const queryString = utils.encodeParams(queryParams);
|
559 |
|
560 | const path = utils.encodeUri("/rooms/$roomId/members?" + queryString,
|
561 | {$roomId: roomId});
|
562 | return this._http.authedRequest(callback, "GET", path);
|
563 | };
|
564 |
|
565 | /**
|
566 | * Upgrades a room to a new protocol version
|
567 | * @param {string} roomId
|
568 | * @param {string} newVersion The target version to upgrade to
|
569 | * @return {Promise} Resolves: Object with key 'replacement_room'
|
570 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
571 | */
|
572 | MatrixBaseApis.prototype.upgradeRoom = function(roomId, newVersion) {
|
573 | const path = utils.encodeUri("/rooms/$roomId/upgrade", {$roomId: roomId});
|
574 | return this._http.authedRequest(
|
575 | undefined, "POST", path, undefined, {new_version: newVersion},
|
576 | );
|
577 | };
|
578 |
|
579 |
|
580 | /**
|
581 | * @param {string} groupId
|
582 | * @return {Promise} Resolves: Group summary object
|
583 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
584 | */
|
585 | MatrixBaseApis.prototype.getGroupSummary = function(groupId) {
|
586 | const path = utils.encodeUri("/groups/$groupId/summary", {$groupId: groupId});
|
587 | return this._http.authedRequest(undefined, "GET", path);
|
588 | };
|
589 |
|
590 | /**
|
591 | * @param {string} groupId
|
592 | * @return {Promise} Resolves: Group profile object
|
593 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
594 | */
|
595 | MatrixBaseApis.prototype.getGroupProfile = function(groupId) {
|
596 | const path = utils.encodeUri("/groups/$groupId/profile", {$groupId: groupId});
|
597 | return this._http.authedRequest(undefined, "GET", path);
|
598 | };
|
599 |
|
600 | /**
|
601 | * @param {string} groupId
|
602 | * @param {Object} profile The group profile object
|
603 | * @param {string=} profile.name Name of the group
|
604 | * @param {string=} profile.avatar_url MXC avatar URL
|
605 | * @param {string=} profile.short_description A short description of the room
|
606 | * @param {string=} profile.long_description A longer HTML description of the room
|
607 | * @return {Promise} Resolves: Empty object
|
608 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
609 | */
|
610 | MatrixBaseApis.prototype.setGroupProfile = function(groupId, profile) {
|
611 | const path = utils.encodeUri("/groups/$groupId/profile", {$groupId: groupId});
|
612 | return this._http.authedRequest(
|
613 | undefined, "POST", path, undefined, profile,
|
614 | );
|
615 | };
|
616 |
|
617 | /**
|
618 | * @param {string} groupId
|
619 | * @param {object} policy The join policy for the group. Must include at
|
620 | * least a 'type' field which is 'open' if anyone can join the group
|
621 | * the group without prior approval, or 'invite' if an invite is
|
622 | * required to join.
|
623 | * @return {Promise} Resolves: Empty object
|
624 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
625 | */
|
626 | MatrixBaseApis.prototype.setGroupJoinPolicy = function(groupId, policy) {
|
627 | const path = utils.encodeUri(
|
628 | "/groups/$groupId/settings/m.join_policy",
|
629 | {$groupId: groupId},
|
630 | );
|
631 | return this._http.authedRequest(
|
632 | undefined, "PUT", path, undefined, {
|
633 | 'm.join_policy': policy,
|
634 | },
|
635 | );
|
636 | };
|
637 |
|
638 | /**
|
639 | * @param {string} groupId
|
640 | * @return {Promise} Resolves: Group users list object
|
641 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
642 | */
|
643 | MatrixBaseApis.prototype.getGroupUsers = function(groupId) {
|
644 | const path = utils.encodeUri("/groups/$groupId/users", {$groupId: groupId});
|
645 | return this._http.authedRequest(undefined, "GET", path);
|
646 | };
|
647 |
|
648 | /**
|
649 | * @param {string} groupId
|
650 | * @return {Promise} Resolves: Group users list object
|
651 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
652 | */
|
653 | MatrixBaseApis.prototype.getGroupInvitedUsers = function(groupId) {
|
654 | const path = utils.encodeUri("/groups/$groupId/invited_users", {$groupId: groupId});
|
655 | return this._http.authedRequest(undefined, "GET", path);
|
656 | };
|
657 |
|
658 | /**
|
659 | * @param {string} groupId
|
660 | * @return {Promise} Resolves: Group rooms list object
|
661 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
662 | */
|
663 | MatrixBaseApis.prototype.getGroupRooms = function(groupId) {
|
664 | const path = utils.encodeUri("/groups/$groupId/rooms", {$groupId: groupId});
|
665 | return this._http.authedRequest(undefined, "GET", path);
|
666 | };
|
667 |
|
668 | /**
|
669 | * @param {string} groupId
|
670 | * @param {string} userId
|
671 | * @return {Promise} Resolves: Empty object
|
672 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
673 | */
|
674 | MatrixBaseApis.prototype.inviteUserToGroup = function(groupId, userId) {
|
675 | const path = utils.encodeUri(
|
676 | "/groups/$groupId/admin/users/invite/$userId",
|
677 | {$groupId: groupId, $userId: userId},
|
678 | );
|
679 | return this._http.authedRequest(undefined, "PUT", path, undefined, {});
|
680 | };
|
681 |
|
682 | /**
|
683 | * @param {string} groupId
|
684 | * @param {string} userId
|
685 | * @return {Promise} Resolves: Empty object
|
686 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
687 | */
|
688 | MatrixBaseApis.prototype.removeUserFromGroup = function(groupId, userId) {
|
689 | const path = utils.encodeUri(
|
690 | "/groups/$groupId/admin/users/remove/$userId",
|
691 | {$groupId: groupId, $userId: userId},
|
692 | );
|
693 | return this._http.authedRequest(undefined, "PUT", path, undefined, {});
|
694 | };
|
695 |
|
696 | /**
|
697 | * @param {string} groupId
|
698 | * @param {string} userId
|
699 | * @param {string} roleId Optional.
|
700 | * @return {Promise} Resolves: Empty object
|
701 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
702 | */
|
703 | MatrixBaseApis.prototype.addUserToGroupSummary = function(groupId, userId, roleId) {
|
704 | const path = utils.encodeUri(
|
705 | roleId ?
|
706 | "/groups/$groupId/summary/$roleId/users/$userId" :
|
707 | "/groups/$groupId/summary/users/$userId",
|
708 | {$groupId: groupId, $roleId: roleId, $userId: userId},
|
709 | );
|
710 | return this._http.authedRequest(undefined, "PUT", path, undefined, {});
|
711 | };
|
712 |
|
713 | /**
|
714 | * @param {string} groupId
|
715 | * @param {string} userId
|
716 | * @return {Promise} Resolves: Empty object
|
717 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
718 | */
|
719 | MatrixBaseApis.prototype.removeUserFromGroupSummary = function(groupId, userId) {
|
720 | const path = utils.encodeUri(
|
721 | "/groups/$groupId/summary/users/$userId",
|
722 | {$groupId: groupId, $userId: userId},
|
723 | );
|
724 | return this._http.authedRequest(undefined, "DELETE", path, undefined, {});
|
725 | };
|
726 |
|
727 | /**
|
728 | * @param {string} groupId
|
729 | * @param {string} roomId
|
730 | * @param {string} categoryId Optional.
|
731 | * @return {Promise} Resolves: Empty object
|
732 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
733 | */
|
734 | MatrixBaseApis.prototype.addRoomToGroupSummary = function(groupId, roomId, categoryId) {
|
735 | const path = utils.encodeUri(
|
736 | categoryId ?
|
737 | "/groups/$groupId/summary/$categoryId/rooms/$roomId" :
|
738 | "/groups/$groupId/summary/rooms/$roomId",
|
739 | {$groupId: groupId, $categoryId: categoryId, $roomId: roomId},
|
740 | );
|
741 | return this._http.authedRequest(undefined, "PUT", path, undefined, {});
|
742 | };
|
743 |
|
744 | /**
|
745 | * @param {string} groupId
|
746 | * @param {string} roomId
|
747 | * @return {Promise} Resolves: Empty object
|
748 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
749 | */
|
750 | MatrixBaseApis.prototype.removeRoomFromGroupSummary = function(groupId, roomId) {
|
751 | const path = utils.encodeUri(
|
752 | "/groups/$groupId/summary/rooms/$roomId",
|
753 | {$groupId: groupId, $roomId: roomId},
|
754 | );
|
755 | return this._http.authedRequest(undefined, "DELETE", path, undefined, {});
|
756 | };
|
757 |
|
758 | /**
|
759 | * @param {string} groupId
|
760 | * @param {string} roomId
|
761 | * @param {bool} isPublic Whether the room-group association is visible to non-members
|
762 | * @return {Promise} Resolves: Empty object
|
763 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
764 | */
|
765 | MatrixBaseApis.prototype.addRoomToGroup = function(groupId, roomId, isPublic) {
|
766 | if (isPublic === undefined) {
|
767 | isPublic = true;
|
768 | }
|
769 | const path = utils.encodeUri(
|
770 | "/groups/$groupId/admin/rooms/$roomId",
|
771 | {$groupId: groupId, $roomId: roomId},
|
772 | );
|
773 | return this._http.authedRequest(undefined, "PUT", path, undefined,
|
774 | { "m.visibility": { type: isPublic ? "public" : "private" } },
|
775 | );
|
776 | };
|
777 |
|
778 | /**
|
779 | * Configure the visibility of a room-group association.
|
780 | * @param {string} groupId
|
781 | * @param {string} roomId
|
782 | * @param {bool} isPublic Whether the room-group association is visible to non-members
|
783 | * @return {Promise} Resolves: Empty object
|
784 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
785 | */
|
786 | MatrixBaseApis.prototype.updateGroupRoomVisibility = function(groupId, roomId, isPublic) {
|
787 | // NB: The /config API is generic but there's not much point in exposing this yet as synapse
|
788 | // is the only server to implement this. In future we should consider an API that allows
|
789 | // arbitrary configuration, i.e. "config/$configKey".
|
790 |
|
791 | const path = utils.encodeUri(
|
792 | "/groups/$groupId/admin/rooms/$roomId/config/m.visibility",
|
793 | {$groupId: groupId, $roomId: roomId},
|
794 | );
|
795 | return this._http.authedRequest(undefined, "PUT", path, undefined,
|
796 | { type: isPublic ? "public" : "private" },
|
797 | );
|
798 | };
|
799 |
|
800 | /**
|
801 | * @param {string} groupId
|
802 | * @param {string} roomId
|
803 | * @return {Promise} Resolves: Empty object
|
804 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
805 | */
|
806 | MatrixBaseApis.prototype.removeRoomFromGroup = function(groupId, roomId) {
|
807 | const path = utils.encodeUri(
|
808 | "/groups/$groupId/admin/rooms/$roomId",
|
809 | {$groupId: groupId, $roomId: roomId},
|
810 | );
|
811 | return this._http.authedRequest(undefined, "DELETE", path, undefined, {});
|
812 | };
|
813 |
|
814 | /**
|
815 | * @param {string} groupId
|
816 | * @param {Object} opts Additional options to send alongside the acceptance.
|
817 | * @return {Promise} Resolves: Empty object
|
818 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
819 | */
|
820 | MatrixBaseApis.prototype.acceptGroupInvite = function(groupId, opts = null) {
|
821 | const path = utils.encodeUri(
|
822 | "/groups/$groupId/self/accept_invite",
|
823 | {$groupId: groupId},
|
824 | );
|
825 | return this._http.authedRequest(undefined, "PUT", path, undefined, opts || {});
|
826 | };
|
827 |
|
828 | /**
|
829 | * @param {string} groupId
|
830 | * @return {Promise} Resolves: Empty object
|
831 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
832 | */
|
833 | MatrixBaseApis.prototype.joinGroup = function(groupId) {
|
834 | const path = utils.encodeUri(
|
835 | "/groups/$groupId/self/join",
|
836 | {$groupId: groupId},
|
837 | );
|
838 | return this._http.authedRequest(undefined, "PUT", path, undefined, {});
|
839 | };
|
840 |
|
841 | /**
|
842 | * @param {string} groupId
|
843 | * @return {Promise} Resolves: Empty object
|
844 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
845 | */
|
846 | MatrixBaseApis.prototype.leaveGroup = function(groupId) {
|
847 | const path = utils.encodeUri(
|
848 | "/groups/$groupId/self/leave",
|
849 | {$groupId: groupId},
|
850 | );
|
851 | return this._http.authedRequest(undefined, "PUT", path, undefined, {});
|
852 | };
|
853 |
|
854 | /**
|
855 | * @return {Promise} Resolves: The groups to which the user is joined
|
856 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
857 | */
|
858 | MatrixBaseApis.prototype.getJoinedGroups = function() {
|
859 | const path = utils.encodeUri("/joined_groups");
|
860 | return this._http.authedRequest(undefined, "GET", path);
|
861 | };
|
862 |
|
863 | /**
|
864 | * @param {Object} content Request content
|
865 | * @param {string} content.localpart The local part of the desired group ID
|
866 | * @param {Object} content.profile Group profile object
|
867 | * @return {Promise} Resolves: Object with key group_id: id of the created group
|
868 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
869 | */
|
870 | MatrixBaseApis.prototype.createGroup = function(content) {
|
871 | const path = utils.encodeUri("/create_group");
|
872 | return this._http.authedRequest(
|
873 | undefined, "POST", path, undefined, content,
|
874 | );
|
875 | };
|
876 |
|
877 | /**
|
878 | * @param {string[]} userIds List of user IDs
|
879 | * @return {Promise} Resolves: Object as exmaple below
|
880 | *
|
881 | * {
|
882 | * "users": {
|
883 | * "@bob:example.com": {
|
884 | * "+example:example.com"
|
885 | * }
|
886 | * }
|
887 | * }
|
888 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
889 | */
|
890 | MatrixBaseApis.prototype.getPublicisedGroups = function(userIds) {
|
891 | const path = utils.encodeUri("/publicised_groups");
|
892 | return this._http.authedRequest(
|
893 | undefined, "POST", path, undefined, { user_ids: userIds },
|
894 | );
|
895 | };
|
896 |
|
897 | /**
|
898 | * @param {string} groupId
|
899 | * @param {bool} isPublic Whether the user's membership of this group is made public
|
900 | * @return {Promise} Resolves: Empty object
|
901 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
902 | */
|
903 | MatrixBaseApis.prototype.setGroupPublicity = function(groupId, isPublic) {
|
904 | const path = utils.encodeUri(
|
905 | "/groups/$groupId/self/update_publicity",
|
906 | {$groupId: groupId},
|
907 | );
|
908 | return this._http.authedRequest(undefined, "PUT", path, undefined, {
|
909 | publicise: isPublic,
|
910 | });
|
911 | };
|
912 |
|
913 | /**
|
914 | * Retrieve a state event.
|
915 | * @param {string} roomId
|
916 | * @param {string} eventType
|
917 | * @param {string} stateKey
|
918 | * @param {module:client.callback} callback Optional.
|
919 | * @return {Promise} Resolves: TODO
|
920 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
921 | */
|
922 | MatrixBaseApis.prototype.getStateEvent = function(roomId, eventType, stateKey, callback) {
|
923 | const pathParams = {
|
924 | $roomId: roomId,
|
925 | $eventType: eventType,
|
926 | $stateKey: stateKey,
|
927 | };
|
928 | let path = utils.encodeUri("/rooms/$roomId/state/$eventType", pathParams);
|
929 | if (stateKey !== undefined) {
|
930 | path = utils.encodeUri(path + "/$stateKey", pathParams);
|
931 | }
|
932 | return this._http.authedRequest(
|
933 | callback, "GET", path,
|
934 | );
|
935 | };
|
936 |
|
937 | /**
|
938 | * @param {string} roomId
|
939 | * @param {string} eventType
|
940 | * @param {Object} content
|
941 | * @param {string} stateKey
|
942 | * @param {module:client.callback} callback Optional.
|
943 | * @return {Promise} Resolves: TODO
|
944 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
945 | */
|
946 | MatrixBaseApis.prototype.sendStateEvent = function(roomId, eventType, content, stateKey,
|
947 | callback) {
|
948 | const pathParams = {
|
949 | $roomId: roomId,
|
950 | $eventType: eventType,
|
951 | $stateKey: stateKey,
|
952 | };
|
953 | let path = utils.encodeUri("/rooms/$roomId/state/$eventType", pathParams);
|
954 | if (stateKey !== undefined) {
|
955 | path = utils.encodeUri(path + "/$stateKey", pathParams);
|
956 | }
|
957 | return this._http.authedRequest(
|
958 | callback, "PUT", path, undefined, content,
|
959 | );
|
960 | };
|
961 |
|
962 | /**
|
963 | * @param {string} roomId
|
964 | * @param {Number} limit
|
965 | * @param {module:client.callback} callback Optional.
|
966 | * @return {Promise} Resolves: TODO
|
967 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
968 | */
|
969 | MatrixBaseApis.prototype.roomInitialSync = function(roomId, limit, callback) {
|
970 | if (utils.isFunction(limit)) {
|
971 | callback = limit; limit = undefined;
|
972 | }
|
973 | const path = utils.encodeUri("/rooms/$roomId/initialSync",
|
974 | {$roomId: roomId},
|
975 | );
|
976 | if (!limit) {
|
977 | limit = 30;
|
978 | }
|
979 | return this._http.authedRequest(
|
980 | callback, "GET", path, { limit: limit },
|
981 | );
|
982 | };
|
983 |
|
984 | /**
|
985 | * Set a marker to indicate the point in a room before which the user has read every
|
986 | * event. This can be retrieved from room account data (the event type is `m.fully_read`)
|
987 | * and displayed as a horizontal line in the timeline that is visually distinct to the
|
988 | * position of the user's own read receipt.
|
989 | * @param {string} roomId ID of the room that has been read
|
990 | * @param {string} rmEventId ID of the event that has been read
|
991 | * @param {string} rrEventId ID of the event tracked by the read receipt. This is here
|
992 | * for convenience because the RR and the RM are commonly updated at the same time as
|
993 | * each other. Optional.
|
994 | * @param {object} opts Options for the read markers.
|
995 | * @param {object} opts.hidden True to hide the read receipt from other users. <b>This
|
996 | * property is currently unstable and may change in the future.</b>
|
997 | * @return {Promise} Resolves: the empty object, {}.
|
998 | */
|
999 | MatrixBaseApis.prototype.setRoomReadMarkersHttpRequest =
|
1000 | function(roomId, rmEventId, rrEventId, opts) {
|
1001 | const path = utils.encodeUri("/rooms/$roomId/read_markers", {
|
1002 | $roomId: roomId,
|
1003 | });
|
1004 |
|
1005 | const content = {
|
1006 | "m.fully_read": rmEventId,
|
1007 | "m.read": rrEventId,
|
1008 | "m.hidden": Boolean(opts ? opts.hidden : false),
|
1009 | };
|
1010 |
|
1011 | return this._http.authedRequest(
|
1012 | undefined, "POST", path, undefined, content,
|
1013 | );
|
1014 | };
|
1015 |
|
1016 | /**
|
1017 | * @return {Promise} Resolves: A list of the user's current rooms
|
1018 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1019 | */
|
1020 | MatrixBaseApis.prototype.getJoinedRooms = function() {
|
1021 | const path = utils.encodeUri("/joined_rooms");
|
1022 | return this._http.authedRequest(undefined, "GET", path);
|
1023 | };
|
1024 |
|
1025 | /**
|
1026 | * Retrieve membership info. for a room.
|
1027 | * @param {string} roomId ID of the room to get membership for
|
1028 | * @return {Promise} Resolves: A list of currently joined users
|
1029 | * and their profile data.
|
1030 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1031 | */
|
1032 | MatrixBaseApis.prototype.getJoinedRoomMembers = function(roomId) {
|
1033 | const path = utils.encodeUri("/rooms/$roomId/joined_members", {
|
1034 | $roomId: roomId,
|
1035 | });
|
1036 | return this._http.authedRequest(undefined, "GET", path);
|
1037 | };
|
1038 |
|
1039 | // Room Directory operations
|
1040 | // =========================
|
1041 |
|
1042 | /**
|
1043 | * @param {Object} options Options for this request
|
1044 | * @param {string} options.server The remote server to query for the room list.
|
1045 | * Optional. If unspecified, get the local home
|
1046 | * server's public room list.
|
1047 | * @param {number} options.limit Maximum number of entries to return
|
1048 | * @param {string} options.since Token to paginate from
|
1049 | * @param {object} options.filter Filter parameters
|
1050 | * @param {string} options.filter.generic_search_term String to search for
|
1051 | * @param {module:client.callback} callback Optional.
|
1052 | * @return {Promise} Resolves: TODO
|
1053 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1054 | */
|
1055 | MatrixBaseApis.prototype.publicRooms = function(options, callback) {
|
1056 | if (typeof(options) == 'function') {
|
1057 | callback = options;
|
1058 | options = {};
|
1059 | }
|
1060 | if (options === undefined) {
|
1061 | options = {};
|
1062 | }
|
1063 |
|
1064 | const query_params = {};
|
1065 | if (options.server) {
|
1066 | query_params.server = options.server;
|
1067 | delete options.server;
|
1068 | }
|
1069 |
|
1070 | if (Object.keys(options).length === 0 && Object.keys(query_params).length === 0) {
|
1071 | return this._http.authedRequest(callback, "GET", "/publicRooms");
|
1072 | } else {
|
1073 | return this._http.authedRequest(
|
1074 | callback, "POST", "/publicRooms", query_params, options,
|
1075 | );
|
1076 | }
|
1077 | };
|
1078 |
|
1079 | /**
|
1080 | * Create an alias to room ID mapping.
|
1081 | * @param {string} alias The room alias to create.
|
1082 | * @param {string} roomId The room ID to link the alias to.
|
1083 | * @param {module:client.callback} callback Optional.
|
1084 | * @return {Promise} Resolves: TODO.
|
1085 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1086 | */
|
1087 | MatrixBaseApis.prototype.createAlias = function(alias, roomId, callback) {
|
1088 | const path = utils.encodeUri("/directory/room/$alias", {
|
1089 | $alias: alias,
|
1090 | });
|
1091 | const data = {
|
1092 | room_id: roomId,
|
1093 | };
|
1094 | return this._http.authedRequest(
|
1095 | callback, "PUT", path, undefined, data,
|
1096 | );
|
1097 | };
|
1098 |
|
1099 | /**
|
1100 | * Delete an alias to room ID mapping. This alias must be on your local server
|
1101 | * and you must have sufficient access to do this operation.
|
1102 | * @param {string} alias The room alias to delete.
|
1103 | * @param {module:client.callback} callback Optional.
|
1104 | * @return {Promise} Resolves: TODO.
|
1105 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1106 | */
|
1107 | MatrixBaseApis.prototype.deleteAlias = function(alias, callback) {
|
1108 | const path = utils.encodeUri("/directory/room/$alias", {
|
1109 | $alias: alias,
|
1110 | });
|
1111 | return this._http.authedRequest(
|
1112 | callback, "DELETE", path, undefined, undefined,
|
1113 | );
|
1114 | };
|
1115 |
|
1116 | /**
|
1117 | * @param {string} roomId
|
1118 | * @param {module:client.callback} callback Optional.
|
1119 | * @return {Promise} Resolves: an object with an `aliases` property, containing an array of local aliases
|
1120 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1121 | */
|
1122 | MatrixBaseApis.prototype.unstableGetLocalAliases =
|
1123 | function(roomId, callback) {
|
1124 | const path = utils.encodeUri("/rooms/$roomId/aliases",
|
1125 | {$roomId: roomId});
|
1126 | const prefix = PREFIX_UNSTABLE + "/org.matrix.msc2432";
|
1127 | return this._http.authedRequest(callback, "GET", path,
|
1128 | null, null, { prefix });
|
1129 | };
|
1130 |
|
1131 | /**
|
1132 | * Get room info for the given alias.
|
1133 | * @param {string} alias The room alias to resolve.
|
1134 | * @param {module:client.callback} callback Optional.
|
1135 | * @return {Promise} Resolves: Object with room_id and servers.
|
1136 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1137 | */
|
1138 | MatrixBaseApis.prototype.getRoomIdForAlias = function(alias, callback) {
|
1139 | // TODO: deprecate this or resolveRoomAlias
|
1140 | const path = utils.encodeUri("/directory/room/$alias", {
|
1141 | $alias: alias,
|
1142 | });
|
1143 | return this._http.authedRequest(
|
1144 | callback, "GET", path,
|
1145 | );
|
1146 | };
|
1147 |
|
1148 | /**
|
1149 | * @param {string} roomAlias
|
1150 | * @param {module:client.callback} callback Optional.
|
1151 | * @return {Promise} Resolves: TODO
|
1152 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1153 | */
|
1154 | MatrixBaseApis.prototype.resolveRoomAlias = function(roomAlias, callback) {
|
1155 | // TODO: deprecate this or getRoomIdForAlias
|
1156 | const path = utils.encodeUri("/directory/room/$alias", {$alias: roomAlias});
|
1157 | return this._http.request(callback, "GET", path);
|
1158 | };
|
1159 |
|
1160 | /**
|
1161 | * Get the visibility of a room in the current HS's room directory
|
1162 | * @param {string} roomId
|
1163 | * @param {module:client.callback} callback Optional.
|
1164 | * @return {Promise} Resolves: TODO
|
1165 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1166 | */
|
1167 | MatrixBaseApis.prototype.getRoomDirectoryVisibility =
|
1168 | function(roomId, callback) {
|
1169 | const path = utils.encodeUri("/directory/list/room/$roomId", {
|
1170 | $roomId: roomId,
|
1171 | });
|
1172 | return this._http.authedRequest(callback, "GET", path);
|
1173 | };
|
1174 |
|
1175 | /**
|
1176 | * Set the visbility of a room in the current HS's room directory
|
1177 | * @param {string} roomId
|
1178 | * @param {string} visibility "public" to make the room visible
|
1179 | * in the public directory, or "private" to make
|
1180 | * it invisible.
|
1181 | * @param {module:client.callback} callback Optional.
|
1182 | * @return {Promise} Resolves: result object
|
1183 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1184 | */
|
1185 | MatrixBaseApis.prototype.setRoomDirectoryVisibility =
|
1186 | function(roomId, visibility, callback) {
|
1187 | const path = utils.encodeUri("/directory/list/room/$roomId", {
|
1188 | $roomId: roomId,
|
1189 | });
|
1190 | return this._http.authedRequest(
|
1191 | callback, "PUT", path, undefined, { "visibility": visibility },
|
1192 | );
|
1193 | };
|
1194 |
|
1195 | /**
|
1196 | * Set the visbility of a room bridged to a 3rd party network in
|
1197 | * the current HS's room directory.
|
1198 | * @param {string} networkId the network ID of the 3rd party
|
1199 | * instance under which this room is published under.
|
1200 | * @param {string} roomId
|
1201 | * @param {string} visibility "public" to make the room visible
|
1202 | * in the public directory, or "private" to make
|
1203 | * it invisible.
|
1204 | * @param {module:client.callback} callback Optional.
|
1205 | * @return {Promise} Resolves: result object
|
1206 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1207 | */
|
1208 | MatrixBaseApis.prototype.setRoomDirectoryVisibilityAppService =
|
1209 | function(networkId, roomId, visibility, callback) {
|
1210 | const path = utils.encodeUri("/directory/list/appservice/$networkId/$roomId", {
|
1211 | $networkId: networkId,
|
1212 | $roomId: roomId,
|
1213 | });
|
1214 | return this._http.authedRequest(
|
1215 | callback, "PUT", path, undefined, { "visibility": visibility },
|
1216 | );
|
1217 | };
|
1218 |
|
1219 | // User Directory Operations
|
1220 | // =========================
|
1221 |
|
1222 | /**
|
1223 | * Query the user directory with a term matching user IDs, display names and domains.
|
1224 | * @param {object} opts options
|
1225 | * @param {string} opts.term the term with which to search.
|
1226 | * @param {number} opts.limit the maximum number of results to return. The server will
|
1227 | * apply a limit if unspecified.
|
1228 | * @return {Promise} Resolves: an array of results.
|
1229 | */
|
1230 | MatrixBaseApis.prototype.searchUserDirectory = function(opts) {
|
1231 | const body = {
|
1232 | search_term: opts.term,
|
1233 | };
|
1234 |
|
1235 | if (opts.limit !== undefined) {
|
1236 | body.limit = opts.limit;
|
1237 | }
|
1238 |
|
1239 | return this._http.authedRequest(
|
1240 | undefined, "POST", "/user_directory/search", undefined, body,
|
1241 | );
|
1242 | };
|
1243 |
|
1244 |
|
1245 | // Media operations
|
1246 | // ================
|
1247 |
|
1248 | /**
|
1249 | * Upload a file to the media repository on the home server.
|
1250 | *
|
1251 | * @param {object} file The object to upload. On a browser, something that
|
1252 | * can be sent to XMLHttpRequest.send (typically a File). Under node.js,
|
1253 | * a a Buffer, String or ReadStream.
|
1254 | *
|
1255 | * @param {object} opts options object
|
1256 | *
|
1257 | * @param {string=} opts.name Name to give the file on the server. Defaults
|
1258 | * to <tt>file.name</tt>.
|
1259 | *
|
1260 | * @param {boolean=} opts.includeFilename if false will not send the filename,
|
1261 | * e.g for encrypted file uploads where filename leaks are undesirable.
|
1262 | * Defaults to true.
|
1263 | *
|
1264 | * @param {string=} opts.type Content-type for the upload. Defaults to
|
1265 | * <tt>file.type</tt>, or <tt>applicaton/octet-stream</tt>.
|
1266 | *
|
1267 | * @param {boolean=} opts.rawResponse Return the raw body, rather than
|
1268 | * parsing the JSON. Defaults to false (except on node.js, where it
|
1269 | * defaults to true for backwards compatibility).
|
1270 | *
|
1271 | * @param {boolean=} opts.onlyContentUri Just return the content URI,
|
1272 | * rather than the whole body. Defaults to false (except on browsers,
|
1273 | * where it defaults to true for backwards compatibility). Ignored if
|
1274 | * opts.rawResponse is true.
|
1275 | *
|
1276 | * @param {Function=} opts.callback Deprecated. Optional. The callback to
|
1277 | * invoke on success/failure. See the promise return values for more
|
1278 | * information.
|
1279 | *
|
1280 | * @param {Function=} opts.progressHandler Optional. Called when a chunk of
|
1281 | * data has been uploaded, with an object containing the fields `loaded`
|
1282 | * (number of bytes transferred) and `total` (total size, if known).
|
1283 | *
|
1284 | * @return {Promise} Resolves to response object, as
|
1285 | * determined by this.opts.onlyData, opts.rawResponse, and
|
1286 | * opts.onlyContentUri. Rejects with an error (usually a MatrixError).
|
1287 | */
|
1288 | MatrixBaseApis.prototype.uploadContent = function(file, opts) {
|
1289 | return this._http.uploadContent(file, opts);
|
1290 | };
|
1291 |
|
1292 | /**
|
1293 | * Cancel a file upload in progress
|
1294 | * @param {Promise} promise The promise returned from uploadContent
|
1295 | * @return {boolean} true if canceled, otherwise false
|
1296 | */
|
1297 | MatrixBaseApis.prototype.cancelUpload = function(promise) {
|
1298 | return this._http.cancelUpload(promise);
|
1299 | };
|
1300 |
|
1301 | /**
|
1302 | * Get a list of all file uploads in progress
|
1303 | * @return {array} Array of objects representing current uploads.
|
1304 | * Currently in progress is element 0. Keys:
|
1305 | * - promise: The promise associated with the upload
|
1306 | * - loaded: Number of bytes uploaded
|
1307 | * - total: Total number of bytes to upload
|
1308 | */
|
1309 | MatrixBaseApis.prototype.getCurrentUploads = function() {
|
1310 | return this._http.getCurrentUploads();
|
1311 | };
|
1312 |
|
1313 |
|
1314 | // Profile operations
|
1315 | // ==================
|
1316 |
|
1317 | /**
|
1318 | * @param {string} userId
|
1319 | * @param {string} info The kind of info to retrieve (e.g. 'displayname',
|
1320 | * 'avatar_url').
|
1321 | * @param {module:client.callback} callback Optional.
|
1322 | * @return {Promise} Resolves: TODO
|
1323 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1324 | */
|
1325 | MatrixBaseApis.prototype.getProfileInfo = function(userId, info, callback) {
|
1326 | if (utils.isFunction(info)) {
|
1327 | callback = info; info = undefined;
|
1328 | }
|
1329 |
|
1330 | const path = info ?
|
1331 | utils.encodeUri("/profile/$userId/$info",
|
1332 | { $userId: userId, $info: info }) :
|
1333 | utils.encodeUri("/profile/$userId",
|
1334 | { $userId: userId });
|
1335 | return this._http.authedRequest(callback, "GET", path);
|
1336 | };
|
1337 |
|
1338 |
|
1339 | // Account operations
|
1340 | // ==================
|
1341 |
|
1342 | /**
|
1343 | * @param {module:client.callback} callback Optional.
|
1344 | * @return {Promise} Resolves: TODO
|
1345 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1346 | */
|
1347 | MatrixBaseApis.prototype.getThreePids = function(callback) {
|
1348 | const path = "/account/3pid";
|
1349 | return this._http.authedRequest(
|
1350 | callback, "GET", path, undefined, undefined,
|
1351 | );
|
1352 | };
|
1353 |
|
1354 | /**
|
1355 | * Add a 3PID to your homeserver account and optionally bind it to an identity
|
1356 | * server as well. An identity server is required as part of the `creds` object.
|
1357 | *
|
1358 | * This API is deprecated, and you should instead use `addThreePidOnly`
|
1359 | * for homeservers that support it.
|
1360 | *
|
1361 | * @param {Object} creds
|
1362 | * @param {boolean} bind
|
1363 | * @param {module:client.callback} callback Optional.
|
1364 | * @return {Promise} Resolves: on success
|
1365 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1366 | */
|
1367 | MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) {
|
1368 | const path = "/account/3pid";
|
1369 | const data = {
|
1370 | 'threePidCreds': creds,
|
1371 | 'bind': bind,
|
1372 | };
|
1373 | return this._http.authedRequest(
|
1374 | callback, "POST", path, null, data,
|
1375 | );
|
1376 | };
|
1377 |
|
1378 | /**
|
1379 | * Add a 3PID to your homeserver account. This API does not use an identity
|
1380 | * server, as the homeserver is expected to handle 3PID ownership validation.
|
1381 | *
|
1382 | * You can check whether a homeserver supports this API via
|
1383 | * `doesServerSupportSeparateAddAndBind`.
|
1384 | *
|
1385 | * @param {Object} data A object with 3PID validation data from having called
|
1386 | * `account/3pid/<medium>/requestToken` on the homeserver.
|
1387 | * @return {Promise} Resolves: on success
|
1388 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1389 | */
|
1390 | MatrixBaseApis.prototype.addThreePidOnly = async function(data) {
|
1391 | const path = "/account/3pid/add";
|
1392 | const prefix = await this.isVersionSupported("r0.6.0") ?
|
1393 | PREFIX_R0 : PREFIX_UNSTABLE;
|
1394 | return this._http.authedRequest(
|
1395 | undefined, "POST", path, null, data, { prefix },
|
1396 | );
|
1397 | };
|
1398 |
|
1399 | /**
|
1400 | * Bind a 3PID for discovery onto an identity server via the homeserver. The
|
1401 | * identity server handles 3PID ownership validation and the homeserver records
|
1402 | * the new binding to track where all 3PIDs for the account are bound.
|
1403 | *
|
1404 | * You can check whether a homeserver supports this API via
|
1405 | * `doesServerSupportSeparateAddAndBind`.
|
1406 | *
|
1407 | * @param {Object} data A object with 3PID validation data from having called
|
1408 | * `validate/<medium>/requestToken` on the identity server. It should also
|
1409 | * contain `id_server` and `id_access_token` fields as well.
|
1410 | * @return {Promise} Resolves: on success
|
1411 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1412 | */
|
1413 | MatrixBaseApis.prototype.bindThreePid = async function(data) {
|
1414 | const path = "/account/3pid/bind";
|
1415 | const prefix = await this.isVersionSupported("r0.6.0") ?
|
1416 | PREFIX_R0 : PREFIX_UNSTABLE;
|
1417 | return this._http.authedRequest(
|
1418 | undefined, "POST", path, null, data, { prefix },
|
1419 | );
|
1420 | };
|
1421 |
|
1422 | /**
|
1423 | * Unbind a 3PID for discovery on an identity server via the homeserver. The
|
1424 | * homeserver removes its record of the binding to keep an updated record of
|
1425 | * where all 3PIDs for the account are bound.
|
1426 | *
|
1427 | * @param {string} medium The threepid medium (eg. 'email')
|
1428 | * @param {string} address The threepid address (eg. 'bob@example.com')
|
1429 | * this must be as returned by getThreePids.
|
1430 | * @return {Promise} Resolves: on success
|
1431 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1432 | */
|
1433 | MatrixBaseApis.prototype.unbindThreePid = async function(medium, address) {
|
1434 | const path = "/account/3pid/unbind";
|
1435 | const data = {
|
1436 | medium,
|
1437 | address,
|
1438 | id_server: this.getIdentityServerUrl(true),
|
1439 | };
|
1440 | const prefix = await this.isVersionSupported("r0.6.0") ?
|
1441 | PREFIX_R0 : PREFIX_UNSTABLE;
|
1442 | return this._http.authedRequest(
|
1443 | undefined, "POST", path, null, data, { prefix },
|
1444 | );
|
1445 | };
|
1446 |
|
1447 | /**
|
1448 | * @param {string} medium The threepid medium (eg. 'email')
|
1449 | * @param {string} address The threepid address (eg. 'bob@example.com')
|
1450 | * this must be as returned by getThreePids.
|
1451 | * @return {Promise} Resolves: The server response on success
|
1452 | * (generally the empty JSON object)
|
1453 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1454 | */
|
1455 | MatrixBaseApis.prototype.deleteThreePid = function(medium, address) {
|
1456 | const path = "/account/3pid/delete";
|
1457 | const data = {
|
1458 | 'medium': medium,
|
1459 | 'address': address,
|
1460 | };
|
1461 | return this._http.authedRequest(undefined, "POST", path, null, data);
|
1462 | };
|
1463 |
|
1464 | /**
|
1465 | * Make a request to change your password.
|
1466 | * @param {Object} authDict
|
1467 | * @param {string} newPassword The new desired password.
|
1468 | * @param {module:client.callback} callback Optional.
|
1469 | * @return {Promise} Resolves: TODO
|
1470 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1471 | */
|
1472 | MatrixBaseApis.prototype.setPassword = function(authDict, newPassword, callback) {
|
1473 | const path = "/account/password";
|
1474 | const data = {
|
1475 | 'auth': authDict,
|
1476 | 'new_password': newPassword,
|
1477 | };
|
1478 |
|
1479 | return this._http.authedRequest(
|
1480 | callback, "POST", path, null, data,
|
1481 | );
|
1482 | };
|
1483 |
|
1484 |
|
1485 | // Device operations
|
1486 | // =================
|
1487 |
|
1488 | /**
|
1489 | * Gets all devices recorded for the logged-in user
|
1490 | * @return {Promise} Resolves: result object
|
1491 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1492 | */
|
1493 | MatrixBaseApis.prototype.getDevices = function() {
|
1494 | return this._http.authedRequest(
|
1495 | undefined, 'GET', "/devices", undefined, undefined,
|
1496 | );
|
1497 | };
|
1498 |
|
1499 | /**
|
1500 | * Update the given device
|
1501 | *
|
1502 | * @param {string} device_id device to update
|
1503 | * @param {Object} body body of request
|
1504 | * @return {Promise} Resolves: result object
|
1505 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1506 | */
|
1507 | MatrixBaseApis.prototype.setDeviceDetails = function(device_id, body) {
|
1508 | const path = utils.encodeUri("/devices/$device_id", {
|
1509 | $device_id: device_id,
|
1510 | });
|
1511 |
|
1512 | return this._http.authedRequest(undefined, "PUT", path, undefined, body);
|
1513 | };
|
1514 |
|
1515 | /**
|
1516 | * Delete the given device
|
1517 | *
|
1518 | * @param {string} device_id device to delete
|
1519 | * @param {object} auth Optional. Auth data to supply for User-Interactive auth.
|
1520 | * @return {Promise} Resolves: result object
|
1521 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1522 | */
|
1523 | MatrixBaseApis.prototype.deleteDevice = function(device_id, auth) {
|
1524 | const path = utils.encodeUri("/devices/$device_id", {
|
1525 | $device_id: device_id,
|
1526 | });
|
1527 |
|
1528 | const body = {};
|
1529 |
|
1530 | if (auth) {
|
1531 | body.auth = auth;
|
1532 | }
|
1533 |
|
1534 | return this._http.authedRequest(undefined, "DELETE", path, undefined, body);
|
1535 | };
|
1536 |
|
1537 | /**
|
1538 | * Delete multiple device
|
1539 | *
|
1540 | * @param {string[]} devices IDs of the devices to delete
|
1541 | * @param {object} auth Optional. Auth data to supply for User-Interactive auth.
|
1542 | * @return {Promise} Resolves: result object
|
1543 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1544 | */
|
1545 | MatrixBaseApis.prototype.deleteMultipleDevices = function(devices, auth) {
|
1546 | const body = {devices};
|
1547 |
|
1548 | if (auth) {
|
1549 | body.auth = auth;
|
1550 | }
|
1551 |
|
1552 | const path = "/delete_devices";
|
1553 | return this._http.authedRequest(undefined, "POST", path, undefined, body);
|
1554 | };
|
1555 |
|
1556 |
|
1557 | // Push operations
|
1558 | // ===============
|
1559 |
|
1560 | /**
|
1561 | * Gets all pushers registered for the logged-in user
|
1562 | *
|
1563 | * @param {module:client.callback} callback Optional.
|
1564 | * @return {Promise} Resolves: Array of objects representing pushers
|
1565 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1566 | */
|
1567 | MatrixBaseApis.prototype.getPushers = function(callback) {
|
1568 | const path = "/pushers";
|
1569 | return this._http.authedRequest(
|
1570 | callback, "GET", path, undefined, undefined,
|
1571 | );
|
1572 | };
|
1573 |
|
1574 | /**
|
1575 | * Adds a new pusher or updates an existing pusher
|
1576 | *
|
1577 | * @param {Object} pusher Object representing a pusher
|
1578 | * @param {module:client.callback} callback Optional.
|
1579 | * @return {Promise} Resolves: Empty json object on success
|
1580 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1581 | */
|
1582 | MatrixBaseApis.prototype.setPusher = function(pusher, callback) {
|
1583 | const path = "/pushers/set";
|
1584 | return this._http.authedRequest(
|
1585 | callback, "POST", path, null, pusher,
|
1586 | );
|
1587 | };
|
1588 |
|
1589 | /**
|
1590 | * @param {module:client.callback} callback Optional.
|
1591 | * @return {Promise} Resolves: TODO
|
1592 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1593 | */
|
1594 | MatrixBaseApis.prototype.getPushRules = function(callback) {
|
1595 | return this._http.authedRequest(callback, "GET", "/pushrules/").then(rules => {
|
1596 | return PushProcessor.rewriteDefaultRules(rules);
|
1597 | });
|
1598 | };
|
1599 |
|
1600 | /**
|
1601 | * @param {string} scope
|
1602 | * @param {string} kind
|
1603 | * @param {string} ruleId
|
1604 | * @param {Object} body
|
1605 | * @param {module:client.callback} callback Optional.
|
1606 | * @return {Promise} Resolves: TODO
|
1607 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1608 | */
|
1609 | MatrixBaseApis.prototype.addPushRule = function(scope, kind, ruleId, body, callback) {
|
1610 | // NB. Scope not uri encoded because devices need the '/'
|
1611 | const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", {
|
1612 | $kind: kind,
|
1613 | $ruleId: ruleId,
|
1614 | });
|
1615 | return this._http.authedRequest(
|
1616 | callback, "PUT", path, undefined, body,
|
1617 | );
|
1618 | };
|
1619 |
|
1620 | /**
|
1621 | * @param {string} scope
|
1622 | * @param {string} kind
|
1623 | * @param {string} ruleId
|
1624 | * @param {module:client.callback} callback Optional.
|
1625 | * @return {Promise} Resolves: TODO
|
1626 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1627 | */
|
1628 | MatrixBaseApis.prototype.deletePushRule = function(scope, kind, ruleId, callback) {
|
1629 | // NB. Scope not uri encoded because devices need the '/'
|
1630 | const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", {
|
1631 | $kind: kind,
|
1632 | $ruleId: ruleId,
|
1633 | });
|
1634 | return this._http.authedRequest(callback, "DELETE", path);
|
1635 | };
|
1636 |
|
1637 | /**
|
1638 | * Enable or disable a push notification rule.
|
1639 | * @param {string} scope
|
1640 | * @param {string} kind
|
1641 | * @param {string} ruleId
|
1642 | * @param {boolean} enabled
|
1643 | * @param {module:client.callback} callback Optional.
|
1644 | * @return {Promise} Resolves: result object
|
1645 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1646 | */
|
1647 | MatrixBaseApis.prototype.setPushRuleEnabled = function(scope, kind,
|
1648 | ruleId, enabled, callback) {
|
1649 | const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/enabled", {
|
1650 | $kind: kind,
|
1651 | $ruleId: ruleId,
|
1652 | });
|
1653 | return this._http.authedRequest(
|
1654 | callback, "PUT", path, undefined, {"enabled": enabled},
|
1655 | );
|
1656 | };
|
1657 |
|
1658 | /**
|
1659 | * Set the actions for a push notification rule.
|
1660 | * @param {string} scope
|
1661 | * @param {string} kind
|
1662 | * @param {string} ruleId
|
1663 | * @param {array} actions
|
1664 | * @param {module:client.callback} callback Optional.
|
1665 | * @return {Promise} Resolves: result object
|
1666 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1667 | */
|
1668 | MatrixBaseApis.prototype.setPushRuleActions = function(scope, kind,
|
1669 | ruleId, actions, callback) {
|
1670 | const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", {
|
1671 | $kind: kind,
|
1672 | $ruleId: ruleId,
|
1673 | });
|
1674 | return this._http.authedRequest(
|
1675 | callback, "PUT", path, undefined, {"actions": actions},
|
1676 | );
|
1677 | };
|
1678 |
|
1679 |
|
1680 | // Search
|
1681 | // ======
|
1682 |
|
1683 | /**
|
1684 | * Perform a server-side search.
|
1685 | * @param {Object} opts
|
1686 | * @param {string} opts.next_batch the batch token to pass in the query string
|
1687 | * @param {Object} opts.body the JSON object to pass to the request body.
|
1688 | * @param {module:client.callback} callback Optional.
|
1689 | * @return {Promise} Resolves: TODO
|
1690 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1691 | */
|
1692 | MatrixBaseApis.prototype.search = function(opts, callback) {
|
1693 | const queryparams = {};
|
1694 | if (opts.next_batch) {
|
1695 | queryparams.next_batch = opts.next_batch;
|
1696 | }
|
1697 | return this._http.authedRequest(
|
1698 | callback, "POST", "/search", queryparams, opts.body,
|
1699 | );
|
1700 | };
|
1701 |
|
1702 | // Crypto
|
1703 | // ======
|
1704 |
|
1705 | /**
|
1706 | * Upload keys
|
1707 | *
|
1708 | * @param {Object} content body of upload request
|
1709 | *
|
1710 | * @param {Object=} opts this method no longer takes any opts,
|
1711 | * used to take opts.device_id but this was not removed from the spec as a redundant parameter
|
1712 | *
|
1713 | * @param {module:client.callback=} callback
|
1714 | *
|
1715 | * @return {Promise} Resolves: result object. Rejects: with
|
1716 | * an error response ({@link module:http-api.MatrixError}).
|
1717 | */
|
1718 | MatrixBaseApis.prototype.uploadKeysRequest = function(content, opts, callback) {
|
1719 | return this._http.authedRequest(callback, "POST", "/keys/upload", undefined, content);
|
1720 | };
|
1721 |
|
1722 | MatrixBaseApis.prototype.uploadKeySignatures = function(content) {
|
1723 | return this._http.authedRequest(
|
1724 | undefined, "POST", '/keys/signatures/upload', undefined,
|
1725 | content, {
|
1726 | prefix: PREFIX_UNSTABLE,
|
1727 | },
|
1728 | );
|
1729 | };
|
1730 |
|
1731 | /**
|
1732 | * Download device keys
|
1733 | *
|
1734 | * @param {string[]} userIds list of users to get keys for
|
1735 | *
|
1736 | * @param {Object=} opts
|
1737 | *
|
1738 | * @param {string=} opts.token sync token to pass in the query request, to help
|
1739 | * the HS give the most recent results
|
1740 | *
|
1741 | * @return {Promise} Resolves: result object. Rejects: with
|
1742 | * an error response ({@link module:http-api.MatrixError}).
|
1743 | */
|
1744 | MatrixBaseApis.prototype.downloadKeysForUsers = function(userIds, opts) {
|
1745 | if (utils.isFunction(opts)) {
|
1746 | // opts used to be 'callback'.
|
1747 | throw new Error(
|
1748 | 'downloadKeysForUsers no longer accepts a callback parameter',
|
1749 | );
|
1750 | }
|
1751 | opts = opts || {};
|
1752 |
|
1753 | const content = {
|
1754 | device_keys: {},
|
1755 | };
|
1756 | if ('token' in opts) {
|
1757 | content.token = opts.token;
|
1758 | }
|
1759 | userIds.forEach((u) => {
|
1760 | content.device_keys[u] = {};
|
1761 | });
|
1762 |
|
1763 | return this._http.authedRequest(undefined, "POST", "/keys/query", undefined, content);
|
1764 | };
|
1765 |
|
1766 | /**
|
1767 | * Claim one-time keys
|
1768 | *
|
1769 | * @param {string[]} devices a list of [userId, deviceId] pairs
|
1770 | *
|
1771 | * @param {string} [key_algorithm = signed_curve25519] desired key type
|
1772 | *
|
1773 | * @param {number} [timeout] the time (in milliseconds) to wait for keys from remote
|
1774 | * servers
|
1775 | *
|
1776 | * @return {Promise} Resolves: result object. Rejects: with
|
1777 | * an error response ({@link module:http-api.MatrixError}).
|
1778 | */
|
1779 | MatrixBaseApis.prototype.claimOneTimeKeys = function(devices, key_algorithm, timeout) {
|
1780 | const queries = {};
|
1781 |
|
1782 | if (key_algorithm === undefined) {
|
1783 | key_algorithm = "signed_curve25519";
|
1784 | }
|
1785 |
|
1786 | for (let i = 0; i < devices.length; ++i) {
|
1787 | const userId = devices[i][0];
|
1788 | const deviceId = devices[i][1];
|
1789 | const query = queries[userId] || {};
|
1790 | queries[userId] = query;
|
1791 | query[deviceId] = key_algorithm;
|
1792 | }
|
1793 | const content = {one_time_keys: queries};
|
1794 | if (timeout) {
|
1795 | content.timeout = timeout;
|
1796 | }
|
1797 | const path = "/keys/claim";
|
1798 | return this._http.authedRequest(undefined, "POST", path, undefined, content);
|
1799 | };
|
1800 |
|
1801 | /**
|
1802 | * Ask the server for a list of users who have changed their device lists
|
1803 | * between a pair of sync tokens
|
1804 | *
|
1805 | * @param {string} oldToken
|
1806 | * @param {string} newToken
|
1807 | *
|
1808 | * @return {Promise} Resolves: result object. Rejects: with
|
1809 | * an error response ({@link module:http-api.MatrixError}).
|
1810 | */
|
1811 | MatrixBaseApis.prototype.getKeyChanges = function(oldToken, newToken) {
|
1812 | const qps = {
|
1813 | from: oldToken,
|
1814 | to: newToken,
|
1815 | };
|
1816 |
|
1817 | const path = "/keys/changes";
|
1818 | return this._http.authedRequest(undefined, "GET", path, qps, undefined);
|
1819 | };
|
1820 |
|
1821 | MatrixBaseApis.prototype.uploadDeviceSigningKeys = function(auth, keys) {
|
1822 | const data = Object.assign({}, keys);
|
1823 | if (auth) Object.assign(data, {auth});
|
1824 | return this._http.authedRequest(
|
1825 | undefined, "POST", "/keys/device_signing/upload", undefined, data, {
|
1826 | prefix: PREFIX_UNSTABLE,
|
1827 | },
|
1828 | );
|
1829 | };
|
1830 |
|
1831 | // Identity Server Operations
|
1832 | // ==========================
|
1833 |
|
1834 | /**
|
1835 | * Register with an Identity Server using the OpenID token from the user's
|
1836 | * Homeserver, which can be retrieved via
|
1837 | * {@link module:client~MatrixClient#getOpenIdToken}.
|
1838 | *
|
1839 | * Note that the `/account/register` endpoint (as well as IS authentication in
|
1840 | * general) was added as part of the v2 API version.
|
1841 | *
|
1842 | * @param {object} hsOpenIdToken
|
1843 | * @return {Promise} Resolves: with object containing an Identity
|
1844 | * Server access token.
|
1845 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1846 | */
|
1847 | MatrixBaseApis.prototype.registerWithIdentityServer = function(hsOpenIdToken) {
|
1848 | if (!this.idBaseUrl) {
|
1849 | throw new Error("No Identity Server base URL set");
|
1850 | }
|
1851 |
|
1852 | const uri = this.idBaseUrl + PREFIX_IDENTITY_V2 + "/account/register";
|
1853 | return this._http.requestOtherUrl(
|
1854 | undefined, "POST", uri,
|
1855 | null, hsOpenIdToken,
|
1856 | );
|
1857 | };
|
1858 |
|
1859 | /**
|
1860 | * Requests an email verification token directly from an identity server.
|
1861 | *
|
1862 | * This API is used as part of binding an email for discovery on an identity
|
1863 | * server. The validation data that results should be passed to the
|
1864 | * `bindThreePid` method to complete the binding process.
|
1865 | *
|
1866 | * @param {string} email The email address to request a token for
|
1867 | * @param {string} clientSecret A secret binary string generated by the client.
|
1868 | * It is recommended this be around 16 ASCII characters.
|
1869 | * @param {number} sendAttempt If an identity server sees a duplicate request
|
1870 | * with the same sendAttempt, it will not send another email.
|
1871 | * To request another email to be sent, use a larger value for
|
1872 | * the sendAttempt param as was used in the previous request.
|
1873 | * @param {string} nextLink Optional If specified, the client will be redirected
|
1874 | * to this link after validation.
|
1875 | * @param {module:client.callback} callback Optional.
|
1876 | * @param {string} identityAccessToken The `access_token` field of the identity
|
1877 | * server `/account/register` response (see {@link registerWithIdentityServer}).
|
1878 | *
|
1879 | * @return {Promise} Resolves: TODO
|
1880 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1881 | * @throws Error if no identity server is set
|
1882 | */
|
1883 | MatrixBaseApis.prototype.requestEmailToken = async function(
|
1884 | email,
|
1885 | clientSecret,
|
1886 | sendAttempt,
|
1887 | nextLink,
|
1888 | callback,
|
1889 | identityAccessToken,
|
1890 | ) {
|
1891 | const params = {
|
1892 | client_secret: clientSecret,
|
1893 | email: email,
|
1894 | send_attempt: sendAttempt,
|
1895 | next_link: nextLink,
|
1896 | };
|
1897 |
|
1898 | return await this._http.idServerRequest(
|
1899 | callback, "POST", "/validate/email/requestToken",
|
1900 | params, PREFIX_IDENTITY_V2, identityAccessToken,
|
1901 | );
|
1902 | };
|
1903 |
|
1904 | /**
|
1905 | * Requests a MSISDN verification token directly from an identity server.
|
1906 | *
|
1907 | * This API is used as part of binding a MSISDN for discovery on an identity
|
1908 | * server. The validation data that results should be passed to the
|
1909 | * `bindThreePid` method to complete the binding process.
|
1910 | *
|
1911 | * @param {string} phoneCountry The ISO 3166-1 alpha-2 code for the country in
|
1912 | * which phoneNumber should be parsed relative to.
|
1913 | * @param {string} phoneNumber The phone number, in national or international
|
1914 | * format
|
1915 | * @param {string} clientSecret A secret binary string generated by the client.
|
1916 | * It is recommended this be around 16 ASCII characters.
|
1917 | * @param {number} sendAttempt If an identity server sees a duplicate request
|
1918 | * with the same sendAttempt, it will not send another SMS.
|
1919 | * To request another SMS to be sent, use a larger value for
|
1920 | * the sendAttempt param as was used in the previous request.
|
1921 | * @param {string} nextLink Optional If specified, the client will be redirected
|
1922 | * to this link after validation.
|
1923 | * @param {module:client.callback} callback Optional.
|
1924 | * @param {string} identityAccessToken The `access_token` field of the Identity
|
1925 | * Server `/account/register` response (see {@link registerWithIdentityServer}).
|
1926 | *
|
1927 | * @return {Promise} Resolves: TODO
|
1928 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1929 | * @throws Error if no identity server is set
|
1930 | */
|
1931 | MatrixBaseApis.prototype.requestMsisdnToken = async function(
|
1932 | phoneCountry,
|
1933 | phoneNumber,
|
1934 | clientSecret,
|
1935 | sendAttempt,
|
1936 | nextLink,
|
1937 | callback,
|
1938 | identityAccessToken,
|
1939 | ) {
|
1940 | const params = {
|
1941 | client_secret: clientSecret,
|
1942 | country: phoneCountry,
|
1943 | phone_number: phoneNumber,
|
1944 | send_attempt: sendAttempt,
|
1945 | next_link: nextLink,
|
1946 | };
|
1947 |
|
1948 | return await this._http.idServerRequest(
|
1949 | callback, "POST", "/validate/msisdn/requestToken",
|
1950 | params, PREFIX_IDENTITY_V2, identityAccessToken,
|
1951 | );
|
1952 | };
|
1953 |
|
1954 | /**
|
1955 | * Submits a MSISDN token to the identity server
|
1956 | *
|
1957 | * This is used when submitting the code sent by SMS to a phone number.
|
1958 | * The ID server has an equivalent API for email but the js-sdk does
|
1959 | * not expose this, since email is normally validated by the user clicking
|
1960 | * a link rather than entering a code.
|
1961 | *
|
1962 | * @param {string} sid The sid given in the response to requestToken
|
1963 | * @param {string} clientSecret A secret binary string generated by the client.
|
1964 | * This must be the same value submitted in the requestToken call.
|
1965 | * @param {string} msisdnToken The MSISDN token, as enetered by the user.
|
1966 | * @param {string} identityAccessToken The `access_token` field of the Identity
|
1967 | * Server `/account/register` response (see {@link registerWithIdentityServer}).
|
1968 | *
|
1969 | * @return {Promise} Resolves: Object, currently with no parameters.
|
1970 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
1971 | * @throws Error if No ID server is set
|
1972 | */
|
1973 | MatrixBaseApis.prototype.submitMsisdnToken = async function(
|
1974 | sid,
|
1975 | clientSecret,
|
1976 | msisdnToken,
|
1977 | identityAccessToken,
|
1978 | ) {
|
1979 | const params = {
|
1980 | sid: sid,
|
1981 | client_secret: clientSecret,
|
1982 | token: msisdnToken,
|
1983 | };
|
1984 |
|
1985 | return await this._http.idServerRequest(
|
1986 | undefined, "POST", "/validate/msisdn/submitToken",
|
1987 | params, PREFIX_IDENTITY_V2, identityAccessToken,
|
1988 | );
|
1989 | };
|
1990 |
|
1991 | /**
|
1992 | * Submits a MSISDN token to an arbitrary URL.
|
1993 | *
|
1994 | * This is used when submitting the code sent by SMS to a phone number in the
|
1995 | * newer 3PID flow where the homeserver validates 3PID ownership (as part of
|
1996 | * `requestAdd3pidMsisdnToken`). The homeserver response may include a
|
1997 | * `submit_url` to specify where the token should be sent, and this helper can
|
1998 | * be used to pass the token to this URL.
|
1999 | *
|
2000 | * @param {string} url The URL to submit the token to
|
2001 | * @param {string} sid The sid given in the response to requestToken
|
2002 | * @param {string} clientSecret A secret binary string generated by the client.
|
2003 | * This must be the same value submitted in the requestToken call.
|
2004 | * @param {string} msisdnToken The MSISDN token, as enetered by the user.
|
2005 | *
|
2006 | * @return {Promise} Resolves: Object, currently with no parameters.
|
2007 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
2008 | */
|
2009 | MatrixBaseApis.prototype.submitMsisdnTokenOtherUrl = function(
|
2010 | url,
|
2011 | sid,
|
2012 | clientSecret,
|
2013 | msisdnToken,
|
2014 | ) {
|
2015 | const params = {
|
2016 | sid: sid,
|
2017 | client_secret: clientSecret,
|
2018 | token: msisdnToken,
|
2019 | };
|
2020 |
|
2021 | return this._http.requestOtherUrl(
|
2022 | undefined, "POST", url, undefined, params,
|
2023 | );
|
2024 | };
|
2025 |
|
2026 | /**
|
2027 | * Gets the V2 hashing information from the identity server. Primarily useful for
|
2028 | * lookups.
|
2029 | * @param {string} identityAccessToken The access token for the identity server.
|
2030 | * @returns {Promise<object>} The hashing information for the identity server.
|
2031 | */
|
2032 | MatrixBaseApis.prototype.getIdentityHashDetails = function(identityAccessToken) {
|
2033 | return this._http.idServerRequest(
|
2034 | undefined, "GET", "/hash_details",
|
2035 | null, PREFIX_IDENTITY_V2, identityAccessToken,
|
2036 | );
|
2037 | };
|
2038 |
|
2039 | /**
|
2040 | * Performs a hashed lookup of addresses against the identity server. This is
|
2041 | * only supported on identity servers which have at least the version 2 API.
|
2042 | * @param {Array<Array<string,string>>} addressPairs An array of 2 element arrays.
|
2043 | * The first element of each pair is the address, the second is the 3PID medium.
|
2044 | * Eg: ["email@example.org", "email"]
|
2045 | * @param {string} identityAccessToken The access token for the identity server.
|
2046 | * @returns {Promise<Array<{address, mxid}>>} A collection of address mappings to
|
2047 | * found MXIDs. Results where no user could be found will not be listed.
|
2048 | */
|
2049 | MatrixBaseApis.prototype.identityHashedLookup = async function(
|
2050 | addressPairs, // [["email@example.org", "email"], ["10005550000", "msisdn"]]
|
2051 | identityAccessToken,
|
2052 | ) {
|
2053 | const params = {
|
2054 | // addresses: ["email@example.org", "10005550000"],
|
2055 | // algorithm: "sha256",
|
2056 | // pepper: "abc123"
|
2057 | };
|
2058 |
|
2059 | // Get hash information first before trying to do a lookup
|
2060 | const hashes = await this.getIdentityHashDetails(identityAccessToken);
|
2061 | if (!hashes || !hashes['lookup_pepper'] || !hashes['algorithms']) {
|
2062 | throw new Error("Unsupported identity server: bad response");
|
2063 | }
|
2064 |
|
2065 | params['pepper'] = hashes['lookup_pepper'];
|
2066 |
|
2067 | const localMapping = {
|
2068 | // hashed identifier => plain text address
|
2069 | // For use in this function's return format
|
2070 | };
|
2071 |
|
2072 | // When picking an algorithm, we pick the hashed over no hashes
|
2073 | if (hashes['algorithms'].includes('sha256')) {
|
2074 | // Abuse the olm hashing
|
2075 | const olmutil = new global.Olm.Utility();
|
2076 | params["addresses"] = addressPairs.map(p => {
|
2077 | const addr = p[0].toLowerCase(); // lowercase to get consistent hashes
|
2078 | const med = p[1].toLowerCase();
|
2079 | const hashed = olmutil.sha256(`${addr} ${med} ${params['pepper']}`)
|
2080 | .replace(/\+/g, '-').replace(/\//g, '_'); // URL-safe base64
|
2081 | // Map the hash to a known (case-sensitive) address. We use the case
|
2082 | // sensitive version because the caller might be expecting that.
|
2083 | localMapping[hashed] = p[0];
|
2084 | return hashed;
|
2085 | });
|
2086 | params["algorithm"] = "sha256";
|
2087 | } else if (hashes['algorithms'].includes('none')) {
|
2088 | params["addresses"] = addressPairs.map(p => {
|
2089 | const addr = p[0].toLowerCase(); // lowercase to get consistent hashes
|
2090 | const med = p[1].toLowerCase();
|
2091 | const unhashed = `${addr} ${med}`;
|
2092 | // Map the unhashed values to a known (case-sensitive) address. We use
|
2093 | // the case sensitive version because the caller might be expecting that.
|
2094 | localMapping[unhashed] = p[0];
|
2095 | return unhashed;
|
2096 | });
|
2097 | params["algorithm"] = "none";
|
2098 | } else {
|
2099 | throw new Error("Unsupported identity server: unknown hash algorithm");
|
2100 | }
|
2101 |
|
2102 | const response = await this._http.idServerRequest(
|
2103 | undefined, "POST", "/lookup",
|
2104 | params, PREFIX_IDENTITY_V2, identityAccessToken,
|
2105 | );
|
2106 |
|
2107 | if (!response || !response['mappings']) return []; // no results
|
2108 |
|
2109 | const foundAddresses = [/* {address: "plain@example.org", mxid} */];
|
2110 | for (const hashed of Object.keys(response['mappings'])) {
|
2111 | const mxid = response['mappings'][hashed];
|
2112 | const plainAddress = localMapping[hashed];
|
2113 | if (!plainAddress) {
|
2114 | throw new Error("Identity server returned more results than expected");
|
2115 | }
|
2116 |
|
2117 | foundAddresses.push({address: plainAddress, mxid});
|
2118 | }
|
2119 | return foundAddresses;
|
2120 | };
|
2121 |
|
2122 | /**
|
2123 | * Looks up the public Matrix ID mapping for a given 3rd party
|
2124 | * identifier from the Identity Server
|
2125 | *
|
2126 | * @param {string} medium The medium of the threepid, eg. 'email'
|
2127 | * @param {string} address The textual address of the threepid
|
2128 | * @param {module:client.callback} callback Optional.
|
2129 | * @param {string} identityAccessToken The `access_token` field of the Identity
|
2130 | * Server `/account/register` response (see {@link registerWithIdentityServer}).
|
2131 | *
|
2132 | * @return {Promise} Resolves: A threepid mapping
|
2133 | * object or the empty object if no mapping
|
2134 | * exists
|
2135 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
2136 | */
|
2137 | MatrixBaseApis.prototype.lookupThreePid = async function(
|
2138 | medium,
|
2139 | address,
|
2140 | callback,
|
2141 | identityAccessToken,
|
2142 | ) {
|
2143 | // Note: we're using the V2 API by calling this function, but our
|
2144 | // function contract requires a V1 response. We therefore have to
|
2145 | // convert it manually.
|
2146 | const response = await this.identityHashedLookup(
|
2147 | [[address, medium]], identityAccessToken,
|
2148 | );
|
2149 | const result = response.find(p => p.address === address);
|
2150 | if (!result) {
|
2151 | if (callback) callback(null, {});
|
2152 | return {};
|
2153 | }
|
2154 |
|
2155 | const mapping = {
|
2156 | address,
|
2157 | medium,
|
2158 | mxid: result.mxid,
|
2159 |
|
2160 | // We can't reasonably fill these parameters:
|
2161 | // not_before
|
2162 | // not_after
|
2163 | // ts
|
2164 | // signatures
|
2165 | };
|
2166 |
|
2167 | if (callback) callback(null, mapping);
|
2168 | return mapping;
|
2169 | };
|
2170 |
|
2171 | /**
|
2172 | * Looks up the public Matrix ID mappings for multiple 3PIDs.
|
2173 | *
|
2174 | * @param {Array.<Array.<string>>} query Array of arrays containing
|
2175 | * [medium, address]
|
2176 | * @param {string} identityAccessToken The `access_token` field of the Identity
|
2177 | * Server `/account/register` response (see {@link registerWithIdentityServer}).
|
2178 | *
|
2179 | * @return {Promise} Resolves: Lookup results from IS.
|
2180 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
2181 | */
|
2182 | MatrixBaseApis.prototype.bulkLookupThreePids = async function(
|
2183 | query,
|
2184 | identityAccessToken,
|
2185 | ) {
|
2186 | // Note: we're using the V2 API by calling this function, but our
|
2187 | // function contract requires a V1 response. We therefore have to
|
2188 | // convert it manually.
|
2189 | const response = await this.identityHashedLookup(
|
2190 | // We have to reverse the query order to get [address, medium] pairs
|
2191 | query.map(p => [p[1], p[0]]), identityAccessToken,
|
2192 | );
|
2193 |
|
2194 | const v1results = [];
|
2195 | for (const mapping of response) {
|
2196 | const originalQuery = query.find(p => p[1] === mapping.address);
|
2197 | if (!originalQuery) {
|
2198 | throw new Error("Identity sever returned unexpected results");
|
2199 | }
|
2200 |
|
2201 | v1results.push([
|
2202 | originalQuery[0], // medium
|
2203 | mapping.address,
|
2204 | mapping.mxid,
|
2205 | ]);
|
2206 | }
|
2207 |
|
2208 | return {threepids: v1results};
|
2209 | };
|
2210 |
|
2211 | /**
|
2212 | * Get account info from the Identity Server. This is useful as a neutral check
|
2213 | * to verify that other APIs are likely to approve access by testing that the
|
2214 | * token is valid, terms have been agreed, etc.
|
2215 | *
|
2216 | * @param {string} identityAccessToken The `access_token` field of the Identity
|
2217 | * Server `/account/register` response (see {@link registerWithIdentityServer}).
|
2218 | *
|
2219 | * @return {Promise} Resolves: an object with account info.
|
2220 | * @return {module:http-api.MatrixError} Rejects: with an error response.
|
2221 | */
|
2222 | MatrixBaseApis.prototype.getIdentityAccount = function(
|
2223 | identityAccessToken,
|
2224 | ) {
|
2225 | return this._http.idServerRequest(
|
2226 | undefined, "GET", "/account",
|
2227 | undefined, PREFIX_IDENTITY_V2, identityAccessToken,
|
2228 | );
|
2229 | };
|
2230 |
|
2231 | // Direct-to-device messaging
|
2232 | // ==========================
|
2233 |
|
2234 | /**
|
2235 | * Send an event to a specific list of devices
|
2236 | *
|
2237 | * @param {string} eventType type of event to send
|
2238 | * @param {Object.<string, Object<string, Object>>} contentMap
|
2239 | * content to send. Map from user_id to device_id to content object.
|
2240 | * @param {string=} txnId transaction id. One will be made up if not
|
2241 | * supplied.
|
2242 | * @return {Promise} Resolves to the result object
|
2243 | */
|
2244 | MatrixBaseApis.prototype.sendToDevice = function(
|
2245 | eventType, contentMap, txnId,
|
2246 | ) {
|
2247 | const path = utils.encodeUri("/sendToDevice/$eventType/$txnId", {
|
2248 | $eventType: eventType,
|
2249 | $txnId: txnId ? txnId : this.makeTxnId(),
|
2250 | });
|
2251 |
|
2252 | const body = {
|
2253 | messages: contentMap,
|
2254 | };
|
2255 |
|
2256 | const targets = Object.keys(contentMap).reduce((obj, key) => {
|
2257 | obj[key] = Object.keys(contentMap[key]);
|
2258 | return obj;
|
2259 | }, {});
|
2260 | logger.log(`PUT ${path}`, targets);
|
2261 |
|
2262 | return this._http.authedRequest(undefined, "PUT", path, undefined, body);
|
2263 | };
|
2264 |
|
2265 | // Third party Lookup API
|
2266 | // ======================
|
2267 |
|
2268 | /**
|
2269 | * Get the third party protocols that can be reached using
|
2270 | * this HS
|
2271 | * @return {Promise} Resolves to the result object
|
2272 | */
|
2273 | MatrixBaseApis.prototype.getThirdpartyProtocols = function() {
|
2274 | return this._http.authedRequest(
|
2275 | undefined, "GET", "/thirdparty/protocols", undefined, undefined,
|
2276 | ).then((response) => {
|
2277 | // sanity check
|
2278 | if (!response || typeof(response) !== 'object') {
|
2279 | throw new Error(
|
2280 | `/thirdparty/protocols did not return an object: ${response}`,
|
2281 | );
|
2282 | }
|
2283 | return response;
|
2284 | });
|
2285 | };
|
2286 |
|
2287 | /**
|
2288 | * Get information on how a specific place on a third party protocol
|
2289 | * may be reached.
|
2290 | * @param {string} protocol The protocol given in getThirdpartyProtocols()
|
2291 | * @param {object} params Protocol-specific parameters, as given in the
|
2292 | * response to getThirdpartyProtocols()
|
2293 | * @return {Promise} Resolves to the result object
|
2294 | */
|
2295 | MatrixBaseApis.prototype.getThirdpartyLocation = function(protocol, params) {
|
2296 | const path = utils.encodeUri("/thirdparty/location/$protocol", {
|
2297 | $protocol: protocol,
|
2298 | });
|
2299 |
|
2300 | return this._http.authedRequest(undefined, "GET", path, params, undefined);
|
2301 | };
|
2302 |
|
2303 | /**
|
2304 | * Get information on how a specific user on a third party protocol
|
2305 | * may be reached.
|
2306 | * @param {string} protocol The protocol given in getThirdpartyProtocols()
|
2307 | * @param {object} params Protocol-specific parameters, as given in the
|
2308 | * response to getThirdpartyProtocols()
|
2309 | * @return {Promise} Resolves to the result object
|
2310 | */
|
2311 | MatrixBaseApis.prototype.getThirdpartyUser = function(protocol, params) {
|
2312 | const path = utils.encodeUri("/thirdparty/user/$protocol", {
|
2313 | $protocol: protocol,
|
2314 | });
|
2315 |
|
2316 | return this._http.authedRequest(undefined, "GET", path, params, undefined);
|
2317 | };
|
2318 |
|
2319 | MatrixBaseApis.prototype.getTerms = function(serviceType, baseUrl) {
|
2320 | const url = termsUrlForService(serviceType, baseUrl);
|
2321 | return this._http.requestOtherUrl(
|
2322 | undefined, 'GET', url,
|
2323 | );
|
2324 | };
|
2325 |
|
2326 | MatrixBaseApis.prototype.agreeToTerms = function(
|
2327 | serviceType, baseUrl, accessToken, termsUrls,
|
2328 | ) {
|
2329 | const url = termsUrlForService(serviceType, baseUrl);
|
2330 | const headers = {
|
2331 | Authorization: "Bearer " + accessToken,
|
2332 | };
|
2333 | return this._http.requestOtherUrl(
|
2334 | undefined, 'POST', url, null, { user_accepts: termsUrls }, { headers },
|
2335 | );
|
2336 | };
|
2337 |
|
2338 | /**
|
2339 | * Reports an event as inappropriate to the server, which may then notify the appropriate people.
|
2340 | * @param {string} roomId The room in which the event being reported is located.
|
2341 | * @param {string} eventId The event to report.
|
2342 | * @param {number} score The score to rate this content as where -100 is most offensive and 0 is inoffensive.
|
2343 | * @param {string} reason The reason the content is being reported. May be blank.
|
2344 | * @returns {Promise} Resolves to an empty object if successful
|
2345 | */
|
2346 | MatrixBaseApis.prototype.reportEvent = function(roomId, eventId, score, reason) {
|
2347 | const path = utils.encodeUri("/rooms/$roomId/report/$eventId", {
|
2348 | $roomId: roomId,
|
2349 | $eventId: eventId,
|
2350 | });
|
2351 |
|
2352 | return this._http.authedRequest(undefined, "POST", path, null, {score, reason});
|
2353 | };
|
2354 |
|