Init matrix_api library

This commit is contained in:
Christian Pauly 2020-06-03 10:16:01 +00:00 committed by Sorunome
parent fbc2a6b1a2
commit c6bf098644
100 changed files with 9712 additions and 3186 deletions

View file

@ -5,5 +5,7 @@ linter:
- camel_case_types
analyzer:
errors:
todo: ignore
# exclude:
# - path/to/excluded/files/**

View file

@ -1,55 +1,39 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
library famedlysdk;
export 'package:famedlysdk/src/sync/room_update.dart';
export 'package:famedlysdk/src/sync/event_update.dart';
export 'package:famedlysdk/src/sync/user_update.dart';
export 'matrix_api.dart';
export 'package:famedlysdk/src/utils/room_update.dart';
export 'package:famedlysdk/src/utils/event_update.dart';
export 'package:famedlysdk/src/utils/device_keys_list.dart';
export 'package:famedlysdk/src/utils/key_verification.dart';
export 'package:famedlysdk/src/utils/matrix_exception.dart';
export 'package:famedlysdk/src/utils/matrix_file.dart';
export 'package:famedlysdk/src/utils/matrix_id_string_extension.dart';
export 'package:famedlysdk/src/utils/uri_extension.dart';
export 'package:famedlysdk/src/utils/matrix_localizations.dart';
export 'package:famedlysdk/src/utils/open_id_credentials.dart';
export 'package:famedlysdk/src/utils/profile.dart';
export 'package:famedlysdk/src/utils/public_rooms_response.dart';
export 'package:famedlysdk/src/utils/push_rules.dart';
export 'package:famedlysdk/src/utils/receipt.dart';
export 'package:famedlysdk/src/utils/states_map.dart';
export 'package:famedlysdk/src/utils/to_device_event.dart';
export 'package:famedlysdk/src/utils/turn_server_credentials.dart';
export 'package:famedlysdk/src/utils/user_device.dart';
export 'package:famedlysdk/src/utils/well_known_informations.dart';
export 'package:famedlysdk/src/account_data.dart';
export 'package:famedlysdk/src/client.dart';
export 'package:famedlysdk/src/event.dart';
export 'package:famedlysdk/src/key_manager.dart';
export 'package:famedlysdk/src/presence.dart';
export 'package:famedlysdk/src/room.dart';
export 'package:famedlysdk/src/room_account_data.dart';
export 'package:famedlysdk/src/timeline.dart';
export 'package:famedlysdk/src/user.dart';
export 'package:famedlysdk/src/database/database.dart' show Database;

63
lib/matrix_api.dart Normal file
View file

@ -0,0 +1,63 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
library matrix_api;
export 'package:famedlysdk/matrix_api/matrix_api.dart';
export 'package:famedlysdk/matrix_api/model/basic_event_with_sender.dart';
export 'package:famedlysdk/matrix_api/model/basic_event.dart';
export 'package:famedlysdk/matrix_api/model/device.dart';
export 'package:famedlysdk/matrix_api/model/basic_room_event.dart';
export 'package:famedlysdk/matrix_api/model/event_context.dart';
export 'package:famedlysdk/matrix_api/model/matrix_event.dart';
export 'package:famedlysdk/matrix_api/model/event_types.dart';
export 'package:famedlysdk/matrix_api/model/events_sync_update.dart';
export 'package:famedlysdk/matrix_api/model/filter.dart';
export 'package:famedlysdk/matrix_api/model/keys_query_response.dart';
export 'package:famedlysdk/matrix_api/model/login_response.dart';
export 'package:famedlysdk/matrix_api/model/login_types.dart';
export 'package:famedlysdk/matrix_api/model/matrix_device_keys.dart';
export 'package:famedlysdk/matrix_api/model/matrix_exception.dart';
export 'package:famedlysdk/matrix_api/model/message_types.dart';
export 'package:famedlysdk/matrix_api/model/presence_content.dart';
export 'package:famedlysdk/matrix_api/model/notifications_query_response.dart';
export 'package:famedlysdk/matrix_api/model/one_time_keys_claim_response.dart';
export 'package:famedlysdk/matrix_api/model/open_graph_data.dart';
export 'package:famedlysdk/matrix_api/model/open_id_credentials.dart';
export 'package:famedlysdk/matrix_api/model/presence.dart';
export 'package:famedlysdk/matrix_api/model/profile.dart';
export 'package:famedlysdk/matrix_api/model/public_rooms_response.dart';
export 'package:famedlysdk/matrix_api/model/push_rule_set.dart';
export 'package:famedlysdk/matrix_api/model/pusher.dart';
export 'package:famedlysdk/matrix_api/model/request_token_response.dart';
export 'package:famedlysdk/matrix_api/model/room_alias_informations.dart';
export 'package:famedlysdk/matrix_api/model/room_summary.dart';
export 'package:famedlysdk/matrix_api/model/server_capabilities.dart';
export 'package:famedlysdk/matrix_api/model/stripped_state_event.dart';
export 'package:famedlysdk/matrix_api/model/supported_protocol.dart';
export 'package:famedlysdk/matrix_api/model/supported_versions.dart';
export 'package:famedlysdk/matrix_api/model/sync_update.dart';
export 'package:famedlysdk/matrix_api/model/tag.dart';
export 'package:famedlysdk/matrix_api/model/third_party_identifier.dart';
export 'package:famedlysdk/matrix_api/model/third_party_location.dart';
export 'package:famedlysdk/matrix_api/model/third_party_user.dart';
export 'package:famedlysdk/matrix_api/model/timeline_history_response.dart';
export 'package:famedlysdk/matrix_api/model/turn_server_credentials.dart';
export 'package:famedlysdk/matrix_api/model/user_search_result.dart';
export 'package:famedlysdk/matrix_api/model/well_known_informations.dart';
export 'package:famedlysdk/matrix_api/model/who_is_info.dart';

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,38 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class BasicEvent {
String type;
Map<String, dynamic> content;
BasicEvent({
this.type,
this.content,
});
BasicEvent.fromJson(Map<String, dynamic> json) {
type = json['type'];
content = Map<String, dynamic>.from(json['content']);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['type'] = type;
data['content'] = content;
return data;
}
}

View file

@ -0,0 +1,39 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'basic_event.dart';
class BasicEventWithSender extends BasicEvent {
String senderId;
BasicEventWithSender();
BasicEventWithSender.fromJson(Map<String, dynamic> json) {
final basicEvent = BasicEvent.fromJson(json);
type = basicEvent.type;
content = basicEvent.content;
senderId = json['sender'];
}
@override
Map<String, dynamic> toJson() {
final data = super.toJson();
data['sender'] = senderId;
return data;
}
}

View file

@ -0,0 +1,46 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/matrix_api/model/basic_event.dart';
class BasicRoomEvent extends BasicEvent {
String roomId;
BasicRoomEvent({
this.roomId,
Map<String, dynamic> content,
String type,
}) : super(
content: content,
type: type,
);
BasicRoomEvent.fromJson(Map<String, dynamic> json) {
final basicEvent = BasicEvent.fromJson(json);
content = basicEvent.content;
type = basicEvent.type;
roomId = json['room_id'];
}
@override
Map<String, dynamic> toJson() {
final data = super.toJson();
if (roomId != null) data['room_id'] = roomId;
return data;
}
}

View file

@ -0,0 +1,46 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class Device {
String deviceId;
String displayName;
String lastSeenIp;
DateTime lastSeenTs;
Device.fromJson(Map<String, dynamic> json) {
deviceId = json['device_id'];
displayName = json['display_name'];
lastSeenIp = json['last_seen_ip'];
lastSeenTs = DateTime.fromMillisecondsSinceEpoch(json['last_seen_ts'] ?? 0);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['device_id'] = deviceId;
if (displayName != null) {
data['display_name'] = displayName;
}
if (lastSeenIp != null) {
data['last_seen_ip'] = lastSeenIp;
}
if (lastSeenTs != null) {
data['last_seen_ts'] = lastSeenTs.millisecondsSinceEpoch;
}
return data;
}
}

View file

