Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions MatrixSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,12 @@
ECF29BDF264195320053E6D6 /* MXAssertedIdentityModel.h in Headers */ = {isa = PBXBuildFile; fileRef = ECF29BDD264195320053E6D6 /* MXAssertedIdentityModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
ECF29BE52641953C0053E6D6 /* MXAssertedIdentityModel.m in Sources */ = {isa = PBXBuildFile; fileRef = ECF29BE42641953C0053E6D6 /* MXAssertedIdentityModel.m */; };
ECF29BE62641953C0053E6D6 /* MXAssertedIdentityModel.m in Sources */ = {isa = PBXBuildFile; fileRef = ECF29BE42641953C0053E6D6 /* MXAssertedIdentityModel.m */; };
ED21F68528104DA2002FF83D /* MXMegolmEncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED21F68428104DA2002FF83D /* MXMegolmEncryptionTests.swift */; };
ED21F68628104DA2002FF83D /* MXMegolmEncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED21F68428104DA2002FF83D /* MXMegolmEncryptionTests.swift */; };
ED35652C281150310002BF6A /* MXOlmInboundGroupSessionUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED35652B281150310002BF6A /* MXOlmInboundGroupSessionUnitTests.swift */; };
ED35652D281150310002BF6A /* MXOlmInboundGroupSessionUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED35652B281150310002BF6A /* MXOlmInboundGroupSessionUnitTests.swift */; };
ED35652F281153480002BF6A /* MXMegolmSessionDataUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED35652E281153480002BF6A /* MXMegolmSessionDataUnitTests.swift */; };
ED356530281153480002BF6A /* MXMegolmSessionDataUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED35652E281153480002BF6A /* MXMegolmSessionDataUnitTests.swift */; };
ED88999127F2065D00718486 /* MXRoomAliasResolution.h in Headers */ = {isa = PBXBuildFile; fileRef = ED88998F27F2065C00718486 /* MXRoomAliasResolution.h */; settings = {ATTRIBUTES = (Public, ); }; };
ED88999227F2065D00718486 /* MXRoomAliasResolution.h in Headers */ = {isa = PBXBuildFile; fileRef = ED88998F27F2065C00718486 /* MXRoomAliasResolution.h */; settings = {ATTRIBUTES = (Public, ); }; };
ED88999327F2065D00718486 /* MXRoomAliasResolution.m in Sources */ = {isa = PBXBuildFile; fileRef = ED88999027F2065D00718486 /* MXRoomAliasResolution.m */; };
Expand Down Expand Up @@ -2720,7 +2726,10 @@
ECF29BD2264194BB0053E6D6 /* MXCallAssertedIdentityEventContent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXCallAssertedIdentityEventContent.m; sourceTree = "<group>"; };
ECF29BDD264195320053E6D6 /* MXAssertedIdentityModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXAssertedIdentityModel.h; sourceTree = "<group>"; };
ECF29BE42641953C0053E6D6 /* MXAssertedIdentityModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXAssertedIdentityModel.m; sourceTree = "<group>"; };
ED21F68428104DA2002FF83D /* MXMegolmEncryptionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXMegolmEncryptionTests.swift; sourceTree = "<group>"; };
ED2F344856EFFCA383E37B22 /* Pods-SDK-MatrixSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDK-MatrixSDK.release.xcconfig"; path = "Target Support Files/Pods-SDK-MatrixSDK/Pods-SDK-MatrixSDK.release.xcconfig"; sourceTree = "<group>"; };
ED35652B281150310002BF6A /* MXOlmInboundGroupSessionUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXOlmInboundGroupSessionUnitTests.swift; sourceTree = "<group>"; };
ED35652E281153480002BF6A /* MXMegolmSessionDataUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXMegolmSessionDataUnitTests.swift; sourceTree = "<group>"; };
ED88998F27F2065C00718486 /* MXRoomAliasResolution.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXRoomAliasResolution.h; sourceTree = "<group>"; };
ED88999027F2065D00718486 /* MXRoomAliasResolution.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXRoomAliasResolution.m; sourceTree = "<group>"; };
ED8943D327E34762000FC39C /* MXMemoryRoomStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXMemoryRoomStoreTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3839,6 +3848,7 @@
32C6F93919DD814400EA4E9C /* MatrixSDKTests */ = {
isa = PBXGroup;
children = (
ED21F67A28104B9A002FF83D /* Crypto */,
EDB4209727DF841A0036AF39 /* JSONModels */,
EDB4208E27DF76C60036AF39 /* Data */,
322985C526FA66FD001890BC /* Utils */,
Expand Down Expand Up @@ -4799,6 +4809,40 @@
path = Common;
sourceTree = "<group>";
};
ED21F67A28104B9A002FF83D /* Crypto */ = {
isa = PBXGroup;
children = (
ED35652A281150230002BF6A /* Data */,
ED21F67B28104BA1002FF83D /* Algorithms */,
);
path = Crypto;
sourceTree = "<group>";
};
ED21F67B28104BA1002FF83D /* Algorithms */ = {
isa = PBXGroup;
children = (
ED21F67C28104BA7002FF83D /* Megolm */,
);
path = Algorithms;
sourceTree = "<group>";
};
ED21F67C28104BA7002FF83D /* Megolm */ = {
isa = PBXGroup;
children = (
ED21F68428104DA2002FF83D /* MXMegolmEncryptionTests.swift */,
);
path = Megolm;
sourceTree = "<group>";
};
ED35652A281150230002BF6A /* Data */ = {
isa = PBXGroup;
children = (
ED35652B281150310002BF6A /* MXOlmInboundGroupSessionUnitTests.swift */,
ED35652E281153480002BF6A /* MXMegolmSessionDataUnitTests.swift */,
);
path = Data;
sourceTree = "<group>";
};
ED8943D127E3474A000FC39C /* Store */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -6308,6 +6352,7 @@
32832B5E1BCC048300241108 /* MXStoreNoStoreTests.m in Sources */,
A816247C25F60C7700A46F05 /* MXDeviceListOperationsPoolUnitTests.swift in Sources */,
B1660F1C260A20B900C3AA12 /* MXSpaceServiceTest.swift in Sources */,
ED35652C281150310002BF6A /* MXOlmInboundGroupSessionUnitTests.swift in Sources */,
32C9B71823E81A1C00C6F30A /* MXCrossSigningVerificationTests.m in Sources */,
323C5A081A70E53500FB0549 /* MXToolsUnitTests.m in Sources */,
3281E89E19E299C000976E1A /* MXErrorUnitTests.m in Sources */,
Expand Down Expand Up @@ -6365,10 +6410,12 @@
32D8CAC219DEE6ED002AF8A0 /* MXRestClientNoAuthAPITests.m in Sources */,
32FCAB4D19E578860049C555 /* MXRestClientTests.m in Sources */,
32C78BA7256D227D008130B1 /* MXCryptoMigrationTests.m in Sources */,
ED21F68528104DA2002FF83D /* MXMegolmEncryptionTests.swift in Sources */,
322985CB26FAF898001890BC /* MXSession.swift in Sources */,
EC131B192779D8D500712964 /* MXThreadEventTimelineUnitTests.swift in Sources */,
B135067427EB201E00BD3276 /* MXLocationServiceTests.swift in Sources */,
18C26C4F273C0EB300805154 /* MXPollAggregatorTests.swift in Sources */,
ED35652F281153480002BF6A /* MXMegolmSessionDataUnitTests.swift in Sources */,
32EEA83F2603CA140041425B /* MXRestClientExtensionsTests.m in Sources */,
18121F7A273E6E4200B68ADF /* PollBuilder.swift in Sources */,
18121F7F273E837300B68ADF /* PollModels.swift in Sources */,
Expand Down Expand Up @@ -6837,6 +6884,7 @@
32C9B71923E81A1C00C6F30A /* MXCrossSigningVerificationTests.m in Sources */,
B1E09A1D2397FCE90057C069 /* MXCryptoKeyVerificationTests.m in Sources */,
B1E09A472397FD990057C069 /* MXEventScanStoreUnitTests.m in Sources */,
ED35652D281150310002BF6A /* MXOlmInboundGroupSessionUnitTests.swift in Sources */,
B1E09A3D2397FD820057C069 /* MXStoreFileStoreTests.m in Sources */,
32CEEF3E23AD134A0039BA98 /* MXCrossSigningTests.m in Sources */,
32EEA8402603CA140041425B /* MXRestClientExtensionsTests.m in Sources */,
Expand Down Expand Up @@ -6894,10 +6942,12 @@
32B477902638133D00EA5800 /* MXAggregatedReferenceUnitTests.m in Sources */,
EC116598270FCA8B0089FA56 /* MXBackgroundTaskUnitTests.swift in Sources */,
B1E09A322397FD750057C069 /* MXRoomTests.m in Sources */,
ED21F68628104DA2002FF83D /* MXMegolmEncryptionTests.swift in Sources */,
322985CC26FAF898001890BC /* MXSession.swift in Sources */,
EC131B1A2779D8D500712964 /* MXThreadEventTimelineUnitTests.swift in Sources */,
B135067527EB201E00BD3276 /* MXLocationServiceTests.swift in Sources */,
18C26C50273C0EB400805154 /* MXPollAggregatorTests.swift in Sources */,
ED356530281153480002BF6A /* MXMegolmSessionDataUnitTests.swift in Sources */,
32C78BA8256D227D008130B1 /* MXCryptoMigrationTests.m in Sources */,
18121F7B273E6E4200B68ADF /* PollBuilder.swift in Sources */,
18121F80273E837400B68ADF /* PollModels.swift in Sources */,
Expand Down
9 changes: 8 additions & 1 deletion MatrixSDK/Background/MXBackgroundSyncService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,14 @@ public enum MXBackgroundSyncServiceError: Error {
senderKey: senderKey,
forwardingCurve25519KeyChain: forwardingKeyChain,
keysClaimed: keysClaimed,
exportFormat: exportFormat)
exportFormat: exportFormat,
sharedHistory: isRoomSharingHistory(roomId: roomId))
}

