From 1b97bb6aa89b8e4c1a848b390b97d5ab3ca57913 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Wed, 8 Feb 2023 09:19:06 +1100 Subject: [PATCH 1/4] Fixed an incorrect size in the FileServerAPI which could result in upload errors --- SessionMessagingKit/File Server/FileServerAPI.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SessionMessagingKit/File Server/FileServerAPI.swift b/SessionMessagingKit/File Server/FileServerAPI.swift index 065a8b94c..5c0363133 100644 --- a/SessionMessagingKit/File Server/FileServerAPI.swift +++ b/SessionMessagingKit/File Server/FileServerAPI.swift @@ -14,7 +14,10 @@ public final class FileServerAPI: NSObject { public static let oldServerPublicKey = "7cb31905b55cd5580c686911debf672577b3fb0bff81df4ce2d5c4cb3a7aaa69" @objc public static let server = "http://filev2.getsession.org" public static let serverPublicKey = "da21e1d886c6fbaea313f75298bd64aab03a97ce985b46bb2dad9f2089c8ee59" - public static let maxFileSize = (10 * 1024 * 1024) // 10 MB + + /// **Note:** The max file size is 10,000,000 bytes (rather than 10MiB which would be `(10 * 1024 * 1024)`), 10,000,000 + /// exactly will be fine but a single byte more will result in an error + public static let maxFileSize = 10_000_000 /// Standard timeout is 10 seconds which is a little too short fir file upload/download with slightly larger files public static let fileTimeout: TimeInterval = 30 From 2286d51db613ef55e4e01f432d9accbc120b2a93 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Wed, 8 Feb 2023 17:46:43 +1100 Subject: [PATCH 2/4] Update the SyncPushTokensJob to reregister every 12 hours --- Session/Notifications/SyncPushTokensJob.swift | 55 ++++++++++--------- .../General/SNUserDefaults.swift | 1 + 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Session/Notifications/SyncPushTokensJob.swift b/Session/Notifications/SyncPushTokensJob.swift index e18bc19b7..4b80934b4 100644 --- a/Session/Notifications/SyncPushTokensJob.swift +++ b/Session/Notifications/SyncPushTokensJob.swift @@ -11,6 +11,7 @@ public enum SyncPushTokensJob: JobExecutor { public static let maxFailureCount: Int = -1 public static let requiresThreadId: Bool = false public static let requiresInteractionId: Bool = false + private static let maxFrequency: TimeInterval = (12 * 60 * 60) public static func run( _ job: Job, @@ -34,45 +35,44 @@ public enum SyncPushTokensJob: JobExecutor { return } - // Push tokens don't normally change while the app is launched, so checking once during launch is - // usually sufficient, but e.g. on iOS11, users who have disabled "Allow Notifications" and disabled - // "Background App Refresh" will not be able to obtain an APN token. Enabling those settings does not - // restart the app, so we check every activation for users who haven't yet registered. - guard job.behaviour != .recurringOnActive || !UIApplication.shared.isRegisteredForRemoteNotifications else { + // Push tokens don't normally change while the app is launched, so you would assume checking once + // during launch is sufficient, but e.g. on iOS11, users who have disabled "Allow Notifications" + // and disabled "Background App Refresh" will not be able to obtain an APN token. Enabling those + // settings does not restart the app, so we check every activation for users who haven't yet + // registered. + // + // It's also possible for a device to successfully register for push notifications but fail to + // register with Session + // + // Due to the above we want to re-register at least once every ~12 hours to ensure users will + // continue to receive push notifications + // + // In addition to this if we are custom running the job (eg. by toggling the push notification + // setting) then we should run regardless of the other settings so users have a mechanism to force + // the registration to run + let lastPushNotificationSync: Date = UserDefaults.standard[.lastPushNotificationSync] + .defaulting(to: Date.distantPast) + + guard + job.behaviour == .runOnce || + !UIApplication.shared.isRegisteredForRemoteNotifications || + Date().timeIntervalSince(lastPushNotificationSync) >= SyncPushTokensJob.maxFrequency + else { deferred(job) // Don't need to do anything if push notifications are already registered return } - Logger.info("Retrying remote notification registration since user hasn't registered yet.") - - // Determine if we want to upload only if stale (Note: This should default to true, and be true if - // 'details' isn't provided) - let uploadOnlyIfStale: Bool = ((try? JSONDecoder().decode(Details.self, from: job.details ?? Data()))?.uploadOnlyIfStale ?? true) - - // Get the app version info (used to determine if we want to update the push tokens) - let lastAppVersion: String? = AppVersion.sharedInstance().lastAppVersion - let currentAppVersion: String? = AppVersion.sharedInstance().currentAppVersion + Logger.info("Re-registering for remote notifications.") + // Perform device registration PushRegistrationManager.shared.requestPushTokens() .then(on: queue) { (pushToken: String, voipToken: String) -> Promise in - let lastPushToken: String? = Storage.shared[.lastRecordedPushToken] - let lastVoipToken: String? = Storage.shared[.lastRecordedVoipToken] - let shouldUploadTokens: Bool = ( - !uploadOnlyIfStale || ( - lastPushToken != pushToken || - lastVoipToken != voipToken - ) || - lastAppVersion != currentAppVersion - ) - - guard shouldUploadTokens else { return Promise.value(()) } - let (promise, seal) = Promise.pending() SyncPushTokensJob.registerForPushNotifications( pushToken: pushToken, voipToken: voipToken, - isForcedUpdate: shouldUploadTokens, + isForcedUpdate: true, success: { seal.fulfill(()) }, failure: seal.reject ) @@ -94,6 +94,7 @@ public enum SyncPushTokensJob: JobExecutor { public static func run(uploadOnlyIfStale: Bool) { guard let job: Job = Job( variant: .syncPushTokens, + behaviour: .runOnce, details: SyncPushTokensJob.Details( uploadOnlyIfStale: uploadOnlyIfStale ) diff --git a/SessionUtilitiesKit/General/SNUserDefaults.swift b/SessionUtilitiesKit/General/SNUserDefaults.swift index 8fbeee36c..eda9cbcba 100644 --- a/SessionUtilitiesKit/General/SNUserDefaults.swift +++ b/SessionUtilitiesKit/General/SNUserDefaults.swift @@ -44,6 +44,7 @@ public enum SNUserDefaults { case lastOpenGroupImageUpdate case lastOpen case lastGarbageCollection + case lastPushNotificationSync } public enum Double: Swift.String { From 93d9f51140c50024172e49a365ebe5a9e069d40c Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Fri, 10 Feb 2023 12:11:32 +1100 Subject: [PATCH 3/4] Included a blinded id comparison for adding the delete action --- .../Conversations/Context Menu/ContextMenuVC+Action.swift | 2 ++ Session/Conversations/ConversationVC+Interaction.swift | 1 + Session/Conversations/ConversationViewModel.swift | 8 +++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Session/Conversations/Context Menu/ContextMenuVC+Action.swift b/Session/Conversations/Context Menu/ContextMenuVC+Action.swift index 904978ab3..91dfd9c19 100644 --- a/Session/Conversations/Context Menu/ContextMenuVC+Action.swift +++ b/Session/Conversations/Context Menu/ContextMenuVC+Action.swift @@ -111,6 +111,7 @@ extension ContextMenuVC { for cellViewModel: MessageViewModel, recentEmojis: [EmojiWithSkinTones], currentUserPublicKey: String, + currentUserBlindedPublicKey: String?, currentUserIsOpenGroupModerator: Bool, currentThreadIsMessageRequest: Bool, delegate: ContextMenuActionDelegate? @@ -165,6 +166,7 @@ extension ContextMenuVC { cellViewModel.threadVariant != .openGroup || currentUserIsOpenGroupModerator || cellViewModel.authorId == currentUserPublicKey || + cellViewModel.authorId == currentUserBlindedPublicKey || cellViewModel.state == .failed ) let canBan: Bool = ( diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index c6794329a..ca2ae2218 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -778,6 +778,7 @@ extension ConversationVC: for: cellViewModel, recentEmojis: (self.viewModel.threadData.recentReactionEmoji ?? []).compactMap { EmojiWithSkinTones(rawValue: $0) }, currentUserPublicKey: self.viewModel.threadData.currentUserPublicKey, + currentUserBlindedPublicKey: self.viewModel.threadData.currentUserBlindedPublicKey, currentUserIsOpenGroupModerator: OpenGroupManager.isUserModeratorOrAdmin( self.viewModel.threadData.currentUserPublicKey, for: self.viewModel.threadData.openGroupRoomToken, diff --git a/Session/Conversations/ConversationViewModel.swift b/Session/Conversations/ConversationViewModel.swift index 92e55e45b..2249474ad 100644 --- a/Session/Conversations/ConversationViewModel.swift +++ b/Session/Conversations/ConversationViewModel.swift @@ -115,6 +115,7 @@ public class ConversationViewModel: OWSAudioPlayerDelegate { } ) ) + .populatingCurrentUserBlindedKey() /// This is all the data the screen needs to populate itself, please see the following link for tips to help optimise /// performance https://github.com/groue/GRDB.swift#valueobservation-performance @@ -130,7 +131,7 @@ public class ConversationViewModel: OWSAudioPlayerDelegate { private func setupObservableThreadData(for threadId: String) -> ValueObservation>> { return ValueObservation - .trackingConstantRegion { db -> SessionThreadViewModel? in + .trackingConstantRegion { [weak self] db -> SessionThreadViewModel? in let userPublicKey: String = getUserHexEncodedPublicKey(db) let recentReactionEmoji: [String] = try Emoji.getRecent(db, withDefaultEmoji: true) let threadViewModel: SessionThreadViewModel? = try SessionThreadViewModel @@ -139,6 +140,11 @@ public class ConversationViewModel: OWSAudioPlayerDelegate { return threadViewModel .map { $0.with(recentReactionEmoji: recentReactionEmoji) } + .map { viewModel -> SessionThreadViewModel in + viewModel.populatingCurrentUserBlindedKey( + currentUserBlindedPublicKeyForThisThread: self?.threadData.currentUserBlindedPublicKey + ) + } } .removeDuplicates() } From 2f8ac7deaf0727318040e3d88c132ef943ef4343 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 13 Feb 2023 16:41:48 +1100 Subject: [PATCH 4/4] update build & version number --- Session.xcodeproj/project.pbxproj | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 015f4439c..201820689 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -6032,7 +6032,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 391; + CURRENT_PROJECT_VERSION = 392; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6057,7 +6057,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.6; + MARKETING_VERSION = 2.2.7; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6105,7 +6105,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 391; + CURRENT_PROJECT_VERSION = 392; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6135,7 +6135,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.6; + MARKETING_VERSION = 2.2.7; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.ShareExtension"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -6171,7 +6171,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 391; + CURRENT_PROJECT_VERSION = 392; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -6194,7 +6194,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.6; + MARKETING_VERSION = 2.2.7; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -6245,7 +6245,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 391; + CURRENT_PROJECT_VERSION = 392; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6273,7 +6273,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.2.6; + MARKETING_VERSION = 2.2.7; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.NotificationServiceExtension"; @@ -7173,7 +7173,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 391; + CURRENT_PROJECT_VERSION = 392; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -7212,7 +7212,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 2.2.6; + MARKETING_VERSION = 2.2.7; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; @@ -7245,7 +7245,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 391; + CURRENT_PROJECT_VERSION = 392; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -7284,7 +7284,7 @@ "$(SRCROOT)", ); LLVM_LTO = NO; - MARKETING_VERSION = 2.2.6; + MARKETING_VERSION = 2.2.7; OTHER_LDFLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger"; PRODUCT_NAME = Session;