Merge branch 'develop' into element_3995

This commit is contained in:
SBiOSoftWhare
2021-02-03 17:16:36 +01:00
committed by GitHub
5 changed files with 182 additions and 81 deletions
+117 -72
View File
@@ -254,7 +254,8 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
// Redirect NSLogs to files only if we are not debugging
if (!isatty(STDERR_FILENO))
{
[MXLogger redirectNSLogToFiles:YES numberOfFiles:50];
NSUInteger sizeLimit = 100 * 1024 * 1024; // 100MB
[MXLogger redirectNSLogToFiles:YES numberOfFiles:50 sizeLimit:sizeLimit];
}
NSLog(@"[AppDelegate] initialize: Done");
@@ -1146,9 +1147,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
[[NSNotificationCenter defaultCenter] postNotificationName:AppDelegateUniversalLinkDidChangeNotification object:nil];
}
if ([webURL.path isEqualToString:@"/"])
if ([self handleServerProvionningLink:webURL])
{
return [self handleServerProvionningLink:webURL];
return YES;
}
NSString *validateEmailSubmitTokenPath = @"validate/email/submitToken";
@@ -1255,6 +1256,10 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
NSLog(@"[AppDelegate] Universal link: handleUniversalLinkFragment: %@", fragment);
// Make sure we have plain utf8 character for separators
fragment = [fragment stringByRemovingPercentEncoding];
NSLog(@"[AppDelegate] Universal link: handleUniversalLinkFragment: %@", fragment);
// The app manages only one universal link at a time
// Discard any pending one
[self resetPendingUniversalLink];
@@ -1376,9 +1381,27 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
withString:[MXTools encodeURIComponent:roomId]
];
universalLinkFragmentPendingRoomAlias = @{roomId: roomIdOrAlias};
// The previous operation can fail because of percent encoding
// TBH we are not clean on data inputs. For the moment, just give another try with no encoding
// TODO: Have a dedicated module and tests to handle universal links (matrix.to, email link, etc)
if ([newUniversalLinkFragment isEqualToString:fragment])
{
newUniversalLinkFragment =
[fragment stringByReplacingOccurrencesOfString:roomIdOrAlias
withString:[MXTools encodeURIComponent:roomId]];
}
[self handleUniversalLinkFragment:newUniversalLinkFragment];
if (![newUniversalLinkFragment isEqualToString:fragment])
{
universalLinkFragmentPendingRoomAlias = @{roomId: roomIdOrAlias};
[self handleUniversalLinkFragment:newUniversalLinkFragment];
}
else
{
// Do not continue. Else we will loop forever
NSLog(@"[AppDelegate] Universal link: Error: Cannot resolve alias in %@ to the room id %@", fragment, roomId);
}
}
} failure:^(NSError *error) {
@@ -1422,40 +1445,32 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
// FIXME: In case of multi-account, ask the user which one to use
MXKAccount* account = accountManager.activeAccounts.firstObject;
RoomPreviewData *roomPreviewData;
RoomPreviewData *roomPreviewData = [[RoomPreviewData alloc] initWithRoomId:roomIdOrAlias
andSession:account.mxSession];
if (queryParams)
{
roomPreviewData.viaServers = queryParams[@"via"];
}
// Is it a link to an event of a room?
// If yes, the event will be displayed once the room is joined
roomPreviewData.eventId = (pathParams.count >= 3) ? pathParams[2] : nil;
// Try to get more information about the room before opening its preview
[roomPreviewData peekInRoom:^(BOOL succeeded) {
// Note: the activity indicator will not disappear if the session is not ready
[homeViewController stopActivityIndicator];
roomPreviewData = [[RoomPreviewData alloc] initWithRoomId:roomIdOrAlias emailInvitationParams:queryParams andSession:account.mxSession];
roomPreviewData.viaServers = queryParams[@"via"];
// If no data is available for this room, we name it with the known room alias (if any).
if (!succeeded && universalLinkFragmentPendingRoomAlias[roomIdOrAlias])
{
roomPreviewData.roomName = universalLinkFragmentPendingRoomAlias[roomIdOrAlias];
}
universalLinkFragmentPendingRoomAlias = nil;
[self showRoomPreview:roomPreviewData];
}
else
{
roomPreviewData = [[RoomPreviewData alloc] initWithRoomId:roomIdOrAlias andSession:account.mxSession];
// Is it a link to an event of a room?
// If yes, the event will be displayed once the room is joined
roomPreviewData.eventId = (pathParams.count >= 3) ? pathParams[2] : nil;
// Try to get more information about the room before opening its preview
[roomPreviewData peekInRoom:^(BOOL succeeded) {
// Note: the activity indicator will not disappear if the session is not ready
[homeViewController stopActivityIndicator];
// If no data is available for this room, we name it with the known room alias (if any).
if (!succeeded && universalLinkFragmentPendingRoomAlias[roomIdOrAlias])
{
roomPreviewData.roomName = universalLinkFragmentPendingRoomAlias[roomIdOrAlias];
}
universalLinkFragmentPendingRoomAlias = nil;
[self showRoomPreview:roomPreviewData];
}];
}
}];
}
}
@@ -2333,6 +2348,11 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
case MXSessionStateSyncInProgress:
// Stay in launching during the first server sync if the store is empty.
isLaunching = (mainSession.rooms.count == 0 && launchAnimationContainerView);
if (mainSession.crypto.crossSigning && mainSession.crypto.crossSigning.state == MXCrossSigningStateCrossSigningExists)
{
[mainSession.crypto setOutgoingKeyRequestsEnabled:NO onComplete:nil];
}
break;
default:
isLaunching = NO;
@@ -3726,81 +3746,100 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
return;
}
MXWeakify(self);
[mxSession.crypto pendingKeyRequests:^(MXUsersDevicesMap<NSArray<MXIncomingRoomKeyRequest *> *> *pendingKeyRequests) {
NSLog(@"[AppDelegate] checkPendingRoomKeyRequestsInSession: pendingKeyRequests.count: %@. Already displayed: %@",
MXStrongifyAndReturnIfNil(self);
NSLog(@"[AppDelegate] checkPendingRoomKeyRequestsInSession: cross-signing state: %ld, pendingKeyRequests.count: %@. Already displayed: %@",
mxSession.crypto.crossSigning.state,
@(pendingKeyRequests.count),
roomKeyRequestViewController ? @"YES" : @"NO");
self->roomKeyRequestViewController ? @"YES" : @"NO");
if (roomKeyRequestViewController)
if (!mxSession.crypto.crossSigning || mxSession.crypto.crossSigning.state == MXCrossSigningStateNotBootstrapped)
{
// Check if the current RoomKeyRequestViewController is still valid
MXSession *currentMXSession = roomKeyRequestViewController.mxSession;
NSString *currentUser = roomKeyRequestViewController.device.userId;
NSString *currentDevice = roomKeyRequestViewController.device.deviceId;
NSArray<MXIncomingRoomKeyRequest *> *currentPendingRequest = [pendingKeyRequests objectForDevice:currentDevice forUser:currentUser];
if (currentMXSession == mxSession && currentPendingRequest.count == 0)
if (self->roomKeyRequestViewController)
{
NSLog(@"[AppDelegate] checkPendingRoomKeyRequestsInSession: Cancel current dialog");
// Check if the current RoomKeyRequestViewController is still valid
MXSession *currentMXSession = self->roomKeyRequestViewController.mxSession;
NSString *currentUser = self->roomKeyRequestViewController.device.userId;
NSString *currentDevice = self->roomKeyRequestViewController.device.deviceId;
// The key request has been probably cancelled, remove the popup
[roomKeyRequestViewController hide];
roomKeyRequestViewController = nil;
NSArray<MXIncomingRoomKeyRequest *> *currentPendingRequest = [pendingKeyRequests objectForDevice:currentDevice forUser:currentUser];
if (currentMXSession == mxSession && currentPendingRequest.count == 0)
{
NSLog(@"[AppDelegate] checkPendingRoomKeyRequestsInSession: Cancel current dialog");
// The key request has been probably cancelled, remove the popup
[self->roomKeyRequestViewController hide];
self->roomKeyRequestViewController = nil;
}
}
}
if (!roomKeyRequestViewController && pendingKeyRequests.count)
if (!self->roomKeyRequestViewController && pendingKeyRequests.count)
{
// Pick the first coming user/device pair
NSString *userId = pendingKeyRequests.userIds.firstObject;
NSString *deviceId = [pendingKeyRequests deviceIdsForUser:userId].firstObject;
// Give the client a chance to refresh the device list
MXWeakify(self);
[mxSession.crypto downloadKeys:@[userId] forceDownload:NO success:^(MXUsersDevicesMap<MXDeviceInfo *> *usersDevicesInfoMap, NSDictionary<NSString *,MXCrossSigningInfo *> *crossSigningKeysMap) {
MXStrongifyAndReturnIfNil(self);
MXDeviceInfo *deviceInfo = [usersDevicesInfoMap objectForDevice:deviceId forUser:userId];
if (deviceInfo)
{
BOOL wasNewDevice = (deviceInfo.trustLevel.localVerificationStatus == MXDeviceUnknown);
void (^openDialog)(void) = ^void()
if (!mxSession.crypto.crossSigning || mxSession.crypto.crossSigning.state == MXCrossSigningStateNotBootstrapped)
{
NSLog(@"[AppDelegate] checkPendingRoomKeyRequestsInSession: Open dialog for %@", deviceInfo);
BOOL wasNewDevice = (deviceInfo.trustLevel.localVerificationStatus == MXDeviceUnknown);
void (^openDialog)(void) = ^void()
{
NSLog(@"[AppDelegate] checkPendingRoomKeyRequestsInSession: Open dialog for %@", deviceInfo);
roomKeyRequestViewController = [[RoomKeyRequestViewController alloc] initWithDeviceInfo:deviceInfo wasNewDevice:wasNewDevice andMatrixSession:mxSession onComplete:^{
self->roomKeyRequestViewController = [[RoomKeyRequestViewController alloc] initWithDeviceInfo:deviceInfo wasNewDevice:wasNewDevice andMatrixSession:mxSession onComplete:^{
roomKeyRequestViewController = nil;
self->roomKeyRequestViewController = nil;
// Check next pending key request, if any
// Check next pending key request, if any
[self checkPendingRoomKeyRequests];
}];
[self->roomKeyRequestViewController show];
};
// If the device was new before, it's not any more.
if (wasNewDevice)
{
[mxSession.crypto setDeviceVerification:MXDeviceUnverified forDevice:deviceId ofUser:userId success:openDialog failure:nil];
}
else
{
openDialog();
}
}
else if (deviceInfo.trustLevel.isVerified)
{
[mxSession.crypto acceptAllPendingKeyRequestsFromUser:userId andDevice:deviceId onComplete:^{
[self checkPendingRoomKeyRequests];
}];
[roomKeyRequestViewController show];
};
// If the device was new before, it's not any more.
if (wasNewDevice)
{
[mxSession.crypto setDeviceVerification:MXDeviceUnverified forDevice:deviceId ofUser:userId success:openDialog failure:nil];
}
else
{
openDialog();
[mxSession.crypto ignoreAllPendingKeyRequestsFromUser:userId andDevice:deviceId onComplete:^{
[self checkPendingRoomKeyRequests];
}];
}
}
else
{
NSLog(@"[AppDelegate] checkPendingRoomKeyRequestsInSession: No details found for device %@:%@", userId, deviceId);
// Ignore this device to avoid to loop on it
[mxSession.crypto ignoreAllPendingKeyRequestsFromUser:userId andDevice:deviceId onComplete:^{
// And check next requests
[self checkPendingRoomKeyRequests];
}];
}
} failure:^(NSError *error) {
// Retry later
NSLog(@"[AppDelegate] checkPendingRoomKeyRequestsInSession: Failed to download device keys. Retry");
@@ -3972,6 +4011,12 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
- (void)keyVerificationCoordinatorBridgePresenterDelegateDidComplete:(KeyVerificationCoordinatorBridgePresenter *)coordinatorBridgePresenter otherUserId:(NSString * _Nonnull)otherUserId otherDeviceId:(NSString * _Nonnull)otherDeviceId
{
MXCrypto *crypto = coordinatorBridgePresenter.session.crypto;
if (!crypto.backup.hasPrivateKeyInCryptoStore || !crypto.backup.enabled)
{
NSLog(@"[AppDelegate][MXKeyVerification] requestAllPrivateKeys: Request key backup private keys");
[crypto setOutgoingKeyRequestsEnabled:YES onComplete:nil];
}
[self dismissKeyVerificationCoordinatorBridgePresenter];
}
@@ -1398,18 +1398,23 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
- (void)sessionStateDidChangeNotification:(NSNotification*)notification
{
MXSession *session = (MXSession*)notification.object;
if (session.state == MXSessionStateRunning)
if (session.state == MXSessionStateStoreDataReady)
{
[self unregisterSessionStateChangeNotification];
if (session.crypto.crossSigning)
{
// Do not make key share requests while the "Complete security" is not complete.
// If the device is self-verified, the SDK will restore the existing key backup.
// Then, it will re-enable outgoing key share requests
[session.crypto setOutgoingKeyRequestsEnabled:NO onComplete:nil];
}
}
else if (session.state == MXSessionStateRunning)
{
[self unregisterSessionStateChangeNotification];
if (session.crypto.crossSigning)
{
[session.crypto.crossSigning refreshStateWithSuccess:^(BOOL stateUpdated) {
NSLog(@"[AuthenticationVC] sessionStateDidChange: crossSigning.state: %@", @(session.crypto.crossSigning.state));
@@ -1619,14 +1624,17 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0;
- (void)keyVerificationCoordinatorBridgePresenterDelegateDidComplete:(KeyVerificationCoordinatorBridgePresenter * _Nonnull)coordinatorBridgePresenter otherUserId:(NSString * _Nonnull)otherUserId otherDeviceId:(NSString * _Nonnull)otherDeviceId
{
MXCrypto *crypto = coordinatorBridgePresenter.session.crypto;
if (!crypto.backup.hasPrivateKeyInCryptoStore || !crypto.backup.enabled)
{
NSLog(@"[AuthenticationVC][MXKeyVerification] requestAllPrivateKeys: Request key backup private keys");
[crypto setOutgoingKeyRequestsEnabled:YES onComplete:nil];
}
[self dismiss];
}
- (void)keyVerificationCoordinatorBridgePresenterDelegateDidCancel:(KeyVerificationCoordinatorBridgePresenter * _Nonnull)coordinatorBridgePresenter
{
// Set outgoing key requests back
[coordinatorBridgePresenter.session.crypto setOutgoingKeyRequestsEnabled:YES onComplete:nil];
[self dismiss];
}
+41
View File
@@ -121,6 +121,9 @@
#import "EventFormatter.h"
#import <MatrixKit/MXKSlashCommands.h>
#import "SettingsViewController.h"
#import "SecurityViewController.h"
#import "Riot-Swift.h"
@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, UIScrollViewAccessibilityDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate, RoomContextualMenuViewControllerDelegate,
@@ -5000,6 +5003,13 @@
{
MXWeakify(self);
__block UIAlertController *alert;
// Force device verification if session has cross-signing activated and device is not yet verified
if (self.mainSession.crypto.crossSigning && self.mainSession.crypto.crossSigning.state == MXCrossSigningStateCrossSigningExists)
{
[self presentReviewUnverifiedSessionsAlert];
return;
}
// Make the re-request
[self.mainSession.crypto reRequestRoomKeyForEvent:event];
@@ -5046,6 +5056,37 @@
[self presentViewController:currentAlert animated:YES completion:nil];
}
- (void)presentReviewUnverifiedSessionsAlert
{
NSLog(@"[MasterTabBarController] presentReviewUnverifiedSessionsAlertWithSession");
[currentAlert dismissViewControllerAnimated:NO completion:nil];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_unverified_sessions_alert_title", @"Vector", nil)
message:NSLocalizedStringFromTable(@"key_verification_self_verify_unverified_sessions_alert_message", @"Vector", nil)
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"key_verification_self_verify_unverified_sessions_alert_validate_action", @"Vector", nil)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
[self showSettingsSecurityScreen];
}]];
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"later", @"Vector", nil)
style:UIAlertActionStyleCancel
handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
currentAlert = alert;
}
- (void)showSettingsSecurityScreen
{
[[AppDelegate theDelegate] presentCompleteSecurityForSession: self.mainSession];
}
#pragma mark Tombstone event
- (void)listenTombstoneEventNotifications