private func isRoomSharingHistory(roomId: String) -> Bool {
let summary = roomSummary(forRoomId: roomId)
let visibility = MXRoomHistoryVisibility(identifier: summary?.historyVisibility)
return visibility == .worldReadable || visibility == .shared
}

private func updateBackgroundServiceStoresIfNeeded() {
Expand Down
10 changes: 9 additions & 1 deletion MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,15 @@ - (void)onRoomKeyEvent:(MXEvent *)event

MXLogDebug(@"[MXMegolmDecryption] onRoomKeyEvent: Adding key for megolm session %@|%@ from %@ event", senderKey, sessionId, event.type);

[olmDevice addInboundGroupSession:sessionId sessionKey:sessionKey roomId:roomId senderKey:senderKey forwardingCurve25519KeyChain:forwardingKeyChain keysClaimed:keysClaimed exportFormat:exportFormat];
BOOL sharedHistory = [crypto isRoomSharingHistory:roomId];
[olmDevice addInboundGroupSession:sessionId
sessionKey:sessionKey
roomId:roomId
senderKey:senderKey
forwardingCurve25519KeyChain:forwardingKeyChain
keysClaimed:keysClaimed
exportFormat:exportFormat
sharedHistory:sharedHistory];

[crypto.backup maybeSendKeyBackup];

Expand Down
43 changes: 34 additions & 9 deletions MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmEncryption.m
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,15 @@ - (MXOutboundSessionInfo *)outboundSession
return outboundSession;
}

