Skip to content

Commit de3b071

Browse files
Merge pull request #1025 from zom/zom_dev
Don't expire last key, group notification fix
2 parents 183f01d + 29f7340 commit de3b071

File tree

9 files changed

+55
-44
lines changed

9 files changed

+55
-44
lines changed

ChatSecure/Classes/Categories/UIApplication+ChatSecure.swift

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public extension UIApplication {
138138
let chatString = WANTS_TO_CHAT_STRING()
139139
let text = "\(name) \(chatString)"
140140
let unreadCount = self.applicationIconBadgeNumber + 1
141-
self.showLocalNotificationWith(identifier: nil, body: text, badge: unreadCount, userInfo: [kOTRNotificationType:kOTRNotificationTypeSubscriptionRequest], recurring: false)
141+
self.showLocalNotificationWith(groupingIdentifier: nil, body: text, badge: unreadCount, userInfo: [kOTRNotificationType:kOTRNotificationTypeSubscriptionRequest], recurring: false)
142142
}
143143
}
144144

@@ -158,7 +158,7 @@ public extension UIApplication {
158158
let userInfo:[AnyHashable:Any] = [kOTRNotificationThreadKey:identifier,
159159
kOTRNotificationThreadCollection:thread.threadCollection,
160160
kOTRNotificationType: kOTRNotificationTypeApprovedBuddy]
161-
self.showLocalNotificationWith(identifier: identifier, body: message, badge: unreadCount, userInfo: userInfo, recurring: false)
161+
self.showLocalNotificationWith(groupingIdentifier: nil, body: message, badge: unreadCount, userInfo: userInfo, recurring: false)
162162
}
163163
}
164164

@@ -173,13 +173,13 @@ public extension UIApplication {
173173
kOTRNotificationThreadCollection:t.threadCollection,
174174
kOTRNotificationType: kOTRNotificationTypeChatMessage]
175175
}
176-
self.showLocalNotificationWith(identifier: identifier, body: text, badge: unreadCount, userInfo: userInfo, recurring: false)
176+
self.showLocalNotificationWith(groupingIdentifier: nil, body: text, badge: unreadCount, userInfo: userInfo, recurring: false)
177177
}
178178
}
179179

