623 lines
23 KiB
Dart
623 lines
23 KiB
Dart
|
|
/* MIT License
|
|
*
|
|
* Copyright (C) 2019, 2020, 2021 Famedly GmbH
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
import '../matrix_api_lite.dart';
|
|
import 'model/auth/authentication_data.dart';
|
|
import 'model/events_sync_update.dart';
|
|
import 'model/matrix_connection_exception.dart';
|
|
import 'model/matrix_exception.dart';
|
|
import 'model/matrix_keys.dart';
|
|
import 'model/request_token_response.dart';
|
|
import 'model/room_keys_keys.dart';
|
|
import 'model/supported_protocol.dart';
|
|
import 'model/third_party_location.dart';
|
|
import 'model/third_party_user.dart';
|
|
import 'model/upload_key_signatures_response.dart';
|
|
|
|
import 'generated/api.dart';
|
|
|
|
enum RequestType { GET, POST, PUT, DELETE }
|
|
|
|
String describeEnum(Object enumEntry) {
|
|
final description = enumEntry.toString();
|
|
final indexOfDot = description.indexOf('.');
|
|
assert(indexOfDot != -1 && indexOfDot < description.length - 1);
|
|
return description.substring(indexOfDot + 1);
|
|
}
|
|
|
|
class MatrixApi extends Api {
|
|
/// The homeserver this client is communicating with.
|
|
Uri? get homeserver => baseUri;
|
|
set homeserver(Uri? uri) => baseUri = uri;
|
|
|
|
/// This is the access token for the matrix client. When it is undefined, then
|
|
/// the user needs to sign in first.
|
|
String? get accessToken => bearerToken;
|
|
set accessToken(String? token) => bearerToken = token;
|
|
|
|
@override
|
|
Never unexpectedResponse(http.BaseResponse response, Uint8List responseBody) {
|
|
if (response.statusCode >= 400 && response.statusCode < 500) {
|
|
throw MatrixException.fromJson(json.decode(utf8.decode(responseBody)));
|
|
}
|
|
super.unexpectedResponse(response, responseBody);
|
|
}
|
|
|
|
MatrixApi({
|
|
Uri? homeserver,
|
|
String? accessToken,
|
|
http.Client? httpClient,
|
|
}) : super(
|
|
httpClient: httpClient,
|
|
baseUri: homeserver,
|
|
bearerToken: accessToken);
|
|
|
|
/// Used for all Matrix json requests using the [c2s API](https://matrix.org/docs/spec/client_server/r0.6.0.html).
|
|
///
|
|
/// Throws: FormatException, MatrixException
|
|
///
|
|
/// You must first set [this.homeserver] and for some endpoints also
|
|
/// [this.accessToken] before you can use this! For example to send a
|
|
/// message to a Matrix room with the id '!fjd823j:example.com' you call:
|
|
/// ```
|
|
/// final resp = await request(
|
|
/// RequestType.PUT,
|
|
/// '/r0/rooms/!fjd823j:example.com/send/m.room.message/$txnId',
|
|
/// data: {
|
|
/// 'msgtype': 'm.text',
|
|
/// 'body': 'hello'
|
|
/// }
|
|
/// );
|
|
/// ```
|
|
///
|
|
Future<Map<String, dynamic>> request(
|
|
RequestType type,
|
|
String action, {
|
|
dynamic data = '',
|
|
String contentType = 'application/json',
|
|
Map<String, dynamic>? query,
|
|
}) async {
|
|
if (homeserver == null) {
|
|
throw ('No homeserver specified.');
|
|
}
|
|
dynamic json;
|
|
(!(data is String)) ? json = jsonEncode(data) : json = data;
|
|
if (data is List<int> || action.startsWith('/media/r0/upload')) json = data;
|
|
|
|
final url = homeserver!
|
|
.resolveUri(Uri(path: '_matrix$action', queryParameters: query));
|
|
|
|
final headers = <String, String>{};
|
|
if (type == RequestType.PUT || type == RequestType.POST) {
|
|
headers['Content-Type'] = contentType;
|
|
}
|
|
if (accessToken != null) {
|
|
headers['Authorization'] = 'Bearer $accessToken';
|
|
}
|
|
|
|
late http.Response resp;
|
|
Map<String, dynamic>? jsonResp = <String, dynamic>{};
|
|
try {
|
|
switch (type) {
|
|
case RequestType.GET:
|
|
resp = await httpClient.get(url, headers: headers);
|
|
break;
|
|
case RequestType.POST:
|
|
resp = await httpClient.post(url, body: json, headers: headers);
|
|
break;
|
|
case RequestType.PUT:
|
|
resp = await httpClient.put(url, body: json, headers: headers);
|
|
break;
|
|
case RequestType.DELETE:
|
|
resp = await httpClient.delete(url, headers: headers);
|
|
break;
|
|
}
|
|
var respBody = resp.body;
|
|
try {
|
|
respBody = utf8.decode(resp.bodyBytes);
|
|
} catch (_) {
|
|
// No-OP
|
|
}
|
|
if (resp.statusCode >= 500 && resp.statusCode < 600) {
|
|
throw Exception(respBody);
|
|
}
|
|
var jsonString = String.fromCharCodes(respBody.runes);
|
|
if (jsonString.startsWith('[') && jsonString.endsWith(']')) {
|
|
jsonString = '\{"chunk":$jsonString\}';
|
|
}
|
|
jsonResp = jsonDecode(jsonString)
|
|
as Map<String, dynamic>?; // May throw FormatException
|
|
} catch (e, s) {
|
|
throw MatrixConnectionException(e, s);
|
|
}
|
|
if (resp.statusCode >= 400 && resp.statusCode < 500) {
|
|
throw MatrixException(resp);
|
|
}
|
|
|
|
return jsonResp!;
|
|
}
|
|
|
|
/// The homeserver must check that the given email address is not already associated
|
|
/// with an account on this homeserver. The homeserver should validate the email
|
|
/// itself, either by sending a validation email itself or by using a service it
|
|
/// has control over.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-register-email-requesttoken
|
|
Future<RequestTokenResponse> requestEmailToken(
|
|
String email,
|
|
String clientSecret,
|
|
int sendAttempt, {
|
|
String? nextLink,
|
|
String? idServer,
|
|
String? idAccessToken,
|
|
}) async {
|
|
final response = await request(
|
|
RequestType.POST, '/client/r0/register/email/requestToken',
|
|
data: {
|
|
'email': email,
|
|
'send_attempt': sendAttempt,
|
|
'client_secret': clientSecret,
|
|
if (nextLink != null) 'next_link': nextLink,
|
|
if (idServer != null) 'id_server': idServer,
|
|
if (idAccessToken != null) 'id_access_token': idAccessToken,
|
|
});
|
|
return RequestTokenResponse.fromJson(response);
|
|
}
|
|
|
|
/// The homeserver must check that the given phone number is not already associated with an
|
|
/// account on this homeserver. The homeserver should validate the phone number itself,
|
|
/// either by sending a validation message itself or by using a service it has control over.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-register-msisdn-requesttoken
|
|
Future<RequestTokenResponse> requestMsisdnToken(
|
|
String country,
|
|
String phoneNumber,
|
|
String clientSecret,
|
|
int sendAttempt, {
|
|
String? nextLink,
|
|
String? idServer,
|
|
String? idAccessToken,
|
|
}) async {
|
|
final response = await request(
|
|
RequestType.POST, '/client/r0/register/msisdn/requestToken',
|
|
data: {
|
|
'country': country,
|
|
'phone_number': phoneNumber,
|
|
'send_attempt': sendAttempt,
|
|
'client_secret': clientSecret,
|
|
if (nextLink != null) 'next_link': nextLink,
|
|
if (idServer != null) 'id_server': idServer,
|
|
if (idAccessToken != null) 'id_access_token': idAccessToken,
|
|
});
|
|
return RequestTokenResponse.fromJson(response);
|
|
}
|
|
|
|
/// The homeserver must check that the given email address is associated with
|
|
/// an account on this homeserver. This API should be used to request
|
|
/// validation tokens when authenticating for the /account/password endpoint.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password-email-requesttoken
|
|
Future<RequestTokenResponse> resetPasswordUsingEmail(
|
|
String email,
|
|
String clientSecret,
|
|
int sendAttempt, {
|
|
String? nextLink,
|
|
String? idServer,
|
|
String? idAccessToken,
|
|
}) async {
|
|
final response = await request(
|
|
RequestType.POST, '/client/r0/account/password/email/requestToken',
|
|
data: {
|
|
'email': email,
|
|
'send_attempt': sendAttempt,
|
|
'client_secret': clientSecret,
|
|
if (nextLink != null) 'next_link': nextLink,
|
|
if (idServer != null) 'id_server': idServer,
|
|
if (idAccessToken != null) 'id_access_token': idAccessToken,
|
|
});
|
|
return RequestTokenResponse.fromJson(response);
|
|
}
|
|
|
|
/// The homeserver must check that the given phone number is associated with
|
|
/// an account on this homeserver. This API should be used to request validation
|
|
/// tokens when authenticating for the /account/password endpoint.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password-msisdn-requesttoken
|
|
Future<RequestTokenResponse> resetPasswordUsingMsisdn(
|
|
String country,
|
|
String phoneNumber,
|
|
String clientSecret,
|
|
int sendAttempt, {
|
|
String? nextLink,
|
|
String? idServer,
|
|
String? idAccessToken,
|
|
}) async {
|
|
final response = await request(
|
|
RequestType.POST, '/client/r0/account/password/msisdn/requestToken',
|
|
data: {
|
|
'country': country,
|
|
'phone_number': phoneNumber,
|
|
'send_attempt': sendAttempt,
|
|
'client_secret': clientSecret,
|
|
if (nextLink != null) 'next_link': nextLink,
|
|
if (idServer != null) 'id_server': idServer,
|
|
if (idAccessToken != null) 'id_access_token': idAccessToken,
|
|
});
|
|
return RequestTokenResponse.fromJson(response);
|
|
}
|
|
|
|
/// This API should be used to request validation tokens when adding an email address to an account.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-email-requesttoken
|
|
Future<RequestTokenResponse> requestEmailValidationToken(
|
|
String email,
|
|
String clientSecret,
|
|
int sendAttempt, {
|
|
String? nextLink,
|
|
String? idServer,
|
|
String? idAccessToken,
|
|
}) async {
|
|
final response = await request(
|
|
RequestType.POST, '/client/r0/account/3pid/email/requestToken',
|
|
data: {
|
|
'email': email,
|
|
'send_attempt': sendAttempt,
|
|
'client_secret': clientSecret,
|
|
if (nextLink != null) 'next_link': nextLink,
|
|
if (idServer != null) 'id_server': idServer,
|
|
if (idAccessToken != null) 'id_access_token': idAccessToken,
|
|
});
|
|
return RequestTokenResponse.fromJson(response);
|
|
}
|
|
|
|
/// This API should be used to request validation tokens when adding a phone number to an account.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken
|
|
Future<RequestTokenResponse> requestMsisdnValidationToken(
|
|
String country,
|
|
String phoneNumber,
|
|
String clientSecret,
|
|
int sendAttempt, {
|
|
String? nextLink,
|
|
String? idServer,
|
|
String? idAccessToken,
|
|
}) async {
|
|
final response = await request(
|
|
RequestType.POST, '/client/r0/account/3pid/msisdn/requestToken',
|
|
data: {
|
|
'country': country,
|
|
'phone_number': phoneNumber,
|
|
'send_attempt': sendAttempt,
|
|
'client_secret': clientSecret,
|
|
if (nextLink != null) 'next_link': nextLink,
|
|
if (idServer != null) 'id_server': idServer,
|
|
if (idAccessToken != null) 'id_access_token': idAccessToken,
|
|
});
|
|
return RequestTokenResponse.fromJson(response);
|
|
}
|
|
|
|
/// Looks up the contents of a state event in a room. If the user is joined to the room then the
|
|
/// state is taken from the current state of the room. If the user has left the room then the
|
|
/// state is taken from the state of the room when they left.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-state-eventtype-statekey
|
|
Future<Map<String, dynamic>> requestStateContent(
|
|
String roomId, String eventType,
|
|
[String? stateKey]) async {
|
|
var url =
|
|
'/client/r0/rooms/${Uri.encodeComponent(roomId)}/state/${Uri.encodeComponent(eventType)}/';
|
|
if (stateKey != null) {
|
|
url += Uri.encodeComponent(stateKey);
|
|
}
|
|
final response = await request(
|
|
RequestType.GET,
|
|
url,
|
|
);
|
|
return response;
|
|
}
|
|
|
|
/// Gets the visibility of a given room on the server's public room directory.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-directory-list-room-roomid
|
|
Future<Visibility> getRoomVisibilityOnDirectory(String roomId) async {
|
|
final response = await request(
|
|
RequestType.GET,
|
|
'/client/r0/directory/list/room/${Uri.encodeComponent(roomId)}',
|
|
);
|
|
return Visibility.values
|
|
.firstWhere((v) => describeEnum(v) == response['visibility']);
|
|
}
|
|
|
|
/// Sets the visibility of a given room in the server's public room directory.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-directory-list-room-roomid
|
|
Future<void> setRoomVisibilityOnDirectory(
|
|
String roomId, Visibility visibility) async {
|
|
await request(
|
|
RequestType.PUT,
|
|
'/client/r0/directory/list/room/${Uri.encodeComponent(roomId)}',
|
|
data: {
|
|
'visibility': describeEnum(visibility),
|
|
},
|
|
);
|
|
return;
|
|
}
|
|
|
|
/// Publishes end-to-end encryption keys for the device.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-keys-query
|
|
Future<Map<String, int>> uploadKeys(
|
|
{MatrixDeviceKeys? deviceKeys,
|
|
Map<String, dynamic>? oneTimeKeys,
|
|
Map<String, dynamic>? fallbackKeys}) async {
|
|
final response = await request(
|
|
RequestType.POST,
|
|
'/client/r0/keys/upload',
|
|
data: {
|
|
if (deviceKeys != null) 'device_keys': deviceKeys.toJson(),
|
|
if (oneTimeKeys != null) 'one_time_keys': oneTimeKeys,
|
|
if (fallbackKeys != null) ...{
|
|
'fallback_keys': fallbackKeys,
|
|
'org.matrix.msc2732.fallback_keys': fallbackKeys,
|
|
},
|
|
},
|
|
);
|
|
return Map<String, int>.from(response['one_time_key_counts']);
|
|
}
|
|
|
|
/// Uploads your own cross-signing keys.
|
|
/// https://github.com/matrix-org/matrix-doc/pull/2536
|
|
Future<void> uploadDeviceSigningKeys({
|
|
MatrixCrossSigningKey? masterKey,
|
|
MatrixCrossSigningKey? selfSigningKey,
|
|
MatrixCrossSigningKey? userSigningKey,
|
|
AuthenticationData? auth,
|
|
}) async {
|
|
await request(
|
|
RequestType.POST,
|
|
'/client/unstable/keys/device_signing/upload',
|
|
data: {
|
|
if (masterKey != null) 'master_key': masterKey.toJson(),
|
|
if (selfSigningKey != null) 'self_signing_key': selfSigningKey.toJson(),
|
|
if (userSigningKey != null) 'user_signing_key': userSigningKey.toJson(),
|
|
if (auth != null) 'auth': auth.toJson(),
|
|
},
|
|
);
|
|
}
|
|
|
|
/// Uploads new signatures of keys
|
|
/// https://github.com/matrix-org/matrix-doc/pull/2536
|
|
Future<UploadKeySignaturesResponse> uploadKeySignatures(
|
|
List<MatrixSignableKey> keys) async {
|
|
final payload = <String, dynamic>{};
|
|
for (final key in keys) {
|
|
if (key.identifier == null ||
|
|
key.signatures == null ||
|
|
key.signatures!.isEmpty) {
|
|
continue;
|
|
}
|
|
if (!payload.containsKey(key.userId)) {
|
|
payload[key.userId] = <String, dynamic>{};
|
|
}
|
|
if (payload[key.userId].containsKey(key.identifier)) {
|
|
// we need to merge signature objects
|
|
payload[key.userId][key.identifier]['signatures']
|
|
.addAll(key.signatures);
|
|
} else {
|
|
// we can just add signatures
|
|
payload[key.userId][key.identifier] = key.toJson();
|
|
}
|
|
}
|
|
final response = await request(
|
|
RequestType.POST,
|
|
'/client/r0/keys/signatures/upload',
|
|
data: payload,
|
|
);
|
|
return UploadKeySignaturesResponse.fromJson(response);
|
|
}
|
|
|
|
/// This endpoint allows the creation, modification and deletion of pushers
|
|
/// for this user ID. The behaviour of this endpoint varies depending on the
|
|
/// values in the JSON body.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-pushers-set
|
|
Future<void> postPusher(Pusher pusher, {bool? append}) async {
|
|
final data = pusher.toJson();
|
|
if (append != null) {
|
|
data['append'] = append;
|
|
}
|
|
await request(
|
|
RequestType.POST,
|
|
'/client/r0/pushers/set',
|
|
data: data,
|
|
);
|
|
return;
|
|
}
|
|
|
|
/// This will listen for new events related to a particular room and return them to the
|
|
/// caller. This will block until an event is received, or until the timeout is reached.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-events
|
|
Future<EventsSyncUpdate> getEvents({
|
|
String? from,
|
|
int? timeout,
|
|
String? roomId,
|
|
}) async {
|
|
final response =
|
|
await request(RequestType.GET, '/client/r0/events', query: {
|
|
if (from != null) 'from': from,
|
|
if (timeout != null) 'timeout': timeout.toString(),
|
|
if (roomId != null) 'roomId': roomId,
|
|
});
|
|
return EventsSyncUpdate.fromJson(response);
|
|
}
|
|
|
|
/// Fetches the overall metadata about protocols supported by the homeserver. Includes
|
|
/// both the available protocols and all fields required for queries against each protocol.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-thirdparty-protocols
|
|
Future<Map<String, SupportedProtocol>> requestSupportedProtocols() async {
|
|
final response = await request(
|
|
RequestType.GET,
|
|
'/client/r0/thirdparty/protocols',
|
|
);
|
|
return response.map((k, v) => MapEntry(k, SupportedProtocol.fromJson(v)));
|
|
}
|
|
|
|
/// Fetches the metadata from the homeserver about a particular third party protocol.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-thirdparty-protocol-protocol
|
|
Future<SupportedProtocol> requestSupportedProtocol(String protocol) async {
|
|
final response = await request(
|
|
RequestType.GET,
|
|
'/client/r0/thirdparty/protocol/${Uri.encodeComponent(protocol)}',
|
|
);
|
|
return SupportedProtocol.fromJson(response);
|
|
}
|
|
|
|
/// Requesting this endpoint with a valid protocol name results in a list of successful
|
|
/// mapping results in a JSON array.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-thirdparty-location-protocol
|
|
Future<List<ThirdPartyLocation>> requestThirdPartyLocations(
|
|
String protocol) async {
|
|
final response = await request(
|
|
RequestType.GET,
|
|
'/client/r0/thirdparty/location/${Uri.encodeComponent(protocol)}',
|
|
);
|
|
return (response['chunk'] as List)
|
|
.map((i) => ThirdPartyLocation.fromJson(i))
|
|
.toList();
|
|
}
|
|
|
|
/// Retrieve a Matrix User ID linked to a user on the third party service, given a set of
|
|
/// user parameters.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-thirdparty-user-protocol
|
|
Future<List<ThirdPartyUser>> requestThirdPartyUsers(String protocol) async {
|
|
final response = await request(
|
|
RequestType.GET,
|
|
'/client/r0/thirdparty/user/${Uri.encodeComponent(protocol)}',
|
|
);
|
|
return (response['chunk'] as List)
|
|
.map((i) => ThirdPartyUser.fromJson(i))
|
|
.toList();
|
|
}
|
|
|
|
/// Retrieve an array of third party network locations from a Matrix room alias.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-thirdparty-location
|
|
Future<List<ThirdPartyLocation>> requestThirdPartyLocationsByAlias(
|
|
String alias) async {
|
|
final response = await request(
|
|
RequestType.GET, '/client/r0/thirdparty/location',
|
|
query: {
|
|
'alias': alias,
|
|
});
|
|
return (response['chunk'] as List)
|
|
.map((i) => ThirdPartyLocation.fromJson(i))
|
|
.toList();
|
|
}
|
|
|
|
/// Retrieve an array of third party users from a Matrix User ID.
|
|
/// https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-thirdparty-user
|
|
Future<List<ThirdPartyUser>> requestThirdPartyUsersByUserId(
|
|
String userId) async {
|
|
final response =
|
|
await request(RequestType.GET, '/client/r0/thirdparty/user', query: {
|
|
'userid': userId,
|
|
});
|
|
return (response['chunk'] as List)
|
|
.map((i) => ThirdPartyUser.fromJson(i))
|
|
.toList();
|
|
}
|
|
|
|
/// Deletes a room key backup
|
|
/// https://matrix.org/docs/spec/client_server/unstable#delete-matrix-client-r0-room-keys-version-version
|
|
Future<void> deleteRoomKeysBackup(String version) async {
|
|
await request(
|
|
RequestType.DELETE,
|
|
'/client/unstable/room_keys/version/${Uri.encodeComponent(version)}',
|
|
);
|
|
}
|
|
|
|
/// Gets a single room key
|
|
/// https://matrix.org/docs/spec/client_server/unstable#get-matrix-client-r0-room-keys-keys-roomid-sessionid
|
|
Future<RoomKeysSingleKey> getRoomKeysSingleKey(
|
|
String roomId, String sessionId, String version) async {
|
|
final ret = await request(
|
|
RequestType.GET,
|
|
'/client/unstable/room_keys/keys/${Uri.encodeComponent(roomId)}/${Uri.encodeComponent(sessionId)}',
|
|
query: {'version': version},
|
|
);
|
|
return RoomKeysSingleKey.fromJson(ret);
|
|
}
|
|
|
|
/// Deletes a single room key
|
|
/// https://matrix.org/docs/spec/client_server/unstable#delete-matrix-client-r0-room-keys-keys-roomid-sessionid
|
|
Future<RoomKeysUpdateResponse> deleteRoomKeysSingleKey(
|
|
String roomId, String sessionId, String version) async {
|
|
final ret = await request(
|
|
RequestType.DELETE,
|
|
'/client/unstable/room_keys/keys/${Uri.encodeComponent(roomId)}/${Uri.encodeComponent(sessionId)}',
|
|
query: {'version': version},
|
|
);
|
|
return RoomKeysUpdateResponse.fromJson(ret);
|
|
}
|
|
|
|
/// Gets room keys for a room
|
|
/// https://matrix.org/docs/spec/client_server/unstable#get-matrix-client-r0-room-keys-keys-roomid
|
|
Future<RoomKeysRoom> getRoomKeysRoom(String roomId, String version) async {
|
|
final ret = await request(
|
|
RequestType.GET,
|
|
'/client/unstable/room_keys/keys/${Uri.encodeComponent(roomId)}',
|
|
query: {'version': version},
|
|
);
|
|
return RoomKeysRoom.fromJson(ret);
|
|
}
|
|
|
|
/// Deletes room keys for a room
|
|
/// https://matrix.org/docs/spec/client_server/unstable#delete-matrix-client-r0-room-keys-keys-roomid
|
|
Future<RoomKeysUpdateResponse> deleteRoomKeysRoom(
|
|
String roomId, String version) async {
|
|
final ret = await request(
|
|
RequestType.DELETE,
|
|
'/client/unstable/room_keys/keys/${Uri.encodeComponent(roomId)}',
|
|
query: {'version': version},
|
|
);
|
|
return RoomKeysUpdateResponse.fromJson(ret);
|
|
}
|
|
|
|
/// get all room keys
|
|
/// https://matrix.org/docs/spec/client_server/unstable#get-matrix-client-r0-room-keys-keys
|
|
Future<RoomKeys> getRoomKeys(String version) async {
|
|
final ret = await request(
|
|
RequestType.GET,
|
|
'/client/unstable/room_keys/keys',
|
|
query: {'version': version},
|
|
);
|
|
return RoomKeys.fromJson(ret);
|
|
}
|
|
|
|
/// delete all room keys
|
|
/// https://matrix.org/docs/spec/client_server/unstable#delete-matrix-client-r0-room-keys-keys
|
|
Future<RoomKeysUpdateResponse> deleteRoomKeys(String version) async {
|
|
final ret = await request(
|
|
RequestType.DELETE,
|
|
'/client/unstable/room_keys/keys',
|
|
query: {'version': version},
|
|
);
|
|
return RoomKeysUpdateResponse.fromJson(ret);
|
|
}
|
|
}
|