From cfe867d991e55cb2d919cd464a56887cf90d83f8 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 8 Jun 2018 17:21:52 +0200 Subject: [PATCH 1/5] RoomVC: Add a re-request keys button on message unable to decrypt #1879 --- Riot/Assets/en.lproj/Vector.strings | 7 ++++ Riot/Utils/EventFormatter.h | 10 ++++++ Riot/Utils/EventFormatter.m | 42 +++++++++++++++++++++- Riot/ViewController/RoomViewController.m | 46 ++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 05f7ed41f..6cd859aed 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -518,6 +518,8 @@ "event_formatter_widget_removed" = "%@ widget removed by %@"; "event_formatter_jitsi_widget_added" = "VoIP conference added by %@"; "event_formatter_jitsi_widget_removed" = "VoIP conference removed by %@"; +"event_formatter_rerequest_keys_part1_link" = "Re-request encryption keys"; +"event_formatter_rerequest_keys_part2" = " from your other devices."; // Others "or" = "or"; @@ -622,3 +624,8 @@ "deactivate_account_password_alert_title" = "Deactivate Account"; "deactivate_account_password_alert_message" = "To continue, please enter your password"; + +// Re-request confirmation dialog +"rerequest_keys_alert_title" = "Re-request encryption keys"; +"rerequest_keys_alert_message" = "Your key share request has been sent - please check your other devices for key share requests.\n\nKey share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, you can request the keys for this session again."; +"rerequest_keys_alert_button" = "Re-request"; diff --git a/Riot/Utils/EventFormatter.h b/Riot/Utils/EventFormatter.h index ba5d6a60c..d55c03257 100644 --- a/Riot/Utils/EventFormatter.h +++ b/Riot/Utils/EventFormatter.h @@ -16,6 +16,16 @@ #import +/** + Link string used in attributed strings to mark a keys re-request action. + */ +FOUNDATION_EXPORT NSString *const kEventFormatterOnReRequestKeysLinkAction; + +/** + Parameters separator in the link string. + */ +FOUNDATION_EXPORT NSString *const kEventFormatterOnReRequestKeysLinkActionSeparator; + /** `EventFormatter` class inherits from `MXKEventFormatter` to define Vector formatting */ diff --git a/Riot/Utils/EventFormatter.m b/Riot/Utils/EventFormatter.m index ef1732e49..09f92f344 100644 --- a/Riot/Utils/EventFormatter.m +++ b/Riot/Utils/EventFormatter.m @@ -21,6 +21,13 @@ #import "WidgetManager.h" +#import "MXDecryptionResult.h" + +#pragma mark - Constants definitions + +NSString *const kEventFormatterOnReRequestKeysLinkAction = @"kEventFormatterOnReRequestKeysLinkAction"; +NSString *const kEventFormatterOnReRequestKeysLinkActionSeparator = @"/"; + @interface EventFormatter () { /** @@ -107,7 +114,40 @@ } } - return [super attributedStringFromEvent:event withRoomState:roomState error:error]; + NSAttributedString *attributedString = [super attributedStringFromEvent:event withRoomState:roomState error:error]; + + if (event.sentState == MXEventSentStateSent + && [event.decryptionError.domain isEqualToString:MXDecryptingErrorDomain] + && event.decryptionError.code == MXDecryptingErrorUnknownInboundSessionIdCode) + { + // Append to the displayed error an attibuted string with a tappable link + // so that the user can try to fix the UTC + NSMutableAttributedString *attributedStringWithRerequestMessage = [attributedString mutableCopy]; + [attributedStringWithRerequestMessage appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]]; + + NSString *linkActionString = [NSString stringWithFormat:@"%@%@%@", kEventFormatterOnReRequestKeysLinkAction, + kEventFormatterOnReRequestKeysLinkActionSeparator, + event.eventId]; + + [attributedStringWithRerequestMessage appendAttributedString: + [[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"event_formatter_rerequest_keys_part1_link", @"Vector", nil) + attributes:@{ + NSLinkAttributeName: linkActionString, + NSForegroundColorAttributeName: self.sendingTextColor, + NSFontAttributeName: self.encryptedMessagesTextFont + }]]; + + [attributedStringWithRerequestMessage appendAttributedString: + [[NSAttributedString alloc] initWithString:NSLocalizedStringFromTable(@"event_formatter_rerequest_keys_part2", @"Vector", nil) + attributes:@{ + NSForegroundColorAttributeName: self.sendingTextColor, + NSFontAttributeName: self.encryptedMessagesTextFont + }]]; + + attributedString = attributedStringWithRerequestMessage; + } + + return attributedString; } - (NSAttributedString*)attributedStringFromEvents:(NSArray*)events withRoomState:(MXRoomState*)roomState error:(MXKEventFormatterError*)error diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index 093f89e17..0e45eaf38 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -117,6 +117,8 @@ #import "WidgetPickerViewController.h" #import "StickerPickerViewController.h" +#import "EventFormatter.h" + @interface RoomViewController () { // The expanded header @@ -2680,6 +2682,20 @@ NSString *fragment = [NSString stringWithFormat:@"/group/%@", [absoluteURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; [[AppDelegate theDelegate] handleUniversalLinkFragment:fragment]; } + else if ([absoluteURLString hasPrefix:kEventFormatterOnReRequestKeysLinkAction]) + { + NSArray *arguments = [absoluteURLString componentsSeparatedByString:kEventFormatterOnReRequestKeysLinkActionSeparator]; + if (arguments.count > 1) + { + NSString *eventId = arguments[1]; + MXEvent *event = [self.roomDataSource eventWithEventId:eventId]; + + if (event) + { + [self showRerequestConfirmationAlert:event]; + } + } + } } return shouldDoAction; @@ -4582,5 +4598,35 @@ [self presentViewController:currentAlert animated:YES completion:nil]; } +#pragma mark - Re-request encryption keys + +- (void)showRerequestConfirmationAlert:(MXEvent*)event +{ + currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"rerequest_keys_alert_title", @"Vector", nil) + message:NSLocalizedStringFromTable(@"rerequest_keys_alert_message", @"Vector", nil) + preferredStyle:UIAlertControllerStyleAlert]; + + MXWeakify(self); + [currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) + { + MXStrongifyAndReturnIfNil(self); + self->currentAlert = nil; + }]]; + + [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"rerequest_keys_alert_button", @"Vector", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) + { + MXStrongifyAndReturnIfNil(self); + self->currentAlert = nil; + + [self.mainSession.crypto reRequestRoomKeyForEvent:event]; + }]]; + + [self presentViewController:currentAlert animated:YES completion:nil]; +} + @end From c85d7c721d89cf485e47d2a5ad3c142ae559c5d3 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 8 Jun 2018 17:23:32 +0200 Subject: [PATCH 2/5] RoomVC: Add a re-request keys button on message unable to decrypt #1879 --- CHANGES.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 3be965fab..fcffdee2c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,12 @@ +Changes in 0.6.18 () +=============================================== + +Improvements: + * Upgrade MatrixKit version (). + * RoomVC: Add a re-request keys button on message unable to decrypt (#1879). + +Bug fix: + Changes in 0.6.17 (2018-06-01) =============================================== From d70c7ad9ed38c7462013ecdd84765947a759c0fc Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 12 Jun 2018 16:28:26 +0200 Subject: [PATCH 3/5] RoomVC: Add a re-request keys button on message unable to decrypt The flow has changed a bit. #1879 --- Riot/Assets/en.lproj/Vector.strings | 5 +-- Riot/ViewController/RoomViewController.m | 50 +++++++++++++++++------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 6cd859aed..dbf93d256 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -626,6 +626,5 @@ "deactivate_account_password_alert_message" = "To continue, please enter your password"; // Re-request confirmation dialog -"rerequest_keys_alert_title" = "Re-request encryption keys"; -"rerequest_keys_alert_message" = "Your key share request has been sent - please check your other devices for key share requests.\n\nKey share requests are sent to your other devices automatically. If you rejected or dismissed the key share request on your other devices, you can request the keys for this session again."; -"rerequest_keys_alert_button" = "Re-request"; +"rerequest_keys_alert_title" = "Request Sent"; +"rerequest_keys_alert_message" = "Please check your other devices for key share requests."; diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index 0e45eaf38..7d6630516 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -2692,7 +2692,7 @@ if (event) { - [self showRerequestConfirmationAlert:event]; + [self reRequestKeysAndShowExplanationAlert:event]; } } } @@ -4600,31 +4600,51 @@ #pragma mark - Re-request encryption keys -- (void)showRerequestConfirmationAlert:(MXEvent*)event +- (void)reRequestKeysAndShowExplanationAlert:(MXEvent*)event { - currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"rerequest_keys_alert_title", @"Vector", nil) + MXWeakify(self); + __block UIAlertController *alert; + + // Make the re-request + [self.mainSession.crypto reRequestRoomKeyForEvent:event]; + + // Observe kMXEventDidDecryptNotification to remove automatically the dialog + // if the user has shared the keys from another device + id didDecryptObserver; + didDecryptObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXEventDidDecryptNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + + MXEvent *decryptedEvent = notif.object; + + if ([decryptedEvent.eventId isEqualToString:event.eventId]) + { + [[NSNotificationCenter defaultCenter] removeObserver:didDecryptObserver]; + + MXStrongifyAndReturnIfNil(self); + if (self->currentAlert == alert) + { + [self->currentAlert dismissViewControllerAnimated:YES completion:nil]; + self->currentAlert = nil; + } + } + }]; + + // Show the explanation dialog + alert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"rerequest_keys_alert_title", @"Vector", nil) message:NSLocalizedStringFromTable(@"rerequest_keys_alert_message", @"Vector", nil) preferredStyle:UIAlertControllerStyleAlert]; + currentAlert = alert; - MXWeakify(self); - [currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] + + [alert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"ok"] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { + [[NSNotificationCenter defaultCenter] removeObserver:didDecryptObserver]; + MXStrongifyAndReturnIfNil(self); self->currentAlert = nil; }]]; - [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"rerequest_keys_alert_button", @"Vector", nil) - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) - { - MXStrongifyAndReturnIfNil(self); - self->currentAlert = nil; - - [self.mainSession.crypto reRequestRoomKeyForEvent:event]; - }]]; - [self presentViewController:currentAlert animated:YES completion:nil]; } From 5c6f92ba283cef0c15d3cda54b4c217c27ea93b8 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 12 Jun 2018 16:35:12 +0200 Subject: [PATCH 4/5] RoomVC: Add a re-request keys button on message unable to decrypt Update string --- Riot/Assets/en.lproj/Vector.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index dbf93d256..801e1e6d7 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -627,4 +627,4 @@ // Re-request confirmation dialog "rerequest_keys_alert_title" = "Request Sent"; -"rerequest_keys_alert_message" = "Please check your other devices for key share requests."; +"rerequest_keys_alert_message" = "Please check your other devices for key share requests"; From ea206a0275f62881f34d5bb278cc7dd2da636189 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 12 Jun 2018 18:21:04 +0200 Subject: [PATCH 5/5] RoomVC: Add a re-request keys button on message unable to decrypt Take Steve's remark into account --- Riot/ViewController/RoomViewController.m | 28 +++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Riot/ViewController/RoomViewController.m b/Riot/ViewController/RoomViewController.m index 7d6630516..325e63ff1 100644 --- a/Riot/ViewController/RoomViewController.m +++ b/Riot/ViewController/RoomViewController.m @@ -183,6 +183,9 @@ // Observer kMXRoomSummaryDidChangeNotification to keep updated the missed discussion count id mxRoomSummaryDidChangeObserver; + + // Observer for removing the re-request explanation/waiting dialog + id mxEventDidDecryptNotificationObserver; // The table view cell in which the read marker is displayed (nil by default). MXKRoomBubbleTableViewCell *readMarkerTableViewCell; @@ -594,6 +597,12 @@ [[NSNotificationCenter defaultCenter] removeObserver:mxRoomSummaryDidChangeObserver]; mxRoomSummaryDidChangeObserver = nil; } + + if (mxEventDidDecryptNotificationObserver) + { + [[NSNotificationCenter defaultCenter] removeObserver:mxEventDidDecryptNotificationObserver]; + mxEventDidDecryptNotificationObserver = nil; + } } - (void)viewDidLayoutSubviews @@ -1105,6 +1114,11 @@ [[NSNotificationCenter defaultCenter] removeObserver:mxRoomSummaryDidChangeObserver]; mxRoomSummaryDidChangeObserver = nil; } + if (mxEventDidDecryptNotificationObserver) + { + [[NSNotificationCenter defaultCenter] removeObserver:mxEventDidDecryptNotificationObserver]; + mxEventDidDecryptNotificationObserver = nil; + } [self removeCallNotificationsListeners]; [self removeWidgetNotificationsListeners]; @@ -4610,16 +4624,16 @@ // Observe kMXEventDidDecryptNotification to remove automatically the dialog // if the user has shared the keys from another device - id didDecryptObserver; - didDecryptObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXEventDidDecryptNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + mxEventDidDecryptNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXEventDidDecryptNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + MXStrongifyAndReturnIfNil(self); MXEvent *decryptedEvent = notif.object; if ([decryptedEvent.eventId isEqualToString:event.eventId]) { - [[NSNotificationCenter defaultCenter] removeObserver:didDecryptObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:self->mxEventDidDecryptNotificationObserver]; + self->mxEventDidDecryptNotificationObserver = nil; - MXStrongifyAndReturnIfNil(self); if (self->currentAlert == alert) { [self->currentAlert dismissViewControllerAnimated:YES completion:nil]; @@ -4639,9 +4653,11 @@ style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { - [[NSNotificationCenter defaultCenter] removeObserver:didDecryptObserver]; - MXStrongifyAndReturnIfNil(self); + + [[NSNotificationCenter defaultCenter] removeObserver:self->mxEventDidDecryptNotificationObserver]; + self->mxEventDidDecryptNotificationObserver = nil; + self->currentAlert = nil; }]];