From 8cdb4d849368db7da5f436792343d2b5620f35c2 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 96cc8df85603010d7f7f82614eea469c97d22710 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 1f45b233d76ea8fe0bf93e38092a8bd8a0acd501 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 bfdc4e898f1b272d87d73ff57a4cc324f7a31491 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 2115970a490d4f34db4f7ef9c4e318a51555a55a 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; }]];