- (BOOL)isSessionSharingHistory:(MXOutboundSessionInfo *)session
{
// We only store the `sharedHistory` flag on inbound sessions. To see if the current outbound session shares history
// see a corresponding inbound session with the same identifier.
MXOlmInboundGroupSession *matchingInboundSession = [crypto.store inboundGroupSessionWithId:session.sessionId
andSenderKey:crypto.olmDevice.deviceCurve25519Key];
return matchingInboundSession.sharedHistory;
}

/*
Get the list of devices which can encrypt data to.

Expand Down Expand Up @@ -241,15 +250,7 @@ - (MXHTTPOperation *)ensureOutboundSession:(MXUsersDevicesMap<MXDeviceInfo *> *)
{
__block MXOutboundSessionInfo *session = self.outboundSession;

// Need to make a brand new session?
if (session && [session needsRotation:sessionRotationPeriodMsgs rotationPeriodMs:sessionRotationPeriodMs])
{
[crypto.olmDevice discardOutboundGroupSessionForRoomWithRoomId:roomId];
session = nil;
}

// Determine if we have shared with anyone we shouldn't have
if (session && [session sharedWithTooManyDevices:devicesInRoom])
if (session && [self shouldResetSession:session devicesInRoom:devicesInRoom])
{
[crypto.olmDevice discardOutboundGroupSessionForRoomWithRoomId:roomId];
session = nil;
Expand Down Expand Up @@ -301,10 +302,33 @@ - (MXHTTPOperation *)ensureOutboundSession:(MXUsersDevicesMap<MXDeviceInfo *> *)
return session.shareOperation;
}

- (BOOL)shouldResetSession:(MXOutboundSessionInfo *)session devicesInRoom:(MXUsersDevicesMap<MXDeviceInfo *> *)devicesInRoom
{
// Need to make a brand new session?
if ([session needsRotation:sessionRotationPeriodMsgs rotationPeriodMs:sessionRotationPeriodMs])
{
return YES;
}

// Determine if we have shared with anyone we shouldn't have
else if ([session sharedWithTooManyDevices:devicesInRoom])
{
return YES;
}

// Check if room's history visibility has changed
else if ([crypto isRoomSharingHistory:roomId] != [self isSessionSharingHistory:session])
{
return YES;
}
return NO;
}

- (MXOutboundSessionInfo*)prepareNewSession
{
MXOlmOutboundGroupSession *session = [crypto.olmDevice createOutboundGroupSessionForRoomWithRoomId:roomId];

BOOL sharedHistory = [crypto isRoomSharingHistory:roomId];
[crypto.olmDevice addInboundGroupSession:session.sessionId
sessionKey:session.sessionKey
roomId:roomId
Expand All @@ -314,6 +338,7 @@ - (MXOutboundSessionInfo*)prepareNewSession
@"ed25519": crypto.olmDevice.deviceEd25519Key
}
exportFormat:NO
sharedHistory:sharedHistory
];

[crypto.backup maybeSendKeyBackup];
Expand Down
8 changes: 8 additions & 0 deletions MatrixSDK/Crypto/Data/MXMegolmSessionData.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@
*/
@property NSString *sessionKey;