@ -0,0 +1,73 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'matrix_event.dart';
class EventContext {
String end;
List<MatrixEvent> eventsAfter;
MatrixEvent event;
List<MatrixEvent> eventsBefore;
String start;
List<MatrixEvent> state;
EventContext.fromJson(Map<String, dynamic> json) {
end = json['end'];
if (json['events_after'] != null) {
eventsAfter = <MatrixEvent>[];
json['events_after'].forEach((v) {
eventsAfter.add(MatrixEvent.fromJson(v));
});
}
event = json['event'] != null ? MatrixEvent.fromJson(json['event']) : null;
if (json['events_before'] != null) {
eventsBefore = <MatrixEvent>[];
json['events_before'].forEach((v) {
eventsBefore.add(MatrixEvent.fromJson(v));
});
}
start = json['start'];
if (json['state'] != null) {
state = <MatrixEvent>[];
json['state'].forEach((v) {
state.add(MatrixEvent.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (end != null) {
data['end'] = end;
}
if (eventsAfter != null) {
data['events_after'] = eventsAfter.map((v) => v.toJson()).toList();
}
if (event != null) {
data['event'] = event.toJson();
}
if (eventsBefore != null) {
data['events_before'] = eventsBefore.map((v) => v.toJson()).toList();
}
data['start'] = start;
if (state != null) {
data['state'] = state.map((v) => v.toJson()).toList();
}
return data;
}
}

View file

@ -0,0 +1,42 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
abstract class EventTypes {
static const String Message = 'm.room.message';
static const String Sticker = 'm.sticker';
static const String Redaction = 'm.room.redaction';
static const String RoomAliases = 'm.room.aliases';
static const String RoomCanonicalAlias = 'm.room.canonical_alias';
static const String RoomCreate = 'm.room.create';
static const String RoomJoinRules = 'm.room.join_rules';
static const String RoomMember = 'm.room.member';
static const String RoomPowerLevels = 'm.room.power_levels';
static const String RoomName = 'm.room.name';
static const String RoomTopic = 'm.room.topic';
static const String RoomAvatar = 'm.room.avatar';
static const String RoomTombstone = 'm.room.tombsone';
static const String GuestAccess = 'm.room.guest_access';
static const String HistoryVisibility = 'm.room.history_visibility';
static const String Encryption = 'm.room.encryption';
static const String Encrypted = 'm.room.encrypted';
static const String CallInvite = 'm.room.call.invite';
static const String CallAnswer = 'm.room.call.answer';
static const String CallCandidates = 'm.room.call.candidates';
static const String CallHangup = 'm.room.call.hangup';
static const String Unknown = 'm.unknown';
}

View file

@ -0,0 +1,47 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'matrix_event.dart';
class EventsSyncUpdate {
String start;
String end;
List<MatrixEvent> chunk;
EventsSyncUpdate.fromJson(Map<String, dynamic> json) {
start = json['start'];
end = json['end'];
chunk = json['chunk'] != null
? (json['chunk'] as List).map((i) => MatrixEvent.fromJson(i)).toList()
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (start != null) {
data['start'] = start;
}
if (end != null) {
data['end'] = end;
}
if (chunk != null) {
data['chunk'] = chunk.map((i) => i.toJson()).toList();
}
return data;
}
}

View file

@ -0,0 +1,222 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
enum EventFormat { client, federation }
class Filter {
RoomFilter room;
EventFilter presence;
EventFilter accountData;
EventFormat eventFormat;
List<String> eventFields;
Filter({
this.room,
this.presence,
this.accountData,
this.eventFormat,
this.eventFields,
});
Filter.fromJson(Map<String, dynamic> json) {
room = json['room'] != null ? RoomFilter.fromJson(json['room']) : null;
presence = json['presence'] != null
? EventFilter.fromJson(json['presence'])
: null;
accountData = json['account_data'] != null
? EventFilter.fromJson(json['account_data'])
: null;
eventFormat = json['event_format'] != null
? EventFormat.values.firstWhere(
(e) => e.toString().split('.').last == json['event_format'])
: null;
eventFields = json['event_fields'] != null
? json['event_fields'].cast<String>()
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (room != null) {
data['room'] = room.toJson();
}
if (presence != null) {
data['presence'] = presence.toJson();
}
if (eventFormat != null) {
data['event_format'] = eventFormat.toString().split('.').last;
}
if (eventFields != null) {
data['event_fields'] = eventFields;
}
if (accountData != null) {
data['account_data'] = accountData.toJson();
}
return data;
}
}
class RoomFilter {
List<String> notRooms;
List<String> rooms;
StateFilter ephemeral;
bool includeLeave;
StateFilter state;
StateFilter timeline;
StateFilter accountData;
RoomFilter({
this.notRooms,
this.rooms,
this.ephemeral,
this.includeLeave,
this.state,
this.timeline,
this.accountData,
});
RoomFilter.fromJson(Map<String, dynamic> json) {
notRooms = json['not_rooms']?.cast<String>();
rooms = json['rooms']?.cast<String>();
state = json['state'] != null ? StateFilter.fromJson(json['state']) : null;
includeLeave = json['include_leave'];
timeline = json['timeline'] != null
? StateFilter.fromJson(json['timeline'])
: null;
ephemeral = json['ephemeral'] != null
? StateFilter.fromJson(json['ephemeral'])
: null;
accountData = json['account_data'] != null
? StateFilter.fromJson(json['account_data'])
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (notRooms != null) {
data['not_rooms'] = notRooms;
}
if (rooms != null) {
data['rooms'] = rooms;
}
if (ephemeral != null) {
data['ephemeral'] = ephemeral.toJson();
}
if (includeLeave != null) {
data['include_leave'] = includeLeave;
}
if (state != null) {
data['state'] = state.toJson();
}
if (timeline != null) {
data['timeline'] = timeline.toJson();
}
if (accountData != null) {
data['account_data'] = accountData.toJson();
}
return data;
}
}
class EventFilter {
int limit;
List<String> senders;
List<String> types;
List<String> notRooms;
List<String> notSenders;
EventFilter(
{this.limit, this.senders, this.types, this.notRooms, this.notSenders});
EventFilter.fromJson(Map<String, dynamic> json) {
limit = json['limit'];
types = json['senders']?.cast<String>();
types = json['types']?.cast<String>();
notRooms = json['not_rooms']?.cast<String>();
notSenders = json['not_senders']?.cast<String>();
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (limit != null) data['limit'] = limit;
if (types != null) data['types'] = types;
if (notRooms != null) data['not_rooms'] = notRooms;
if (notSenders != null) data['not_senders'] = notSenders;
return data;
}
}
class StateFilter extends EventFilter {
List<String> notTypes;
bool lazyLoadMembers;
bool includeRedundantMembers;
bool containsUrl;
StateFilter({
this.notTypes,
this.lazyLoadMembers,
this.includeRedundantMembers,
this.containsUrl,
int limit,
List<String> senders,
List<String> types,
List<String> notRooms,
List<String> notSenders,
}) : super(
limit: limit,
senders: senders,
types: types,
notRooms: notRooms,
notSenders: notSenders,
);
StateFilter.fromJson(Map<String, dynamic> json) {
final eventFilter = EventFilter.fromJson(json);
limit = eventFilter.limit;
senders = eventFilter.senders;
types = eventFilter.types;
notRooms = eventFilter.notRooms;
notSenders = eventFilter.notSenders;
notTypes = json['not_types']?.cast<String>();
lazyLoadMembers = json['lazy_load_members'];
includeRedundantMembers = json['include_redundant_members'];
containsUrl = json['contains_url'];
}
@override
Map<String, dynamic> toJson() {
final data = super.toJson();
if (limit != null) {
data['limit'] = limit;
}
if (notTypes != null) {
data['not_types'] = notTypes;
}
if (lazyLoadMembers != null) {
data['lazy_load_members'] = notTypes;
}
if (includeRedundantMembers != null) {
data['include_redundant_members'] = notTypes;
}
if (containsUrl != null) {
data['contains_url'] = notTypes;
}
return data;
}
}

View file

@ -0,0 +1,62 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'matrix_device_keys.dart';
class KeysQueryResponse {
Map<String, dynamic> failures;
Map<String, Map<String, MatrixDeviceKeys>> deviceKeys;
KeysQueryResponse.fromJson(Map<String, dynamic> json) {
failures = Map<String, dynamic>.from(json['failures']);
deviceKeys = json['device_keys'] != null
? (json['device_keys'] as Map).map(
(k, v) => MapEntry(
k,
(v as Map).map(
(k, v) => MapEntry(
k,
MatrixDeviceKeys.fromJson(v),
),
),
),
)
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (failures != null) {
data['failures'] = failures;
}
if (deviceKeys != null) {
data['device_keys'] = deviceKeys.map(
(k, v) => MapEntry(
k,
v.map(
(k, v) => MapEntry(
k,
v.toJson(),
),
),
),
);
}
return data;
}
}

View file

@ -0,0 +1,47 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'well_known_informations.dart';
class LoginResponse {
String userId;
String accessToken;
String deviceId;
WellKnownInformations wellKnownInformations;
LoginResponse.fromJson(Map<String, dynamic> json) {
userId = json['user_id'];
accessToken = json['access_token'];
deviceId = json['device_id'];
if (json.containsKey('well_known')) {
wellKnownInformations =
WellKnownInformations.fromJson(json['well_known']);
}
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (userId != null) data['user_id'] = userId;
if (accessToken != null) data['access_token'] = accessToken;
if (deviceId != null) data['device_id'] = deviceId;
if (wellKnownInformations != null) {
data['well_known'] = wellKnownInformations.toJson();
}
return data;
}
}

View file

@ -0,0 +1,52 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class LoginTypes {
List<Flows> flows;
LoginTypes.fromJson(Map<String, dynamic> json) {
if (json['flows'] != null) {
flows = <Flows>[];
json['flows'].forEach((v) {
flows.add(Flows.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (flows != null) {
data['flows'] = flows.map((v) => v.toJson()).toList();
}
return data;
}
}
class Flows {
String type;
Flows.fromJson(Map<String, dynamic> json) {
type = json['type'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['type'] = type;
return data;
}
}

View file

@ -0,0 +1,70 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class MatrixDeviceKeys {
String userId;
String deviceId;
List<String> algorithms;
Map<String, String> keys;
Map<String, Map<String, String>> signatures;
Map<String, dynamic> unsigned;
String get deviceDisplayName =>
unsigned != null ? unsigned['device_display_name'] : null;
// This object is used for signing so we need the raw json too
Map<String, dynamic> _json;
MatrixDeviceKeys(
this.userId,
this.deviceId,
this.algorithms,
this.keys,
this.signatures, {
this.unsigned,
});
MatrixDeviceKeys.fromJson(Map<String, dynamic> json) {
_json = json;
userId = json['user_id'];
deviceId = json['device_id'];
algorithms = json['algorithms'].cast<String>();
keys = Map<String, String>.from(json['keys']);
signatures = Map<String, Map<String, String>>.from(
(json['signatures'] as Map)
.map((k, v) => MapEntry(k, Map<String, String>.from(v))));
unsigned = json['unsigned'] != null
? Map<String, dynamic>.from(json['unsigned'])
: null;
}
Map<String, dynamic> toJson() {
final data = _json ?? <String, dynamic>{};
data['user_id'] = userId;
data['device_id'] = deviceId;
data['algorithms'] = algorithms;
data['keys'] = keys;
if (signatures != null) {
data['signatures'] = signatures;
}
if (unsigned != null) {
data['unsigned'] = unsigned;
}
return data;
}
}

View file

@ -0,0 +1,67 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/matrix_api/model/stripped_state_event.dart';
class MatrixEvent extends StrippedStateEvent {
String eventId;
String roomId;
DateTime originServerTs;
Map<String, dynamic> unsigned;
Map<String, dynamic> prevContent;
MatrixEvent();
MatrixEvent.fromJson(Map<String, dynamic> json) {
final strippedStateEvent = StrippedStateEvent.fromJson(json);
content = strippedStateEvent.content;
type = strippedStateEvent.type;
senderId = strippedStateEvent.senderId;
stateKey = strippedStateEvent.stateKey;
eventId = json['event_id'];
roomId = json['room_id'];
originServerTs =
DateTime.fromMillisecondsSinceEpoch(json['origin_server_ts']);
unsigned = json['unsigned'] != null
? Map<String, dynamic>.from(json['unsigned'])
: null;
prevContent = json['prev_content'] != null
? Map<String, dynamic>.from(json['prev_content'])
: null;
}
@override
Map<String, dynamic> toJson() {
final data = super.toJson();
data['event_id'] = eventId;
data['origin_server_ts'] = originServerTs.millisecondsSinceEpoch;
if (unsigned != null) {
data['unsigned'] = unsigned;
}
if (prevContent != null) {
data['prev_content'] = prevContent;
}
if (roomId != null) {
data['room_id'] = roomId;
}
if (data['state_key'] == null) {
data.remove('state_key');
}
return data;
}
}

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:convert';
@ -62,6 +57,7 @@ class MatrixException implements Exception {
http.Response response;
MatrixException(this.response) : raw = json.decode(response.body);
MatrixException.fromJson(Map<String, dynamic> content) : raw = content;
@override
String toString() => '$errcode: $errorMessage';
@ -78,7 +74,9 @@ class MatrixException implements Exception {
String get session => raw['session'];
/// Returns true if the server requires additional authentication.
bool get requireAdditionalAuthentication => response.statusCode == 401;
bool get requireAdditionalAuthentication => response != null
? response.statusCode == 401
: authenticationFlows != null;
/// For each endpoint, a server offers one or more 'flows' that the client can use
/// to authenticate itself. Each flow comprises a series of stages. If this request

View file

@ -0,0 +1,32 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
abstract class MessageTypes {
static const String Text = 'm.text';
static const String Emote = 'm.emote';
static const String Notice = 'm.notice';
static const String Image = 'm.image';
static const String Video = 'm.video';
static const String Audio = 'm.audio';
static const String File = 'm.file';
static const String Location = 'm.location';
static const String Reply = 'm.relates_to';
static const String Sticker = 'm.sticker';
static const String BadEncrypted = 'm.bad.encrypted';
static const String None = 'm.none';
}

View file

@ -0,0 +1,72 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'matrix_event.dart';
class NotificationsQueryResponse {
String nextToken;
List<Notification> notifications;
NotificationsQueryResponse.fromJson(Map<String, dynamic> json) {
nextToken = json['next_token'];
notifications = <Notification>[];
json['notifications'].forEach((v) {
notifications.add(Notification.fromJson(v));
});
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (nextToken != null) {
data['next_token'] = nextToken;
}
data['notifications'] = notifications.map((v) => v.toJson()).toList();
return data;
}
}
class Notification {
List<String> actions;
String profileTag;
bool read;
String roomId;
int ts;
MatrixEvent event;
Notification.fromJson(Map<String, dynamic> json) {
actions = json['actions'].cast<String>();
profileTag = json['profile_tag'];
read = json['read'];
roomId = json['room_id'];
ts = json['ts'];
event = MatrixEvent.fromJson(json['event']);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['actions'] = actions;
if (profileTag != null) {
data['profile_tag'] = profileTag;
}
data['read'] = read;
data['room_id'] = roomId;
data['ts'] = ts;
data['event'] = event.toJson();
return data;
}
}

View file

@ -0,0 +1,38 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class OneTimeKeysClaimResponse {
Map<String, dynamic> failures;
Map<String, Map<String, dynamic>> oneTimeKeys;
OneTimeKeysClaimResponse.fromJson(Map<String, dynamic> json) {
failures = Map<String, dynamic>.from(json['failures']);
oneTimeKeys = Map<String, Map<String, dynamic>>.from(json['one_time_keys']);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (failures != null) {
data['failures'] = failures;
}
if (oneTimeKeys != null) {
data['one_time_keys'] = oneTimeKeys;
}
return data;
}
}

View file

@ -0,0 +1,63 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class OpenGraphData {
String ogTitle;
String ogDescription;
String ogImage;
String ogImageType;
int ogImageHeight;
int ogImageWidth;
int matrixImageSize;
OpenGraphData.fromJson(Map<String, dynamic> json) {
ogTitle = json['og:title'];
ogDescription = json['og:description'];
ogImage = json['og:image'];
ogImageType = json['og:image:type'];
ogImageHeight = json['og:image:height'];
ogImageWidth = json['og:image:width'];
matrixImageSize = json['matrix:image:size'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (ogTitle != null) {
data['og:title'] = ogTitle;
}
if (ogDescription != null) {
data['og:description'] = ogDescription;
}
if (ogImage != null) {
data['og:image'] = ogImage;
}
if (ogImageType != null) {
data['og:image:type'] = ogImageType;
}
if (ogImageHeight != null) {
data['og:image:height'] = ogImageHeight;
}
if (ogImageWidth != null) {
data['og:image:width'] = ogImageWidth;
}
if (matrixImageSize != null) {
data['matrix:image:size'] = matrixImageSize;
}
return data;
}
}

View file

@ -0,0 +1,40 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class OpenIdCredentials {
String accessToken;
String tokenType;
String matrixServerName;
int expiresIn;
OpenIdCredentials.fromJson(Map<String, dynamic> json) {
accessToken = json['access_token'];
tokenType = json['token_type'];
matrixServerName = json['matrix_server_name'];
expiresIn = json['expires_in'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['access_token'] = accessToken;
data['token_type'] = tokenType;
data['matrix_server_name'] = matrixServerName;
data['expires_in'] = expiresIn;
return data;
}
}

View file

@ -0,0 +1,32 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'basic_event_with_sender.dart';
import 'presence_content.dart';
class Presence extends BasicEventWithSender {
PresenceContent presence;
Presence.fromJson(Map<String, dynamic> json) {
final basicEvent = BasicEventWithSender.fromJson(json);
type = basicEvent.type;
content = basicEvent.content;
senderId = basicEvent.senderId;
presence = PresenceContent.fromJson(content);
}
}

View file

@ -0,0 +1,49 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
enum PresenceType { online, offline, unavailable }
class PresenceContent {
PresenceType presence;
int lastActiveAgo;
String statusMsg;
bool currentlyActive;
PresenceContent.fromJson(Map<String, dynamic> json) {
presence = PresenceType.values
.firstWhere((p) => p.toString().split('.').last == json['presence']);
lastActiveAgo = json['last_active_ago'];
statusMsg = json['status_msg'];
currentlyActive = json['currently_active'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['presence'] = presence.toString().split('.').last;
if (lastActiveAgo != null) {
data['last_active_ago'] = lastActiveAgo;
}
if (statusMsg != null) {
data['status_msg'] = statusMsg;
}
if (currentlyActive != null) {
data['currently_active'] = currentlyActive;
}
return data;
}
}

View file

@ -0,0 +1,44 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class Profile {
/// The user's avatar URL if they have set one, otherwise null.
Uri avatarUrl;
/// The user's display name if they have set one, otherwise null.
String displayname;
/// The matrix ID of this user. May be omitted.
String userId;
Map<String, dynamic> additionalContent;
Profile(this.displayname, this.avatarUrl,
{this.additionalContent = const {}});
Profile.fromJson(Map<String, dynamic> json)
: avatarUrl =
json['avatar_url'] != null ? Uri.parse(json['avatar_url']) : null,
displayname = json['display_name'] ?? json['displayname'],
userId = json['user_id'],
additionalContent = json;
Map<String, dynamic> toJson() {
return additionalContent;
}
}

View file

@ -0,0 +1,97 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class PublicRoomsResponse {
List<PublicRoom> chunk;
String nextBatch;
String prevBatch;
int totalRoomCountEstimate;
PublicRoomsResponse.fromJson(Map<String, dynamic> json) {
chunk = <PublicRoom>[];
json['chunk'].forEach((v) {
chunk.add(PublicRoom.fromJson(v));
});
nextBatch = json['next_batch'];
prevBatch = json['prev_batch'];
totalRoomCountEstimate = json['total_room_count_estimate'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['chunk'] = chunk.map((v) => v.toJson()).toList();
if (nextBatch != null) {
data['next_batch'] = nextBatch;
}
if (prevBatch != null) {
data['prev_batch'] = prevBatch;
}
if (totalRoomCountEstimate != null) {
data['total_room_count_estimate'] = totalRoomCountEstimate;
}
return data;
}
}
class PublicRoom {
List<String> aliases;
String avatarUrl;
bool guestCanJoin;
String name;
int numJoinedMembers;
String roomId;
String topic;
bool worldReadable;
String canonicalAlias;
PublicRoom.fromJson(Map<String, dynamic> json) {
aliases = json['aliases']?.cast<String>();
avatarUrl = json['avatar_url'];
guestCanJoin = json['guest_can_join'];
canonicalAlias = json['canonical_alias'];
name = json['name'];
numJoinedMembers = json['num_joined_members'];
roomId = json['room_id'];
topic = json['topic'];
worldReadable = json['world_readable'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (aliases != null) {
data['aliases'] = aliases;
}
if (canonicalAlias != null) {
data['canonical_alias'] = canonicalAlias;
}
if (avatarUrl != null) {
data['avatar_url'] = avatarUrl;
}
data['guest_can_join'] = guestCanJoin;
if (name != null) {
data['name'] = name;
}
data['num_joined_members'] = numJoinedMembers;
data['room_id'] = roomId;
if (topic != null) {
data['topic'] = topic;
}
data['world_readable'] = worldReadable;
return data;
}
}

View file

@ -0,0 +1,143 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
enum PushRuleKind { content, override, room, sender, underride }
enum PushRuleAction { notify, dont_notify, coalesce, set_tweak }
class PushRuleSet {
List<PushRule> content;
List<PushRule> override;
List<PushRule> room;
List<PushRule> sender;
List<PushRule> underride;
PushRuleSet.fromJson(Map<String, dynamic> json) {
if (json['content'] != null) {
content =
(json['content'] as List).map((i) => PushRule.fromJson(i)).toList();
}
if (json['override'] != null) {
override =
(json['override'] as List).map((i) => PushRule.fromJson(i)).toList();
}
if (json['room'] != null) {
room = (json['room'] as List).map((i) => PushRule.fromJson(i)).toList();
}
if (json['sender'] != null) {
sender =
(json['sender'] as List).map((i) => PushRule.fromJson(i)).toList();
}
if (json['underride'] != null) {
underride =
(json['underride'] as List).map((i) => PushRule.fromJson(i)).toList();
}
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (content != null) {
data['content'] = content.map((v) => v.toJson()).toList();
}
if (override != null) {
data['override'] = override.map((v) => v.toJson()).toList();
}
if (room != null) {
data['room'] = room.map((v) => v.toJson()).toList();
}
if (sender != null) {
data['sender'] = sender.map((v) => v.toJson()).toList();
}
if (underride != null) {
data['underride'] = underride.map((v) => v.toJson()).toList();
}
return data;
}
}
class PushRule {
List<dynamic> actions;
List<PushConditions> conditions;
bool isDefault;
bool enabled;
String pattern;
String ruleId;
PushRule.fromJson(Map<String, dynamic> json) {
actions = json['actions'];
isDefault = json['default'];
enabled = json['enabled'];
pattern = json['pattern'];
ruleId = json['rule_id'];
conditions = json['conditions'] != null
? (json['conditions'] as List)
.map((i) => PushConditions.fromJson(i))
.toList()
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['actions'] = actions;
data['default'] = isDefault;
data['enabled'] = enabled;
if (pattern != null) {
data['pattern'] = pattern;
}
if (conditions != null) {
data['conditions'] = conditions.map((i) => i.toJson()).toList();
}
data['rule_id'] = ruleId;
return data;
}
}
class PushConditions {
String key;
String kind;
String pattern;
String isOperator;
PushConditions(
this.kind, {
this.key,
this.pattern,
this.isOperator,
});
PushConditions.fromJson(Map<String, dynamic> json) {
key = json['key'];
kind = json['kind'];
pattern = json['pattern'];
isOperator = json['is'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (key != null) {
data['key'] = key;
}
data['kind'] = kind;
if (pattern != null) {
data['pattern'] = pattern;
}
if (isOperator != null) {
data['is'] = isOperator;
}
return data;
}
}

View file

@ -0,0 +1,91 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class Pusher {
String pushkey;
String kind;
String appId;
String appDisplayName;
String deviceDisplayName;
String profileTag;
String lang;
PusherData data;
Pusher(
this.pushkey,
this.appId,
this.appDisplayName,
this.deviceDisplayName,
this.lang,
this.data, {
this.profileTag,
this.kind,
});
Pusher.fromJson(Map<String, dynamic> json) {
pushkey = json['pushkey'];
kind = json['kind'];
appId = json['app_id'];
appDisplayName = json['app_display_name'];
deviceDisplayName = json['device_display_name'];
profileTag = json['profile_tag'];
lang = json['lang'];
data = PusherData.fromJson(json['data']);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['pushkey'] = pushkey;
data['kind'] = kind;
data['app_id'] = appId;
data['app_display_name'] = appDisplayName;
data['device_display_name'] = deviceDisplayName;
if (profileTag != null) {
data['profile_tag'] = profileTag;
}
data['lang'] = lang;
data['data'] = this.data.toJson();
return data;
}
}
class PusherData {
Uri url;
String format;
PusherData({
this.url,
this.format,
});
PusherData.fromJson(Map<String, dynamic> json) {
url = Uri.parse(json['url']);
format = json['format'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (url != null) {
data['url'] = url.toString();
}
if (format != null) {
data['format'] = format;
}
return data;
}
}

View file

@ -0,0 +1,34 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class RequestTokenResponse {
String sid;
String submitUrl;
RequestTokenResponse.fromJson(Map<String, dynamic> json) {
sid = json['sid'];
submitUrl = json['submit_url'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['sid'] = sid;
data['submit_url'] = submitUrl;
return data;
}
}

View file

@ -0,0 +1,34 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class RoomAliasInformations {
String roomId;
List<String> servers;
RoomAliasInformations.fromJson(Map<String, dynamic> json) {
roomId = json['room_id'];
servers = json['servers'].cast<String>();
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['room_id'] = roomId;
data['servers'] = servers;
return data;
}
}

View file

@ -0,0 +1,42 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class RoomSummary {
List<String> mHeroes;
int mJoinedMemberCount;
int mInvitedMemberCount;
RoomSummary.fromJson(Map<String, dynamic> json) {
mHeroes =
json['m.heroes'] != null ? List<String>.from(json['m.heroes']) : null;
mJoinedMemberCount = json['m.joined_member_count'];
mInvitedMemberCount = json['m.invited_member_count'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (mHeroes != null) {
data['m.heroes'] = mHeroes;
}
if (mJoinedMemberCount != null) {
data['m.joined_member_count'] = mJoinedMemberCount;
}
if (mInvitedMemberCount != null) {
data['m.invited_member_count'] = mInvitedMemberCount;
}
return data;
}
}

View file

@ -0,0 +1,89 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
enum RoomVersionStability { stable, unstable }
class ServerCapabilities {
MChangePassword mChangePassword;
MRoomVersions mRoomVersions;
Map<String, dynamic> customCapabilities;
ServerCapabilities.fromJson(Map<String, dynamic> json) {
mChangePassword = json['m.change_password'] != null
? MChangePassword.fromJson(json['m.change_password'])
: null;
mRoomVersions = json['m.room_versions'] != null
? MRoomVersions.fromJson(json['m.room_versions'])
: null;
customCapabilities = Map<String, dynamic>.from(json);
customCapabilities.remove('m.change_password');
customCapabilities.remove('m.room_versions');
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (mChangePassword != null) {
data['m.change_password'] = mChangePassword.toJson();
}
if (mRoomVersions != null) {
data['m.room_versions'] = mRoomVersions.toJson();
}
for (final entry in customCapabilities.entries) {
data[entry.key] = entry.value;
}
return data;
}
}
class MChangePassword {
bool enabled;
MChangePassword.fromJson(Map<String, dynamic> json) {
enabled = json['enabled'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['enabled'] = enabled;
return data;
}
}
class MRoomVersions {
String defaultVersion;
Map<String, RoomVersionStability> available;
MRoomVersions.fromJson(Map<String, dynamic> json) {
defaultVersion = json['default'];
available = (json['available'] as Map).map<String, RoomVersionStability>(
(k, v) => MapEntry(
k,
RoomVersionStability.values
.firstWhere((r) => r.toString().split('.').last == v),
),
);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['default'] = defaultVersion;
data['available'] = available.map<String, dynamic>(
(k, v) => MapEntry(k, v.toString().split('.').last));
return data;
}
}

View file

@ -0,0 +1,39 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/matrix_api/model/basic_event_with_sender.dart';
class StrippedStateEvent extends BasicEventWithSender {
String stateKey;
StrippedStateEvent();
StrippedStateEvent.fromJson(Map<String, dynamic> json) {
final basicEvent = BasicEventWithSender.fromJson(json);
content = basicEvent.content;
type = basicEvent.type;
senderId = basicEvent.senderId;
stateKey = json['state_key'];
}
@override
Map<String, dynamic> toJson() {
final data = super.toJson();
data['state_key'] = stateKey;
return data;
}
}

View file

@ -0,0 +1,92 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class SupportedProtocol {
List<String> userFields;
List<String> locationFields;
String icon;
Map<String, ProtocolFieldType> fieldTypes;
List<ProtocolInstance> instances;
SupportedProtocol.fromJson(Map<String, dynamic> json) {
userFields = json['user_fields'].cast<String>();
locationFields = json['location_fields'].cast<String>();
icon = json['icon'];
fieldTypes = (json['field_types'] as Map)
.map((k, v) => MapEntry(k, ProtocolFieldType.fromJson(v)));
instances = <ProtocolInstance>[];
json['instances'].forEach((v) {
instances.add(ProtocolInstance.fromJson(v));
});
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['user_fields'] = userFields;
data['location_fields'] = locationFields;
data['icon'] = icon;
data['field_types'] = fieldTypes.map((k, v) => MapEntry(k, v.toJson()));
data['instances'] = instances.map((v) => v.toJson()).toList();
return data;
}
}
class ProtocolFieldType {
String regexp;
String placeholder;
ProtocolFieldType.fromJson(Map<String, dynamic> json) {
regexp = json['regexp'];
placeholder = json['placeholder'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['regexp'] = regexp;
data['placeholder'] = placeholder;
return data;
}
}
class ProtocolInstance {
String networkId;
String desc;
String icon;
dynamic fields;
ProtocolInstance.fromJson(Map<String, dynamic> json) {
networkId = json['network_id'];
desc = json['desc'];
icon = json['icon'];
fields = json['fields'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['network_id'] = networkId;
data['desc'] = desc;
if (icon != null) {
data['icon'] = icon;
}
data['fields'] = fields;
return data;
}
}

View file

@ -0,0 +1,36 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class SupportedVersions {
List<String> versions;
Map<String, bool> unstableFeatures;
SupportedVersions.fromJson(Map<String, dynamic> json) {
versions = json['versions'].cast<String>();
unstableFeatures = Map<String, bool>.from(json['unstable_features']);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['versions'] = versions;
if (unstableFeatures != null) {
data['unstable_features'] = unstableFeatures;
}
return data;
}
}

View file

@ -0,0 +1,321 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'basic_event_with_sender.dart';
import 'basic_room_event.dart';
import 'stripped_state_event.dart';
import 'matrix_event.dart';
import 'basic_event.dart';
import 'presence.dart';
import 'room_summary.dart';
class SyncUpdate {
String nextBatch;
RoomsUpdate rooms;
List<Presence> presence;
List<BasicEvent> accountData;
List<BasicEventWithSender> toDevice;
DeviceListsUpdate deviceLists;
Map<String, int> deviceOneTimeKeysCount;
SyncUpdate.fromJson(Map<String, dynamic> json) {
nextBatch = json['next_batch'];
rooms = json['rooms'] != null ? RoomsUpdate.fromJson(json['rooms']) : null;
presence = (json['presence'] != null && json['presence']['events'] != null)
? (json['presence']['events'] as List)
.map((i) => Presence.fromJson(i))
.toList()
: null;
accountData =
(json['account_data'] != null && json['account_data']['events'] != null)
? (json['account_data']['events'] as List)
.map((i) => BasicEvent.fromJson(i))
.toList()
: null;
toDevice =
(json['to_device'] != null && json['to_device']['events'] != null)
? (json['to_device']['events'] as List)
.map((i) => BasicEventWithSender.fromJson(i))
.toList()
: null;
deviceLists = json['device_lists'] != null
? DeviceListsUpdate.fromJson(json['device_lists'])
: null;
deviceOneTimeKeysCount = json['device_one_time_keys_count'] != null
? Map<String, int>.from(json['device_one_time_keys_count'])
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['next_batch'] = nextBatch;
if (rooms != null) {
data['rooms'] = rooms.toJson();
}
if (presence != null) {
data['presence'] = {
'events': presence.map((i) => i.toJson()).toList(),
};
}
if (accountData != null) {
data['account_data'] = {
'events': accountData.map((i) => i.toJson()).toList(),
};
}
if (toDevice != null) {
data['to_device'] = {
'events': toDevice.map((i) => i.toJson()).toList(),
};
}
if (deviceLists != null) {
data['device_lists'] = deviceLists.toJson();
}
if (deviceOneTimeKeysCount != null) {
data['device_one_time_keys_count'] = deviceOneTimeKeysCount;
}
return data;
}
}
class RoomsUpdate {
Map<String, JoinedRoomUpdate> join;
Map<String, InvitedRoomUpdate> invite;
Map<String, LeftRoomUpdate> leave;
RoomsUpdate.fromJson(Map<String, dynamic> json) {
join = json['join'] != null
? (json['join'] as Map)
.map((k, v) => MapEntry(k, JoinedRoomUpdate.fromJson(v)))
: null;
invite = json['invite'] != null
? (json['invite'] as Map)
.map((k, v) => MapEntry(k, InvitedRoomUpdate.fromJson(v)))
: null;
leave = json['leave'] != null
? (json['leave'] as Map)
.map((k, v) => MapEntry(k, LeftRoomUpdate.fromJson(v)))
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (join != null) {
data['join'] = join.map((k, v) => MapEntry(k, v.toJson()));
}
if (invite != null) {
data['invite'] = invite.map((k, v) => MapEntry(k, v.toJson()));
}
if (leave != null) {
data['leave'] = leave.map((k, v) => MapEntry(k, v.toJson()));
}
return data;
}
}
abstract class SyncRoomUpdate {}
class JoinedRoomUpdate extends SyncRoomUpdate {
RoomSummary summary;
List<MatrixEvent> state;
TimelineUpdate timeline;
List<BasicRoomEvent> ephemeral;
List<BasicRoomEvent> accountData;
UnreadNotificationCounts unreadNotifications;
JoinedRoomUpdate.fromJson(Map<String, dynamic> json) {
summary =
json['summary'] != null ? RoomSummary.fromJson(json['summary']) : null;
state = (json['state'] != null && json['state']['events'] != null)
? (json['state']['events'] as List)
.map((i) => MatrixEvent.fromJson(i))
.toList()
: null;
timeline = json['timeline'] != null
? TimelineUpdate.fromJson(json['timeline'])
: null;
ephemeral =
(json['ephemeral'] != null && json['ephemeral']['events'] != null)
? (json['ephemeral']['events'] as List)
.map((i) => BasicRoomEvent.fromJson(i))
.toList()
: null;
accountData =
(json['account_data'] != null && json['account_data']['events'] != null)
? (json['account_data']['events'] as List)
.map((i) => BasicRoomEvent.fromJson(i))
.toList()
: null;
unreadNotifications = json['unread_notifications'] != null
? UnreadNotificationCounts.fromJson(json['unread_notifications'])
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (summary != null) {
data['summary'] = summary.toJson();
}
if (state != null) {
data['state'] = {
'events': state.map((i) => i.toJson()).toList(),
};
}
if (timeline != null) {
data['timeline'] = timeline.toJson();
}
if (ephemeral != null) {
data['ephemeral'] = {
'events': ephemeral.map((i) => i.toJson()).toList(),
};
}
if (accountData != null) {
data['account_data'] = {
'events': accountData.map((i) => i.toJson()).toList(),
};
}
if (unreadNotifications != null) {
data['unread_notifications'] = unreadNotifications.toJson();
}
return data;
}
}
class InvitedRoomUpdate extends SyncRoomUpdate {
List<StrippedStateEvent> inviteState;
InvitedRoomUpdate.fromJson(Map<String, dynamic> json) {
inviteState =
(json['invite_state'] != null && json['invite_state']['events'] != null)
? (json['invite_state']['events'] as List)
.map((i) => StrippedStateEvent.fromJson(i))
.toList()
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (inviteState != null) {
data['invite_state'] = {
'events': inviteState.map((i) => i.toJson()).toList(),
};
}
return data;
}
}
class LeftRoomUpdate extends SyncRoomUpdate {
List<MatrixEvent> state;
TimelineUpdate timeline;
List<BasicRoomEvent> accountData;
LeftRoomUpdate.fromJson(Map<String, dynamic> json) {
state = (json['state'] != null && json['state']['events'] != null)
? (json['state']['events'] as List)
.map((i) => MatrixEvent.fromJson(i))
.toList()
: null;
timeline = json['timeline'] != null
? TimelineUpdate.fromJson(json['timeline'])
: null;
accountData =
(json['account_data'] != null && json['account_data']['events'] != null)
? (json['account_data']['events'] as List)
.map((i) => BasicRoomEvent.fromJson(i))
.toList()
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (state != null) {
data['state'] = {
'events': state.map((i) => i.toJson()).toList(),
};
}
if (timeline != null) {
data['timeline'] = timeline.toJson();
}
if (accountData != null) {
data['account_data'] = {
'events': accountData.map((i) => i.toJson()).toList(),
};
}
return data;
}
}
class TimelineUpdate {
List<MatrixEvent> events;
bool limited;
String prevBatch;
TimelineUpdate.fromJson(Map<String, dynamic> json) {
events = json['events'] != null
? (json['events'] as List).map((i) => MatrixEvent.fromJson(i)).toList()
: null;
limited = json['limited'];
prevBatch = json['prev_batch'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (events != null) {
data['events'] = events.map((i) => i.toJson()).toList();
}
if (limited != null) {
data['limited'] = limited;
}
if (prevBatch != null) {
data['prev_batch'] = prevBatch;
}
return data;
}
}
class UnreadNotificationCounts {
int highlightCount;
int notificationCount;
UnreadNotificationCounts.fromJson(Map<String, dynamic> json) {
highlightCount = json['highlight_count'];
notificationCount = json['notification_count'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (highlightCount != null) {
data['highlight_count'] = highlightCount;
}
if (notificationCount != null) {
data['notification_count'] = notificationCount;
}
return data;
}
}
class DeviceListsUpdate {
List<String> changed;
List<String> left;
DeviceListsUpdate.fromJson(Map<String, dynamic> json) {
changed = List<String>.from(json['changed']);
left = List<String>.from(json['left']);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (changed != null) {
data['changed'] = changed;
}
if (left != null) {
data['left'] = left;
}
return data;
}
}

View file

@ -0,0 +1,33 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class Tag {
double order;
Tag.fromJson(Map<String, dynamic> json) {
order = json['order'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (order != null) {
data['order'] = order;
}
return data;
}
}

View file

@ -0,0 +1,40 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class ThirdPartyIdentifier {
String medium;
String address;
int validatedAt;
int addedAt;
ThirdPartyIdentifier.fromJson(Map<String, dynamic> json) {
medium = json['medium'];
address = json['address'];
validatedAt = json['validated_at'];
addedAt = json['added_at'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['medium'] = medium;
data['address'] = address;
data['validated_at'] = validatedAt;
data['added_at'] = addedAt;
return data;
}
}

View file

@ -0,0 +1,37 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class ThirdPartyLocation {
String alias;
String protocol;
Map<String, dynamic> fields;
ThirdPartyLocation.fromJson(Map<String, dynamic> json) {
alias = json['alias'];
protocol = json['protocol'];
fields = Map<String, dynamic>.from(json['fields']);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['alias'] = alias;
data['protocol'] = protocol;
data['fields'] = fields;
return data;
}
}

View file

@ -0,0 +1,37 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class ThirdPartyUser {
String userId;
String protocol;
Map<String, dynamic> fields;
ThirdPartyUser.fromJson(Map<String, dynamic> json) {
userId = json['userid'];
protocol = json['protocol'];
fields = Map<String, dynamic>.from(json['fields']);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['userid'] = userId;
data['protocol'] = protocol;
data['fields'] = fields;
return data;
}
}

View file

@ -0,0 +1,46 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'matrix_event.dart';
class TimelineHistoryResponse {
String start;
String end;
List<MatrixEvent> chunk;
List<MatrixEvent> state;
TimelineHistoryResponse.fromJson(Map<String, dynamic> json) {
start = json['start'];
end = json['end'];
chunk = json['chunk'] != null
? (json['chunk'] as List).map((i) => MatrixEvent.fromJson(i)).toList()
: null;
state = json['state'] != null
? (json['state'] as List).map((i) => MatrixEvent.fromJson(i)).toList()
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (start != null) data['start'] = start;
if (end != null) data['end'] = end;
if (chunk != null) data['chunk'] = chunk.map((i) => i.toJson());
if (state != null) data['state'] = state.map((i) => i.toJson());
return data;
}
}

View file

@ -0,0 +1,40 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class TurnServerCredentials {
String username;
String password;
List<String> uris;
int ttl;
TurnServerCredentials.fromJson(Map<String, dynamic> json) {
username = json['username'];
password = json['password'];
uris = json['uris'].cast<String>();
ttl = json['ttl'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['username'] = username;
data['password'] = password;
data['uris'] = uris;
data['ttl'] = ttl;
return data;
}
}

View file

@ -0,0 +1,41 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'profile.dart';
class UserSearchResult {
List<Profile> results;
bool limited;
UserSearchResult.fromJson(Map<String, dynamic> json) {
results = <Profile>[];
json['results'].forEach((v) {
results.add(Profile.fromJson(v));
});
limited = json['limited'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['results'] = results.map((v) => v.toJson()).toList();
data['limited'] = limited;
return data;
}
}

View file

@ -0,0 +1,54 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class WellKnownInformations {
MHomeserver mHomeserver;
MHomeserver mIdentityServer;
Map<String, dynamic> content;
WellKnownInformations.fromJson(Map<String, dynamic> json) {
content = json;
mHomeserver = json['m.homeserver'] != null
? MHomeserver.fromJson(json['m.homeserver'])
: null;
mIdentityServer = json['m.identity_server'] != null
? MHomeserver.fromJson(json['m.identity_server'])
: null;
}
Map<String, dynamic> toJson() {
final data = content;
data['m.homeserver'] = mHomeserver.toJson();
data['m.identity_server'] = mIdentityServer.toJson();
return data;
}
}
class MHomeserver {
String baseUrl;
MHomeserver.fromJson(Map<String, dynamic> json) {
baseUrl = json['base_url'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['base_url'] = baseUrl;
return data;
}
}

View file

@ -0,0 +1,107 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class WhoIsInfo {
String userId;
Map<String, DeviceInfo> devices;
WhoIsInfo.fromJson(Map<String, dynamic> json) {
userId = json['user_id'];
devices = json['devices'] != null
? (json['devices'] as Map)
.map((k, v) => MapEntry(k, DeviceInfo.fromJson(v)))
: null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['user_id'] = userId;
if (devices != null) {
data['devices'] = devices.map((k, v) => MapEntry(k, v.toJson()));
}
return data;
}
}
class DeviceInfo {
List<Sessions> sessions;
DeviceInfo.fromJson(Map<String, dynamic> json) {
if (json['sessions'] != null) {
sessions = <Sessions>[];
json['sessions'].forEach((v) {
sessions.add(Sessions.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (sessions != null) {
data['sessions'] = sessions.map((v) => v.toJson()).toList();
}
return data;
}
}
class Sessions {
List<Connections> connections;
Sessions.fromJson(Map<String, dynamic> json) {
if (json['connections'] != null) {
connections = <Connections>[];
json['connections'].forEach((v) {
connections.add(Connections.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (connections != null) {
data['connections'] = connections.map((v) => v.toJson()).toList();
}
return data;
}
}
class Connections {
String ip;
int lastSeen;
String userAgent;
Connections.fromJson(Map<String, dynamic> json) {
ip = json['ip'];
lastSeen = json['last_seen'];
userAgent = json['user_agent'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (ip != null) {
data['ip'] = ip;
}
if (lastSeen != null) {
data['last_seen'] = lastSeen;
}
if (userAgent != null) {
data['user_agent'] = userAgent;
}
return data;
}
}

View file

@ -1,48 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import './database/database.dart' show DbAccountData;
/// The global private data created by this user.
class AccountData {
/// The json payload of the content. The content highly depends on the type.
final Map<String, dynamic> content;
/// The type String of this event. For example 'm.room.message'.
final String typeKey;
AccountData({this.content, this.typeKey});
/// Get a State event from a table row or from the event stream.
factory AccountData.fromJson(Map<String, dynamic> jsonPayload) {
final content = Event.getMapFromPayload(jsonPayload['content']);
return AccountData(content: content, typeKey: jsonPayload['type']);
}
/// Get account data from DbAccountData
factory AccountData.fromDb(DbAccountData dbEntry) {
final content = Event.getMapFromPayload(dbEntry.content);
return AccountData(content: content, typeKey: dbEntry.type);
}
}

File diff suppressed because it is too large Load diff

View file

@ -2,8 +2,11 @@ import 'package:moor/moor.dart';
import 'dart:convert';
import 'package:famedlysdk/famedlysdk.dart' as sdk;
import 'package:famedlysdk/matrix_api.dart' as api;
import 'package:olm/olm.dart' as olm;
import '../../matrix_api.dart';
part 'database.g.dart';
@UseMoor(
@ -134,20 +137,31 @@ class Database extends _$Database {
return roomList;
}
Future<Map<String, sdk.AccountData>> getAccountData(int clientId) async {
final newAccountData = <String, sdk.AccountData>{};
Future<Map<String, api.BasicEvent>> getAccountData(int clientId) async {
final newAccountData = <String, api.BasicEvent>{};
final rawAccountData = await getAllAccountData(clientId).get();
for (final d in rawAccountData) {
newAccountData[d.type] = sdk.AccountData.fromDb(d);
final content = sdk.Event.getMapFromPayload(d.content);
newAccountData[d.type] = api.BasicEvent(
content: content,
type: d.type,
);
}
return newAccountData;
}
Future<Map<String, sdk.Presence>> getPresences(int clientId) async {
final newPresences = <String, sdk.Presence>{};
Future<Map<String, api.Presence>> getPresences(int clientId) async {
final newPresences = <String, api.Presence>{};
final rawPresences = await getAllPresences(clientId).get();
for (final d in rawPresences) {
newPresences[d.sender] = sdk.Presence.fromDb(d);
// TODO: Why is this not working?
try {
final content = sdk.Event.getMapFromPayload(d.content);
var presence = api.Presence.fromJson(content);
presence.senderId = d.sender;
presence.type = d.type;
newPresences[d.sender] = api.Presence.fromJson(content);
} catch (_) {}
}
return newPresences;
}
@ -158,7 +172,7 @@ class Database extends _$Database {
Future<void> storeRoomUpdate(int clientId, sdk.RoomUpdate roomUpdate,
[sdk.Room oldRoom]) async {
final setKey = '${clientId};${roomUpdate.id}';
if (roomUpdate.membership != sdk.Membership.leave) {
if (roomUpdate.membership != api.Membership.leave) {
if (!_ensuredRooms.contains(setKey)) {
await ensureRoomExists(clientId, roomUpdate.id,
roomUpdate.membership.toString().split('.').last);
@ -219,16 +233,17 @@ class Database extends _$Database {
/// Stores an UserUpdate object in the database. Must be called inside of
/// [transaction].
Future<void> storeUserEventUpdate(
int clientId, sdk.UserUpdate userUpdate) async {
if (userUpdate.type == 'account_data') {
await storeAccountData(clientId, userUpdate.eventType,
json.encode(userUpdate.content['content']));
} else if (userUpdate.type == 'presence') {
await storePresence(
clientId,
userUpdate.eventType,
userUpdate.content['sender'],
json.encode(userUpdate.content['content']));
int clientId,
String type,
String eventType,
Map<String, dynamic> content,
) async {
if (type == 'account_data') {
await storeAccountData(
clientId, eventType, json.encode(content['content']));
} else if (type == 'presence') {
await storePresence(clientId, eventType, content['sender'],
json.encode(content['content']));
}
}
@ -247,7 +262,7 @@ class Database extends _$Database {
stateKey = eventContent['state_key'];
}
if (eventUpdate.eventType == 'm.room.redaction') {
if (eventUpdate.eventType == EventTypes.Redaction) {
await redactMessage(clientId, eventUpdate);
}

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:convert';
@ -27,49 +22,24 @@ import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/receipt.dart';
import 'package:http/http.dart' as http;
import 'package:matrix_file_e2ee/matrix_file_e2ee.dart';
import '../matrix_api.dart';
import './room.dart';
import 'utils/matrix_localizations.dart';
import './database/database.dart' show DbRoomState, DbEvent;
/// All data exchanged over Matrix is expressed as an "event". Typically each client action (e.g. sending a message) correlates with exactly one event.
class Event {
/// The Matrix ID for this event in the format '$localpart:server.abc'. Please not
/// that account data, presence and other events may not have an eventId.
final String eventId;
/// The json payload of the content. The content highly depends on the type.
Map<String, dynamic> content;
/// The type String of this event. For example 'm.room.message'.
final String typeKey;
/// The ID of the room this event belongs to.
final String roomId;
/// The user who has sent this event if it is not a global account data event.
final String senderId;
class Event extends MatrixEvent {
User get sender => room.getUserByMXIDSync(senderId ?? '@unknown');
/// The time this event has received at the server. May be null for events like
/// account data.
final DateTime time;
@Deprecated('Use [originServerTs] instead')
DateTime get time => originServerTs;
/// Optional additional content for this event.
Map<String, dynamic> unsigned;
@Deprecated('Use [type] instead')
String get typeKey => type;
/// The room this event belongs to. May be null.
final Room room;
/// Optional. The previous content for this state.
/// This will be present only for state events appearing in the timeline.
/// If this is not a state event, or there is no previous content, this key will be null.
Map<String, dynamic> prevContent;
/// Optional. This key will only be present for state events. A unique key which defines
/// the overwriting semantics for this piece of room state.
final String stateKey;
/// The status of this event.
/// -1=ERROR
/// 0=SENDING
@ -101,17 +71,27 @@ class Event {
Event(
{this.status = defaultStatus,
this.content,
this.typeKey,
this.eventId,
this.roomId,
this.senderId,
this.time,
this.unsigned,
this.prevContent,
this.stateKey,
Map<String, dynamic> content,
String type,
String eventId,
String roomId,
String senderId,
DateTime originServerTs,
Map<String, dynamic> unsigned,
Map<String, dynamic> prevContent,
String stateKey,
this.room,
this.sortOrder = 0.0});
this.sortOrder = 0.0}) {
this.content = content;
this.type = type;
this.eventId = eventId;
this.roomId = roomId ?? room?.id;
this.senderId = senderId;
this.unsigned = unsigned;
this.prevContent = prevContent;
this.stateKey = stateKey;
this.originServerTs = originServerTs;
}
static Map<String, dynamic> getMapFromPayload(dynamic payload) {
if (payload is String) {
@ -125,6 +105,27 @@ class Event {
return {};
}
factory Event.fromMatrixEvent(
MatrixEvent matrixEvent,
Room room, {
double sortOrder,
int status,
}) =>
Event(
status: status,
content: matrixEvent.content,
type: matrixEvent.type,
eventId: matrixEvent.eventId,
roomId: room.id,
senderId: matrixEvent.senderId,
originServerTs: matrixEvent.originServerTs,
unsigned: matrixEvent.unsigned,
prevContent: matrixEvent.prevContent,
stateKey: matrixEvent.stateKey,
room: room,
sortOrder: sortOrder,
);
/// Get a State event from a table row or from the event stream.
factory Event.fromJson(Map<String, dynamic> jsonPayload, Room room,
[double sortOrder]) {
@ -136,11 +137,11 @@ class Event {
stateKey: jsonPayload['state_key'],
prevContent: prevContent,
content: content,
typeKey: jsonPayload['type'],
type: jsonPayload['type'],
eventId: jsonPayload['event_id'],
roomId: jsonPayload['room_id'],
senderId: jsonPayload['sender'],
time: jsonPayload.containsKey('origin_server_ts')
originServerTs: jsonPayload.containsKey('origin_server_ts')
? DateTime.fromMillisecondsSinceEpoch(jsonPayload['origin_server_ts'])
: DateTime.now(),
unsigned: unsigned,
@ -162,17 +163,18 @@ class Event {
stateKey: dbEntry.stateKey,
prevContent: prevContent,
content: content,
typeKey: dbEntry.type,
type: dbEntry.type,
eventId: dbEntry.eventId,
roomId: dbEntry.roomId,
senderId: dbEntry.sender,
time: dbEntry.originServerTs ?? DateTime.now(),
originServerTs: dbEntry.originServerTs ?? DateTime.now(),
unsigned: unsigned,
room: room,
sortOrder: dbEntry.sortOrder ?? 0.0,
);
}
@override
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (stateKey != null) data['state_key'] = stateKey;
@ -180,116 +182,33 @@ class Event {
data['prev_content'] = prevContent;
}
data['content'] = content;
data['type'] = typeKey;
data['type'] = type;
data['event_id'] = eventId;
data['room_id'] = roomId;
data['sender'] = senderId;
data['origin_server_ts'] = time.millisecondsSinceEpoch;
data['origin_server_ts'] = originServerTs.millisecondsSinceEpoch;
if (unsigned != null && unsigned.isNotEmpty) {
data['unsigned'] = unsigned;
}
return data;
}
/// The unique key of this event. For events with a [stateKey], it will be the
/// stateKey. Otherwise it will be the [type] as a string.
@deprecated
String get key => stateKey == null || stateKey.isEmpty ? typeKey : stateKey;
User get asUser => User.fromState(
stateKey: stateKey,
prevContent: prevContent,
content: content,
typeKey: typeKey,
typeKey: type,
eventId: eventId,
roomId: roomId,
senderId: senderId,
time: time,
originServerTs: originServerTs,
unsigned: unsigned,
room: room);
/// Get the real type.
EventTypes get type {
switch (typeKey) {
case 'm.room.avatar':
return EventTypes.RoomAvatar;
case 'm.room.name':
return EventTypes.RoomName;
case 'm.room.topic':
return EventTypes.RoomTopic;
case 'm.room.aliases':
return EventTypes.RoomAliases;
case 'm.room.canonical_alias':
return EventTypes.RoomCanonicalAlias;
case 'm.room.create':
return EventTypes.RoomCreate;
case 'm.room.redaction':
return EventTypes.Redaction;
case 'm.room.join_rules':
return EventTypes.RoomJoinRules;
case 'm.room.member':
return EventTypes.RoomMember;
case 'm.room.power_levels':
return EventTypes.RoomPowerLevels;
case 'm.room.guest_access':
return EventTypes.GuestAccess;
case 'm.room.history_visibility':
return EventTypes.HistoryVisibility;
case 'm.sticker':
return EventTypes.Sticker;
case 'm.room.message':
return EventTypes.Message;
case 'm.room.encrypted':
return EventTypes.Encrypted;
case 'm.room.encryption':
return EventTypes.Encryption;
case 'm.room.tombsone':
return EventTypes.RoomTombstone;
case 'm.call.invite':
return EventTypes.CallInvite;
case 'm.call.answer':
return EventTypes.CallAnswer;
case 'm.call.candidates':
return EventTypes.CallCandidates;
case 'm.call.hangup':
return EventTypes.CallHangup;
}
return EventTypes.Unknown;
}
///
MessageTypes get messageType {
switch (content['msgtype'] ?? 'm.text') {
case 'm.text':
if (content.containsKey('m.relates_to')) {
return MessageTypes.Reply;
}
return MessageTypes.Text;
case 'm.notice':
return MessageTypes.Notice;
case 'm.emote':
return MessageTypes.Emote;
case 'm.image':
return MessageTypes.Image;
case 'm.video':
return MessageTypes.Video;
case 'm.audio':
return MessageTypes.Audio;
case 'm.file':
return MessageTypes.File;
case 'm.sticker':
return MessageTypes.Sticker;
case 'm.location':
return MessageTypes.Location;
case 'm.bad.encrypted':
return MessageTypes.BadEncrypted;
default:
if (type == EventTypes.Message) {
return MessageTypes.Text;
}
return MessageTypes.None;
}
}
String get messageType => (content.containsKey('m.relates_to') &&
content['m.relates_to']['m.in_reply_to'] != null)
? MessageTypes.Reply
: content['msgtype'] ?? MessageTypes.Text;
void setRedactionEvent(Event redactedBecause) {
unsigned = {
@ -341,9 +260,6 @@ class Event {
/// Returns the formatted boy of this event if it has a formatted body.
String get formattedText => content['formatted_body'] ?? '';
@Deprecated('Use [body] instead.')
String getBody() => body;
/// Use this to get the body.
String get body {
if (redacted) return 'Redacted';
@ -374,7 +290,7 @@ class Event {
room.client.onEvent.add(EventUpdate(
roomID: room.id,
type: 'timeline',
eventType: typeKey,
eventType: type,
content: {
'event_id': eventId,
'status': -2,
@ -434,7 +350,7 @@ class Event {
await room.client.database?.storeEventUpdate(
room.client.id,
EventUpdate(
eventType: newEvent.typeKey,
eventType: newEvent.type,
content: newEvent.toJson(),
roomID: newEvent.roomId,
type: updateType,
@ -473,7 +389,7 @@ class Event {
Future<MatrixFile> downloadAndDecryptAttachment(
{bool getThumbnail = false}) async {
if (![EventTypes.Message, EventTypes.Sticker].contains(type)) {
throw ("This event has the type '$typeKey' and so it can't contain an attachment.");
throw ("This event has the type '$type' and so it can't contain an attachment.");
}
if (!getThumbnail &&
!content.containsKey('url') &&
@ -741,7 +657,7 @@ class Event {
}
break;
default:
localizedBody = i18n.unknownEvent(typeKey);
localizedBody = i18n.unknownEvent(type);
}
// Hide reply fallback
@ -762,7 +678,7 @@ class Event {
return localizedBody;
}
static const Set<MessageTypes> textOnlyMessageTypes = {
static const Set<String> textOnlyMessageTypes = {
MessageTypes.Text,
MessageTypes.Reply,
MessageTypes.Notice,
@ -770,43 +686,3 @@ class Event {
MessageTypes.None,
};
}
enum MessageTypes {
Text,
Emote,
Notice,
Image,
Video,
Audio,
File,
Location,
Reply,
Sticker,
BadEncrypted,
None,
}
enum EventTypes {
Message,
Sticker,
Redaction,
RoomAliases,
RoomCanonicalAlias,
RoomCreate,
RoomJoinRules,
RoomMember,
RoomPowerLevels,
RoomName,
RoomTopic,
RoomAvatar,
RoomTombstone,
GuestAccess,
HistoryVisibility,
Encryption,
Encrypted,
CallInvite,
CallAnswer,
CallCandidates,
CallHangup,
Unknown,
}

View file

@ -1,91 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import './database/database.dart' show DbPresence;
enum PresenceType { online, offline, unavailable }
/// Informs the client of a user's presence state change.
class Presence {
/// The user who sent this presence.
final String sender;
/// The current display name for this user, if any.
final String displayname;
/// The current avatar URL for this user, if any.
final Uri avatarUrl;
final bool currentlyActive;
final int lastActiveAgo;
final PresenceType presence;
final String statusMsg;
final DateTime time;
Presence(
{this.sender,
this.displayname,
this.avatarUrl,
this.currentlyActive,
this.lastActiveAgo,
this.presence,
this.statusMsg,
this.time});
Presence.fromJson(Map<String, dynamic> json)
: sender = json['sender'],
displayname = json['content']['displayname'],
avatarUrl = json['content']['avatar_url'] != null
? Uri.parse(json['content']['avatar_url'])
: null,
currentlyActive = json['content']['currently_active'],
lastActiveAgo = json['content']['last_active_ago'],
time = DateTime.fromMillisecondsSinceEpoch(
DateTime.now().millisecondsSinceEpoch -
(json['content']['last_active_ago'] ?? 0)),
presence = PresenceType.values.firstWhere(
(e) =>
e.toString() == "PresenceType.${json['content']['presence']}",
orElse: () => null),
statusMsg = json['content']['status_msg'];
factory Presence.fromDb(DbPresence dbEntry) {
final content = Event.getMapFromPayload(dbEntry.content);
return Presence(
sender: dbEntry.sender,
displayname: content['displayname'],
avatarUrl: content['avatar_url'] != null
? Uri.parse(content['avatar_url'])
: null,
currentlyActive: content['currently_active'],
lastActiveAgo: content['last_active_ago'],
time: DateTime.fromMillisecondsSinceEpoch(
DateTime.now().millisecondsSinceEpoch -
(content['last_active_ago'] ?? 0)),
presence: PresenceType.values.firstWhere(
(e) => e.toString() == "PresenceType.${content['presence']}",
orElse: () => null),
statusMsg: content['status_msg'],
);
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,60 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/account_data.dart';
import 'package:famedlysdk/src/event.dart';
import './database/database.dart' show DbRoomAccountData;
/// Stripped down events for account data and ephemrals of a room.
class RoomAccountData extends AccountData {
/// The user who has sent this event if it is not a global account data event.
final String roomId;
final Room room;
RoomAccountData(
{this.roomId, this.room, Map<String, dynamic> content, String typeKey})
: super(content: content, typeKey: typeKey);
/// Get a State event from a table row or from the event stream.
factory RoomAccountData.fromJson(
Map<String, dynamic> jsonPayload, Room room) {
final content = Event.getMapFromPayload(jsonPayload['content']);
return RoomAccountData(
content: content,
typeKey: jsonPayload['type'],
roomId: jsonPayload['room_id'],
room: room);
}
/// get room account data from DbRoomAccountData
factory RoomAccountData.fromDb(DbRoomAccountData dbEntry, Room room) {
final content = Event.getMapFromPayload(dbEntry.content);
return RoomAccountData(
content: content,
typeKey: dbEntry.type,
roomId: dbEntry.roomId,
room: room);
}
}

View file

@ -1,75 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import '../user.dart';
/// Represents a new room or an update for an
/// already known room.
class RoomUpdate {
/// All rooms have an idea in the format: !uniqueid:server.abc
final String id;
/// The current membership state of the user in this room.
final Membership membership;
/// Represents the number of unead notifications. This probably doesn't fit the number
/// of unread messages.
final num notification_count;
// The number of unread highlighted notifications.
final num highlight_count;
/// If there are too much new messages, the [homeserver] will only send the
/// last X (default is 10) messages and set the [limitedTimelinbe] flag to true.
final bool limitedTimeline;
/// Represents the current position of the client in the room history.
final String prev_batch;
final RoomSummary summary;
RoomUpdate({
this.id,
this.membership,
this.notification_count,
this.highlight_count,
this.limitedTimeline,
this.prev_batch,
this.summary,
});
}
class RoomSummary {
List<String> mHeroes;
int mJoinedMemberCount;
int mInvitedMemberCount;
RoomSummary(
{this.mHeroes, this.mJoinedMemberCount, this.mInvitedMemberCount});
RoomSummary.fromJson(Map<String, dynamic> json) {
mHeroes = json['m.heroes']?.cast<String>();
mJoinedMemberCount = json['m.joined_member_count'];
mInvitedMemberCount = json['m.invited_member_count'];
}
}

View file

@ -1,37 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
/// Represents a new global event like presence or account_data.
class UserUpdate {
/// Usually 'presence', 'account_data' or whatever.
final String eventType;
/// See (Matrix Events)[https://matrix.org/docs/spec/client_server/r0.4.0.html]
/// for more informations.
final String type;
// The json payload of the content of this event.
final dynamic content;
UserUpdate({this.eventType, this.type, this.content});
}

View file

@ -1,32 +1,29 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:async';
import 'package:famedlysdk/matrix_api.dart';
import 'event.dart';
import 'room.dart';
import 'sync/event_update.dart';
import 'sync/room_update.dart';
import 'utils/event_update.dart';
import 'utils/room_update.dart';
typedef onTimelineUpdateCallback = void Function();
typedef onTimelineInsertCallback = void Function(int insertID);
@ -135,7 +132,7 @@ class Timeline {
if (eventUpdate.type == 'timeline' || eventUpdate.type == 'history') {
// Redaction events are handled as modification for existing events.
if (eventUpdate.eventType == 'm.room.redaction') {
if (eventUpdate.eventType == EventTypes.Redaction) {
final eventId = _findEvent(event_id: eventUpdate.content['redacts']);
if (eventId != null) {
events[eventId].setRedactionEvent(Event.fromJson(
@ -161,7 +158,8 @@ class Timeline {
} else {
Event newEvent;
var senderUser = room
.getState('m.room.member', eventUpdate.content['sender'])
.getState(
EventTypes.RoomMember, eventUpdate.content['sender'])
?.asUser ??
await room.client.database?.getUser(
room.client.id, eventUpdate.content['sender'], room);

View file

@ -1,32 +1,26 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/room.dart';
import 'package:famedlysdk/src/event.dart';
enum Membership { join, invite, leave, ban }
/// Represents a Matrix User which may be a participant in a Matrix Room.
class User extends Event {
factory User(
@ -43,10 +37,10 @@ class User extends Event {
return User.fromState(
stateKey: id,
content: content,
typeKey: 'm.room.member',
typeKey: EventTypes.RoomMember,
roomId: room?.id,
room: room,
time: DateTime.now(),
originServerTs: DateTime.now(),
);
}
@ -58,18 +52,18 @@ class User extends Event {
String eventId,
String roomId,
String senderId,
DateTime time,
DateTime originServerTs,
dynamic unsigned,
Room room})
: super(
stateKey: stateKey,
prevContent: prevContent,
content: content,
typeKey: typeKey,
type: typeKey,
eventId: eventId,
roomId: roomId,
senderId: senderId,
time: time,
originServerTs: originServerTs,
unsigned: unsigned,
room: room);
@ -142,16 +136,11 @@ class User extends Event {
if (roomID != null) return roomID;
// Start a new direct chat
final dynamic resp = await room.client.jsonRequest(
type: HTTPType.POST,
action: '/client/r0/createRoom',
data: {
'invite': [id],
'is_direct': true,
'preset': 'trusted_private_chat'
});
final String newRoomID = resp['room_id'];
final newRoomID = await room.client.api.createRoom(
invite: [id],
isDirect: true,
preset: CreateRoomPreset.trusted_private_chat,
);
if (newRoomID == null) return newRoomID;

View file

@ -1,5 +1,7 @@
import 'dart:convert';
import 'package:famedlysdk/matrix_api.dart';
import '../client.dart';
import '../database/database.dart' show DbUserDeviceKey, DbUserDeviceKeysKey;
import '../event.dart';
@ -55,13 +57,7 @@ class DeviceKeysList {
DeviceKeysList(this.userId);
}
class DeviceKeys {
String userId;
String deviceId;
List<String> algorithms;
Map<String, String> keys;
Map<String, dynamic> signatures;
Map<String, dynamic> unsigned;
class DeviceKeys extends MatrixDeviceKeys {
bool verified;
bool blocked;
@ -93,63 +89,68 @@ class DeviceKeys {
}
DeviceKeys({
this.userId,
this.deviceId,
this.algorithms,
this.keys,
this.signatures,
this.unsigned,
String userId,
String deviceId,
List<String> algorithms,
Map<String, String> keys,
Map<String, Map<String, String>> signatures,
Map<String, dynamic> unsigned,
this.verified,
this.blocked,
});
}) : super(userId, deviceId, algorithms, keys, signatures,
unsigned: unsigned);
DeviceKeys.fromDb(DbUserDeviceKeysKey dbEntry) {
factory DeviceKeys.fromMatrixDeviceKeys(MatrixDeviceKeys matrixDeviceKeys) =>
DeviceKeys(
userId: matrixDeviceKeys.userId,
deviceId: matrixDeviceKeys.deviceId,
algorithms: matrixDeviceKeys.algorithms,
keys: matrixDeviceKeys.keys,
signatures: matrixDeviceKeys.signatures,
unsigned: matrixDeviceKeys.unsigned,
verified: false,
blocked: false,
);
static DeviceKeys fromDb(DbUserDeviceKeysKey dbEntry) {
var deviceKeys = DeviceKeys();
final content = Event.getMapFromPayload(dbEntry.content);
userId = dbEntry.userId;
deviceId = dbEntry.deviceId;
algorithms = content['algorithms'].cast<String>();
keys = content['keys'] != null
deviceKeys.userId = dbEntry.userId;
deviceKeys.deviceId = dbEntry.deviceId;
deviceKeys.algorithms = content['algorithms'].cast<String>();
deviceKeys.keys = content['keys'] != null
? Map<String, String>.from(content['keys'])
: null;
signatures = content['signatures'] != null
? Map<String, dynamic>.from(content['signatures'])
deviceKeys.signatures = content['signatures'] != null
? Map<String, Map<String, String>>.from((content['signatures'] as Map)
.map((k, v) => MapEntry(k, Map<String, String>.from(v))))
: null;
unsigned = content['unsigned'] != null
deviceKeys.unsigned = content['unsigned'] != null
? Map<String, dynamic>.from(content['unsigned'])
: null;
verified = dbEntry.verified;
blocked = dbEntry.blocked;
deviceKeys.verified = dbEntry.verified;
deviceKeys.blocked = dbEntry.blocked;
return deviceKeys;
}
DeviceKeys.fromJson(Map<String, dynamic> json) {
userId = json['user_id'];
deviceId = json['device_id'];
algorithms = json['algorithms'].cast<String>();
keys = json['keys'] != null ? Map<String, String>.from(json['keys']) : null;
signatures = json['signatures'] != null
? Map<String, dynamic>.from(json['signatures'])
: null;
unsigned = json['unsigned'] != null
? Map<String, dynamic>.from(json['unsigned'])
: null;
verified = json['verified'] ?? false;
blocked = json['blocked'] ?? false;
static DeviceKeys fromJson(Map<String, dynamic> json) {
var matrixDeviceKeys = MatrixDeviceKeys.fromJson(json);
var deviceKeys = DeviceKeys(
userId: matrixDeviceKeys.userId,
deviceId: matrixDeviceKeys.deviceId,
algorithms: matrixDeviceKeys.algorithms,
keys: matrixDeviceKeys.keys,
signatures: matrixDeviceKeys.signatures,
unsigned: matrixDeviceKeys.unsigned,
);
deviceKeys.verified = json['verified'] ?? false;
deviceKeys.blocked = json['blocked'] ?? false;
return deviceKeys;
}
@override
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['user_id'] = userId;
data['device_id'] = deviceId;
data['algorithms'] = algorithms;
if (keys != null) {
data['keys'] = keys;
}
if (signatures != null) {
data['signatures'] = signatures;
}
if (unsigned != null) {
data['unsigned'] = unsigned;
}
final data = super.toJson();
data['verified'] = verified;
data['blocked'] = blocked;
return data;

View file

@ -1,27 +1,23 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import '../../famedlysdk.dart';
import '../../matrix_api.dart';
/// Represents a new event (e.g. a message in a room) or an update for an
/// already known event.
@ -47,14 +43,14 @@ class EventUpdate {
{this.eventType, this.roomID, this.type, this.content, this.sortOrder});
EventUpdate decrypt(Room room) {
if (eventType != 'm.room.encrypted') {
if (eventType != EventTypes.Encrypted) {
return this;
}
try {
var decrpytedEvent =
room.decryptGroupMessage(Event.fromJson(content, room, sortOrder));
return EventUpdate(
eventType: decrpytedEvent.typeKey,
eventType: decrpytedEvent.type,
roomID: roomID,
type: type,
content: decrpytedEvent.toJson(),

View file

@ -2,6 +2,7 @@ import 'dart:typed_data';
import 'package:random_string/random_string.dart';
import 'package:canonical_json/canonical_json.dart';
import 'package:olm/olm.dart' as olm;
import '../../matrix_api.dart';
import 'device_keys_list.dart';
import '../client.dart';
import '../room.dart';
@ -378,7 +379,7 @@ class KeyVerification {
payload['to'] = userId;
payload['body'] =
'Attempting verification request. (${type}) Apparently your client doesn\'t support this';
type = 'm.room.message';
type = EventTypes.Message;
}
final newTransactionId = await room.sendEvent(payload, type: type);
if (transactionId == null) {

View file

@ -1,23 +0,0 @@
class OpenIdCredentials {
String accessToken;
String tokenType;
String matrixServerName;
num expiresIn;
OpenIdCredentials.fromJson(Map<String, dynamic> json) {
accessToken = json['access_token'];
tokenType = json['token_type'];
matrixServerName = json['matrix_server_name'];
expiresIn = json['expires_in'];
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
final data = map;
data['access_token'] = accessToken;
data['token_type'] = tokenType;
data['matrix_server_name'] = matrixServerName;
data['expires_in'] = expiresIn;
return data;
}
}

View file

@ -1,25 +0,0 @@
/// Represents a user profile returned by a /profile request.
class Profile {
/// The user's avatar URL if they have set one, otherwise null.
final Uri avatarUrl;
/// The user's display name if they have set one, otherwise null.
final String displayname;
/// This API may return keys which are not limited to displayname or avatar_url.
final Map<String, dynamic> content;
const Profile(this.displayname, this.avatarUrl, {this.content = const {}});
Profile.fromJson(Map<String, dynamic> json)
: avatarUrl =
json['avatar_url'] != null ? Uri.parse(json['avatar_url']) : null,
displayname = json['displayname'],
content = json;
@override
bool operator ==(dynamic other) =>
(other is Profile) &&
avatarUrl == other.avatarUrl &&
displayname == other.displayname;
}

View file

@ -1,48 +0,0 @@
import '../client.dart';
class PublicRoomsResponse {
List<PublicRoomEntry> publicRooms;
final String nextBatch;
final String prevBatch;
final int totalRoomCountEstimate;
Client client;
PublicRoomsResponse.fromJson(Map<String, dynamic> json, Client client)
: nextBatch = json['next_batch'],
prevBatch = json['prev_batch'],
client = client,
totalRoomCountEstimate = json['total_room_count_estimate'] {
if (json['chunk'] != null) {
publicRooms = <PublicRoomEntry>[];
json['chunk'].forEach((v) {
publicRooms.add(PublicRoomEntry.fromJson(v, client));
});
}
}
}
class PublicRoomEntry {
final List<String> aliases;
final String avatarUrl;
final bool guestCanJoin;
final String name;
final int numJoinedMembers;
final String roomId;
final String topic;
final bool worldReadable;
Client client;
Future<void> join() => client.joinRoomById(roomId);
PublicRoomEntry.fromJson(Map<String, dynamic> json, Client client)
: aliases =
json.containsKey('aliases') ? json['aliases'].cast<String>() : [],
avatarUrl = json['avatar_url'],
guestCanJoin = json['guest_can_join'],
name = json['name'],
numJoinedMembers = json['num_joined_members'],
roomId = json['room_id'],
topic = json['topic'],
worldReadable = json['world_readable'],
client = client;
}

View file

@ -1,83 +0,0 @@
/// The global ruleset.
class PushRules {
final GlobalPushRules global;
PushRules.fromJson(Map<String, dynamic> json)
: global = GlobalPushRules.fromJson(json['global']);
}
/// The global ruleset.
class GlobalPushRules {
final List<PushRule> content;
final List<PushRule> override;
final List<PushRule> room;
final List<PushRule> sender;
final List<PushRule> underride;
GlobalPushRules.fromJson(Map<String, dynamic> json)
: content = json.containsKey('content')
? PushRule.fromJsonList(json['content'])
: null,
override = json.containsKey('override')
? PushRule.fromJsonList(json['content'])
: null,
room = json.containsKey('room')
? PushRule.fromJsonList(json['room'])
: null,
sender = json.containsKey('sender')
? PushRule.fromJsonList(json['sender'])
: null,
underride = json.containsKey('underride')
? PushRule.fromJsonList(json['underride'])
: null;
}
/// A single pushrule.
class PushRule {
final List actions;
final bool isDefault;
final bool enabled;
final String ruleId;
final List<PushRuleConditions> conditions;
final String pattern;
static List<PushRule> fromJsonList(List<dynamic> list) {
var objList = <PushRule>[];
list.forEach((json) {
objList.add(PushRule.fromJson(json));
});
return objList;
}
PushRule.fromJson(Map<String, dynamic> json)
: actions = json['actions'],
isDefault = json['default'],
enabled = json['enabled'],
ruleId = json['rule_id'],
conditions = json.containsKey('conditions')
? PushRuleConditions.fromJsonList(json['conditions'])
: null,
pattern = json['pattern'];
}
/// Conditions when this pushrule should be active.
class PushRuleConditions {
final String kind;
final String key;
final String pattern;
final String is_;
static List<PushRuleConditions> fromJsonList(List<dynamic> list) {
var objList = <PushRuleConditions>[];
list.forEach((json) {
objList.add(PushRuleConditions.fromJson(json));
});
return objList;
}
PushRuleConditions.fromJson(Map<String, dynamic> json)
: kind = json['kind'],
key = json['key'],
pattern = json['pattern'],
is_ = json['is'];
}

View file

@ -1,53 +0,0 @@
class Pusher {
String pushkey;
String kind;
String appId;
String appDisplayName;
String deviceDisplayName;
String profileTag;
String lang;
PusherData data;
Pusher.fromJson(Map<String, dynamic> json) {
pushkey = json['pushkey'];
kind = json['kind'];
appId = json['app_id'];
appDisplayName = json['app_display_name'];
deviceDisplayName = json['device_display_name'];
profileTag = json['profile_tag'];
lang = json['lang'];
data = json['data'] != null ? PusherData.fromJson(json['data']) : null;
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['pushkey'] = pushkey;
data['kind'] = kind;
data['app_id'] = appId;
data['app_display_name'] = appDisplayName;
data['device_display_name'] = deviceDisplayName;
data['profile_tag'] = profileTag;
data['lang'] = lang;
if (this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
}
class PusherData {
String url;
String format;
PusherData.fromJson(Map<String, dynamic> json) {
url = json['url'];
format = json['format'];
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
if (url != null) data['url'] = url;
if (format != null) data['format'] = format;
return data;
}
}

View file

@ -0,0 +1,92 @@
/*
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/matrix_api.dart';
/// Represents a new room or an update for an
/// already known room.
class RoomUpdate {
/// All rooms have an idea in the format: !uniqueid:server.abc
final String id;
/// The current membership state of the user in this room.
final Membership membership;
/// Represents the number of unead notifications. This probably doesn't fit the number
/// of unread messages.
final num notification_count;
// The number of unread highlighted notifications.
final num highlight_count;
/// If there are too much new messages, the [homeserver] will only send the
/// last X (default is 10) messages and set the [limitedTimelinbe] flag to true.
final bool limitedTimeline;
/// Represents the current position of the client in the room history.
final String prev_batch;
final RoomSummary summary;
RoomUpdate({
this.id,
this.membership,
this.notification_count,
this.highlight_count,
this.limitedTimeline,
this.prev_batch,
this.summary,
});
factory RoomUpdate.fromSyncRoomUpdate(
SyncRoomUpdate update,
String roomId,
) =>
update is JoinedRoomUpdate
? RoomUpdate(
id: roomId,
membership: Membership.join,
notification_count:
update.unreadNotifications?.notificationCount ?? 0,
highlight_count: update.unreadNotifications?.highlightCount ?? 0,
limitedTimeline: update.timeline?.limited ?? false,
prev_batch: update.timeline?.prevBatch ?? '',
summary: update.summary,
)
: update is InvitedRoomUpdate
? RoomUpdate(
id: roomId,
membership: Membership.invite,
notification_count: 0,
highlight_count: 0,
limitedTimeline: false,
prev_batch: '',
summary: null,
)
: update is LeftRoomUpdate
? RoomUpdate(
id: roomId,
membership: Membership.leave,
notification_count: 0,
highlight_count: 0,
limitedTimeline: update.timeline?.limited ?? false,
prev_batch: update.timeline?.prevBatch ?? '',
summary: null,
)
: null;
}

View file

@ -1,5 +1,7 @@
import 'package:famedlysdk/famedlysdk.dart';
import '../../matrix_api.dart';
/// Matrix room states are addressed by a tuple of the [type] and an
/// optional [stateKey].
class StatesMap {
@ -11,8 +13,10 @@ class StatesMap {
//print("[Warning] This method will be depracated in the future!");
if (key == null) return null;
if (key.startsWith('@') && key.contains(':')) {
if (!states.containsKey('m.room.member')) states['m.room.member'] = {};
return states['m.room.member'][key];
if (!states.containsKey(EventTypes.RoomMember)) {
states[EventTypes.RoomMember] = {};
}
return states[EventTypes.RoomMember][key];
}
if (!states.containsKey(key)) states[key] = {};
if (states[key][''] is Event) {
@ -27,8 +31,10 @@ class StatesMap {
void operator []=(String key, Event val) {
//print("[Warning] This method will be depracated in the future!");
if (key.startsWith('@') && key.contains(':')) {
if (!states.containsKey('m.room.member')) states['m.room.member'] = {};
states['m.room.member'][key] = val;
if (!states.containsKey(EventTypes.RoomMember)) {
states[EventTypes.RoomMember] = {};
}
states[EventTypes.RoomMember][key] = val;
}
if (!states.containsKey(key)) states[key] = {};
states[key][val.stateKey ?? ''] = val;

View file

@ -1,28 +1,27 @@
class ToDeviceEvent {
String sender;
String type;
Map<String, dynamic> content;
import 'package:famedlysdk/matrix_api.dart';
class ToDeviceEvent extends BasicEventWithSender {
Map<String, dynamic> encryptedContent;
ToDeviceEvent({this.sender, this.type, this.content, this.encryptedContent});
String get sender => senderId;
set sender(String sender) => senderId = sender;
ToDeviceEvent({
String sender,
String type,
Map<String, dynamic> content,
this.encryptedContent,
}) {
senderId = sender;
this.type = type;
this.content = content;
}
ToDeviceEvent.fromJson(Map<String, dynamic> json) {
sender = json['sender'];
type = json['type'];
content = json['content'] != null
? Map<String, dynamic>.from(json['content'])
: null;
}
Map<String, dynamic> toJson() {
var map = <String, dynamic>{};
final data = map;
data['sender'] = sender;
data['type'] = type;
if (content != null) {
data['content'] = content;
}
return data;
final event = BasicEventWithSender.fromJson(json);
senderId = event.senderId;
type = event.type;
content = event.content;
}
}
@ -34,7 +33,7 @@ class ToDeviceEventDecryptionError extends ToDeviceEvent {
this.exception,
this.stackTrace,
}) : super(
sender: toDeviceEvent.sender,
sender: toDeviceEvent.senderId,
content: toDeviceEvent.content,
type: toDeviceEvent.type,
);

View file

@ -1,23 +0,0 @@
/// Credentials for the client to use when initiating calls.
class TurnServerCredentials {
/// The username to use.
final String username;
/// The password to use.
final String password;
/// A list of TURN URIs
final List<String> uris;
/// The time-to-live in seconds
final double ttl;
const TurnServerCredentials(
this.username, this.password, this.uris, this.ttl);
TurnServerCredentials.fromJson(Map<String, dynamic> json)
: username = json['username'],
password = json['password'],
uris = json['uris'].cast<String>(),
ttl = json['ttl'];
}

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Famedly Matrix SDK
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/src/client.dart';
@ -27,8 +22,8 @@ import 'dart:core';
extension MxcUriExtension on Uri {
/// Returns a download Link to this content.
String getDownloadLink(Client matrix) => isScheme('mxc')
? matrix.homeserver != null
? '${matrix.homeserver}/_matrix/media/r0/download/$host$path'
? matrix.api.homeserver != null
? '${matrix.api.homeserver.toString()}/_matrix/media/r0/download/$host$path'
: ''
: toString();
@ -41,8 +36,8 @@ extension MxcUriExtension on Uri {
final methodStr = method.toString().split('.').last;
width = width.round();
height = height.round();
return matrix.homeserver != null
? '${matrix.homeserver}/_matrix/media/r0/thumbnail/$host$path?width=$width&height=$height&method=$methodStr'
return matrix.api.homeserver != null
? '${matrix.api.homeserver.toString()}/_matrix/media/r0/thumbnail/$host$path?width=$width&height=$height&method=$methodStr'
: '';
}
}

View file

@ -1,54 +0,0 @@
import '../client.dart';
/// Registered device for this user.
class UserDevice {
/// Identifier of this device.
final String deviceId;
/// Display name set by the user for this device. Absent if no name has been set.
final String displayName;
/// The IP address where this device was last seen. (May be a few minutes out of date, for efficiency reasons).
final String lastSeenIp;
/// The time when this devices was last seen. (May be a few minutes out of date, for efficiency reasons).
final DateTime lastSeenTs;
final Client _client;
/// Updates the metadata on the given device.
Future<void> updateMetaData(String newName) async {
await _client.jsonRequest(
type: HTTPType.PUT,
action: '/client/r0/devices/$deviceId',
data: {'display_name': newName},
);
return;
}
/// Deletes the given device, and invalidates any access token associated with it.
Future<void> deleteDevice(Map<String, dynamic> auth) async {
await _client.jsonRequest(
type: HTTPType.DELETE,
action: '/client/r0/devices/$deviceId',
data: auth != null ? {'auth': auth} : null,
);
return;
}
UserDevice(
this._client, {
this.deviceId,
this.displayName,
this.lastSeenIp,
this.lastSeenTs,
});
UserDevice.fromJson(Map<String, dynamic> json, Client client)
: deviceId = json['device_id'],
displayName = json['display_name'],
lastSeenIp = json['last_seen_ip'],
lastSeenTs =
DateTime.fromMillisecondsSinceEpoch(json['last_seen_ts'] ?? 0),
_client = client;
}

View file

@ -1,23 +0,0 @@
class WellKnownInformations {
MHomeserver mHomeserver;
MHomeserver mIdentityServer;
Map<String, dynamic> content;
WellKnownInformations.fromJson(Map<String, dynamic> json) {
content = json;
mHomeserver = json['m.homeserver'] != null
? MHomeserver.fromJson(json['m.homeserver'])
: null;
mIdentityServer = json['m.identity_server'] != null
? MHomeserver.fromJson(json['m.identity_server'])
: null;
}
}
class MHomeserver {
String baseUrl;
MHomeserver.fromJson(Map<String, dynamic> json) {
baseUrl = json['base_url'];
}
}

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:canonical_json/canonical_json.dart';

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:async';
@ -26,14 +21,10 @@ import 'dart:convert';
import 'dart:typed_data';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/account_data.dart';
import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/client.dart';
import 'package:famedlysdk/src/presence.dart';
import 'package:famedlysdk/src/user.dart';
import 'package:famedlysdk/src/sync/event_update.dart';
import 'package:famedlysdk/src/sync/room_update.dart';
import 'package:famedlysdk/src/sync/user_update.dart';
import 'package:famedlysdk/src/utils/matrix_exception.dart';
import 'package:famedlysdk/src/utils/event_update.dart';
import 'package:famedlysdk/src/utils/room_update.dart';
import 'package:famedlysdk/src/utils/matrix_file.dart';
import 'package:olm/olm.dart' as olm;
import 'package:test/test.dart';
@ -46,7 +37,6 @@ void main() {
Future<List<RoomUpdate>> roomUpdateListFuture;
Future<List<EventUpdate>> eventUpdateListFuture;
Future<List<UserUpdate>> userUpdateListFuture;
Future<List<ToDeviceEvent>> toDeviceUpdateListFuture;
const pickledOlmAccount =
@ -58,12 +48,10 @@ void main() {
group('FluffyMatrix', () {
/// Check if all Elements get created
matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
matrix = Client('testclient', debug: true, httpClient: FakeMatrixApi());
roomUpdateListFuture = matrix.onRoomUpdate.stream.toList();
eventUpdateListFuture = matrix.onEvent.stream.toList();
userUpdateListFuture = matrix.onUserEvent.stream.toList();
toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList();
var olmEnabled = true;
try {
@ -81,11 +69,11 @@ void main() {
matrix.onPresence.stream.listen((Presence data) {
presenceCounter++;
});
matrix.onAccountData.stream.listen((AccountData data) {
matrix.onAccountData.stream.listen((BasicEvent data) {
accountDataCounter++;
});
expect(matrix.homeserver, null);
expect(matrix.api.homeserver, null);
try {
await matrix.checkServer('https://fakeserver.wrongaddress');
@ -93,61 +81,51 @@ void main() {
expect(exception != null, true);
}
await matrix.checkServer('https://fakeserver.notexisting');
expect(matrix.homeserver, 'https://fakeserver.notexisting');
expect(
matrix.api.homeserver.toString(), 'https://fakeserver.notexisting');
final resp = await matrix
.jsonRequest(type: HTTPType.POST, action: '/client/r0/login', data: {
'type': 'm.login.password',
'user': 'test',
'password': '1234',
'initial_device_display_name': 'Fluffy Matrix Client'
});
final resp = await matrix.api.login(
type: 'm.login.password',
user: 'test',
password: '1234',
initialDeviceDisplayName: 'Fluffy Matrix Client',
);
final available = await matrix.usernameAvailable('testuser');
final available = await matrix.api.usernameAvailable('testuser');
expect(available, true);
Map registerResponse = await matrix.register(username: 'testuser');
expect(registerResponse['user_id'], '@testuser:example.com');
registerResponse =
await matrix.register(username: 'testuser', kind: 'user');
expect(registerResponse['user_id'], '@testuser:example.com');
registerResponse =
await matrix.register(username: 'testuser', kind: 'guest');
expect(registerResponse['user_id'], '@testuser:example.com');
var loginStateFuture = matrix.onLoginStateChanged.stream.first;
var firstSyncFuture = matrix.onFirstSync.stream.first;
var syncFuture = matrix.onSync.stream.first;
matrix.connect(
newToken: resp['access_token'],
newUserID: resp['user_id'],
newHomeserver: matrix.homeserver,
newToken: resp.accessToken,
newUserID: resp.userId,
newHomeserver: matrix.api.homeserver,
newDeviceName: 'Text Matrix Client',
newDeviceID: resp['device_id'],
newDeviceID: resp.deviceId,
newOlmAccount: pickledOlmAccount,
);
await Future.delayed(Duration(milliseconds: 50));
expect(matrix.accessToken == resp['access_token'], true);
expect(matrix.api.accessToken == resp.accessToken, true);
expect(matrix.deviceName == 'Text Matrix Client', true);
expect(matrix.deviceID == resp['device_id'], true);
expect(matrix.userID == resp['user_id'], true);
expect(matrix.deviceID == resp.deviceId, true);
expect(matrix.userID == resp.userId, true);
var loginState = await loginStateFuture;
var firstSync = await firstSyncFuture;
dynamic sync = await syncFuture;
var sync = await syncFuture;
expect(loginState, LoginState.logged);
expect(firstSync, true);
expect(matrix.encryptionEnabled, olmEnabled);
if (olmEnabled) {
expect(matrix.pickledOlmAccount, pickledOlmAccount);
expect(matrix.identityKey, identityKey);
expect(matrix.fingerprintKey, fingerprintKey);
}
expect(sync['next_batch'] == matrix.prevBatch, true);
expect(sync.nextBatch == matrix.prevBatch, true);
expect(matrix.accountData.length, 3);
expect(matrix.getDirectChatFromUserId('@bob:example.com'),
@ -192,14 +170,14 @@ void main() {
expect(matrix.rooms[1].canonicalAlias,
"#famedlyContactDiscovery:${matrix.userID.split(":")[1]}");
final contacts = await matrix.loadFamedlyContacts();
expect(contacts.length, 1);
expect(contacts.length, 2);
expect(contacts[0].senderId, '@alice:example.com');
expect(
matrix.presences['@alice:example.com'].presence, PresenceType.online);
expect(matrix.presences['@alice:example.com'].presence.presence,
PresenceType.online);
expect(presenceCounter, 1);
expect(accountDataCounter, 3);
await Future.delayed(Duration(milliseconds: 50));
expect(matrix.userDeviceKeys.length, 2);
expect(matrix.userDeviceKeys.length, 3);
expect(matrix.userDeviceKeys['@alice:example.com'].outdated, false);
expect(matrix.userDeviceKeys['@alice:example.com'].deviceKeys.length, 2);
expect(
@ -207,7 +185,7 @@ void main() {
.verified,
false);
await matrix.handleSync({
await matrix.handleSync(SyncUpdate.fromJson({
'device_lists': {
'changed': [
'@alice:example.com',
@ -216,12 +194,12 @@ void main() {
'@bob:example.com',
],
}
});
}));
await Future.delayed(Duration(milliseconds: 50));
expect(matrix.userDeviceKeys.length, 2);
expect(matrix.userDeviceKeys['@alice:example.com'].outdated, true);
await matrix.handleSync({
await matrix.handleSync(SyncUpdate.fromJson({
'rooms': {
'join': {
'!726s6s6q:example.com': {
@ -240,7 +218,7 @@ void main() {
}
}
}
});
}));
await Future.delayed(Duration(milliseconds: 50));
expect(
@ -253,27 +231,15 @@ void main() {
expect(altContacts[0].senderId, '@alice:example.com');
});
test('Try to get ErrorResponse', () async {
MatrixException expectedException;
try {
await matrix.jsonRequest(
type: HTTPType.PUT, action: '/non/existing/path');
} on MatrixException catch (exception) {
expectedException = exception;
}
expect(expectedException.error, MatrixError.M_UNRECOGNIZED);
});
test('Logout', () async {
await matrix.jsonRequest(
type: HTTPType.POST, action: '/client/r0/logout');
await matrix.api.logout();
var loginStateFuture = matrix.onLoginStateChanged.stream.first;
matrix.clear();
expect(matrix.accessToken == null, true);
expect(matrix.homeserver == null, true);
expect(matrix.api.accessToken == null, true);
expect(matrix.api.homeserver == null, true);
expect(matrix.userID == null, true);
expect(matrix.deviceID == null, true);
expect(matrix.deviceName == null, true);
@ -288,7 +254,7 @@ void main() {
var roomUpdateList = await roomUpdateListFuture;
expect(roomUpdateList.length, 3);
expect(roomUpdateList.length, 4);
expect(roomUpdateList[0].id == '!726s6s6q:example.com', true);
expect(roomUpdateList[0].membership == Membership.join, true);
@ -361,23 +327,6 @@ void main() {
expect(eventUpdateList[11].type, 'invite_state');
});
test('User Update Test', () async {
await matrix.onUserEvent.close();
var eventUpdateList = await userUpdateListFuture;
expect(eventUpdateList.length, 4);
expect(eventUpdateList[0].eventType, 'm.presence');
expect(eventUpdateList[0].type, 'presence');
expect(eventUpdateList[1].eventType, 'm.push_rules');
expect(eventUpdateList[1].type, 'account_data');
expect(eventUpdateList[2].eventType, 'org.example.custom.config');
expect(eventUpdateList[2].type, 'account_data');
});
test('To Device Update Test', () async {
await matrix.onToDeviceEvent.close();
@ -390,12 +339,10 @@ void main() {
});
test('Login', () async {
matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
matrix = Client('testclient', debug: true, httpClient: FakeMatrixApi());
roomUpdateListFuture = matrix.onRoomUpdate.stream.toList();
eventUpdateListFuture = matrix.onEvent.stream.toList();
userUpdateListFuture = matrix.onUserEvent.stream.toList();
final checkResp =
await matrix.checkServer('https://fakeServer.notExisting');
@ -405,55 +352,14 @@ void main() {
expect(loginResp, true);
});
test('createRoom', () async {
final openId = await matrix.requestOpenIdCredentials();
expect(openId.accessToken, 'SomeT0kenHere');
expect(openId.tokenType, 'Bearer');
expect(openId.matrixServerName, 'example.com');
expect(openId.expiresIn, 3600);
expect(openId.toJson(), {
'access_token': 'SomeT0kenHere',
'token_type': 'Bearer',
'matrix_server_name': 'example.com',
'expires_in': 3600
});
});
test('createRoom', () async {
final users = [
User('@alice:fakeServer.notExisting'),
User('@bob:fakeServer.notExisting')
];
final newID = await matrix.createRoom(invite: users);
expect(newID, '!1234:fakeServer.notExisting');
});
test('setAvatar', () async {
final testFile =
MatrixFile(bytes: Uint8List(0), path: 'fake/path/file.jpeg');
await matrix.setAvatar(testFile);
});
test('setPushers', () async {
await matrix.setPushers('abcdefg', 'http', 'com.famedly.famedlysdk',
'famedlySDK', 'GitLabCi', 'en', 'https://examplepushserver.com',
format: 'event_id_only');
});
test('joinRoomById', () async {
final roomID = '1234';
final Map<String, dynamic> resp = await matrix.joinRoomById(roomID);
expect(resp['room_id'], roomID);
});
test('requestUserDevices', () async {
final userDevices = await matrix.requestUserDevices();
expect(userDevices.length, 1);
expect(userDevices.first.deviceId, 'QBUAZIFURK');
expect(userDevices.first.displayName, 'android');
expect(userDevices.first.lastSeenIp, '1.2.3.4');
expect(
userDevices.first.lastSeenTs.millisecondsSinceEpoch, 1474491775024);
test('setMuteAllPushNotifications', () async {
await matrix.setMuteAllPushNotifications(false);
});
test('get archive', () async {
@ -476,8 +382,6 @@ void main() {
getFromRooms: false);
expect(profile.avatarUrl.toString(), 'mxc://test');
expect(profile.displayname, 'You got me');
expect(profile.content['avatar_url'], profile.avatarUrl.toString());
expect(profile.content['displayname'], profile.displayname);
final aliceProfile =
await matrix.getProfileFromUserId('@alice:example.com');
expect(aliceProfile.avatarUrl.toString(),
@ -533,9 +437,9 @@ void main() {
test('Track oneTimeKeys', () async {
if (matrix.encryptionEnabled) {
var last = matrix.lastTimeKeysUploaded ?? DateTime.now();
await matrix.handleSync({
await matrix.handleSync(SyncUpdate.fromJson({
'device_one_time_keys_count': {'signed_curve25519': 49}
});
}));
await Future.delayed(Duration(milliseconds: 50));
expect(
matrix.lastTimeKeysUploaded.millisecondsSinceEpoch >
@ -548,7 +452,7 @@ void main() {
expect(matrix.rooms[1].outboundGroupSession == null, true);
await matrix.rooms[1].createOutboundGroupSession();
expect(matrix.rooms[1].outboundGroupSession != null, true);
await matrix.handleSync({
await matrix.handleSync(SyncUpdate.fromJson({
'device_lists': {
'changed': [
'@alice:example.com',
@ -557,7 +461,7 @@ void main() {
'@bob:example.com',
],
}
});
}));
await Future.delayed(Duration(milliseconds: 50));
expect(matrix.rooms[1].outboundGroupSession != null, true);
}
@ -568,7 +472,7 @@ void main() {
expect(matrix.rooms[1].outboundGroupSession == null, true);
await matrix.rooms[1].createOutboundGroupSession();
expect(matrix.rooms[1].outboundGroupSession != null, true);
await matrix.handleSync({
await matrix.handleSync(SyncUpdate.fromJson({
'rooms': {
'join': {
'!726s6s6q:example.com': {
@ -588,7 +492,7 @@ void main() {
}
}
}
});
}));
await Future.delayed(Duration(milliseconds: 50));
expect(matrix.rooms[1].outboundGroupSession != null, true);
}
@ -627,29 +531,15 @@ void main() {
'body': 'Hello world',
});
});
test('Logout when token is unknown', () async {
var loginStateFuture = matrix.onLoginStateChanged.stream.first;
try {
await matrix.jsonRequest(
type: HTTPType.DELETE, action: '/unknown/token');
} on MatrixException catch (exception) {
expect(exception.error, MatrixError.M_UNKNOWN_TOKEN);
}
var state = await loginStateFuture;
expect(state, LoginState.loggedOut);
expect(matrix.isLogged(), false);
});
test('Test the fake store api', () async {
var client1 = Client('testclient', debug: true);
client1.httpClient = FakeMatrixApi();
var client1 =
Client('testclient', debug: true, httpClient: FakeMatrixApi());
client1.database = getDatabase();
client1.connect(
newToken: 'abc123',
newUserID: '@test:fakeServer.notExisting',
newHomeserver: 'https://fakeServer.notExisting',
newHomeserver: Uri.parse('https://fakeServer.notExisting'),
newDeviceName: 'Text Matrix Client',
newDeviceID: 'GHTYAJCE',
newOlmAccount: pickledOlmAccount,
@ -667,17 +557,17 @@ void main() {
expect(client1.isLogged(), true);
expect(client1.rooms.length, 2);
var client2 = Client('testclient', debug: true);
client2.httpClient = FakeMatrixApi();
var client2 =
Client('testclient', debug: true, httpClient: FakeMatrixApi());
client2.database = client1.database;
client2.connect();
await Future.delayed(Duration(milliseconds: 100));
expect(client2.isLogged(), true);
expect(client2.accessToken, client1.accessToken);
expect(client2.api.accessToken, client1.api.accessToken);
expect(client2.userID, client1.userID);
expect(client2.homeserver, client1.homeserver);
expect(client2.api.homeserver, client1.api.homeserver);
expect(client2.deviceID, client1.deviceID);
expect(client2.deviceName, client1.deviceName);
if (client2.encryptionEnabled) {
@ -692,5 +582,12 @@ void main() {
await client1.logout();
await client2.logout();
});
test('changePassword', () async {
await matrix.changePassword('1234', oldPassword: '123456');
});
test('dispose', () async {
await matrix.dispose(closeDatabase: true);
});
});
}

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:convert';

View file

@ -1,33 +1,30 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:convert';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/event.dart';
import 'package:test/test.dart';
import 'fake_matrix_api.dart';
import 'fake_matrix_localizations.dart';
void main() {
/// All Tests related to the Event
@ -52,9 +49,11 @@ void main() {
'status': 2,
'content': contentJson,
};
var client = Client('testclient', debug: true, httpClient: FakeMatrixApi());
var event = Event.fromJson(
jsonObj, Room(id: '!localpart:server.abc', client: client));
test('Create from json', () async {
var event = Event.fromJson(jsonObj, null);
jsonObj.remove('status');
jsonObj['content'] = json.decode(contentJson);
expect(event.toJson(), jsonObj);
@ -124,6 +123,7 @@ void main() {
jsonObj['type'] = 'm.room.message';
jsonObj['content'] = json.decode(jsonObj['content']);
jsonObj['content'].remove('m.relates_to');
jsonObj['content']['msgtype'] = 'm.notice';
event = Event.fromJson(jsonObj, null);
expect(event.messageType, MessageTypes.Notice);
@ -163,7 +163,19 @@ void main() {
});
test('redact', () async {
final room = Room(id: '1234', client: Client('testclient', debug: true));
final redactJsonObj = Map<String, dynamic>.from(jsonObj);
final testTypes = [
EventTypes.RoomMember,
EventTypes.RoomCreate,
EventTypes.RoomJoinRules,
EventTypes.RoomPowerLevels,
EventTypes.RoomAliases,
EventTypes.HistoryVisibility,
];
for (final testType in testTypes) {
redactJsonObj['type'] = testType;
final room =
Room(id: '1234', client: Client('testclient', debug: true));
final redactionEventJson = {
'content': {'reason': 'Spamming'},
'event_id': '143273582443PhrSn:example.org',
@ -175,13 +187,14 @@ void main() {
'unsigned': {'age': 1234}
};
var redactedBecause = Event.fromJson(redactionEventJson, room);
var event = Event.fromJson(jsonObj, room);
var event = Event.fromJson(redactJsonObj, room);
event.setRedactionEvent(redactedBecause);
expect(event.redacted, true);
expect(event.redactedBecause.toJson(), redactedBecause.toJson());
expect(event.content.isEmpty, true);
redactionEventJson.remove('redacts');
expect(event.unsigned['redacted_because'], redactionEventJson);
}
});
test('remove', () async {
@ -195,8 +208,8 @@ void main() {
});
test('sendAgain', () async {
var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
var matrix =
Client('testclient', debug: true, httpClient: FakeMatrixApi());
await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login('test', '1234');
@ -212,8 +225,8 @@ void main() {
});
test('requestKey', () async {
var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
var matrix =
Client('testclient', debug: true, httpClient: FakeMatrixApi());
await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login('test', '1234');
@ -227,7 +240,7 @@ void main() {
}
expect(exception, 'Session key not unknown');
event = Event.fromJson({
var event2 = Event.fromJson({
'event_id': id,
'sender': senderID,
'origin_server_ts': timestamp,
@ -245,9 +258,535 @@ void main() {
}),
}, Room(id: '!1234:example.com', client: matrix));
await event.requestKey();
await event2.requestKey();
await matrix.dispose(closeDatabase: true);
});
test('requestKey', () async {
jsonObj['state_key'] = '@alice:example.com';
var event = Event.fromJson(
jsonObj, Room(id: '!localpart:server.abc', client: client));
expect(event.stateKeyUser.id, '@alice:example.com');
});
test('canRedact', () async {
expect(event.canRedact, true);
});
test('getLocalizedBody', () async {
final matrix =
Client('testclient', debug: true, httpClient: FakeMatrixApi());
final room = Room(id: '!1234:example.com', client: matrix);
var event = Event.fromJson({
'content': {
'avatar_url': 'mxc://example.org/SEsfnsuifSDFSSEF',
'displayname': 'Alice Margatroid',
'membership': 'join'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member',
'unsigned': {
'age': 1234,
'redacted_because': {
'content': {'reason': 'Spamming'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'redacts': '\$143273582443PhrSn:example.org',
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.redaction',
'unsigned': {'age': 1234}
}
}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'body': 'Landing',
'info': {
'h': 200,
'mimetype': 'image/png',
'size': 73602,
'thumbnail_info': {
'h': 200,
'mimetype': 'image/png',
'size': 73602,
'w': 140
},
'thumbnail_url': 'mxc://matrix.org/sHhqkFCvSkFwtmvtETOtKnLP',
'w': 140
},
'url': 'mxc://matrix.org/sHhqkFCvSkFwtmvtETOtKnLP'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.sticker',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'reason': 'Spamming'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'redacts': '\$143273582443PhrSn:example.org',
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.redaction',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'aliases': ['#somewhere:example.org', '#another:example.org']
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': 'example.org',
'type': 'm.room.aliases',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'aliases': ['#somewhere:example.org', '#another:example.org']
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': 'example.org',
'type': 'm.room.aliases',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'alias': '#somewhere:localhost'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.canonical_alias',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'creator': '@example:example.org',
'm.federate': true,
'predecessor': {
'event_id': '\$something:example.org',
'room_id': '!oldroom:example.org'
},
'room_version': '1'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.create',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'body': 'This room has been replaced',
'replacement_room': '!newroom:example.org'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.tombstone',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'join_rule': 'public'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.join_rules',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'avatar_url': 'mxc://example.org/SEsfnsuifSDFSSEF',
'displayname': 'Alice Margatroid',
'membership': 'join'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'membership': 'invite'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member'
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'membership': 'leave'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member',
'unsigned': {
'prev_content': {'membership': 'join'},
}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'membership': 'ban'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member',
'unsigned': {
'prev_content': {'membership': 'join'},
}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'membership': 'join'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member',
'unsigned': {
'prev_content': {'membership': 'invite'},
}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'membership': 'invite'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member',
'unsigned': {
'prev_content': {'membership': 'join'},
}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'membership': 'leave'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member',
'unsigned': {
'prev_content': {'membership': 'invite'},
}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'membership': 'leave'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@alice:example.org',
'state_key': '@alice:example.org',
'type': 'm.room.member',
'unsigned': {
'prev_content': {'membership': 'invite'},
}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'ban': 50,
'events': {'m.room.name': 100, 'm.room.power_levels': 100},
'events_default': 0,
'invite': 50,
'kick': 50,
'notifications': {'room': 20},
'redact': 50,
'state_default': 50,
'users': {'@example:localhost': 100},
'users_default': 0
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.power_levels',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'name': 'The room name'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.name',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'topic': 'A room topic'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.topic',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'info': {'h': 398, 'mimetype': 'image/jpeg', 'size': 31037, 'w': 394},
'url': 'mxc://example.org/JWEIFJgwEIhweiWJE'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.avatar',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {'history_visibility': 'shared'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.history_visibility',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'algorithm': 'm.megolm.v1.aes-sha2',
'rotation_period_ms': 604800000,
'rotation_period_msgs': 100
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.encryption',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()),
'Example activatedEndToEndEncryption. needPantalaimonWarning');
event = Event.fromJson({
'content': {
'body': 'This is an example text message',
'format': 'org.matrix.custom.html',
'formatted_body': '<b>This is an example text message</b>',
'msgtype': 'm.text'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.message',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()),
'This is an example text message');
event = Event.fromJson({
'content': {
'body': 'thinks this is an example emote',
'format': 'org.matrix.custom.html',
'formatted_body': 'thinks <b>this</b> is an example emote',
'msgtype': 'm.emote'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.message',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()),
'* thinks this is an example emote');
event = Event.fromJson({
'content': {
'body': 'This is an example notice',
'format': 'org.matrix.custom.html',
'formatted_body': 'This is an <strong>example</strong> notice',
'msgtype': 'm.notice'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.message',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()),
'This is an example notice');
event = Event.fromJson({
'content': {
'body': 'filename.jpg',
'info': {'h': 398, 'mimetype': 'image/jpeg', 'size': 31037, 'w': 394},
'msgtype': 'm.image',
'url': 'mxc://example.org/JWEIFJgwEIhweiWJE'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.message',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'body': 'something-important.doc',
'filename': 'something-important.doc',
'info': {'mimetype': 'application/msword', 'size': 46144},
'msgtype': 'm.file',
'url': 'mxc://example.org/FHyPlCeYUSFFxlgbQYZmoEoe'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.message',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'body': 'Bee Gees - Stayin Alive',
'info': {
'duration': 2140786,
'mimetype': 'audio/mpeg',
'size': 1563685
},
'msgtype': 'm.audio',
'url': 'mxc://example.org/ffed755USFFxlgbQYZGtryd'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.message',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'body': 'Big Ben, London, UK',
'geo_uri': 'geo:51.5008,0.1247',
'info': {
'thumbnail_info': {
'h': 300,
'mimetype': 'image/jpeg',
'size': 46144,
'w': 300
},
'thumbnail_url': 'mxc://example.org/FHyPlCeYUSFFxlgbQYZmoEoe'
},
'msgtype': 'm.location'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.message',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
event = Event.fromJson({
'content': {
'body': 'Gangnam Style',
'info': {
'duration': 2140786,
'h': 320,
'mimetype': 'video/mp4',
'size': 1563685,
'thumbnail_info': {
'h': 300,
'mimetype': 'image/jpeg',
'size': 46144,
'w': 300
},
'thumbnail_url': 'mxc://example.org/FHyPlCeYUSFFxlgbQYZmoEoe',
'w': 480
},
'msgtype': 'm.video',
'url': 'mxc://example.org/a526eYUSFFxlgbQYZmo442'
},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'type': 'm.room.message',
'unsigned': {'age': 1234}
}, room);
expect(event.getLocalizedBody(FakeMatrixLocalizations()), null);
});
});
}

View file

@ -1,6 +1,26 @@
/*
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:moor/moor.dart';
import 'package:moor_ffi/moor_ffi.dart' as moor;
Database getDatabase() {
moorRuntimeOptions.dontWarnAboutMultipleDatabases = true;
return Database(moor.VmDatabase.memory());
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,309 @@
/*
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
class FakeMatrixLocalizations extends MatrixLocalizations {
@override
String acceptedTheInvitation(String targetName) {
// TODO: implement acceptedTheInvitation
return null;
}
@override
String activatedEndToEndEncryption(String senderName) {
// TODO: implement activatedEndToEndEncryption
return '$senderName activatedEndToEndEncryption';
}
@override
// TODO: implement anyoneCanJoin
String get anyoneCanJoin => null;
@override
String bannedUser(String senderName, String targetName) {
// TODO: implement bannedUser
return null;
}
@override
String changedTheChatAvatar(String senderName) {
// TODO: implement changedTheChatAvatar
return null;
}
@override
String changedTheChatDescriptionTo(String senderName, String content) {
// TODO: implement changedTheChatDescriptionTo
return null;
}
@override
String changedTheChatNameTo(String senderName, String content) {
// TODO: implement changedTheChatNameTo
return null;
}
@override
String changedTheChatPermissions(String senderName) {
// TODO: implement changedTheChatPermissions
return null;
}
@override
String changedTheDisplaynameTo(String targetName, String newDisplayname) {
// TODO: implement changedTheDisplaynameTo
return null;
}
@override
String changedTheGuestAccessRules(String senderName) {
// TODO: implement changedTheGuestAccessRules
return null;
}
@override
String changedTheGuestAccessRulesTo(
String senderName, String localizedString) {
// TODO: implement changedTheGuestAccessRulesTo
return null;
}
@override
String changedTheHistoryVisibility(String senderName) {
// TODO: implement changedTheHistoryVisibility
return null;
}
@override
String changedTheHistoryVisibilityTo(
String senderName, String localizedString) {
// TODO: implement changedTheHistoryVisibilityTo
return null;
}
@override
String changedTheJoinRules(String senderName) {
// TODO: implement changedTheJoinRules
return null;
}
@override
String changedTheJoinRulesTo(String senderName, String localizedString) {
// TODO: implement changedTheJoinRulesTo
return null;
}
@override
String changedTheProfileAvatar(String targetName) {
// TODO: implement changedTheProfileAvatar
return null;
}
@override
String changedTheRoomAliases(String senderName) {
// TODO: implement changedTheRoomAliases
return null;
}
@override
String changedTheRoomInvitationLink(String senderName) {
// TODO: implement changedTheRoomInvitationLink
return null;
}
@override
// TODO: implement channelCorruptedDecryptError
String get channelCorruptedDecryptError => null;
@override
String couldNotDecryptMessage(String errorText) {
// TODO: implement couldNotDecryptMessage
return null;
}
@override
String createdTheChat(String senderName) {
// TODO: implement createdTheChat
return null;
}
@override
// TODO: implement emptyChat
String get emptyChat => null;
@override
// TODO: implement encryptionNotEnabled
String get encryptionNotEnabled => null;
@override
// TODO: implement fromJoining
String get fromJoining => null;
@override
// TODO: implement fromTheInvitation
String get fromTheInvitation => null;
@override
String groupWith(String displayname) {
// TODO: implement groupWith
return null;
}
@override
// TODO: implement guestsAreForbidden
String get guestsAreForbidden => null;
@override
// TODO: implement guestsCanJoin
String get guestsCanJoin => null;
@override
String hasWithdrawnTheInvitationFor(String senderName, String targetName) {
// TODO: implement hasWithdrawnTheInvitationFor
return null;
}
@override
String invitedUser(String senderName, String targetName) {
// TODO: implement invitedUser
return null;
}
@override
// TODO: implement invitedUsersOnly
String get invitedUsersOnly => null;
@override
String joinedTheChat(String targetName) {
// TODO: implement joinedTheChat
return null;
}
@override
String kicked(String senderName, String targetName) {
// TODO: implement kicked
return null;
}
@override
String kickedAndBanned(String senderName, String targetName) {
// TODO: implement kickedAndBanned
return null;
}
@override
// TODO: implement needPantalaimonWarning
String get needPantalaimonWarning => 'needPantalaimonWarning';
@override
// TODO: implement noPermission
String get noPermission => 'noPermission';
@override
String redactedAnEvent(String senderName) {
// TODO: implement redactedAnEvent
return null;
}
@override
String rejectedTheInvitation(String targetName) {
// TODO: implement rejectedTheInvitation
return null;
}
@override
String removedBy(String calcDisplayname) {
// TODO: implement removedBy
return null;
}
@override
// TODO: implement roomHasBeenUpgraded
String get roomHasBeenUpgraded => null;
@override
String sentAFile(String senderName) {
// TODO: implement sentAFile
return null;
}
@override
String sentAPicture(String senderName) {
// TODO: implement sentAPicture
return null;
}
@override
String sentASticker(String senderName) {
// TODO: implement sentASticker
return null;
}
@override
String sentAVideo(String senderName) {
// TODO: implement sentAVideo
return null;
}
@override
String sentAnAudio(String senderName) {
// TODO: implement sentAnAudio
return null;
}
@override
String sharedTheLocation(String senderName) {
// TODO: implement sharedTheLocation
return null;
}
@override
String unbannedUser(String senderName, String targetName) {
// TODO: implement unbannedUser
return null;
}
@override
// TODO: implement unknownEncryptionAlgorithm
String get unknownEncryptionAlgorithm => null;
@override
String unknownEvent(String typeKey) {
// TODO: implement unknownEvent
return null;
}
@override
String userLeftTheChat(String targetName) {
// TODO: implement userLeftTheChat
return null;
}
@override
// TODO: implement visibleForAllParticipants
String get visibleForAllParticipants => null;
@override
// TODO: implement visibleForEveryone
String get visibleForEveryone => null;
@override
// TODO: implement you
String get you => null;
}

View file

@ -0,0 +1,97 @@
/*
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm;
import 'fake_matrix_api.dart';
void main() {
/// All Tests related to the ChatTime
group('Key Verification', () {
var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (_) {
olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString());
}
print('[LibOlm] Enabled: $olmEnabled');
var client = Client('testclient', debug: true, httpClient: FakeMatrixApi());
client.api.homeserver = Uri.parse('https://fakeserver.notexisting');
var room = Room(id: '!localpart:server.abc', client: client);
var updateCounter = 0;
final keyVerification = KeyVerification(
client: client,
room: room,
userId: '@alice:example.com',
deviceId: 'ABCD',
onUpdate: () => updateCounter++,
);
if (!olmEnabled) return;
test('acceptSas', () async {
await keyVerification.acceptSas();
});
test('acceptVerification', () async {
await keyVerification.acceptVerification();
});
test('cancel', () async {
await keyVerification.cancel('m.cancelcode');
expect(keyVerification.canceled, true);
expect(keyVerification.canceledCode, 'm.cancelcode');
expect(keyVerification.canceledReason, null);
});
test('handlePayload', () async {
await keyVerification.handlePayload('m.key.verification.request', {
'from_device': 'AliceDevice2',
'methods': ['m.sas.v1'],
'timestamp': 1559598944869,
'transaction_id': 'S0meUniqueAndOpaqueString'
});
await keyVerification.handlePayload('m.key.verification.start', {
'from_device': 'BobDevice1',
'method': 'm.sas.v1',
'transaction_id': 'S0meUniqueAndOpaqueString'
});
await keyVerification.handlePayload('m.key.verification.cancel', {
'code': 'm.user',
'reason': 'User rejected the key verification request',
'transaction_id': 'S0meUniqueAndOpaqueString'
});
});
test('rejectSas', () async {
await keyVerification.rejectSas();
});
test('rejectVerification', () async {
await keyVerification.rejectVerification();
});
test('start', () async {
await keyVerification.start();
});
test('verifyActivity', () async {
final verified = await keyVerification.verifyActivity();
expect(verified, true);
});
keyVerification.dispose();
});
}

View file

@ -1,3 +1,21 @@
/*
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/src/utils/markdown.dart';
import 'package:test/test.dart';

1518
test/matrix_api_test.dart Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';

View file

@ -1,26 +1,21 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart';
import 'package:http/http.dart';
import 'package:test/test.dart';

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:typed_data';

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:test/test.dart';

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:test/test.dart';

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:test/test.dart';
@ -31,21 +26,20 @@ void main() {
/// All Tests related to the MxContent
group('MxContent', () {
test('Formatting', () async {
var client = Client('testclient');
client.httpClient = FakeMatrixApi();
var client = Client('testclient', httpClient: FakeMatrixApi());
await client.checkServer('https://fakeserver.notexisting');
final mxc = 'mxc://exampleserver.abc/abcdefghijklmn';
final content = Uri.parse(mxc);
expect(content.isScheme('mxc'), true);
expect(content.getDownloadLink(client),
'${client.homeserver}/_matrix/media/r0/download/exampleserver.abc/abcdefghijklmn');
'${client.api.homeserver.toString()}/_matrix/media/r0/download/exampleserver.abc/abcdefghijklmn');
expect(content.getThumbnail(client, width: 50, height: 50),
'${client.homeserver}/_matrix/media/r0/thumbnail/exampleserver.abc/abcdefghijklmn?width=50&height=50&method=crop');
'${client.api.homeserver.toString()}/_matrix/media/r0/thumbnail/exampleserver.abc/abcdefghijklmn?width=50&height=50&method=crop');
expect(
content.getThumbnail(client,
width: 50, height: 50, method: ThumbnailMethod.scale),
'${client.homeserver}/_matrix/media/r0/thumbnail/exampleserver.abc/abcdefghijklmn?width=50&height=50&method=scale');
'${client.api.homeserver.toString()}/_matrix/media/r0/thumbnail/exampleserver.abc/abcdefghijklmn?width=50&height=50&method=scale');
});
});
}

View file

@ -1,51 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:test/test.dart';
void main() {
/// All Tests related to the ChatTime
group('Presence', () {
test('fromJson', () async {
var rawPresence = <String, dynamic>{
'content': {
'avatar_url': 'mxc://example.org/wefuiwegh8742w',
'currently_active': false,
'last_active_ago': 2478593,
'presence': 'online',
'status_msg': 'Making cupcakes'
},
'sender': '@example:localhost',
'type': 'm.presence'
};
var presence = Presence.fromJson(rawPresence);
expect(presence.sender, '@example:localhost');
expect(presence.avatarUrl.toString(), 'mxc://example.org/wefuiwegh8742w');
expect(presence.currentlyActive, false);
expect(presence.lastActiveAgo, 2478593);
expect(presence.presence, PresenceType.online);
expect(presence.statusMsg, 'Making cupcakes');
});
});
}

View file

@ -1,59 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:test/test.dart';
import 'fake_matrix_api.dart';
void main() {
/// All Tests related to device keys
group('Public Rooms Response', () {
Client client;
test('Public Rooms Response', () async {
client = Client('testclient', debug: true);
client.httpClient = FakeMatrixApi();
await client.checkServer('https://fakeServer.notExisting');
final responseMap = {
'chunk': [
{
'aliases': ['#murrays:cheese.bar'],
'avatar_url': 'mxc://bleeker.street/CHEDDARandBRIE',
'guest_can_join': false,
'name': 'CHEESE',
'num_joined_members': 37,
'room_id': '1234',
'topic': 'Tasty tasty cheese',
'world_readable': true
}
],
'next_batch': 'p190q',
'prev_batch': 'p1902',
'total_room_count_estimate': 115
};
final publicRoomsResponse =
PublicRoomsResponse.fromJson(responseMap, client);
await publicRoomsResponse.publicRooms.first.join();
});
});
}

View file

@ -1,185 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/src/utils/push_rules.dart';
import 'package:test/test.dart';
void main() {
/// All Tests related to the MxContent
group('PushRules', () {
test('Create', () async {
final json = {
'global': {
'content': [
{
'actions': [
'notify',
{'set_tweak': 'sound', 'value': 'default'},
{'set_tweak': 'highlight'}
],
'default': true,
'enabled': true,
'pattern': 'alice',
'rule_id': '.m.rule.contains_user_name'
}
],
'override': [
{
'actions': ['dont_notify'],
'conditions': [],
'default': true,
'enabled': false,
'rule_id': '.m.rule.master'
},
{
'actions': ['dont_notify'],
'conditions': [
{
'key': 'content.msgtype',
'kind': 'event_match',
'pattern': 'm.notice'
}
],
'default': true,
'enabled': true,
'rule_id': '.m.rule.suppress_notices'
}
],
'room': [],
'sender': [],
'underride': [
{
'actions': [
'notify',
{'set_tweak': 'sound', 'value': 'ring'},
{'set_tweak': 'highlight', 'value': false}
],
'conditions': [
{
'key': 'type',
'kind': 'event_match',
'pattern': 'm.call.invite'
}
],
'default': true,
'enabled': true,
'rule_id': '.m.rule.call'
},
{
'actions': [
'notify',
{'set_tweak': 'sound', 'value': 'default'},
{'set_tweak': 'highlight'}
],
'conditions': [
{'kind': 'contains_display_name'}
],
'default': true,
'enabled': true,
'rule_id': '.m.rule.contains_display_name'
},
{
'actions': [
'notify',
{'set_tweak': 'sound', 'value': 'default'},
{'set_tweak': 'highlight', 'value': false}
],
'conditions': [
{'kind': 'room_member_count', 'is': '2'},
{
'kind': 'event_match',
'key': 'type',
'pattern': 'm.room.message'
}
],
'default': true,
'enabled': true,
'rule_id': '.m.rule.room_one_to_one'
},
{
'actions': [
'notify',
{'set_tweak': 'sound', 'value': 'default'},
{'set_tweak': 'highlight', 'value': false}
],
'conditions': [
{
'key': 'type',
'kind': 'event_match',
'pattern': 'm.room.member'
},
{
'key': 'content.membership',
'kind': 'event_match',
'pattern': 'invite'
},
{
'key': 'state_key',
'kind': 'event_match',
'pattern': '@alice:example.com'
}
],
'default': true,
'enabled': true,
'rule_id': '.m.rule.invite_for_me'
},
{
'actions': [
'notify',
{'set_tweak': 'highlight', 'value': false}
],
'conditions': [
{
'key': 'type',
'kind': 'event_match',
'pattern': 'm.room.member'
}
],
'default': true,
'enabled': true,
'rule_id': '.m.rule.member_event'
},
{
'actions': [
'notify',
{'set_tweak': 'highlight', 'value': false}
],
'conditions': [
{
'key': 'type',
'kind': 'event_match',
'pattern': 'm.room.message'
}
],
'default': true,
'enabled': true,
'rule_id': '.m.rule.message'
}
]
}
};
expect(PushRules.fromJson(json) != null, true);
});
});
}

View file

@ -1,45 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/src/utils/pusher.dart';
import 'package:test/test.dart';
void main() {
/// All Tests related to device keys
group('Pusher', () {
test('Pusher', () {
final rawPusher = {
'pushkey': 'Xp/MzCt8/9DcSNE9cuiaoT5Ac55job3TdLSSmtmYl4A=',
'kind': 'http',
'app_id': 'face.mcapp.appy.prod',
'app_display_name': 'Appy McAppface',
'device_display_name': "Alice's Phone",
'profile_tag': 'xyz',
'lang': 'en-US',
'data': {'url': 'https://example.com/_matrix/push/v1/notify'}
};
final pusher = Pusher.fromJson(rawPusher);
expect(pusher.toJson(), rawPusher);
});
});
}

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:convert';
@ -62,9 +57,16 @@ void main() {
expect(toDeviceEvent.content, rawJson['content']);
expect(toDeviceEvent.sender, rawJson['sender']);
expect(toDeviceEvent.type, rawJson['type']);
expect(
ToDeviceEventDecryptionError(
exception: Exception('test'),
stackTrace: null,
toDeviceEvent: toDeviceEvent)
.sender,
rawJson['sender'],
);
var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
var matrix = Client('testclient', debug: true, httpClient: FakeMatrixApi());
matrix.database = getDatabase();
await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login('test', '1234');
@ -91,8 +93,7 @@ void main() {
await matrix.dispose(closeDatabase: true);
});
test('Create Request', () async {
var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
var matrix = Client('testclient', debug: true, httpClient: FakeMatrixApi());
matrix.database = getDatabase();
await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login('test', '1234');
@ -124,8 +125,7 @@ void main() {
});
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
test('Reply To Request', () async {
var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
var matrix = Client('testclient', debug: true, httpClient: FakeMatrixApi());
matrix.database = getDatabase();
await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login('test', '1234');
@ -135,8 +135,12 @@ void main() {
}
matrix.setUserId('@alice:example.com'); // we need to pretend to be alice
FakeMatrixApi.calledEndpoints.clear();
await matrix.userDeviceKeys['@alice:example.com'].deviceKeys['OTHERDEVICE']
.setBlocked(false, matrix);
await matrix.userDeviceKeys['@alice:example.com'].deviceKeys['OTHERDEVICE']
.setVerified(true, matrix);
await matrix.userDeviceKeys['@alice:example.com'].deviceKeys['OTHERDEVICE']
.startVerification(matrix);
// test a successful share
var event = ToDeviceEvent(
sender: '@alice:example.com',
@ -268,8 +272,7 @@ void main() {
await matrix.dispose(closeDatabase: true);
});
test('Receive shared keys', () async {
var matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
var matrix = Client('testclient', debug: true, httpClient: FakeMatrixApi());
matrix.database = getDatabase();
await matrix.checkServer('https://fakeServer.notExisting');
await matrix.login('test', '1234');

View file

@ -1,26 +1,22 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/client.dart';
import 'package:famedlysdk/src/event.dart';
import 'package:famedlysdk/src/room.dart';
@ -41,8 +37,7 @@ void main() {
/// All Tests related to the Event
group('Room', () {
test('Login', () async {
matrix = Client('testclient', debug: true);
matrix.httpClient = FakeMatrixApi();
matrix = Client('testclient', debug: true, httpClient: FakeMatrixApi());
final checkResp =
await matrix.checkServer('https://fakeServer.notExisting');
@ -123,7 +118,7 @@ void main() {
room.states['m.room.canonical_alias'] = Event(
senderId: '@test:example.com',
typeKey: 'm.room.canonical_alias',
type: 'm.room.canonical_alias',
roomId: room.id,
room: room,
eventId: '123',
@ -134,7 +129,7 @@ void main() {
room.states['m.room.name'] = Event(
senderId: '@test:example.com',
typeKey: 'm.room.name',
type: 'm.room.name',
roomId: room.id,
room: room,
eventId: '123',
@ -145,7 +140,7 @@ void main() {
expect(room.topic, '');
room.states['m.room.topic'] = Event(
senderId: '@test:example.com',
typeKey: 'm.room.topic',
type: 'm.room.topic',
roomId: room.id,
room: room,
eventId: '123',
@ -156,7 +151,7 @@ void main() {
expect(room.avatar, null);
room.states['m.room.avatar'] = Event(
senderId: '@test:example.com',
typeKey: 'm.room.avatar',
type: 'm.room.avatar',
roomId: room.id,
room: room,
eventId: '123',
@ -165,22 +160,26 @@ void main() {
expect(room.avatar.toString(), 'mxc://testurl');
room.states['m.room.message'] = Event(
senderId: '@test:example.com',
typeKey: 'm.room.message',
type: 'm.room.message',
roomId: room.id,
room: room,
eventId: '12345',
time: DateTime.now(),
originServerTs: DateTime.now(),
content: {'msgtype': 'm.text', 'body': 'test'},
stateKey: '');
expect(room.lastEvent.eventId, '12345');
expect(room.lastMessage, 'test');
expect(room.timeCreated, room.lastEvent.time);
expect(room.timeCreated, room.lastEvent.originServerTs);
});
test('sendReadReceipt', () async {
await room.sendReadReceipt('§1234:fakeServer.notExisting');
});
test('enableEncryption', () async {
await room.enableEncryption();
});
test('requestParticipants', () async {
final participants = await room.requestParticipants();
expect(participants.length, 1);
@ -222,7 +221,7 @@ void main() {
test('PowerLevels', () async {
room.states['m.room.power_levels'] = Event(
senderId: '@test:example.com',
typeKey: 'm.room.power_levels',
type: 'm.room.power_levels',
roomId: room.id,
room: room,
eventId: '123',
@ -258,7 +257,7 @@ void main() {
room.states['m.room.power_levels'] = Event(
senderId: '@test:example.com',
typeKey: 'm.room.power_levels',
type: 'm.room.power_levels',
roomId: room.id,
room: room,
eventId: '123abc',
@ -298,16 +297,16 @@ void main() {
test('getParticipants', () async {
room.setState(Event(
senderId: '@alice:test.abc',
typeKey: 'm.room.member',
type: 'm.room.member',
roomId: room.id,
room: room,
eventId: '12345',
time: DateTime.now(),
originServerTs: DateTime.now(),
content: {'displayname': 'alice'},
stateKey: '@alice:test.abc'));
final userList = room.getParticipants();
expect(userList.length, 5);
expect(userList[3].displayName, 'Alice Margatroid');
expect(userList.length, 4);
expect(userList[3].displayName, 'alice');
});
test('addToDirectChat', () async {
@ -325,7 +324,7 @@ void main() {
user = await room.getUserByMXID('@getme:example.com');
} catch (_) {}
expect(user.stateKey, '@getme:example.com');
expect(user.calcDisplayname(), 'You got me');
expect(user.calcDisplayname(), 'Getme');
});
test('setAvatar', () async {
@ -375,11 +374,11 @@ void main() {
room.setState(
Event(
senderId: '@alice:test.abc',
typeKey: 'm.room.encryption',
type: 'm.room.encryption',
roomId: room.id,
room: room,
eventId: '12345',
time: DateTime.now(),
originServerTs: DateTime.now(),
content: {
'algorithm': 'm.megolm.v1.aes-sha2',
'rotation_period_ms': 604800000,
@ -433,18 +432,83 @@ void main() {
var encryptedEvent = Event(
content: encryptedPayload,
typeKey: 'm.room.encrypted',
type: 'm.room.encrypted',
senderId: room.client.userID,
eventId: '1234',
roomId: room.id,
room: room,
time: DateTime.now(),
originServerTs: DateTime.now(),
);
var decryptedEvent = room.decryptGroupMessage(encryptedEvent);
expect(decryptedEvent.typeKey, 'm.room.message');
expect(decryptedEvent.type, 'm.room.message');
expect(decryptedEvent.content, payload);
});
test('setPushRuleState', () async {
await room.setPushRuleState(PushRuleState.notify);
await room.setPushRuleState(PushRuleState.dont_notify);
await room.setPushRuleState(PushRuleState.mentions_only);
await room.setPushRuleState(PushRuleState.notify);
});
test('Test call methods', () async {
await room.inviteToCall('1234', 1234, 'sdp', txid: '1234');
await room.answerCall('1234', 'sdp', txid: '1234');
await room.hangupCall('1234', txid: '1234');
await room.sendCallCandidates('1234', [], txid: '1234');
});
test('joinRules', () async {
expect(room.canChangeJoinRules, false);
expect(room.joinRules, JoinRules.public);
room.setState(Event.fromJson({
'content': {'join_rule': 'invite'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.join_rules',
'unsigned': {'age': 1234}
}, room));
expect(room.joinRules, JoinRules.invite);
await room.setJoinRules(JoinRules.invite);
});
test('guestAccess', () async {
expect(room.canChangeGuestAccess, false);
expect(room.guestAccess, GuestAccess.forbidden);
room.setState(Event.fromJson({
'content': {'guest_access': 'can_join'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.guest_access',
'unsigned': {'age': 1234}
}, room));
expect(room.guestAccess, GuestAccess.can_join);
await room.setGuestAccess(GuestAccess.can_join);
});
test('historyVisibility', () async {
expect(room.canChangeHistoryVisibility, false);
expect(room.historyVisibility, null);
room.setState(Event.fromJson({
'content': {'history_visibility': 'shared'},
'event_id': '\$143273582443PhrSn:example.org',
'origin_server_ts': 1432735824653,
'room_id': '!jEsUZKDJdhlrceRyVU:example.org',
'sender': '@example:example.org',
'state_key': '',
'type': 'm.room.history_visibility',
'unsigned': {'age': 1234}
}, room));
expect(room.historyVisibility, HistoryVisibility.shared);
await room.setHistoryVisibility(HistoryVisibility.joined);
});
test('logout', () async {
await matrix.logout();
});

View file

@ -0,0 +1,56 @@
/*
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'dart:convert';
import 'package:famedlysdk/src/utils/session_key.dart';
import 'package:olm/olm.dart' as olm;
import 'package:test/test.dart';
void main() {
/// All Tests related to the ChatTime
group('SessionKey', () {
var olmEnabled = true;
try {
olm.init();
olm.Account();
} catch (_) {
olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString());
}
print('[LibOlm] Enabled: $olmEnabled');
test('SessionKey test', () {
if (olmEnabled) {
final sessionKey = SessionKey(
content: {
'algorithm': 'm.megolm.v1.aes-sha2',
'room_id': '!Cuyf34gef24t:localhost',
'session_id': 'X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ',
'session_key':
'AgAAAADxKHa9uFxcXzwYoNueL5Xqi69IkD4sni8LlfJL7qNBEY...'
},
inboundGroupSession: olm.InboundGroupSession(),
key: '1234',
indexes: {},
);
expect(sessionKey.senderClaimedEd25519Key, '');
expect(sessionKey.toJson(),
SessionKey.fromJson(sessionKey.toJson(), '1234').toJson());
expect(sessionKey.toString(), json.encode(sessionKey.toJson()));
}
});
});
}

View file

@ -1,24 +1,19 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
@ -33,7 +28,7 @@ void main() {
states['m.room.name'] = Event(
eventId: '1',
content: {'name': 'test'},
typeKey: 'm.room.name',
type: 'm.room.name',
stateKey: '',
roomId: '!test:test.test',
senderId: '@alice:test.test');
@ -41,7 +36,7 @@ void main() {
states['@alice:test.test'] = Event(
eventId: '2',
content: {'membership': 'join'},
typeKey: 'm.room.name',
type: 'm.room.name',
stateKey: '@alice:test.test',
roomId: '!test:test.test',
senderId: '@alice:test.test');
@ -49,7 +44,7 @@ void main() {
states['m.room.member']['@bob:test.test'] = Event(
eventId: '3',
content: {'membership': 'join'},
typeKey: 'm.room.name',
type: 'm.room.name',
stateKey: '@bob:test.test',
roomId: '!test:test.test',
senderId: '@bob:test.test');
@ -57,7 +52,7 @@ void main() {
states['com.test.custom'] = Event(
eventId: '4',
content: {'custom': 'stuff'},
typeKey: 'com.test.custom',
type: 'com.test.custom',
stateKey: 'customStateKey',
roomId: '!test:test.test',
senderId: '@bob:test.test');

View file

@ -1,34 +1,28 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/src/room_account_data.dart';
import 'package:famedlysdk/matrix_api.dart';
import 'package:test/test.dart';
import 'package:famedlysdk/src/client.dart';
import 'package:famedlysdk/src/room.dart';
import 'package:famedlysdk/src/timeline.dart';
import 'package:famedlysdk/src/user.dart';
import 'package:famedlysdk/src/sync/event_update.dart';
import 'package:famedlysdk/src/sync/room_update.dart';
import 'package:famedlysdk/src/utils/event_update.dart';
import 'package:famedlysdk/src/utils/room_update.dart';
import 'fake_matrix_api.dart';
void main() {
@ -39,8 +33,7 @@ void main() {
var updateCount = 0;
var insertList = <int>[];
var client = Client('testclient', debug: true);
client.httpClient = FakeMatrixApi();
var client = Client('testclient', debug: true, httpClient: FakeMatrixApi());
var room = Room(
id: roomID, client: client, prev_batch: '1234', roomAccountData: {});
@ -94,15 +87,16 @@ void main() {
expect(timeline.events.length, 2);
expect(timeline.events[0].eventId, '1');
expect(timeline.events[0].sender.id, '@alice:example.com');
expect(timeline.events[0].time.millisecondsSinceEpoch, testTimeStamp);
expect(timeline.events[0].originServerTs.millisecondsSinceEpoch,
testTimeStamp);
expect(timeline.events[0].body, 'Testcase');
expect(
timeline.events[0].time.millisecondsSinceEpoch >
timeline.events[1].time.millisecondsSinceEpoch,
timeline.events[0].originServerTs.millisecondsSinceEpoch >
timeline.events[1].originServerTs.millisecondsSinceEpoch,
true);
expect(timeline.events[0].receipts, []);
room.roomAccountData['m.receipt'] = RoomAccountData.fromJson({
room.roomAccountData['m.receipt'] = BasicRoomEvent.fromJson({
'type': 'm.receipt',
'content': {
'@alice:example.com': {
@ -111,7 +105,7 @@ void main() {
}
},
'room_id': roomID,
}, room);
});
await Future.delayed(Duration(milliseconds: 50));
@ -241,6 +235,7 @@ void main() {
expect(timeline.events[7].eventId, '2143273582443PhrSn:example.org');
expect(timeline.events[8].eventId, '1143273582443PhrSn:example.org');
expect(room.prev_batch, 't47409-4357353_219380_26003_2265');
await timeline.events[8].redact(reason: 'test', txid: '1234');
});
test('Clear cache on limited timeline', () async {

View file

@ -1,33 +1,48 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
* Ansible inventory script used at Famedly GmbH for managing many hosts
* Copyright (C) 2019, 2020 Famedly GmbH
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/event.dart';
import 'package:famedlysdk/src/user.dart';
import 'package:test/test.dart';
import 'fake_matrix_api.dart';
void main() {
/// All Tests related to the Event
group('User', () {
var client = Client('testclient', debug: true, httpClient: FakeMatrixApi());
final user1 = User(
'@alice:example.com',
membership: 'join',
displayName: 'Alice M',
avatarUrl: 'mxc://bla',
room: Room(id: '!localpart:server.abc', client: client),
);
test('create', () async {
expect(user1.powerLevel, 0);
expect(user1.stateKey, '@alice:example.com');
expect(user1.id, '@alice:example.com');
expect(user1.membership, Membership.join);
expect(user1.avatarUrl.toString(), 'mxc://bla');
expect(user1.displayName, 'Alice M');
});
test('Create from json', () async {
final id = '@alice:server.abc';
final membership = Membership.join;
@ -65,6 +80,56 @@ void main() {
expect(user1.calcDisplayname(), 'Alice');
expect(user2.calcDisplayname(), 'SuperAlice');
expect(user3.calcDisplayname(), 'Alice Mep');
expect(user3.calcDisplayname(formatLocalpart: false), 'alice_mep');
});
test('kick', () async {
await client.checkServer('https://fakeserver.notexisting');
await user1.kick();
});
test('ban', () async {
await client.checkServer('https://fakeserver.notexisting');
await user1.ban();
});
test('unban', () async {
await client.checkServer('https://fakeserver.notexisting');
await user1.unban();
});
test('setPower', () async {
await client.checkServer('https://fakeserver.notexisting');
await user1.setPower(50);
});
test('startDirectChat', () async {
await client.checkServer('https://fakeserver.notexisting');
await client.login('test', '1234');
await user1.startDirectChat();
});
test('getPresence', () async {
await client.checkServer('https://fakeserver.notexisting');
await client.handleSync(SyncUpdate.fromJson({
'presence': {
'events': [
{
'sender': '@alice:example.com',
'type': 'm.presence',
'content': {'presence': 'online'}
}
]
}
}));
expect(user1.presence.presence.presence, PresenceType.online);
});
test('canBan', () async {
await client.checkServer('https://fakeserver.notexisting');
expect(user1.canBan, false);
});
test('canKick', () async {
await client.checkServer('https://fakeserver.notexisting');
expect(user1.canKick, false);
});
test('canChangePowerLevel', () async {
await client.checkServer('https://fakeserver.notexisting');
expect(user1.canChangePowerLevel, false);
});
client.dispose();
});
}

View file

@ -1,40 +0,0 @@
/*
* Copyright (c) 2019 Zender & Kurtz GbR.
*
* Authors:
* Christian Pauly <krille@famedly.com>
* Marcel Radzio <mtrnord@famedly.com>
*
* This file is part of famedlysdk.
*
* famedlysdk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* famedlysdk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with famedlysdk. If not, see <http://www.gnu.org/licenses/>.
*/
import 'package:famedlysdk/famedlysdk.dart';
import 'package:test/test.dart';
void main() {
/// All Tests related to device keys
group('WellKnownInformations', () {
test('WellKnownInformations', () {
final json = {
'm.homeserver': {'base_url': 'https://matrix.example.com'},
'm.identity_server': {'base_url': 'https://identity.example.com'},
'org.example.custom.property': {
'app_url': 'https://custom.app.example.org'
}
};
WellKnownInformations.fromJson(json);
});
});
}

View file

@ -1,4 +1,5 @@
import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart';
import '../test/fake_database.dart';
void main() => test();
@ -17,14 +18,14 @@ const String testMessage6 = 'Hello mars';
void test() async {
print('++++ Login $testUserA ++++');
var testClientA = Client('TestClient', debug: false);
var testClientA = Client('TestClientA', debug: false);
testClientA.database = getDatabase();
await testClientA.checkServer(homeserver);
await testClientA.login(testUserA, testPasswordA);
assert(testClientA.encryptionEnabled);
print('++++ Login $testUserB ++++');
var testClientB = Client('TestClient', debug: false);
var testClientB = Client('TestClientB', debug: false);
testClientB.database = getDatabase();
await testClientB.checkServer(homeserver);
await testClientB.login(testUserB, testPasswordA);
@ -39,9 +40,7 @@ void test() async {
try {
await room.leave();
await room.forget();
} catch (e) {
print(e);
}
} catch (_) {}
}
print('++++ ($testUserB) Leave all rooms ++++');
@ -51,9 +50,7 @@ void test() async {
try {
await room.leave();
await room.forget();
} catch (e) {
print(e);
}
} catch (_) {}
}
}
@ -74,7 +71,7 @@ void test() async {
.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID].blocked);
print('++++ ($testUserA) Create room and invite $testUserB ++++');
await testClientA.createRoom(invite: [User(testUserB)]);
await testClientA.api.createRoom(invite: [testUserB]);
await Future.delayed(Duration(seconds: 1));
var room = testClientA.rooms.first;
assert(room != null);
@ -174,12 +171,11 @@ void test() async {
"++++ ($testUserA) Received decrypted message: '${room.lastMessage}' ++++");
print('++++ Login $testUserB in another client ++++');
var testClientC = Client('TestClient', debug: false);
testClientC.database = getDatabase();
var testClientC =
Client('TestClientC', debug: false, database: getDatabase());
await testClientC.checkServer(homeserver);
await testClientC.login(testUserB, testPasswordA);
await Future.delayed(Duration(seconds: 3));
assert(room.outboundGroupSession == null);
print("++++ ($testUserA) Send again encrypted message: '$testMessage4' ++++");
await room.sendTextEvent(testMessage4);
@ -202,11 +198,10 @@ void test() async {
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
print('++++ Logout $testUserB another client ++++');
await testClientC.dispose();
await testClientC.logout();
testClientC = null;
await Future.delayed(Duration(seconds: 5));
assert(room.outboundGroupSession == null);
assert(inviteRoom.outboundGroupSession == null);
print("++++ ($testUserA) Send again encrypted message: '$testMessage6' ++++");
await room.sendTextEvent(testMessage6);
@ -224,11 +219,14 @@ void test() async {
print(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
print('++++ ($testUserA) Restore user ++++');
final clientADatabase = testClientA.database;
/* print('++++ ($testUserA) Restore user ++++');
await testClientA.dispose();
testClientA = null;
testClientA = Client('TestClient', debug: false);
testClientA.database = clientADatabase;
testClientA = Client(
'TestClientA',
debug: false,
database: getDatabase(),
);
testClientA.connect();
await Future.delayed(Duration(seconds: 3));
var restoredRoom = testClientA.rooms.first;
@ -255,14 +253,11 @@ void test() async {
assert(testClientB.olmSessions[testClientA.identityKey].length == 1);
assert(testClientA.olmSessions[testClientB.identityKey].first.session_id() ==
testClientB.olmSessions[testClientA.identityKey].first.session_id());
/*assert(restoredRoom.outboundGroupSession.session_id() == currentSessionIdA);
assert(inviteRoom.inboundGroupSessions
.containsKey(restoredRoom.outboundGroupSession.session_id()));*/
assert(restoredRoom.lastMessage == testMessage5);
assert(inviteRoom.lastMessage == testMessage5);
assert(testClientB.getRoomById(roomId).lastMessage == testMessage5);
print(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");*/
print('++++ Logout $testUserA and $testUserB ++++');
await room.leave();
@ -270,10 +265,10 @@ void test() async {
await inviteRoom.leave();
await inviteRoom.forget();
await Future.delayed(Duration(seconds: 1));
await testClientA.jsonRequest(
type: HTTPType.POST, action: '/client/r0/logout/all');
await testClientB.jsonRequest(
type: HTTPType.POST, action: '/client/r0/logout/all');
await testClientA.dispose();
await testClientB.dispose();
await testClientA.api.logoutAll();
await testClientB.api.logoutAll();
testClientA = null;
testClientB = null;
return;