180-
@objc public func showLocalNotificationWith(identifier:String?, body:String, badge:Int, userInfo:[AnyHashable:Any]?, recurring:Bool) {
180+
@objc public func showLocalNotificationWith(groupingIdentifier:String?, body:String, badge:Int, userInfo:[AnyHashable:Any]?, recurring:Bool) {
181181
DispatchQueue.main.async {
182-
if recurring, self.hasRecurringLocalNotificationWith(identifier: identifier) {
182+
if recurring, self.hasRecurringLocalNotificationWith(identifier: groupingIdentifier) {
183183
return // Already pending
184184
}
185185
// Use the new UserNotifications.framework on iOS 10+
@@ -188,8 +188,8 @@ public extension UIApplication {
188188
localNotification.body = body
189189
localNotification.badge = NSNumber(integerLiteral: badge)
190190
localNotification.sound = UNNotificationSound.default()
191-
if let identifier = identifier {
192-
localNotification.threadIdentifier = identifier
191+
if let threadKey = userInfo?[kOTRNotificationThreadKey] as? String {
192+
localNotification.threadIdentifier = threadKey
193193
}
194194
if let userInfo = userInfo {
195195
localNotification.userInfo = userInfo
@@ -201,7 +201,7 @@ public extension UIApplication {
201201
date.minute = 0
202202
trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
203203
}
204-
let request = UNNotificationRequest(identifier: UUID().uuidString, content: localNotification, trigger: trigger) // Schedule the notification.
204+
let request = UNNotificationRequest(identifier: groupingIdentifier ?? UUID().uuidString, content: localNotification, trigger: trigger) // Schedule the notification.
205205
let center = UNUserNotificationCenter.current()
206206
center.add(request, withCompletionHandler: { (error: Error?) in
207207
if let error = error as NSError? {
@@ -325,19 +325,6 @@ public extension UIApplication {
325325
let userInfo = [kOTRNotificationType: kOTRNotificationTypeConnectionError,
326326
kOTRNotificationAccountKey: accountKey]
327327

328-
if #available(iOS 10.0, *) {
329-
UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: { (notifications) in
330-
// FIXME: this deduplication code doesn't seem to work
331-
// if we are already showing a notification, let's not spam the user too much with more of them
332-
for notification in notifications {
333-
if notification.request.identifier == accountKey {
334-
return
335-
}
336-
}
337-
self.showLocalNotificationWith(identifier: accountKey, body: body, badge: badge, userInfo: userInfo, recurring: false)
338-
})
339-
} else {
340-
showLocalNotificationWith(identifier: accountKey, body: body, badge: badge, userInfo: userInfo, recurring: false)
341-
}
328+
self.showLocalNotificationWith(groupingIdentifier: accountKey, body: body, badge: badge, userInfo: userInfo, recurring: false)
342329
}
343330
}

ChatSecure/Classes/Model/Yap Storage/OMEMO-Storage/OMEMODevice.m

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,19 @@ - (BOOL) isTrusted {
4444
return (_trustLevel == OMEMOTrustLevelTrustedTofu || _trustLevel == OMEMOTrustLevelTrustedUser) && ![self isExpired];
4545
}
4646

47-
/** if lastSeenDate is > 30 days */
47+
/** if lastSeenDate is > 30 days, but not if ALL keys are expired and this is the one last seen */
4848
- (BOOL) isExpired {
49+
if ([self _isExpired]) {
50+
if (self.lastSeenDate && [OMEMODevice isLastSeenExpiredDevice:self]) {
51+
return NO;
52+
}
53+
return YES;
54+
}
55+
return NO;
56+
}
57+
58+
/** if lastSeenDate is > 30 days */
59+
- (BOOL) _isExpired {
4960
if (!self.lastSeenDate) {
5061
return YES;
5162
}
@@ -57,6 +68,35 @@ - (BOOL) isExpired {
5768
return NO;
5869
}
5970

71+
/** If ALL devices are considered expired, return TRUE if device is the one that was last seen of them all. Kind of hackish, but would have required major refactoring. */
72+
+ (BOOL) isLastSeenExpiredDevice:(OMEMODevice *)device {
73+
__block NSArray <OMEMODevice *>* devices = nil;
74+
[[OTRDatabaseManager.shared connections].read readWithBlock:^(YapDatabaseReadTransaction * _Nonnull transaction) {
75+
devices = [OMEMODevice allDevicesForParentKey:device.parentKey collection:device.parentCollection transaction:transaction];
76+
}];
77+
if (devices != nil && [devices count] > 0) {
78+
NSArray *sortedDevices = [devices sortedArrayUsingComparator:^NSComparisonResult(OMEMODevice * _Nonnull obj1, OMEMODevice * _Nonnull obj2) {
79+
NSDate *date1 = [NSDate distantPast];
80+
NSDate *date2 = [NSDate distantPast];
81+
if (obj1.lastSeenDate) {
82+
date1 = obj1.lastSeenDate;
83+
}
84+
if (obj2.lastSeenDate) {
85+
date2 = obj2.lastSeenDate;
86+
}
87+
// Latest first
88+
return [date2 compare:date1];
89+
}];
90+
OMEMODevice *first = [sortedDevices firstObject];
91+
92+
// They are ordered by date, so if "first" _isExpired they all are!
93+
if (first.lastSeenDate && [first _isExpired] && [device.uniqueId isEqualToString:first.uniqueId]) {
94+
return YES;
95+
}
96+
}
97+
return NO;
98+
}
99+
60100
- (NSString*) humanReadableFingerprint {
61101
if (!self.publicIdentityKeyData) {
62102
return @"";

ChatSecure/Classes/Model/Yap Storage/OTRXMPPRoom.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import UIKit
1010
import YapDatabase.YapDatabaseRelationship
11-
import OTRAssets
1211

1312
@objc public enum RoomSecurity: Int {
1413
/// will choose omemo if _any_ occupants have available keys
@@ -35,7 +34,7 @@ import OTRAssets
3534
/// JID of the room itself
3635
@objc private var jid:String?
3736

38-
@objc open var preferredSecurity: RoomSecurity = OTRBranding.defaultGroupPlaintext ? .plaintext : .best
37+
@objc open var preferredSecurity: RoomSecurity = .best
3938

4039
/// XMPPJID of the room itself
4140
@objc public var roomJID: XMPPJID? {

ChatSecure/Classes/View Controllers/OTRConversationViewController.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ - (void) continueOnboarding:(BOOL)hasAccounts {
156156
notificationBody = [NSString stringWithFormat:MIGRATION_NOTIFICATION_WITH_DATE_STRING(), days];
157157
}
158158

159-
[[UIApplication sharedApplication] showLocalNotificationWithIdentifier:@"Migration" body:notificationBody badge:1 userInfo:[[NSDictionary alloc] initWithObjectsAndKeys:kOTRNotificationTypeNone, kOTRNotificationType, @"Migration", kOTRNotificationThreadKey, nil] recurring:YES];
159+
[[UIApplication sharedApplication] showLocalNotificationWithGroupingIdentifier:@"Migration" body:notificationBody badge:1 userInfo:[[NSDictionary alloc] initWithObjectsAndKeys:kOTRNotificationTypeNone, kOTRNotificationType, @"Migration", kOTRNotificationThreadKey, nil] recurring:YES];
160160
}
161161
} else {
162162
[[UIApplication sharedApplication] cancelRecurringLocalNotificationWithIdentifier:@"Migration"];

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
source "https://rubygems.org"
22

3-
gem 'cocoapods', '~> 1.5.0'
3+
gem 'cocoapods', '~> 1.5.3'

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ PLATFORMS
7070
ruby
7171

7272
DEPENDENCIES
73-
cocoapods (~> 1.5.0)
73+
cocoapods (~> 1.5.3)
7474

7575
BUNDLED WITH
76-
1.16.1
76+
1.16.2

OTRAssets/OTRBranding.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,5 @@ FOUNDATION_EXPORT NSString *const kOTRSettingKeyLanguage;
9898
/** If enabled, will allow OMEMO functionality within the app. Defaults to YES if setting key is not present. */
9999
@property (class, readonly) BOOL allowOMEMO;
100100

101-
/** If enabled, will enter groups in plaintext mode. Defaults to NO if setting key is not present, which will result in setting transport security to "best". */
102-
@property (class, readonly) BOOL defaultGroupPlaintext;
103-
104101
@end
105102
NS_ASSUME_NONNULL_END

OTRAssets/OTRBranding.m

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,16 +168,6 @@ + (BOOL) allowOMEMO {
168168
}
169169
}
170170

171-
+ (BOOL) defaultGroupPlaintext {
172-
NSNumber *result = [[self defaultPlist] objectForKey:@"DefaultGroupPlaintext"];
173-
if (!result) {
174-
return NO;
175-
} else {
176-
return result.boolValue;
177-
}
178-
}
179-
180-
181171
/** Returns true if we're running the official ChatSecure */
182172
+ (BOOL) matchesUpstream {
183173
return [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.chrisballinger.ChatSecure"];

OTRResources/Branding.plist

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,5 @@
4848
<false/>
4949
<key>AllowOMEMO</key>
5050
<true/>
51-
<key>DefaultGroupPlaintext</key>
52-
<false/>
5351
</dict>
5452
</plist>

0 commit comments

Comments
 (0)