/**
Flag indicating whether the history of this room is considered as shared.

This is typically the case if room's `historyVisibility` is set to `world_readable` or `shared`.
In this case the keys are allowed to be shared with other users upon invite.
*/
@property BOOL sharedHistory;

/**
The algorithm used.
*/
Expand Down
2 changes: 2 additions & 0 deletions MatrixSDK/Crypto/Data/MXMegolmSessionData.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ + (id)modelFromJSON:(NSDictionary *)JSONDictionary
MXJSONModelSetString(sessionData.roomId, JSONDictionary[@"room_id"]);
MXJSONModelSetString(sessionData.sessionId, JSONDictionary[@"session_id"]);
MXJSONModelSetString(sessionData.sessionKey, JSONDictionary[@"session_key"]);
MXJSONModelSetBoolean(sessionData.sharedHistory, JSONDictionary[@"shared_history"]);
MXJSONModelSetString(sessionData.algorithm, JSONDictionary[@"algorithm"]);
MXJSONModelSetArray(sessionData.forwardingCurve25519KeyChain, JSONDictionary[@"forwarding_curve25519_key_chain"])
}
Expand All @@ -43,6 +44,7 @@ - (NSDictionary *)JSONDictionary
@"room_id": _roomId,
@"session_id": _sessionId,
@"session_key":_sessionKey,
@"shared_history": @(_sharedHistory),
@"algorithm": _algorithm,
@"forwarding_curve25519_key_chain": _forwardingCurve25519KeyChain ? _forwardingCurve25519KeyChain : @[]
};
Expand Down
8 changes: 8 additions & 0 deletions MatrixSDK/Crypto/Data/MXOlmInboundGroupSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@
*/
@property (nonatomic) NSDictionary<NSString*, NSString*> *keysClaimed;

/**
Flag indicating whether the history of this room is considered as shared.

This is typically the case if room's `historyVisibility` is set to `world_readable` or `shared`.
In this case the keys are allowed to be shared with other users upon invite.
*/
@property (nonatomic) BOOL sharedHistory;


#pragma mark - import/export

Expand Down
4 changes: 4 additions & 0 deletions MatrixSDK/Crypto/Data/MXOlmInboundGroupSession.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ - (MXMegolmSessionData *)exportSessionDataAtMessageIndex:(NSUInteger)messageInde
sessionData.sessionId = _session.sessionIdentifier;
sessionData.sessionKey = sessionKey;
sessionData.algorithm = kMXCryptoMegolmAlgorithm;
sessionData.sharedHistory = _sharedHistory;
}
else
{
Expand Down Expand Up @@ -97,6 +98,7 @@ - (instancetype)initWithImportedSessionData:(MXMegolmSessionData *)data
_forwardingCurve25519KeyChain = data.forwardingCurve25519KeyChain;
_keysClaimed = data.senderClaimedKeys;
_roomId = data.roomId;
_sharedHistory = data.sharedHistory;
}
return self;
}
Expand All @@ -113,6 +115,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder
_senderKey = [aDecoder decodeObjectForKey:@"senderKey"];
_forwardingCurve25519KeyChain = [aDecoder decodeObjectForKey:@"forwardingCurve25519KeyChain"];
_keysClaimed = [aDecoder decodeObjectForKey:@"keysClaimed"];
_sharedHistory = [[aDecoder decodeObjectForKey:@"sharedHistory"] boolValue];
}
return self;
}
Expand All @@ -124,6 +127,7 @@ - (void)encodeWithCoder:(NSCoder *)aCoder
[aCoder encodeObject:_senderKey forKey:@"senderKey"];
[aCoder encodeObject:_keysClaimed forKey:@"keysClaimed"];
[aCoder encodeObject:_forwardingCurve25519KeyChain forKey:@"forwardingCurve25519KeyChain"];
[aCoder encodeObject:@(_sharedHistory) forKey:@"sharedHistory"];
}

@end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#import "MXBackgroundModeHandler.h"
#import "RLMRealm+MatrixSDK.h"

NSUInteger const kMXRealmCryptoStoreVersion = 17;
NSUInteger const kMXRealmCryptoStoreVersion = 18;

static NSString *const kMXRealmCryptoStoreFolder = @"MXRealmCryptoStore";

Expand Down Expand Up @@ -114,6 +114,7 @@ @implementation MXRealmOlmSession
@interface MXRealmOlmInboundGroupSession : RLMObject
@property NSString *sessionId;
@property NSString *senderKey;
@property NSString *roomId;
@property NSData *olmInboundGroupSessionData;

// A primary key is required to update `backedUp`.
Expand All @@ -122,6 +123,9 @@ @interface MXRealmOlmInboundGroupSession : RLMObject

// Indicate if the key has been backed up to the homeserver
@property BOOL backedUp;

@property BOOL sharedHistory;

@end

@implementation MXRealmOlmInboundGroupSession
Expand Down Expand Up @@ -950,8 +954,10 @@ - (void)storeInboundGroupSessions:(NSArray<MXOlmInboundGroupSession *>*)sessions
realmSession = [[MXRealmOlmInboundGroupSession alloc] initWithValue:@{
@"sessionId": session.session.sessionIdentifier,
@"senderKey": session.senderKey,
@"roomId": session.roomId,
@"sessionIdSenderKey": sessionIdSenderKey,
@"olmInboundGroupSessionData": [NSKeyedArchiver archivedDataWithRootObject:session]
@"olmInboundGroupSessionData": [NSKeyedArchiver archivedDataWithRootObject:session],
@"sharedHistory": @(session.sharedHistory)
}];

[realm addObject:realmSession];
Expand Down Expand Up @@ -2149,6 +2155,8 @@ + (BOOL)finaliseMigrationWith:(RLMMigration *)migration oldSchemaVersion:(uint64
newObject[@"cryptoVersion"] = @(MXCryptoVersion2);
}
}];
case 17:
MXLogDebug(@"[MXRealmCryptoStore] Migration from schema #17 -> #18: Automatically adding MXRealmOlmInboundGroupSession.roomId and MXRealmOlmInboundGroupSession.sharedHistory");
}
}

Expand Down
3 changes: 2 additions & 1 deletion MatrixSDK/Crypto/KeyBackup/MXKeyBackup.m
Original file line number Diff line number Diff line change
Expand Up @@ -1611,7 +1611,8 @@ - (MXKeyBackupData*)encryptGroupSession:(MXOlmInboundGroupSession*)session
@"sender_key": sessionData.senderKey,
@"sender_claimed_keys": sessionData.senderClaimedKeys,
@"forwarding_curve25519_key_chain": sessionData.forwardingCurve25519KeyChain ? sessionData.forwardingCurve25519KeyChain : @[],
@"session_key": sessionData.sessionKey
@"session_key": sessionData.sessionKey,
@"shared_history": @(sessionData.sharedHistory)
};
OLMPkMessage *encryptedSessionBackupData = [_backupKey encryptMessage:[MXTools serialiseJSONObject:sessionBackupData] error:nil];
if (![self checkOLMPkMessage:encryptedSessionBackupData])
Expand Down
6 changes: 6 additions & 0 deletions MatrixSDK/Crypto/MXCrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,12 @@ extern NSString *const MXDeviceListDidUpdateUsersDevicesNotification;
*/
- (BOOL)isRoomEncrypted:(NSString *)roomId;

/**
Get the current shared history status of the room, which depends on its `m.room.history_visibility`
(history is considered shared if visibility is set to `shared` or `world_readable`)
*/
- (BOOL)isRoomSharingHistory:(NSString *)roomId;

/**he
Set the blacklist of unverified devices in a room.

Expand Down
Loading