From 63e6cdd9ecb1812b0e08d15f6038715f3b2ee37b Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Tue, 15 Feb 2022 16:30:11 +1100 Subject: [PATCH] Renamed OpenGroupAPIV2 to OpenGroupAPI Added the inbox endpoints --- Session.xcodeproj/project.pbxproj | 26 +- .../ConversationVC+Interaction.swift | 4 +- Session/Conversations/ConversationVC.swift | 2 +- Session/Conversations/ConversationViewItem.m | 12 +- .../Input View/MentionSelectionView.swift | 2 +- .../Message Cells/VisibleMessageCell.swift | 2 +- Session/Home/HomeVC.swift | 2 +- Session/Meta/AppDelegate.m | 2 +- Session/Open Groups/JoinOpenGroupVC.swift | 4 +- .../Open Groups/OpenGroupSuggestionGrid.swift | 14 +- .../Jobs/AttachmentDownloadJob.swift | 2 +- .../Jobs/AttachmentUploadJob.swift | 2 +- .../Models/AuthTokenResponse.swift | 8 +- .../Open Groups/Models/BatchRequestInfo.swift | 14 +- .../Open Groups/Models/Capabilities.swift | 2 +- .../Models/DeletedMessagesResponse.swift | 2 +- .../Open Groups/Models/Deletion.swift | 2 +- .../Open Groups/Models/DirectMessage.swift | 19 + .../Open Groups/Models/FileResponse.swift | 2 +- .../Models/LegacyCompactPollBody.swift | 2 +- .../Models/LegacyCompactPollResponse.swift | 2 +- .../Models/LegacyGetInfoResponse.swift | 2 +- .../Open Groups/Models/LegacyRoomInfo.swift | 2 +- .../Models/LegacyRoomsResponse.swift | 2 +- .../Models/MemberCountResponse.swift | 2 +- .../Models/ModeratorsResponse.swift | 2 +- .../Open Groups/Models/OGMessage.swift | 10 +- .../Models/OpenGroupMessageV2.swift | 4 +- .../Open Groups/Models/PinnedMessage.swift | 2 +- .../Open Groups/Models/PublicKeyBody.swift | 2 +- .../Open Groups/Models/Room.swift | 8 +- .../Open Groups/Models/RoomPollInfo.swift | 2 +- .../Models/SendDirectMessageRequest.swift | 19 + .../Models/SendMessageRequest.swift | 2 +- .../Open Groups/Models/UserBanRequest.swift | 2 +- .../Models/UserDeleteMessagesRequest.swift | 2 +- .../Models/UserDeleteMessagesResponse.swift | 2 +- .../Models/UserModeratorRequest.swift | 2 +- .../Models/UserPermissionsRequest.swift | 2 +- .../Open Groups/Models/UserUnbanRequest.swift | 2 +- ...IV2+ObjC.swift => OpenGroupAPI+ObjC.swift} | 4 +- ...penGroupAPIV2.swift => OpenGroupAPI.swift} | 246 +++++++----- .../Open Groups/OpenGroupManagerV2.swift | 10 +- .../Open Groups/Types/Dependencies.swift | 2 +- .../Open Groups/Types/Endpoint.swift | 378 +++++++++--------- .../Open Groups/Types/Error.swift | 2 +- .../Types/NonceGenerator16Byte.swift | 2 +- .../Open Groups/Types/Personalization.swift | 2 +- .../Open Groups/Types/Request.swift | 2 +- .../Sending & Receiving/MessageSender.swift | 2 +- .../Pollers/OpenGroupPollerV2.swift | 28 +- .../Utilities/Promise+Utilities.swift | 2 +- .../MessageSender+Convenience.swift | 4 +- 53 files changed, 490 insertions(+), 392 deletions(-) create mode 100644 SessionMessagingKit/Open Groups/Models/DirectMessage.swift create mode 100644 SessionMessagingKit/Open Groups/Models/SendDirectMessageRequest.swift rename SessionMessagingKit/Open Groups/{OpenGroupAPIV2+ObjC.swift => OpenGroupAPI+ObjC.swift} (88%) rename SessionMessagingKit/Open Groups/{OpenGroupAPIV2.swift => OpenGroupAPI.swift} (86%) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index f65d6f9b8..f1ff64623 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -233,7 +233,7 @@ B886B4A72398B23E00211ABE /* QRCodeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B886B4A62398B23E00211ABE /* QRCodeVC.swift */; }; B886B4A92398BA1500211ABE /* QRCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B886B4A82398BA1500211ABE /* QRCode.swift */; }; B88A1AC725C90A4700E6D421 /* TypingIndicatorInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B6A904218B4C90007C4606 /* TypingIndicatorInteraction.swift */; }; - B88FA7B826045D100049422F /* OpenGroupAPIV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88FA7B726045D100049422F /* OpenGroupAPIV2.swift */; }; + B88FA7B826045D100049422F /* OpenGroupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88FA7B726045D100049422F /* OpenGroupAPI.swift */; }; B88FA7F2260C3EB10049422F /* OpenGroupSuggestionGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88FA7F1260C3EB10049422F /* OpenGroupSuggestionGrid.swift */; }; B88FA7FB26114EA70049422F /* Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88FA7FA26114EA70049422F /* Hex.swift */; }; B893063F2383961A005EAA8E /* ScanQRCodeWrapperVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */; }; @@ -754,7 +754,7 @@ C3DAB3242480CB2B00725F25 /* SRCopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */; }; C3DB66AC260ACA42001EFC55 /* OpenGroupManagerV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DB66AB260ACA42001EFC55 /* OpenGroupManagerV2.swift */; }; C3DB66C3260ACCE6001EFC55 /* OpenGroupPollerV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DB66C2260ACCE6001EFC55 /* OpenGroupPollerV2.swift */; }; - C3DB66CC260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DB66CB260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift */; }; + C3DB66CC260AF1F3001EFC55 /* OpenGroupAPI+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DB66CB260AF1F3001EFC55 /* OpenGroupAPI+ObjC.swift */; }; C3DFFAC623E96F0D0058DAF8 /* Sheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */; }; C3E5C2FA251DBABB0040DFFC /* EditClosedGroupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */; }; C3ECBF7B257056B700EA7FCE /* Threading.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3ECBF7A257056B700EA7FCE /* Threading.swift */; }; @@ -844,6 +844,8 @@ FDC438BD27BB2AB400C60D73 /* Mockable.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC438BC27BB2AB400C60D73 /* Mockable.swift */; }; FDC438C127BB4E6800C60D73 /* Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC438C027BB4E6800C60D73 /* Dependencies.swift */; }; FDC438C327BB512200C60D73 /* SodiumProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC438C227BB512200C60D73 /* SodiumProtocols.swift */; }; + FDC438C727BB6DF000C60D73 /* DirectMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC438C627BB6DF000C60D73 /* DirectMessage.swift */; }; + FDC438C927BB706500C60D73 /* SendDirectMessageRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDC438C827BB706500C60D73 /* SendDirectMessageRequest.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -1323,7 +1325,7 @@ B885D5F52334A32100EE0D8E /* UIView+Constraints.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Constraints.swift"; sourceTree = ""; }; B886B4A62398B23E00211ABE /* QRCodeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeVC.swift; sourceTree = ""; }; B886B4A82398BA1500211ABE /* QRCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCode.swift; sourceTree = ""; }; - B88FA7B726045D100049422F /* OpenGroupAPIV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupAPIV2.swift; sourceTree = ""; }; + B88FA7B726045D100049422F /* OpenGroupAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupAPI.swift; sourceTree = ""; }; B88FA7F1260C3EB10049422F /* OpenGroupSuggestionGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupSuggestionGrid.swift; sourceTree = ""; }; B88FA7FA26114EA70049422F /* Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hex.swift; sourceTree = ""; }; B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQRCodeWrapperVC.swift; sourceTree = ""; }; @@ -1859,7 +1861,7 @@ C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = ""; }; C3DB66AB260ACA42001EFC55 /* OpenGroupManagerV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupManagerV2.swift; sourceTree = ""; }; C3DB66C2260ACCE6001EFC55 /* OpenGroupPollerV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupPollerV2.swift; sourceTree = ""; }; - C3DB66CB260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenGroupAPIV2+ObjC.swift"; sourceTree = ""; }; + C3DB66CB260AF1F3001EFC55 /* OpenGroupAPI+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenGroupAPI+ObjC.swift"; sourceTree = ""; }; C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = ""; }; C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditClosedGroupVC.swift; sourceTree = ""; }; C3E7134E251C867C009649BB /* Sodium+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sodium+Utilities.swift"; sourceTree = ""; }; @@ -1974,6 +1976,8 @@ FDC438BC27BB2AB400C60D73 /* Mockable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mockable.swift; sourceTree = ""; }; FDC438C027BB4E6800C60D73 /* Dependencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dependencies.swift; sourceTree = ""; }; FDC438C227BB512200C60D73 /* SodiumProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SodiumProtocols.swift; sourceTree = ""; }; + FDC438C627BB6DF000C60D73 /* DirectMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectMessage.swift; sourceTree = ""; }; + FDC438C827BB706500C60D73 /* SendDirectMessageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendDirectMessageRequest.swift; sourceTree = ""; }; FEDBAE1B98C49BBE8C87F575 /* Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit/Pods-GlobalDependencies-FrameworkAndExtensionDependencies-ExtendedDependencies-SessionUtilitiesKit.debug.xcconfig"; sourceTree = ""; }; FF9BA33D021B115B1F5B4E46 /* Pods-SessionMessagingKit.app store release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SessionMessagingKit.app store release.xcconfig"; path = "Pods/Target Support Files/Pods-SessionMessagingKit/Pods-SessionMessagingKit.app store release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -3351,8 +3355,8 @@ children = ( FDC4381827B34EAD00C60D73 /* Models */, FDC4380727B31D3A00C60D73 /* Types */, - B88FA7B726045D100049422F /* OpenGroupAPIV2.swift */, - C3DB66CB260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift */, + B88FA7B726045D100049422F /* OpenGroupAPI.swift */, + C3DB66CB260AF1F3001EFC55 /* OpenGroupAPI+ObjC.swift */, C3DB66AB260ACA42001EFC55 /* OpenGroupManagerV2.swift */, ); path = "Open Groups"; @@ -3834,12 +3838,15 @@ FDC4384B27B47F7700C60D73 /* OpenGroupV2.swift */, FDC4381B27B354AC00C60D73 /* PublicKeyBody.swift */, FDC4386A27B4E88F00C60D73 /* BatchRequestInfo.swift */, + FDC4386627B4E10E00C60D73 /* Capabilities.swift */, FDC4385C27B4C18900C60D73 /* Room.swift */, FDC4386427B4DE7600C60D73 /* RoomPollInfo.swift */, FDC4385E27B4C4A200C60D73 /* PinnedMessage.swift */, FDC4386027B4CDDF00C60D73 /* FileResponse.swift */, FDC4387727B5C35400C60D73 /* SendMessageRequest.swift */, FDC4386227B4D94E00C60D73 /* OGMessage.swift */, + FDC438C627BB6DF000C60D73 /* DirectMessage.swift */, + FDC438C827BB706500C60D73 /* SendDirectMessageRequest.swift */, FDC438A327BB107F00C60D73 /* UserBanRequest.swift */, FDC438A527BB113A00C60D73 /* UserUnbanRequest.swift */, FDC438A727BB11CD00C60D73 /* UserPermissionsRequest.swift */, @@ -3849,7 +3856,6 @@ FDC4382B27B380E300C60D73 /* MemberCountResponse.swift */, FDC4382527B37F6900C60D73 /* DeletedMessagesResponse.swift */, FDC4384627B47F4D00C60D73 /* Deletion.swift */, - FDC4386627B4E10E00C60D73 /* Capabilities.swift */, FDC4382727B37FD300C60D73 /* ModeratorsResponse.swift */, FDC4381927B34EBA00C60D73 /* LegacyCompactPollBody.swift */, FDC4384527B47F4D00C60D73 /* LegacyCompactPollResponse.swift */, @@ -5163,6 +5169,7 @@ FDC4385927B484E800C60D73 /* FileUploadBody.swift in Sources */, C32C5E5B256DDF45003C73A2 /* OWSStorage.m in Sources */, C32C5E15256DDC78003C73A2 /* SSKPreferences.swift in Sources */, + FDC438C727BB6DF000C60D73 /* DirectMessage.swift in Sources */, C32C5D9C256DD6DC003C73A2 /* OWSOutgoingReceiptManager.m in Sources */, B8AE760B25ABFB5A001A84D2 /* GeneralUtilities.m in Sources */, C32C5C4F256DCC36003C73A2 /* Storage+OpenGroups.swift in Sources */, @@ -5194,13 +5201,14 @@ C32C599E256DB02B003C73A2 /* TypingIndicators.swift in Sources */, FDC4380927B31D4E00C60D73 /* Error.swift in Sources */, FDC4382027B36ADC00C60D73 /* Endpoint.swift in Sources */, - C3DB66CC260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift in Sources */, + C3DB66CC260AF1F3001EFC55 /* OpenGroupAPI+ObjC.swift in Sources */, C32C5BEF256DC8EE003C73A2 /* OWSDisappearingMessagesJob.m in Sources */, C34A977425A3E34A00852C71 /* ClosedGroupControlMessage.swift in Sources */, FDC4384C27B47F7700C60D73 /* OpenGroupV2.swift in Sources */, FDC4382627B37F6900C60D73 /* DeletedMessagesResponse.swift in Sources */, - B88FA7B826045D100049422F /* OpenGroupAPIV2.swift in Sources */, + B88FA7B826045D100049422F /* OpenGroupAPI.swift in Sources */, C32C5E97256DE0CB003C73A2 /* OWSPrimaryStorage.m in Sources */, + FDC438C927BB706500C60D73 /* SendDirectMessageRequest.swift in Sources */, C32C5EB9256DE130003C73A2 /* OWSQuotedReplyModel+Conversion.swift in Sources */, C3A71D1F25589AC30043A11F /* WebSocketResources.pb.swift in Sources */, B8856E94256F1C37001CE70E /* OWSSounds.m in Sources */, diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 13b0ec5ab..b2d02e13d 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -700,7 +700,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in let publicKey = message.authorId guard let openGroupV2 = Storage.shared.getV2OpenGroup(for: threadID) else { return } - OpenGroupAPIV2.legacyBan(publicKey, from: openGroupV2.room, on: openGroupV2.server).retainUntilComplete() + OpenGroupAPI.legacyBan(publicKey, from: openGroupV2.room, on: openGroupV2.server).retainUntilComplete() })) alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil)) present(alert, animated: true, completion: nil) @@ -714,7 +714,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in let publicKey = message.authorId guard let openGroupV2 = Storage.shared.getV2OpenGroup(for: threadID) else { return } - OpenGroupAPIV2.legacyBanAndDeleteAllMessages(publicKey, from: openGroupV2.room, on: openGroupV2.server).retainUntilComplete() + OpenGroupAPI.legacyBanAndDeleteAllMessages(publicKey, from: openGroupV2.room, on: openGroupV2.server).retainUntilComplete() })) alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil)) present(alert, animated: true, completion: nil) diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index aeca31155..86de50e68 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -373,7 +373,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat // Update member count if this is a V2 open group // TODO: Non-legacy version (I assue this comes through room updates... 'activeUsers'? if let v2OpenGroup = Storage.shared.getV2OpenGroup(for: thread.uniqueId!) { - OpenGroupAPIV2.legacyGetMemberCount(for: v2OpenGroup.room, on: v2OpenGroup.server).retainUntilComplete() + OpenGroupAPI.legacyGetMemberCount(for: v2OpenGroup.room, on: v2OpenGroup.server).retainUntilComplete() } } diff --git a/Session/Conversations/ConversationViewItem.m b/Session/Conversations/ConversationViewItem.m index 4ebdd168a..8afcf5442 100644 --- a/Session/Conversations/ConversationViewItem.m +++ b/Session/Conversations/ConversationViewItem.m @@ -1006,11 +1006,11 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) // If it's an incoming message the user must have moderator status if (self.interaction.interactionType == OWSInteractionType_IncomingMessage) { NSString *userPublicKey = [LKStorage.shared getUserPublicKey]; - if (![SNOpenGroupAPIV2 isUserModerator:userPublicKey forRoom:openGroupV2.room onServer:openGroupV2.server]) { return; } + if (![SNOpenGroupAPI isUserModerator:userPublicKey forRoom:openGroupV2.room onServer:openGroupV2.server]) { return; } } // Delete the message - [[SNOpenGroupAPIV2 deleteMessageWithServerID:message.openGroupServerMessageID fromRoom:openGroupV2.room onServer:openGroupV2.server].catch(^(NSError *error) { + [[SNOpenGroupAPI deleteMessageWithServerID:message.openGroupServerMessageID fromRoom:openGroupV2.room onServer:openGroupV2.server].catch(^(NSError *error) { // Roll back [self.interaction save]; }) retainUntilComplete]; @@ -1060,14 +1060,14 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) if (self.interaction.interactionType == OWSInteractionType_IncomingMessage) { NSString *userPublicKey = [LKStorage.shared getUserPublicKey]; if (openGroupV2 != nil) { - if (![SNOpenGroupAPIV2 isUserModerator:userPublicKey forRoom:openGroupV2.room onServer:openGroupV2.server]) { return; } + if (![SNOpenGroupAPI isUserModerator:userPublicKey forRoom:openGroupV2.room onServer:openGroupV2.server]) { return; } } } // Delete the message BOOL wasSentByUser = (interationType == OWSInteractionType_OutgoingMessage); if (openGroupV2 != nil) { - [[SNOpenGroupAPIV2 deleteMessageWithServerID:message.openGroupServerMessageID fromRoom:openGroupV2.room onServer:openGroupV2.server].catch(^(NSError *error) { + [[SNOpenGroupAPI deleteMessageWithServerID:message.openGroupServerMessageID fromRoom:openGroupV2.room onServer:openGroupV2.server].catch(^(NSError *error) { // Roll back [self.interaction save]; }) retainUntilComplete]; @@ -1133,7 +1133,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) if (interationType == OWSInteractionType_IncomingMessage) { // Only allow deletion on incoming messages if the user has moderation permission if (openGroupV2 != nil) { - return [SNOpenGroupAPIV2 isUserModerator:[SNGeneralUtilities getUserPublicKey] forRoom:openGroupV2.room onServer:openGroupV2.server]; + return [SNOpenGroupAPI isUserModerator:[SNGeneralUtilities getUserPublicKey] forRoom:openGroupV2.room onServer:openGroupV2.server]; } } else { return YES; @@ -1155,7 +1155,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) // Check that we're a moderator if (openGroupV2 != nil) { - return [SNOpenGroupAPIV2 isUserModerator:[SNGeneralUtilities getUserPublicKey] forRoom:openGroupV2.room onServer:openGroupV2.server]; + return [SNOpenGroupAPI isUserModerator:[SNGeneralUtilities getUserPublicKey] forRoom:openGroupV2.room onServer:openGroupV2.server]; } } diff --git a/Session/Conversations/Input View/MentionSelectionView.swift b/Session/Conversations/Input View/MentionSelectionView.swift index 1c33b00f6..580710569 100644 --- a/Session/Conversations/Input View/MentionSelectionView.swift +++ b/Session/Conversations/Input View/MentionSelectionView.swift @@ -163,7 +163,7 @@ private extension MentionSelectionView { profilePictureView.publicKey = mentionCandidate.publicKey profilePictureView.update() if let server = openGroupServer, let room = openGroupRoom { - let isUserModerator = OpenGroupAPIV2.isUserModerator(mentionCandidate.publicKey, for: room, on: server) + let isUserModerator = OpenGroupAPI.isUserModerator(mentionCandidate.publicKey, for: room, on: server) moderatorIconImageView.isHidden = !isUserModerator } else { moderatorIconImageView.isHidden = true diff --git a/Session/Conversations/Message Cells/VisibleMessageCell.swift b/Session/Conversations/Message Cells/VisibleMessageCell.swift index 1106b2d10..65584efbd 100644 --- a/Session/Conversations/Message Cells/VisibleMessageCell.swift +++ b/Session/Conversations/Message Cells/VisibleMessageCell.swift @@ -219,7 +219,7 @@ final class VisibleMessageCell : MessageCell, LinkPreviewViewDelegate { } if let senderSessionID = senderSessionID, message.isOpenGroupMessage { if let openGroupV2 = Storage.shared.getV2OpenGroup(for: message.uniqueThreadId) { - let isUserModerator = OpenGroupAPIV2.isUserModerator(senderSessionID, for: openGroupV2.room, on: openGroupV2.server) + let isUserModerator = OpenGroupAPI.isUserModerator(senderSessionID, for: openGroupV2.room, on: openGroupV2.server) moderatorIconImageView.isHidden = !isUserModerator || profilePictureView.isHidden } else { moderatorIconImageView.isHidden = true diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index 72bc407a6..d0a15cae3 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -160,7 +160,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv let _ = IP2Country.shared.populateCacheIfNeeded() } // Get default open group rooms if needed - OpenGroupAPIV2.legacyGetDefaultRoomsIfNeeded() + OpenGroupAPI.legacyGetDefaultRoomsIfNeeded() } override func viewDidAppear(_ animated: Bool) { diff --git a/Session/Meta/AppDelegate.m b/Session/Meta/AppDelegate.m index e0ca1d383..0bb1a4964 100644 --- a/Session/Meta/AppDelegate.m +++ b/Session/Meta/AppDelegate.m @@ -383,7 +383,7 @@ static NSTimeInterval launchStartedAt; } if (CurrentAppContext().isMainApp) { - [SNOpenGroupAPIV2 legacyGetDefaultRoomsIfNeeded]; + [SNOpenGroupAPI legacyGetDefaultRoomsIfNeeded]; } [[SNSnodeAPI getSnodePool] retainUntilComplete]; diff --git a/Session/Open Groups/JoinOpenGroupVC.swift b/Session/Open Groups/JoinOpenGroupVC.swift index 7eb4bb567..fcd9b0a71 100644 --- a/Session/Open Groups/JoinOpenGroupVC.swift +++ b/Session/Open Groups/JoinOpenGroupVC.swift @@ -238,8 +238,8 @@ private final class EnterURLVC : UIViewController, UIGestureRecognizerDelegate, return !suggestionGrid.frame.contains(location) } - func join(_ room: OpenGroupAPIV2.LegacyRoomInfo) { - joinOpenGroupVC.joinV2OpenGroup(room: room.id, server: OpenGroupAPIV2.defaultServer, publicKey: OpenGroupAPIV2.defaultServerPublicKey) + func join(_ room: OpenGroupAPI.LegacyRoomInfo) { + joinOpenGroupVC.joinV2OpenGroup(room: room.id, server: OpenGroupAPI.defaultServer, publicKey: OpenGroupAPI.defaultServerPublicKey) } @objc private func joinOpenGroup() { diff --git a/Session/Open Groups/OpenGroupSuggestionGrid.swift b/Session/Open Groups/OpenGroupSuggestionGrid.swift index 2fb2d86df..3ac1f5e69 100644 --- a/Session/Open Groups/OpenGroupSuggestionGrid.swift +++ b/Session/Open Groups/OpenGroupSuggestionGrid.swift @@ -3,7 +3,7 @@ import NVActivityIndicatorView final class OpenGroupSuggestionGrid : UIView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { private let maxWidth: CGFloat - private var rooms: [OpenGroupAPIV2.LegacyRoomInfo] = [] { didSet { update() } } + private var rooms: [OpenGroupAPI.LegacyRoomInfo] = [] { didSet { update() } } private var heightConstraint: NSLayoutConstraint! var delegate: OpenGroupSuggestionGridDelegate? @@ -59,10 +59,10 @@ final class OpenGroupSuggestionGrid : UIView, UICollectionViewDataSource, UIColl spinner.startAnimating() heightConstraint = set(.height, to: OpenGroupSuggestionGrid.cellHeight) widthAnchor.constraint(greaterThanOrEqualToConstant: OpenGroupSuggestionGrid.cellHeight).isActive = true - if OpenGroupAPIV2.defaultRoomsPromise == nil { - OpenGroupAPIV2.legacyGetDefaultRoomsIfNeeded() + if OpenGroupAPI.defaultRoomsPromise == nil { + OpenGroupAPI.legacyGetDefaultRoomsIfNeeded() } - let _ = OpenGroupAPIV2.legacyDefaultRoomsPromise?.done { [weak self] rooms in + let _ = OpenGroupAPI.legacyDefaultRoomsPromise?.done { [weak self] rooms in // TODO: Update this for the new rooms API self?.rooms = rooms } @@ -105,7 +105,7 @@ final class OpenGroupSuggestionGrid : UIView, UICollectionViewDataSource, UIColl extension OpenGroupSuggestionGrid { fileprivate final class Cell : UICollectionViewCell { - var room: OpenGroupAPIV2.LegacyRoomInfo? { didSet { update() } } + var room: OpenGroupAPI.LegacyRoomInfo? { didSet { update() } } static let identifier = "OpenGroupSuggestionGridCell" @@ -173,7 +173,7 @@ extension OpenGroupSuggestionGrid { private func update() { guard let room = room else { return } - let promise = OpenGroupAPIV2.legacyGetGroupImage(for: room.id, on: OpenGroupAPIV2.defaultServer) + let promise = OpenGroupAPI.legacyGetGroupImage(for: room.id, on: OpenGroupAPI.defaultServer) imageView.image = given(promise.value) { UIImage(data: $0)! } imageView.isHidden = (imageView.image == nil) label.text = room.name @@ -184,5 +184,5 @@ extension OpenGroupSuggestionGrid { // MARK: Delegate protocol OpenGroupSuggestionGridDelegate { - func join(_ room: OpenGroupAPIV2.LegacyRoomInfo) + func join(_ room: OpenGroupAPI.LegacyRoomInfo) } diff --git a/SessionMessagingKit/Jobs/AttachmentDownloadJob.swift b/SessionMessagingKit/Jobs/AttachmentDownloadJob.swift index c3d5d4c32..30842c939 100644 --- a/SessionMessagingKit/Jobs/AttachmentDownloadJob.swift +++ b/SessionMessagingKit/Jobs/AttachmentDownloadJob.swift @@ -102,7 +102,7 @@ public final class AttachmentDownloadJob : NSObject, Job, NSCoding { // NSObject return handleFailure(Error.invalidURL) } // TODO: Upgrade this to use the non-legacy version - OpenGroupAPIV2.legacyDownload(file, from: v2OpenGroup.room, on: v2OpenGroup.server).done(on: DispatchQueue.global(qos: .userInitiated)) { data in + OpenGroupAPI.legacyDownload(file, from: v2OpenGroup.room, on: v2OpenGroup.server).done(on: DispatchQueue.global(qos: .userInitiated)) { data in self.handleDownloadedAttachment(data: data, temporaryFilePath: temporaryFilePath, pointer: pointer, failureHandler: handleFailure) }.catch(on: DispatchQueue.global()) { error in handleFailure(error) diff --git a/SessionMessagingKit/Jobs/AttachmentUploadJob.swift b/SessionMessagingKit/Jobs/AttachmentUploadJob.swift index e48255979..0630cef7c 100644 --- a/SessionMessagingKit/Jobs/AttachmentUploadJob.swift +++ b/SessionMessagingKit/Jobs/AttachmentUploadJob.swift @@ -73,7 +73,7 @@ public final class AttachmentUploadJob : NSObject, Job, NSCoding { // NSObject/N stream, using: { data in // TODO: Upgrade this to use the non-legacy version - return OpenGroupAPIV2.legacyUpload(data, to: v2OpenGroup.room, on: v2OpenGroup.server) + return OpenGroupAPI.legacyUpload(data, to: v2OpenGroup.room, on: v2OpenGroup.server) }, encrypt: false, onSuccess: handleSuccess, diff --git a/SessionMessagingKit/Open Groups/Models/AuthTokenResponse.swift b/SessionMessagingKit/Open Groups/Models/AuthTokenResponse.swift index d4340a053..0823b3016 100644 --- a/SessionMessagingKit/Open Groups/Models/AuthTokenResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/AuthTokenResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct AuthTokenResponse: Codable { struct Challenge: Codable { enum CodingKeys: String, CodingKey { @@ -20,7 +20,7 @@ extension OpenGroupAPIV2 { // MARK: - Codable -extension OpenGroupAPIV2.AuthTokenResponse.Challenge { +extension OpenGroupAPI.AuthTokenResponse.Challenge { init(from decoder: Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: CodingKeys.self) @@ -28,10 +28,10 @@ extension OpenGroupAPIV2.AuthTokenResponse.Challenge { let base64EncodedEphemeralPublicKey: String = try container.decode(String.self, forKey: .ephemeralPublicKey) guard let ciphertext = Data(base64Encoded: base64EncodedCiphertext), let ephemeralPublicKey = Data(base64Encoded: base64EncodedEphemeralPublicKey) else { - throw OpenGroupAPIV2.Error.parsingFailed + throw OpenGroupAPI.Error.parsingFailed } - self = OpenGroupAPIV2.AuthTokenResponse.Challenge( + self = OpenGroupAPI.AuthTokenResponse.Challenge( ciphertext: ciphertext, ephemeralPublicKey: ephemeralPublicKey ) diff --git a/SessionMessagingKit/Open Groups/Models/BatchRequestInfo.swift b/SessionMessagingKit/Open Groups/Models/BatchRequestInfo.swift index b5ac2812a..28525723d 100644 --- a/SessionMessagingKit/Open Groups/Models/BatchRequestInfo.swift +++ b/SessionMessagingKit/Open Groups/Models/BatchRequestInfo.swift @@ -5,7 +5,7 @@ import PromiseKit import SessionUtilitiesKit import SessionSnodeKit -extension OpenGroupAPIV2 { +extension OpenGroupAPI { // MARK: - BatchSubRequest struct BatchSubRequest: Codable { @@ -68,17 +68,17 @@ public extension Decodable { } extension Promise where T == (OnionRequestResponseInfoType, Data?) { - func decoded(as types: OpenGroupAPIV2.BatchResponseTypes, on queue: DispatchQueue? = nil, error: Error) -> Promise { - self.map(on: queue) { responseInfo, maybeData -> OpenGroupAPIV2.BatchResponse in + func decoded(as types: OpenGroupAPI.BatchResponseTypes, on queue: DispatchQueue? = nil, error: Error) -> Promise { + self.map(on: queue) { responseInfo, maybeData -> OpenGroupAPI.BatchResponse in // Need to split the data into an array of data so each item can be Decoded correctly - guard let data: Data = maybeData else { throw OpenGroupAPIV2.Error.parsingFailed } + guard let data: Data = maybeData else { throw OpenGroupAPI.Error.parsingFailed } guard let jsonObject: Any = try? JSONSerialization.jsonObject(with: data, options: [.fragmentsAllowed]) else { - throw OpenGroupAPIV2.Error.parsingFailed + throw OpenGroupAPI.Error.parsingFailed } - guard let anyArray: [Any] = jsonObject as? [Any] else { throw OpenGroupAPIV2.Error.parsingFailed } + guard let anyArray: [Any] = jsonObject as? [Any] else { throw OpenGroupAPI.Error.parsingFailed } let dataArray: [Data] = anyArray.compactMap { try? JSONSerialization.data(withJSONObject: $0) } - guard dataArray.count == types.count else { throw OpenGroupAPIV2.Error.parsingFailed } + guard dataArray.count == types.count else { throw OpenGroupAPI.Error.parsingFailed } do { return try zip(dataArray, types) diff --git a/SessionMessagingKit/Open Groups/Models/Capabilities.swift b/SessionMessagingKit/Open Groups/Models/Capabilities.swift index b87873016..1e132ed11 100644 --- a/SessionMessagingKit/Open Groups/Models/Capabilities.swift +++ b/SessionMessagingKit/Open Groups/Models/Capabilities.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct Capabilities: Codable { public enum Capability: CaseIterable, Codable { public static var allCases: [Capability] { diff --git a/SessionMessagingKit/Open Groups/Models/DeletedMessagesResponse.swift b/SessionMessagingKit/Open Groups/Models/DeletedMessagesResponse.swift index 5b8e34921..a701594b4 100644 --- a/SessionMessagingKit/Open Groups/Models/DeletedMessagesResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/DeletedMessagesResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct DeletedMessagesResponse: Codable { enum CodingKeys: String, CodingKey { case deletions = "ids" diff --git a/SessionMessagingKit/Open Groups/Models/Deletion.swift b/SessionMessagingKit/Open Groups/Models/Deletion.swift index d7a3e9bd9..407fcec41 100644 --- a/SessionMessagingKit/Open Groups/Models/Deletion.swift +++ b/SessionMessagingKit/Open Groups/Models/Deletion.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct Deletion: Codable { enum CodingKeys: String, CodingKey { case id diff --git a/SessionMessagingKit/Open Groups/Models/DirectMessage.swift b/SessionMessagingKit/Open Groups/Models/DirectMessage.swift new file mode 100644 index 000000000..47976bb19 --- /dev/null +++ b/SessionMessagingKit/Open Groups/Models/DirectMessage.swift @@ -0,0 +1,19 @@ +// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. + +import Foundation + +extension OpenGroupAPI { + public struct DirectMessage: Codable { + enum CodingKeys: String, CodingKey { + case id + case sender + case expires = "expires_at" + case base64EncodedData = "data" + } + + public let id: Int64 + public let sender: String + public let expires: TimeInterval + public let base64EncodedData: String + } +} diff --git a/SessionMessagingKit/Open Groups/Models/FileResponse.swift b/SessionMessagingKit/Open Groups/Models/FileResponse.swift index 6ec0f9888..d2c723e00 100644 --- a/SessionMessagingKit/Open Groups/Models/FileResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/FileResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct FileResponse: Codable { enum CodingKeys: String, CodingKey { case fileName = "filename" diff --git a/SessionMessagingKit/Open Groups/Models/LegacyCompactPollBody.swift b/SessionMessagingKit/Open Groups/Models/LegacyCompactPollBody.swift index 9180bcc8c..70036c1e2 100644 --- a/SessionMessagingKit/Open Groups/Models/LegacyCompactPollBody.swift +++ b/SessionMessagingKit/Open Groups/Models/LegacyCompactPollBody.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct LegacyCompactPollBody: Codable { struct Room: Codable { enum CodingKeys: String, CodingKey { diff --git a/SessionMessagingKit/Open Groups/Models/LegacyCompactPollResponse.swift b/SessionMessagingKit/Open Groups/Models/LegacyCompactPollResponse.swift index 8988a72b5..963ef1449 100644 --- a/SessionMessagingKit/Open Groups/Models/LegacyCompactPollResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/LegacyCompactPollResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct LegacyCompactPollResponse: Codable { public struct Result: Codable { enum CodingKeys: String, CodingKey { diff --git a/SessionMessagingKit/Open Groups/Models/LegacyGetInfoResponse.swift b/SessionMessagingKit/Open Groups/Models/LegacyGetInfoResponse.swift index fe00c940e..b3e4317f3 100644 --- a/SessionMessagingKit/Open Groups/Models/LegacyGetInfoResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/LegacyGetInfoResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct LegacyGetInfoResponse: Codable { let room: LegacyRoomInfo } diff --git a/SessionMessagingKit/Open Groups/Models/LegacyRoomInfo.swift b/SessionMessagingKit/Open Groups/Models/LegacyRoomInfo.swift index 1afce0b96..bccd9ea93 100644 --- a/SessionMessagingKit/Open Groups/Models/LegacyRoomInfo.swift +++ b/SessionMessagingKit/Open Groups/Models/LegacyRoomInfo.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct LegacyRoomInfo: Codable { enum CodingKeys: String, CodingKey { case id diff --git a/SessionMessagingKit/Open Groups/Models/LegacyRoomsResponse.swift b/SessionMessagingKit/Open Groups/Models/LegacyRoomsResponse.swift index 7251a9ce4..162e629fc 100644 --- a/SessionMessagingKit/Open Groups/Models/LegacyRoomsResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/LegacyRoomsResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct LegacyRoomsResponse: Codable { let rooms: [LegacyRoomInfo] } diff --git a/SessionMessagingKit/Open Groups/Models/MemberCountResponse.swift b/SessionMessagingKit/Open Groups/Models/MemberCountResponse.swift index 2bc0ec604..8ca0d8e43 100644 --- a/SessionMessagingKit/Open Groups/Models/MemberCountResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/MemberCountResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct MemberCountResponse: Codable { enum CodingKeys: String, CodingKey { case memberCount = "member_count" diff --git a/SessionMessagingKit/Open Groups/Models/ModeratorsResponse.swift b/SessionMessagingKit/Open Groups/Models/ModeratorsResponse.swift index 82c00e656..40b8fb08a 100644 --- a/SessionMessagingKit/Open Groups/Models/ModeratorsResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/ModeratorsResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct ModeratorsResponse: Codable { let moderators: [String] } diff --git a/SessionMessagingKit/Open Groups/Models/OGMessage.swift b/SessionMessagingKit/Open Groups/Models/OGMessage.swift index d748f3306..4101dca7c 100644 --- a/SessionMessagingKit/Open Groups/Models/OGMessage.swift +++ b/SessionMessagingKit/Open Groups/Models/OGMessage.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct Message: Codable { enum CodingKeys: String, CodingKey { case id @@ -34,7 +34,7 @@ extension OpenGroupAPIV2 { // MARK: - Decoder -extension OpenGroupAPIV2.Message { +extension OpenGroupAPI.Message { public init(from decoder: Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: CodingKeys.self) @@ -45,7 +45,7 @@ extension OpenGroupAPIV2.Message { // If we have data and a signature (ie. the message isn't a deletion) then validate the signature if let base64EncodedData: String = maybeBase64EncodedData, let base64EncodedSignature: String = maybeBase64EncodedSignature { guard let sender: String = maybeSender, let data = Data(base64Encoded: base64EncodedData), let signature = Data(base64Encoded: base64EncodedSignature) else { - throw OpenGroupAPIV2.Error.parsingFailed + throw OpenGroupAPI.Error.parsingFailed } let publicKey: Data = Data(hex: sender.removingIdPrefixIfNeeded()) @@ -53,11 +53,11 @@ extension OpenGroupAPIV2.Message { guard isValid else { SNLog("Ignoring message with invalid signature.") - throw OpenGroupAPIV2.Error.parsingFailed + throw OpenGroupAPI.Error.parsingFailed } } - self = OpenGroupAPIV2.Message( + self = OpenGroupAPI.Message( id: try container.decode(Int64.self, forKey: .id), sender: try? container.decode(String.self, forKey: .sender), posted: try container.decode(TimeInterval.self, forKey: .posted), diff --git a/SessionMessagingKit/Open Groups/Models/OpenGroupMessageV2.swift b/SessionMessagingKit/Open Groups/Models/OpenGroupMessageV2.swift index 4f7bf2163..c7a89ea83 100644 --- a/SessionMessagingKit/Open Groups/Models/OpenGroupMessageV2.swift +++ b/SessionMessagingKit/Open Groups/Models/OpenGroupMessageV2.swift @@ -49,7 +49,7 @@ extension OpenGroupMessageV2 { // Validate the message signature guard let data = Data(base64Encoded: base64EncodedData), let signature = Data(base64Encoded: base64EncodedSignature) else { - throw OpenGroupAPIV2.Error.parsingFailed + throw OpenGroupAPI.Error.parsingFailed } let publicKey = Data(hex: sender.removingIdPrefixIfNeeded()) @@ -57,7 +57,7 @@ extension OpenGroupMessageV2 { guard isValid else { SNLog("Ignoring message with invalid signature.") - throw OpenGroupAPIV2.Error.parsingFailed + throw OpenGroupAPI.Error.parsingFailed } self = OpenGroupMessageV2( diff --git a/SessionMessagingKit/Open Groups/Models/PinnedMessage.swift b/SessionMessagingKit/Open Groups/Models/PinnedMessage.swift index 610daa5db..bd8e9625f 100644 --- a/SessionMessagingKit/Open Groups/Models/PinnedMessage.swift +++ b/SessionMessagingKit/Open Groups/Models/PinnedMessage.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct PinnedMessage: Codable { enum CodingKeys: String, CodingKey { case id diff --git a/SessionMessagingKit/Open Groups/Models/PublicKeyBody.swift b/SessionMessagingKit/Open Groups/Models/PublicKeyBody.swift index d7a5c6e24..b10e6bdbc 100644 --- a/SessionMessagingKit/Open Groups/Models/PublicKeyBody.swift +++ b/SessionMessagingKit/Open Groups/Models/PublicKeyBody.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct PublicKeyBody: Codable { enum CodingKeys: String, CodingKey { case publicKey = "public_key" diff --git a/SessionMessagingKit/Open Groups/Models/Room.swift b/SessionMessagingKit/Open Groups/Models/Room.swift index 4e116cb29..77e4785d8 100644 --- a/SessionMessagingKit/Open Groups/Models/Room.swift +++ b/SessionMessagingKit/Open Groups/Models/Room.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct Room: Codable { enum CodingKeys: String, CodingKey { case token @@ -68,11 +68,11 @@ extension OpenGroupAPIV2 { // MARK: - Decoding -extension OpenGroupAPIV2.Room { +extension OpenGroupAPI.Room { public init(from decoder: Decoder) throws { let container: KeyedDecodingContainer = try decoder.container(keyedBy: CodingKeys.self) - self = OpenGroupAPIV2.Room( + self = OpenGroupAPI.Room( token: try container.decode(String.self, forKey: .token), created: try container.decode(TimeInterval.self, forKey: .created), name: try container.decode(String.self, forKey: .name), @@ -83,7 +83,7 @@ extension OpenGroupAPIV2.Room { messageSequence: try container.decode(Int64.self, forKey: .messageSequence), activeUsers: try container.decode(Int64.self, forKey: .activeUsers), activeUsersCutoff: try container.decode(Int64.self, forKey: .activeUsersCutoff), - pinnedMessages: try? container.decode([OpenGroupAPIV2.PinnedMessage].self, forKey: .pinnedMessages), + pinnedMessages: try? container.decode([OpenGroupAPI.PinnedMessage].self, forKey: .pinnedMessages), admin: ((try? container.decode(Bool.self, forKey: .admin)) ?? false), globalAdmin: ((try? container.decode(Bool.self, forKey: .globalAdmin)) ?? false), diff --git a/SessionMessagingKit/Open Groups/Models/RoomPollInfo.swift b/SessionMessagingKit/Open Groups/Models/RoomPollInfo.swift index d48bc24a9..01803253c 100644 --- a/SessionMessagingKit/Open Groups/Models/RoomPollInfo.swift +++ b/SessionMessagingKit/Open Groups/Models/RoomPollInfo.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { /// This only contains ephemeral data public struct RoomPollInfo: Codable { enum CodingKeys: String, CodingKey { diff --git a/SessionMessagingKit/Open Groups/Models/SendDirectMessageRequest.swift b/SessionMessagingKit/Open Groups/Models/SendDirectMessageRequest.swift new file mode 100644 index 000000000..2fe3e44c1 --- /dev/null +++ b/SessionMessagingKit/Open Groups/Models/SendDirectMessageRequest.swift @@ -0,0 +1,19 @@ +// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. + +import Foundation + +extension OpenGroupAPI { + public struct SendDirectMessageRequest: Codable { + let data: Data + let signature: Data + + // MARK: - Encodable + + public func encode(to encoder: Encoder) throws { + var container: KeyedEncodingContainer = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(data.base64EncodedString(), forKey: .data) + try container.encode(signature.base64EncodedString(), forKey: .signature) + } + } +} diff --git a/SessionMessagingKit/Open Groups/Models/SendMessageRequest.swift b/SessionMessagingKit/Open Groups/Models/SendMessageRequest.swift index 848e677bf..068575d81 100644 --- a/SessionMessagingKit/Open Groups/Models/SendMessageRequest.swift +++ b/SessionMessagingKit/Open Groups/Models/SendMessageRequest.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct SendMessageRequest: Codable { enum CodingKeys: String, CodingKey { case data diff --git a/SessionMessagingKit/Open Groups/Models/UserBanRequest.swift b/SessionMessagingKit/Open Groups/Models/UserBanRequest.swift index 48144df8d..2e21bca42 100644 --- a/SessionMessagingKit/Open Groups/Models/UserBanRequest.swift +++ b/SessionMessagingKit/Open Groups/Models/UserBanRequest.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct UserBanRequest: Codable { let rooms: [String]? let global: Bool? diff --git a/SessionMessagingKit/Open Groups/Models/UserDeleteMessagesRequest.swift b/SessionMessagingKit/Open Groups/Models/UserDeleteMessagesRequest.swift index c4ac800c8..0719528cc 100644 --- a/SessionMessagingKit/Open Groups/Models/UserDeleteMessagesRequest.swift +++ b/SessionMessagingKit/Open Groups/Models/UserDeleteMessagesRequest.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct UserDeleteMessagesRequest: Codable { let rooms: [String]? let global: Bool? diff --git a/SessionMessagingKit/Open Groups/Models/UserDeleteMessagesResponse.swift b/SessionMessagingKit/Open Groups/Models/UserDeleteMessagesResponse.swift index 68406a13a..9cbde6f7f 100644 --- a/SessionMessagingKit/Open Groups/Models/UserDeleteMessagesResponse.swift +++ b/SessionMessagingKit/Open Groups/Models/UserDeleteMessagesResponse.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct UserDeleteMessagesResponse: Codable { enum CodingKeys: String, CodingKey { case id diff --git a/SessionMessagingKit/Open Groups/Models/UserModeratorRequest.swift b/SessionMessagingKit/Open Groups/Models/UserModeratorRequest.swift index 468e9e950..3e815ea86 100644 --- a/SessionMessagingKit/Open Groups/Models/UserModeratorRequest.swift +++ b/SessionMessagingKit/Open Groups/Models/UserModeratorRequest.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct UserModeratorRequest: Codable { /// List of room tokens to which the moderator status should be applied. The invoking user must be an admin of all of the given rooms. /// diff --git a/SessionMessagingKit/Open Groups/Models/UserPermissionsRequest.swift b/SessionMessagingKit/Open Groups/Models/UserPermissionsRequest.swift index 66bbe19a7..d67fa69b0 100644 --- a/SessionMessagingKit/Open Groups/Models/UserPermissionsRequest.swift +++ b/SessionMessagingKit/Open Groups/Models/UserPermissionsRequest.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct UserPermissionsRequest: Codable { let rooms: [String] let timeout: TimeInterval diff --git a/SessionMessagingKit/Open Groups/Models/UserUnbanRequest.swift b/SessionMessagingKit/Open Groups/Models/UserUnbanRequest.swift index 5e77485ee..2d28b21cb 100644 --- a/SessionMessagingKit/Open Groups/Models/UserUnbanRequest.swift +++ b/SessionMessagingKit/Open Groups/Models/UserUnbanRequest.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct UserUnbanRequest: Codable { let rooms: [String]? let global: Bool? diff --git a/SessionMessagingKit/Open Groups/OpenGroupAPIV2+ObjC.swift b/SessionMessagingKit/Open Groups/OpenGroupAPI+ObjC.swift similarity index 88% rename from SessionMessagingKit/Open Groups/OpenGroupAPIV2+ObjC.swift rename to SessionMessagingKit/Open Groups/OpenGroupAPI+ObjC.swift index 8c7b7420e..89ba6e8c1 100644 --- a/SessionMessagingKit/Open Groups/OpenGroupAPIV2+ObjC.swift +++ b/SessionMessagingKit/Open Groups/OpenGroupAPI+ObjC.swift @@ -1,10 +1,10 @@ import PromiseKit -extension OpenGroupAPIV2 { +extension OpenGroupAPI { @objc(deleteMessageWithServerID:fromRoom:onServer:) public static func objc_deleteMessage(with serverID: Int64, from room: String, on server: String) -> AnyPromise { - // TODO: Upgrade this to use the non-legacy version + // TODO: Upgrade this to use the non-legacy version. return AnyPromise.from(legacyDeleteMessage(with: serverID, from: room, on: server)) } diff --git a/SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift b/SessionMessagingKit/Open Groups/OpenGroupAPI.swift similarity index 86% rename from SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift rename to SessionMessagingKit/Open Groups/OpenGroupAPI.swift index c490dedcc..0f909e71a 100644 --- a/SessionMessagingKit/Open Groups/OpenGroupAPIV2.swift +++ b/SessionMessagingKit/Open Groups/OpenGroupAPI.swift @@ -3,8 +3,8 @@ import SessionSnodeKit import Sodium import Curve25519Kit -@objc(SNOpenGroupAPIV2) -public final class OpenGroupAPIV2: NSObject { +@objc(SNOpenGroupAPI) +public final class OpenGroupAPI: NSObject { // MARK: - Settings @@ -16,7 +16,7 @@ public final class OpenGroupAPIV2: NSObject { private static var authTokenPromises: Atomic<[String: Promise]> = Atomic([:]) private static var hasPerformedInitialPoll: [String: Bool] = [:] private static var hasUpdatedLastOpenDate = false - public static let workQueue = DispatchQueue(label: "OpenGroupAPIV2.workQueue", qos: .userInitiated) // It's important that this is a serial queue + public static let workQueue = DispatchQueue(label: "OpenGroupAPI.workQueue", qos: .userInitiated) // It's important that this is a serial queue public static var moderators: [String: [String: Set]] = [:] // Server URL to room ID to set of moderator IDs public static var defaultRoomsPromise: Promise<[Room]>? public static var groupImagePromises: [String: Promise] = [:] @@ -30,13 +30,7 @@ public final class OpenGroupAPIV2: NSObject { // MARK: - Batching & Polling /// This is a convenience method which calls `/batch` with a pre-defined set of requests used to update an Open Group - public static func poll( - _ server: String, - through api: OnionRequestAPIType.Type = OnionRequestAPI.self, - using storage: SessionMessagingKitStorageProtocol = SNMessagingKitConfiguration.shared.storage, - nonceGenerator: NonceGenerator16ByteType = NonceGenerator16Byte(), - date: Date = Date() - ) -> Promise<[Endpoint: (OnionRequestResponseInfoType, Codable)]> { + public static func poll(_ server: String, using dependencies: Dependencies = Dependencies()) -> Promise<[Endpoint: (OnionRequestResponseInfoType, Codable)]> { // TODO: Remove comments // Capabilities // Fetch each room @@ -64,10 +58,10 @@ public final class OpenGroupAPIV2: NSObject { ) ] .appending( - storage.getAllV2OpenGroups().values + dependencies.storage.getAllV2OpenGroups().values .filter { $0.server == server.lowercased() } // Note: The `OpenGroupV2` converts the server value to lowercase during init .flatMap { openGroup -> [BatchRequestInfo] in - let lastSeqNo: Int64? = storage.getLastMessageServerID(for: openGroup.room, on: server) + let lastSeqNo: Int64? = dependencies.storage.getLastMessageServerID(for: openGroup.room, on: server) let targetSeqNo: Int64 = (lastSeqNo ?? 0) return [ @@ -93,8 +87,8 @@ public final class OpenGroupAPIV2: NSObject { } ) - // TODO: Handle response (maybe in the poller or the OpenGroupManagerV2?) - return batch(server, requests: requestResponseType, through: api, using: storage, nonceGenerator: nonceGenerator, date: date) + // TODO: Handle response (maybe in the poller or the OpenGroupManagerV2?). + return batch(server, requests: requestResponseType, using: dependencies) } /// This is used, for example, to poll multiple rooms on the same server for updates in a single query rather than needing to make multiple requests for each room. @@ -102,14 +96,7 @@ public final class OpenGroupAPIV2: NSObject { /// No guarantee is made as to the order in which sub-requests are processed; use the `/sequence` instead if you need that. /// /// For contained subrequests that specify a body (i.e. POST or PUT requests) exactly one of `json`, `b64`, or `bytes` must be provided with the request body. - private static func batch( - _ server: String, - requests: [BatchRequestInfo], - through api: OnionRequestAPIType.Type = OnionRequestAPI.self, - using storage: SessionMessagingKitStorageProtocol = SNMessagingKitConfiguration.shared.storage, - nonceGenerator: NonceGenerator16ByteType = NonceGenerator16Byte(), - date: Date = Date() - ) -> Promise<[Endpoint: (OnionRequestResponseInfoType, Codable)]> { + private static func batch(_ server: String, requests: [BatchRequestInfo], using dependencies: Dependencies = Dependencies()) -> Promise<[Endpoint: (OnionRequestResponseInfoType, Codable)]> { let requestBody: BatchRequest = requests.map { BatchSubRequest(request: $0.request) } let responseTypes = requests.map { $0.responseType } @@ -124,8 +111,8 @@ public final class OpenGroupAPIV2: NSObject { body: body ) - return send(request, through: api, using: storage, nonceGenerator: nonceGenerator, date: date) - .decoded(as: responseTypes, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + return send(request, using: dependencies) + .decoded(as: responseTypes, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) .map { result in result.enumerated() .reduce(into: [:]) { prev, next in @@ -134,11 +121,10 @@ public final class OpenGroupAPIV2: NSObject { } } - // TODO: `/sequence` request + // TODO: `/sequence` request. - public static func compactPoll(_ server: String, api: OnionRequestAPIType.Type = OnionRequestAPI.self) -> Promise { - let storage: SessionMessagingKitStorageProtocol = SNMessagingKitConfiguration.shared.storage - let rooms: [String] = storage.getAllV2OpenGroups().values + public static func compactPoll(_ server: String, using dependencies: Dependencies = Dependencies()) -> Promise { + let rooms: [String] = dependencies.storage.getAllV2OpenGroups().values .filter { $0.server == server } .map { $0.room } let useMessageLimit = (hasPerformedInitialPoll[server] != true && timeSinceLastOpen > OpenGroupPollerV2.maxInactivityPeriod) @@ -146,7 +132,7 @@ public final class OpenGroupAPIV2: NSObject { hasPerformedInitialPoll[server] = true if !hasUpdatedLastOpenDate { - UserDefaults.standard[.lastOpen] = Date() + UserDefaults.standard[.lastOpen] = dependencies.date hasUpdatedLastOpenDate = true } @@ -156,10 +142,10 @@ public final class OpenGroupAPIV2: NSObject { LegacyCompactPollBody.Room( id: roomId, fromMessageServerId: (useMessageLimit ? nil : - storage.getLastMessageServerID(for: roomId, on: server) + dependencies.storage.getLastMessageServerID(for: roomId, on: server) ), fromDeletionServerId: (useMessageLimit ? nil : - storage.getLastDeletionServerID(for: roomId, on: server) + dependencies.storage.getLastDeletionServerID(for: roomId, on: server) ), legacyAuthToken: nil ) @@ -177,8 +163,8 @@ public final class OpenGroupAPIV2: NSObject { body: body ) - return send(request, through: api) - .then(on: OpenGroupAPIV2.workQueue) { _, maybeData -> Promise in + return send(request, using: dependencies) + .then(on: OpenGroupAPI.workQueue) { _, maybeData -> Promise in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: LegacyCompactPollResponse = try data.decoded(as: LegacyCompactPollResponse.self, customError: Error.parsingFailed) @@ -187,11 +173,11 @@ public final class OpenGroupAPIV2: NSObject { fulfilled: response.results .map { (result: LegacyCompactPollResponse.Result) in legacyProcess(messages: result.messages, for: result.room, on: server) - .then(on: OpenGroupAPIV2.workQueue) { _ in + .then(on: OpenGroupAPI.workQueue) { _ in process(deletions: result.deletions, for: result.room, on: server) } } - ).then(on: OpenGroupAPIV2.workQueue) { _ in Promise.value(response) } + ).then(on: OpenGroupAPI.workQueue) { _ in Promise.value(response) } } } @@ -204,9 +190,9 @@ public final class OpenGroupAPIV2: NSObject { queryParameters: [:] // TODO: Add any requirements '.required'. ) - // TODO: Handle a `412` response (ie. a required capability isn't supported). + // TODO: Handle a `412` response (ie. a required capability isn't supported) return send(request, using: dependencies) - .decoded(as: Capabilities.self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: Capabilities.self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } // MARK: - Room @@ -218,7 +204,7 @@ public final class OpenGroupAPIV2: NSObject { ) return send(request, using: dependencies) - .decoded(as: [Room].self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: [Room].self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } public static func room(for roomToken: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, Room)> { @@ -228,7 +214,7 @@ public final class OpenGroupAPIV2: NSObject { ) return send(request, using: dependencies) - .decoded(as: Room.self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: Room.self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } public static func roomPollInfo(lastUpdated: Int64, for roomToken: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, RoomPollInfo)> { @@ -238,7 +224,7 @@ public final class OpenGroupAPIV2: NSObject { ) return send(request, using: dependencies) - .decoded(as: RoomPollInfo.self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: RoomPollInfo.self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } // MARK: - Messages @@ -262,7 +248,7 @@ public final class OpenGroupAPIV2: NSObject { signature: signedRequest.signature, whisperTo: whisperTo, whisperMods: whisperMods, - fileIds: nil // TODO: Add support for 'fileIds' + fileIds: nil // TODO: Add support for 'fileIds'. ) guard let body: Data = try? JSONEncoder().encode(requestBody) else { @@ -277,60 +263,61 @@ public final class OpenGroupAPIV2: NSObject { ) return send(request, using: dependencies) - .decoded(as: Message.self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: Message.self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } public static func recentMessages(in roomToken: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, [Message])> { + // TODO: Recent vs. Since?. let request: Request = Request( server: server, endpoint: .roomMessagesRecent(roomToken) - // TODO: Limit? + // TODO: Limit?. // queryParameters: [ // .fromServerId: storage.getLastMessageServerID(for: room, on: server).map { String($0) } // ].compactMapValues { $0 } ) return send(request, using: dependencies) - .decoded(as: [Message].self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) - .then(on: OpenGroupAPIV2.workQueue) { responseInfo, messages -> Promise<(OnionRequestResponseInfoType, [Message])> in + .decoded(as: [Message].self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) + .then(on: OpenGroupAPI.workQueue) { responseInfo, messages -> Promise<(OnionRequestResponseInfoType, [Message])> in process(messages: messages, for: roomToken, on: server, using: dependencies) .map { processedMessages in (responseInfo, processedMessages) } } } public static func messagesBefore(messageId: Int64, in roomToken: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, [Message])> { - // TODO: Recent vs. Since? + // TODO: Recent vs. Since?. let request: Request = Request( server: server, endpoint: .roomMessagesBefore(roomToken, id: messageId) - // TODO: Limit? + // TODO: Limit?. // queryParameters: [ // .fromServerId: storage.getLastMessageServerID(for: room, on: server).map { String($0) } // ].compactMapValues { $0 } ) return send(request, using: dependencies) - .decoded(as: [Message].self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) - .then(on: OpenGroupAPIV2.workQueue) { responseInfo, messages -> Promise<(OnionRequestResponseInfoType, [Message])> in + .decoded(as: [Message].self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) + .then(on: OpenGroupAPI.workQueue) { responseInfo, messages -> Promise<(OnionRequestResponseInfoType, [Message])> in process(messages: messages, for: roomToken, on: server, using: dependencies) .map { processedMessages in (responseInfo, processedMessages) } } } - public static func messagesSince(seqNo: Int64, in roomToken: String, on server: String) -> Promise<(OnionRequestResponseInfoType, [Message])> { - // TODO: Recent vs. Since? + public static func messagesSince(seqNo: Int64, in roomToken: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, [Message])> { + // TODO: Recent vs. Since?. let request: Request = Request( server: server, endpoint: .roomMessagesSince(roomToken, seqNo: seqNo) - // TODO: Limit? + // TODO: Limit?. // queryParameters: [ // .fromServerId: storage.getLastMessageServerID(for: room, on: server).map { String($0) } // ].compactMapValues { $0 } ) return send(request, using: dependencies) - .decoded(as: [Message].self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) - .then(on: OpenGroupAPIV2.workQueue) { responseInfo, messages -> Promise<(OnionRequestResponseInfoType, [Message])> in + .decoded(as: [Message].self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) + .then(on: OpenGroupAPI.workQueue) { responseInfo, messages -> Promise<(OnionRequestResponseInfoType, [Message])> in process(messages: messages, for: roomToken, on: server, using: dependencies) .map { processedMessages in (responseInfo, processedMessages) } } @@ -373,7 +360,7 @@ public final class OpenGroupAPIV2: NSObject { // MARK: - Files - // TODO: Shift this logic to the `OpenGroupManager` (makes more sense since it's not API logic) + // TODO: Shift this logic to the `OpenGroupManager` (makes more sense since it's not API logic). public static func roomImage(_ fileId: Int64, for roomToken: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise { // Normally the image for a given group is stored with the group thread, so it's only // fetched once. However, on the join open group screen we show images for groups the @@ -399,7 +386,7 @@ public final class OpenGroupAPIV2: NSObject { let promise: Promise = downloadFile(fileId, from: roomToken, on: server, using: dependencies) .map { _, data in data } - _ = promise.done(on: OpenGroupAPIV2.workQueue) { imageData in + _ = promise.done(on: OpenGroupAPI.workQueue) { imageData in if server == defaultServer { dependencies.storage.write { transaction in dependencies.storage.setOpenGroupImage(to: imageData, for: roomToken, on: server, using: transaction) @@ -422,7 +409,7 @@ public final class OpenGroupAPIV2: NSObject { ) return send(request, using: dependencies) - .decoded(as: FileUploadResponse.self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: FileUploadResponse.self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } /// Warning: This approach is less efficient as it expects the data to be base64Encoded (with is 33% larger than binary), please use the binary approach @@ -437,7 +424,7 @@ public final class OpenGroupAPIV2: NSObject { ) return send(request, using: dependencies) - .decoded(as: FileUploadResponse.self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: FileUploadResponse.self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } public static func downloadFile(_ fileId: Int64, from roomToken: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, Data)> { @@ -459,9 +446,57 @@ public final class OpenGroupAPIV2: NSObject { server: server, endpoint: .roomFileIndividualJson(roomToken, fileId) ) - // TODO: This endpoint is getting rewritten to return just data (properties would come through as headers) + // TODO: This endpoint is getting rewritten to return just data (properties would come through as headers). return send(request, using: dependencies) - .decoded(as: FileDownloadResponse.self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: FileDownloadResponse.self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) + } + + // MARK: - Inbox (Message Requests) + + public static func messageRequests(on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, [DirectMessage])> { + let request: Request = Request( + server: server, + endpoint: .inbox + ) + + return send(request, using: dependencies) + .decoded(as: [DirectMessage].self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) + } + + public static func messageRequestsSince(id: Int64, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, [DirectMessage])> { + let request: Request = Request( + server: server, + endpoint: .inboxSince(id: id) + ) + + return send(request, using: dependencies) + .decoded(as: [DirectMessage].self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) + } + + public static func sendMessageRequest(_ plaintext: Data, to sessionId: String, on server: String, with serverPublicKey: String, using dependencies: Dependencies = Dependencies()) -> Promise<(OnionRequestResponseInfoType, [DirectMessage])> { + // TODO: Change this to use '.blinded' once it's working + guard let signedRequest: (data: Data, signature: Data) = SendMessageRequest.sign(message: plaintext, for: .standard, with: serverPublicKey) else { + return Promise(error: Error.signingFailed) + } + + let requestBody: SendDirectMessageRequest = SendDirectMessageRequest( + data: signedRequest.data, + signature: signedRequest.signature + ) + + guard let body: Data = try? JSONEncoder().encode(requestBody) else { + return Promise(error: Error.parsingFailed) + } + + let request: Request = Request( + method: .post, + server: server, + endpoint: .inboxFor(sessionId: sessionId), + body: body + ) + + return send(request, using: dependencies) + .decoded(as: [DirectMessage].self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } // MARK: - Users @@ -571,11 +606,11 @@ public final class OpenGroupAPIV2: NSObject { ) return send(request, using: dependencies) - .decoded(as: UserDeleteMessagesResponse.self, on: OpenGroupAPIV2.workQueue, error: Error.parsingFailed) + .decoded(as: UserDeleteMessagesResponse.self, on: OpenGroupAPI.workQueue, error: Error.parsingFailed) } // MARK: - Processing - // TODO: Move these methods to the OpenGroupManager? (seems odd for them to be in the API) + // TODO: Move these methods to the OpenGroupManager? (seems odd for them to be in the API). private static func process(messages: [Message]?, for room: String, on server: String, using dependencies: Dependencies = Dependencies()) -> Promise<[Message]> { guard let messages: [Message] = messages, !messages.isEmpty else { return Promise.value([]) } @@ -631,7 +666,7 @@ public final class OpenGroupAPIV2: NSObject { // MARK: - General - // TODO: Shift this to the OpenGroupManagerV2? (seems more at place there than in the API) + // TODO: Shift this to the OpenGroupManagerV2? (seems more at place there than in the API). public static func getDefaultRoomsIfNeeded(using dependencies: Dependencies = Dependencies()) { Storage.shared.write( with: { transaction in @@ -639,10 +674,10 @@ public final class OpenGroupAPIV2: NSObject { }, completion: { let promise = attempt(maxRetryCount: 8, recoveringOn: DispatchQueue.main) { - OpenGroupAPIV2.rooms(for: defaultServer, using: dependencies) + OpenGroupAPI.rooms(for: defaultServer, using: dependencies) .map { _, data in data } } - _ = promise.done(on: OpenGroupAPIV2.workQueue) { items in + _ = promise.done(on: OpenGroupAPI.workQueue) { items in items .compactMap { room -> (Int64, String)? in guard let imageId: Int64 = room.imageId else { return nil} @@ -654,8 +689,8 @@ public final class OpenGroupAPIV2: NSObject { .retainUntilComplete() } } - promise.catch(on: OpenGroupAPIV2.workQueue) { _ in - OpenGroupAPIV2.defaultRoomsPromise = nil + promise.catch(on: OpenGroupAPI.workQueue) { _ in + OpenGroupAPI.defaultRoomsPromise = nil } defaultRoomsPromise = promise } @@ -681,7 +716,7 @@ public final class OpenGroupAPIV2: NSObject { // guard let blindedKeyPair: ECKeyPair = try? userKeyPair.convert(to: .blinded, with: publicKey) else { // return nil // } - // TODO: Change this back once you figure out why it's busted + // TODO: Change this back once you figure out why it's busted. let blindedKeyPair: ECKeyPair = userKeyPair /// Generate the sharedSecret by "aB || A || B" where @@ -703,8 +738,10 @@ public final class OpenGroupAPIV2: NSObject { let secretHashMessage: Bytes = method.bytes .appending(path.bytes) .appending("\(timestamp)".bytes) - .appending(request.httpBody?.bytes ?? []) // TODO: Might need to do the 'httpBodyStream' as well??? - + .appending(request.httpBody?.bytes ?? []) // TODO: Might need to do the 'httpBodyStream' as well???. + print("RAWR 1 \(blindedKeyPair.hexEncodedPublicKey)") + print("RAWR 2 \(maybeSharedSecret?.hexadecimalString)") + print("RAWR '\(String(describing: String(data: Data(secretHashMessage), encoding: .utf8)))'") guard let sharedSecret: Data = maybeSharedSecret else { return nil } guard let intermediateHash: Bytes = dependencies.genericHash.hashSaltPersonal(message: sharedSecret.bytes, outputLength: 42, key: nil, salt: nonce.bytes, personal: Personalization.sharedKeys.bytes) else { return nil @@ -712,7 +749,8 @@ public final class OpenGroupAPIV2: NSObject { guard let secretHash: Bytes = dependencies.genericHash.hashSaltPersonal(message: secretHashMessage, outputLength: 42, key: intermediateHash, salt: nonce.bytes, personal: Personalization.authHeader.bytes) else { return nil } - + print("RAWR3 '\(intermediateHash.toHexString())'") // This is the one we can compare + print("RAWR4 '\(secretHash.toHexString())'") updatedRequest.allHTTPHeaderFields = (request.allHTTPHeaderFields ?? [:]) .updated(with: [ Header.sogsPubKey.rawValue: blindedKeyPair.hexEncodedPublicKey, @@ -747,7 +785,7 @@ public final class OpenGroupAPIV2: NSObject { return Promise(error: Error.signingFailed) } - // TODO: 'removeAuthToken' as a migration??? (would previously do this when getting a `401`). + // TODO: 'removeAuthToken' as a migration??? (would previously do this when getting a `401`) return dependencies.api.sendOnionRequest(signedRequest, to: request.server, with: publicKey) } @@ -779,8 +817,8 @@ public final class OpenGroupAPIV2: NSObject { } let promise: Promise = legacyRequestNewAuthToken(for: room, on: server) - .then(on: OpenGroupAPIV2.workQueue) { legacyClaimAuthToken($0, for: room, on: server) } - .then(on: OpenGroupAPIV2.workQueue) { authToken -> Promise in + .then(on: OpenGroupAPI.workQueue) { legacyClaimAuthToken($0, for: room, on: server) } + .then(on: OpenGroupAPI.workQueue) { authToken -> Promise in let (promise, seal) = Promise.pending() storage.write(with: { transaction in storage.setAuthToken(for: room, on: server, to: authToken, using: transaction) @@ -791,10 +829,10 @@ public final class OpenGroupAPIV2: NSObject { } promise - .done(on: OpenGroupAPIV2.workQueue) { _ in + .done(on: OpenGroupAPI.workQueue) { _ in authTokenPromises.wrappedValue["\(server).\(room)"] = nil } - .catch(on: OpenGroupAPIV2.workQueue) { _ in + .catch(on: OpenGroupAPI.workQueue) { _ in authTokenPromises.wrappedValue["\(server).\(room)"] = nil } @@ -819,7 +857,7 @@ public final class OpenGroupAPIV2: NSObject { isAuthRequired: false ) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let response = try data.decoded(as: AuthTokenResponse.self, customError: Error.parsingFailed) let symmetricKey = try AESGCM.generateSymmetricKey(x25519PublicKey: response.challenge.ephemeralPublicKey, x25519PrivateKey: userKeyPair.privateKey) @@ -853,7 +891,7 @@ public final class OpenGroupAPIV2: NSObject { isAuthRequired: false ) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _ in authToken } + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _ in authToken } } /// Should be called when leaving a group. @@ -866,7 +904,7 @@ public final class OpenGroupAPIV2: NSObject { endpoint: .legacyAuthToken(legacyAuth: true) ) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _ in + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _ in let storage = SNMessagingKitConfiguration.shared.storage storage.write { transaction in @@ -914,7 +952,7 @@ public final class OpenGroupAPIV2: NSObject { ) return when(fulfilled: [Promise](getAuthTokenPromises.values)) - .then(on: OpenGroupAPIV2.workQueue) { _ -> Promise in + .then(on: OpenGroupAPI.workQueue) { _ -> Promise in let requestBodyWithAuthTokens: LegacyCompactPollBody = LegacyCompactPollBody( requests: requestBody.requests.compactMap { oldRoom -> LegacyCompactPollBody.Room? in guard let authToken: String = getAuthTokenPromises[oldRoom.id]?.value else { return nil } @@ -941,7 +979,7 @@ public final class OpenGroupAPIV2: NSObject { ) return legacySend(request) - .then(on: OpenGroupAPIV2.workQueue) { _, maybeData -> Promise in + .then(on: OpenGroupAPI.workQueue) { _, maybeData -> Promise in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: LegacyCompactPollResponse = try data.decoded(as: LegacyCompactPollResponse.self, customError: Error.parsingFailed) @@ -962,11 +1000,11 @@ public final class OpenGroupAPIV2: NSObject { } return legacyProcess(messages: result.messages, for: result.room, on: server) - .then(on: OpenGroupAPIV2.workQueue) { _ -> Promise<[Deletion]> in + .then(on: OpenGroupAPI.workQueue) { _ -> Promise<[Deletion]> in legacyProcess(deletions: result.deletions, for: result.room, on: server) } } - ).then(on: OpenGroupAPIV2.workQueue) { _ in Promise.value(response) } + ).then(on: OpenGroupAPI.workQueue) { _ in Promise.value(response) } } } } @@ -979,13 +1017,13 @@ public final class OpenGroupAPIV2: NSObject { }, completion: { let promise = attempt(maxRetryCount: 8, recoveringOn: DispatchQueue.main) { - OpenGroupAPIV2.legacyGetAllRooms(from: defaultServer) + OpenGroupAPI.legacyGetAllRooms(from: defaultServer) } - _ = promise.done(on: OpenGroupAPIV2.workQueue) { items in + _ = promise.done(on: OpenGroupAPI.workQueue) { items in items.forEach { legacyGetGroupImage(for: $0.id, on: defaultServer).retainUntilComplete() } } - promise.catch(on: OpenGroupAPIV2.workQueue) { _ in - OpenGroupAPIV2.defaultRoomsPromise = nil + promise.catch(on: OpenGroupAPI.workQueue) { _ in + OpenGroupAPI.defaultRoomsPromise = nil } legacyDefaultRoomsPromise = promise } @@ -1001,7 +1039,7 @@ public final class OpenGroupAPIV2: NSObject { ) return legacySend(request) - .map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + .map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: LegacyRoomsResponse = try data.decoded(as: LegacyRoomsResponse.self, customError: Error.parsingFailed) @@ -1019,7 +1057,7 @@ public final class OpenGroupAPIV2: NSObject { ) return legacySend(request) - .map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + .map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: LegacyGetInfoResponse = try data.decoded(as: LegacyGetInfoResponse.self, customError: Error.parsingFailed) @@ -1058,7 +1096,7 @@ public final class OpenGroupAPIV2: NSObject { isAuthRequired: false ) - let promise: Promise = legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + let promise: Promise = legacySend(request).map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: LegacyFileDownloadResponse = try data.decoded(as: LegacyFileDownloadResponse.self, customError: Error.parsingFailed) @@ -1085,7 +1123,7 @@ public final class OpenGroupAPIV2: NSObject { ) return legacySend(request) - .map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + .map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: MemberCountResponse = try data.decoded(as: MemberCountResponse.self, customError: Error.parsingFailed) @@ -1110,7 +1148,7 @@ public final class OpenGroupAPIV2: NSObject { let request = Request(method: .post, server: server, room: room, endpoint: .legacyFiles, body: body) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: LegacyFileUploadResponse = try data.decoded(as: LegacyFileUploadResponse.self, customError: Error.parsingFailed) @@ -1122,7 +1160,7 @@ public final class OpenGroupAPIV2: NSObject { public static func legacyDownload(_ file: UInt64, from room: String, on server: String) -> Promise { let request = Request(server: server, room: room, endpoint: .legacyFile(file)) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: LegacyFileDownloadResponse = try data.decoded(as: LegacyFileDownloadResponse.self, customError: Error.parsingFailed) @@ -1140,7 +1178,7 @@ public final class OpenGroupAPIV2: NSObject { } let request = Request(method: .post, server: server, room: room, endpoint: .legacyMessages, body: body) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let message: OpenGroupMessageV2 = try data.decoded(as: OpenGroupMessageV2.self, customError: Error.parsingFailed) Storage.shared.write { transaction in @@ -1162,7 +1200,7 @@ public final class OpenGroupAPIV2: NSObject { ].compactMapValues { $0 } ) - return legacySend(request).then(on: OpenGroupAPIV2.workQueue) { _, maybeData -> Promise<[OpenGroupMessageV2]> in + return legacySend(request).then(on: OpenGroupAPI.workQueue) { _, maybeData -> Promise<[OpenGroupMessageV2]> in guard let data: Data = maybeData else { throw Error.parsingFailed } let messages: [OpenGroupMessageV2] = try data.decoded(as: [OpenGroupMessageV2].self, customError: Error.parsingFailed) @@ -1172,7 +1210,7 @@ public final class OpenGroupAPIV2: NSObject { // MARK: - Legacy Message Deletion - // TODO: No delete method???? + // TODO: No delete method????. @available(*, deprecated, message: "Use v4 endpoint instead") public static func legacyDeleteMessage(with serverID: Int64, from room: String, on server: String) -> Promise { let request: Request = Request( @@ -1182,7 +1220,7 @@ public final class OpenGroupAPIV2: NSObject { endpoint: .legacyMessagesForServer(serverID) ) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _ in } + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _ in } } @available(*, deprecated, message: "Use v4 endpoint instead") @@ -1198,7 +1236,7 @@ public final class OpenGroupAPIV2: NSObject { ].compactMapValues { $0 } ) - return legacySend(request).then(on: OpenGroupAPIV2.workQueue) { _, maybeData -> Promise<[Deletion]> in + return legacySend(request).then(on: OpenGroupAPI.workQueue) { _, maybeData -> Promise<[Deletion]> in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: DeletedMessagesResponse = try data.decoded(as: DeletedMessagesResponse.self, customError: Error.parsingFailed) @@ -1217,7 +1255,7 @@ public final class OpenGroupAPIV2: NSObject { ) return legacySend(request) - .map(on: OpenGroupAPIV2.workQueue) { _, maybeData in + .map(on: OpenGroupAPI.workQueue) { _, maybeData in guard let data: Data = maybeData else { throw Error.parsingFailed } let response: ModeratorsResponse = try data.decoded(as: ModeratorsResponse.self, customError: Error.parsingFailed) @@ -1249,7 +1287,7 @@ public final class OpenGroupAPIV2: NSObject { body: body ) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _ in } + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _ in } } @available(*, deprecated, message: "Use v4 endpoint instead") @@ -1268,7 +1306,7 @@ public final class OpenGroupAPIV2: NSObject { body: body ) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _ in } + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _ in } } @available(*, deprecated, message: "Use v4 endpoint instead") @@ -1280,7 +1318,7 @@ public final class OpenGroupAPIV2: NSObject { endpoint: .legacyBlockListIndividual(publicKey) ) - return legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _ in } + return legacySend(request).map(on: OpenGroupAPI.workQueue) { _ in } } // MARK: - Processing @@ -1364,11 +1402,11 @@ public final class OpenGroupAPIV2: NSObject { } return legacyGetAuthToken(for: room, on: request.server) - .then(on: OpenGroupAPIV2.workQueue) { authToken -> Promise<(OnionRequestResponseInfoType, Data?)> in + .then(on: OpenGroupAPI.workQueue) { authToken -> Promise<(OnionRequestResponseInfoType, Data?)> in urlRequest.setValue(authToken, forHTTPHeaderField: Header.authorization.rawValue) let promise = api.sendOnionRequest(urlRequest, to: request.server, using: .v3, with: publicKey) - promise.catch(on: OpenGroupAPIV2.workQueue) { error in + promise.catch(on: OpenGroupAPI.workQueue) { error in // A 401 means that we didn't provide a (valid) auth token for a route // that required one. We use this as an indication that the token we're // using has expired. Note that a 403 has a different meaning; it means diff --git a/SessionMessagingKit/Open Groups/OpenGroupManagerV2.swift b/SessionMessagingKit/Open Groups/OpenGroupManagerV2.swift index c29191ae1..3f6e42bbd 100644 --- a/SessionMessagingKit/Open Groups/OpenGroupManagerV2.swift +++ b/SessionMessagingKit/Open Groups/OpenGroupManagerV2.swift @@ -42,7 +42,7 @@ public final class OpenGroupManagerV2 : NSObject { transaction.addCompletionQueue(DispatchQueue.global(qos: .userInitiated)) { // Get the group info // TODO: Remove this legacy method -// OpenGroupAPIV2.legacyGetRoomInfo(for: room, on: server).done(on: DispatchQueue.global(qos: .userInitiated)) { info in +// OpenGroupAPI.legacyGetRoomInfo(for: room, on: server).done(on: DispatchQueue.global(qos: .userInitiated)) { info in // // Create the open group model and the thread // let openGroup = OpenGroupV2(server: server, room: room, name: info.name, publicKey: publicKey, imageID: info.imageID) // let groupID = LKGroupUtilities.getEncodedOpenGroupIDAsData(openGroup.id) @@ -62,7 +62,7 @@ public final class OpenGroupManagerV2 : NSObject { // OpenGroupManagerV2.shared.pollers[server] = poller // } // // Fetch the group image -// OpenGroupAPIV2.legacyGetGroupImage(for: room, on: server).done(on: DispatchQueue.global(qos: .userInitiated)) { data in +// OpenGroupAPI.legacyGetGroupImage(for: room, on: server).done(on: DispatchQueue.global(qos: .userInitiated)) { data in // storage.write { transaction in // // Update the thread // let transaction = transaction as! YapDatabaseReadWriteTransaction @@ -78,7 +78,7 @@ public final class OpenGroupManagerV2 : NSObject { // seal.reject(error) // } - OpenGroupAPIV2.room(for: room, on: server) + OpenGroupAPI.room(for: room, on: server) .done(on: DispatchQueue.global(qos: .userInitiated)) { _, room in // Create the open group model and the thread let openGroup: OpenGroupV2 = OpenGroupV2( @@ -120,7 +120,7 @@ public final class OpenGroupManagerV2 : NSObject { // TODO: Need to test this // TODO: Clean this up (can we avoid the if/else with fancy promise wrangling?) if let imageId: Int64 = room.imageId { - OpenGroupAPIV2.roomImage(imageId, for: room.token, on: server) + OpenGroupAPI.roomImage(imageId, for: room.token, on: server) .done(on: DispatchQueue.global(qos: .userInitiated)) { data in storage.write { transaction in // Update the thread @@ -176,7 +176,7 @@ public final class OpenGroupManagerV2 : NSObject { Storage.shared.removeReceivedMessageTimestamps(messageTimestamps, using: transaction) Storage.shared.removeLastMessageServerID(for: openGroup.room, on: openGroup.server, using: transaction) Storage.shared.removeLastDeletionServerID(for: openGroup.room, on: openGroup.server, using: transaction) - let _ = OpenGroupAPIV2.legacyDeleteAuthToken(for: openGroup.room, on: openGroup.server) + let _ = OpenGroupAPI.legacyDeleteAuthToken(for: openGroup.room, on: openGroup.server) thread.removeAllThreadInteractions(with: transaction) thread.remove(with: transaction) Storage.shared.removeV2OpenGroup(for: thread.uniqueId!, using: transaction) diff --git a/SessionMessagingKit/Open Groups/Types/Dependencies.swift b/SessionMessagingKit/Open Groups/Types/Dependencies.swift index 58d4e4fc0..ba2a9ceff 100644 --- a/SessionMessagingKit/Open Groups/Types/Dependencies.swift +++ b/SessionMessagingKit/Open Groups/Types/Dependencies.swift @@ -4,7 +4,7 @@ import Foundation import Sodium import SessionSnodeKit -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public struct Dependencies { let api: OnionRequestAPIType.Type let storage: SessionMessagingKitStorageProtocol diff --git a/SessionMessagingKit/Open Groups/Types/Endpoint.swift b/SessionMessagingKit/Open Groups/Types/Endpoint.swift index 7d8514571..5cdc19785 100644 --- a/SessionMessagingKit/Open Groups/Types/Endpoint.swift +++ b/SessionMessagingKit/Open Groups/Types/Endpoint.swift @@ -2,196 +2,210 @@ import Foundation -public enum Endpoint: Hashable { - // Utility +extension OpenGroupAPI { + public enum Endpoint: Hashable { + // Utility + + case onion + case batch + case sequence + case capabilities + + // Rooms + + case rooms + case room(String) + case roomPollInfo(String, Int64) + + // Messages + + case roomMessage(String) + case roomMessageIndividual(String, String) + case roomMessagesRecent(String) + case roomMessagesBefore(String, id: Int64) + case roomMessagesSince(String, seqNo: Int64) + + // Pinning + + case roomPinMessage(String, id: Int64) + case roomUnpinMessage(String, id: Int64) + case roomUnpinAll(String) + + // Files + + case roomFile(String) + case roomFileJson(String) + case roomFileIndividual(String, Int64) + case roomFileIndividualJson(String, Int64) + + // Inbox (Message Requests) + + case inbox + case inboxSince(id: Int64) + case inboxFor(sessionId: String) + + // Users + + case userBan(String) + case userUnban(String) + case userPermission(String) + case userModerator(String) + case userDeleteMessages(String) + + // Legacy endpoints (to be deprecated and removed) + + @available(*, deprecated, message: "Use v4 endpoint") case legacyFiles + @available(*, deprecated, message: "Use v4 endpoint") case legacyFile(UInt64) + + @available(*, deprecated, message: "Use v4 endpoint") case legacyMessages + @available(*, deprecated, message: "Use v4 endpoint") case legacyMessagesForServer(Int64) + @available(*, deprecated, message: "Use v4 endpoint") case legacyDeletedMessages + + @available(*, deprecated, message: "Use v4 endpoint") case legacyModerators + + @available(*, deprecated, message: "Use v4 endpoint") case legacyBlockList + @available(*, deprecated, message: "Use v4 endpoint") case legacyBlockListIndividual(String) + @available(*, deprecated, message: "Use v4 endpoint") case legacyBanAndDeleteAll + + @available(*, deprecated, message: "Use v4 endpoint") case legacyCompactPoll(legacyAuth: Bool) + @available(*, deprecated, message: "Use request signing") case legacyAuthToken(legacyAuth: Bool) + @available(*, deprecated, message: "Use request signing") case legacyAuthTokenChallenge(legacyAuth: Bool) + @available(*, deprecated, message: "Use request signing") case legacyAuthTokenClaim(legacyAuth: Bool) + + @available(*, deprecated, message: "Use v4 endpoint") case legacyRooms + @available(*, deprecated, message: "Use v4 endpoint") case legacyRoomInfo(String) + @available(*, deprecated, message: "Use v4 endpoint") case legacyRoomImage(String) + @available(*, deprecated, message: "Use v4 endpoint") case legacyMemberCount(legacyAuth: Bool) + + var path: String { + switch self { + // Utility + + case .onion: return "oxen/v4/lsrpc" + case .batch: return "batch" + case .sequence: return "sequence" + case .capabilities: return "capabilities" + + // Rooms + + case .rooms: return "rooms" + case .room(let roomToken): return "room/\(roomToken)" + case .roomPollInfo(let roomToken, let infoUpdated): return "room/\(roomToken)/pollInfo/\(infoUpdated)" + + // Messages + + case .roomMessage(let roomToken): + return "room/\(roomToken)/message" + + case .roomMessageIndividual(let roomToken, let messageId): + return "room/\(roomToken)/message/\(messageId)" + + case .roomMessagesRecent(let roomToken): + return "room/\(roomToken)/messages/recent" + + case .roomMessagesBefore(let roomToken, let messageId): + return "room/\(roomToken)/messages/before/\(messageId)" + + case .roomMessagesSince(let roomToken, let seqNo): + return "room/\(roomToken)/messages/since/\(seqNo)" + + // Pinning + + case .roomPinMessage(let roomToken, let messageId): + return "room/\(roomToken)/pin/\(messageId)" + + case .roomUnpinMessage(let roomToken, let messageId): + return "room/\(roomToken)/unpin/\(messageId)" + + case .roomUnpinAll(let roomToken): + return "room/\(roomToken)/unpin/all" + + // Files + + case .roomFile(let roomToken): return "room/\(roomToken)/file" + case .roomFileJson(let roomToken): return "room/\(roomToken)/fileJSON" + case .roomFileIndividual(let roomToken, let fileId): + // Note: The 'fileName' value is ignored by the server and is only used to distinguish + // this from the 'Json' variant + let fileName: String = "" + return "room/\(roomToken)/file/\(fileId)/\(fileName)" + + case .roomFileIndividualJson(let roomToken, let fileId): + return "room/\(roomToken)/file/\(fileId)" + + // Inbox (Message Requests) - case onion - case batch - case sequence - case capabilities - - // Rooms - - case rooms - case room(String) - case roomPollInfo(String, Int64) - - // Messages - - case roomMessage(String) - case roomMessageIndividual(String, String) - case roomMessagesRecent(String) - case roomMessagesBefore(String, id: Int64) - case roomMessagesSince(String, seqNo: Int64) - - // Pinning - - case roomPinMessage(String, id: Int64) - case roomUnpinMessage(String, id: Int64) - case roomUnpinAll(String) - - // Files - - case roomFile(String) - case roomFileJson(String) - case roomFileIndividual(String, Int64) - case roomFileIndividualJson(String, Int64) - - // Users - - case userBan(String) - case userUnban(String) - case userPermission(String) - case userModerator(String) - case userDeleteMessages(String) - - // Legacy endpoints (to be deprecated and removed) - - @available(*, deprecated, message: "Use v4 endpoint") case legacyFiles - @available(*, deprecated, message: "Use v4 endpoint") case legacyFile(UInt64) - - @available(*, deprecated, message: "Use v4 endpoint") case legacyMessages - @available(*, deprecated, message: "Use v4 endpoint") case legacyMessagesForServer(Int64) - @available(*, deprecated, message: "Use v4 endpoint") case legacyDeletedMessages - - @available(*, deprecated, message: "Use v4 endpoint") case legacyModerators - - @available(*, deprecated, message: "Use v4 endpoint") case legacyBlockList - @available(*, deprecated, message: "Use v4 endpoint") case legacyBlockListIndividual(String) - @available(*, deprecated, message: "Use v4 endpoint") case legacyBanAndDeleteAll - - @available(*, deprecated, message: "Use v4 endpoint") case legacyCompactPoll(legacyAuth: Bool) - @available(*, deprecated, message: "Use request signing") case legacyAuthToken(legacyAuth: Bool) - @available(*, deprecated, message: "Use request signing") case legacyAuthTokenChallenge(legacyAuth: Bool) - @available(*, deprecated, message: "Use request signing") case legacyAuthTokenClaim(legacyAuth: Bool) - - @available(*, deprecated, message: "Use v4 endpoint") case legacyRooms - @available(*, deprecated, message: "Use v4 endpoint") case legacyRoomInfo(String) - @available(*, deprecated, message: "Use v4 endpoint") case legacyRoomImage(String) - @available(*, deprecated, message: "Use v4 endpoint") case legacyMemberCount(legacyAuth: Bool) - - var path: String { - switch self { - // Utility - - case .onion: return "oxen/v4/lsrpc" - case .batch: return "batch" - case .sequence: return "sequence" - case .capabilities: return "capabilities" + case .inbox: return "inbox" + case .inboxSince(let id): return "inbox/\(id)" + case .inboxFor(let sessionId): return "inbox/\(sessionId)" - // Rooms + // Users - case .rooms: return "rooms" - case .room(let roomToken): return "room/\(roomToken)" - case .roomPollInfo(let roomToken, let infoUpdated): return "room/\(roomToken)/pollInfo/\(infoUpdated)" + case .userBan(let sessionId): return "user/\(sessionId)/ban" + case .userUnban(let sessionId): return "user/\(sessionId)/unban" + case .userPermission(let sessionId): return "user/\(sessionId)/permission" + case .userModerator(let sessionId): return "user/\(sessionId)/moderator" + case .userDeleteMessages(let sessionId): return "user/\(sessionId)/deleteMessages" - // Messages - - case .roomMessage(let roomToken): - return "room/\(roomToken)/message" + // Legacy endpoints (to be deprecated and removed) + // TODO: Look for a nicer way to prepend 'legacy'? (OnionRequestAPI messes with this but the new auth needs it to be correct...) + + + case .legacyFiles: return "legacy/files" + case .legacyFile(let fileId): return "legacy/files/\(fileId)" - case .roomMessageIndividual(let roomToken, let messageId): - return "room/\(roomToken)/message/\(messageId)" - - case .roomMessagesRecent(let roomToken): - return "room/\(roomToken)/messages/recent" + case .legacyMessages: return "legacy/messages" + case .legacyMessagesForServer(let serverId): return "legacy/messages/\(serverId)" + case .legacyDeletedMessages: return "legacy/deleted_messages" + + case .legacyModerators: return "legacy/moderators" + + case .legacyBlockList: return "legacy/block_list" + case .legacyBlockListIndividual(let publicKey): return "legacy/block_list/\(publicKey)" + case .legacyBanAndDeleteAll: return "legacy/ban_and_delete_all" - case .roomMessagesBefore(let roomToken, let messageId): - return "room/\(roomToken)/messages/before/\(messageId)" - - case .roomMessagesSince(let roomToken, let seqNo): - return "room/\(roomToken)/messages/since/\(seqNo)" - - // Pinning - - case .roomPinMessage(let roomToken, let messageId): - return "room/\(roomToken)/pin/\(messageId)" - - case .roomUnpinMessage(let roomToken, let messageId): - return "room/\(roomToken)/unpin/\(messageId)" - - case .roomUnpinAll(let roomToken): - return "room/\(roomToken)/unpin/all" - - // Files - - case .roomFile(let roomToken): return "room/\(roomToken)/file" - case .roomFileJson(let roomToken): return "room/\(roomToken)/fileJSON" - case .roomFileIndividual(let roomToken, let fileId): - // Note: The 'fileName' value is ignored by the server and is only used to distinguish - // this from the 'Json' variant - let fileName: String = "" - return "room/\(roomToken)/file/\(fileId)/\(fileName)" - - case .roomFileIndividualJson(let roomToken, let fileId): - return "room/\(roomToken)/file/\(fileId)" - - // Users - - case .userBan(let sessionId): return "user/\(sessionId)/ban" - case .userUnban(let sessionId): return "user/\(sessionId)/unban" - case .userPermission(let sessionId): return "user/\(sessionId)/permission" - case .userModerator(let sessionId): return "user/\(sessionId)/moderator" - case .userDeleteMessages(let sessionId): return "user/\(sessionId)/deleteMessages" - - // Legacy endpoints (to be deprecated and removed) - // TODO: Look for a nicer way to prepend 'legacy'? (OnionRequestAPI messes with this but the new auth needs it to be correct... ) - - - case .legacyFiles: return "legacy/files" - case .legacyFile(let fileId): return "legacy/files/\(fileId)" - - case .legacyMessages: return "legacy/messages" - case .legacyMessagesForServer(let serverId): return "legacy/messages/\(serverId)" - case .legacyDeletedMessages: return "legacy/deleted_messages" - - case .legacyModerators: return "legacy/moderators" - - case .legacyBlockList: return "legacy/block_list" - case .legacyBlockListIndividual(let publicKey): return "legacy/block_list/\(publicKey)" - case .legacyBanAndDeleteAll: return "legacy/ban_and_delete_all" - - case .legacyCompactPoll(let useLegacyAuth): - return "\(useLegacyAuth ? "" : "legacy/")compact_poll" - - case .legacyAuthToken(let useLegacyAuth): - return "\(useLegacyAuth ? "" : "legacy/")auth_token" - - case .legacyAuthTokenChallenge(let useLegacyAuth): - return "\(useLegacyAuth ? "" : "legacy/")auth_token_challenge" - - case .legacyAuthTokenClaim(let useLegacyAuth): - return "\(useLegacyAuth ? "" : "legacy/")claim_auth_token" - - case .legacyRooms: return "legacy/rooms" - case .legacyRoomInfo(let roomName): return "legacy/rooms/\(roomName)" - case .legacyRoomImage(let roomName): return "legacy/rooms/\(roomName)/image" - - case .legacyMemberCount(let useLegacyAuth): - return "\(useLegacyAuth ? "" : "legacy/")member_count" + case .legacyCompactPoll(let useLegacyAuth): + return "\(useLegacyAuth ? "" : "legacy/")compact_poll" + + case .legacyAuthToken(let useLegacyAuth): + return "\(useLegacyAuth ? "" : "legacy/")auth_token" + + case .legacyAuthTokenChallenge(let useLegacyAuth): + return "\(useLegacyAuth ? "" : "legacy/")auth_token_challenge" + + case .legacyAuthTokenClaim(let useLegacyAuth): + return "\(useLegacyAuth ? "" : "legacy/")claim_auth_token" + + case .legacyRooms: return "legacy/rooms" + case .legacyRoomInfo(let roomName): return "legacy/rooms/\(roomName)" + case .legacyRoomImage(let roomName): return "legacy/rooms/\(roomName)/image" + + case .legacyMemberCount(let useLegacyAuth): + return "\(useLegacyAuth ? "" : "legacy/")member_count" + } } - } - - var useLegacyAuth: Bool { - switch self { - // File upload/download should use legacy auth - case .legacyFiles, .legacyFile, .legacyMessages, - .legacyMessagesForServer, .legacyDeletedMessages, - .legacyModerators, .legacyBlockList, - .legacyBlockListIndividual, .legacyBanAndDeleteAll: - return true + + var useLegacyAuth: Bool { + switch self { + // File upload/download should use legacy auth + case .legacyFiles, .legacyFile, .legacyMessages, + .legacyMessagesForServer, .legacyDeletedMessages, + .legacyModerators, .legacyBlockList, + .legacyBlockListIndividual, .legacyBanAndDeleteAll: + return true + + case .legacyCompactPoll(let useLegacyAuth), + .legacyAuthToken(let useLegacyAuth), + .legacyAuthTokenChallenge(let useLegacyAuth), + .legacyAuthTokenClaim(let useLegacyAuth), + .legacyMemberCount(let useLegacyAuth): + return useLegacyAuth + + case .legacyRooms, .legacyRoomInfo, .legacyRoomImage: + return true - case .legacyCompactPoll(let useLegacyAuth), - .legacyAuthToken(let useLegacyAuth), - .legacyAuthTokenChallenge(let useLegacyAuth), - .legacyAuthTokenClaim(let useLegacyAuth), - .legacyMemberCount(let useLegacyAuth): - return useLegacyAuth - - case .legacyRooms, .legacyRoomInfo, .legacyRoomImage: - return true - - default: return false + default: return false + } } } } diff --git a/SessionMessagingKit/Open Groups/Types/Error.swift b/SessionMessagingKit/Open Groups/Types/Error.swift index 52610469f..87eb8b255 100644 --- a/SessionMessagingKit/Open Groups/Types/Error.swift +++ b/SessionMessagingKit/Open Groups/Types/Error.swift @@ -2,7 +2,7 @@ import Foundation -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public enum Error: LocalizedError { case generic case parsingFailed diff --git a/SessionMessagingKit/Open Groups/Types/NonceGenerator16Byte.swift b/SessionMessagingKit/Open Groups/Types/NonceGenerator16Byte.swift index b4c5cb2e1..e8e1626ad 100644 --- a/SessionMessagingKit/Open Groups/Types/NonceGenerator16Byte.swift +++ b/SessionMessagingKit/Open Groups/Types/NonceGenerator16Byte.swift @@ -10,7 +10,7 @@ extension NonceGenerator16ByteType { } -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public class NonceGenerator16Byte: NonceGenerator, NonceGenerator16ByteType { public var NonceBytes: Int { 16 } diff --git a/SessionMessagingKit/Open Groups/Types/Personalization.swift b/SessionMessagingKit/Open Groups/Types/Personalization.swift index 44235af0d..e1285c212 100644 --- a/SessionMessagingKit/Open Groups/Types/Personalization.swift +++ b/SessionMessagingKit/Open Groups/Types/Personalization.swift @@ -3,7 +3,7 @@ import Foundation import Sodium -extension OpenGroupAPIV2 { +extension OpenGroupAPI { public enum Personalization: String { case sharedKeys = "sogs.shared_keys" case authHeader = "sogs.auth_header" diff --git a/SessionMessagingKit/Open Groups/Types/Request.swift b/SessionMessagingKit/Open Groups/Types/Request.swift index 955a5e07c..d6ad29671 100644 --- a/SessionMessagingKit/Open Groups/Types/Request.swift +++ b/SessionMessagingKit/Open Groups/Types/Request.swift @@ -3,7 +3,7 @@ import Foundation import SessionUtilitiesKit -extension OpenGroupAPIV2 { +extension OpenGroupAPI { struct Request { let method: HTTP.Verb let server: String diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index bd2d2fcc3..b6a3cdacd 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -373,7 +373,7 @@ public final class MessageSender : NSObject { preconditionFailure() } - OpenGroupAPIV2 + OpenGroupAPI .send( plaintext, to: room, diff --git a/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift b/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift index 23e0331a3..3497c884a 100644 --- a/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift +++ b/SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupPollerV2.swift @@ -48,13 +48,13 @@ public final class OpenGroupPollerV2 : NSObject { let (promise, seal) = Promise.pending() promise.retainUntilComplete() - OpenGroupAPIV2.poll(server) - .done(on: OpenGroupAPIV2.workQueue) { [weak self] response in + OpenGroupAPI.poll(server) + .done(on: OpenGroupAPI.workQueue) { [weak self] response in self?.isPolling = false self?.handlePollResponse(response, isBackgroundPoll: isBackgroundPoll) seal.fulfill(()) } - .catch(on: OpenGroupAPIV2.workQueue) { [weak self] error in + .catch(on: OpenGroupAPI.workQueue) { [weak self] error in SNLog("Open group polling failed due to error: \(error).") self?.isPolling = false seal.fulfill(()) // The promise is just used to keep track of when we're done @@ -63,13 +63,13 @@ public final class OpenGroupPollerV2 : NSObject { return promise } - private func handlePollResponse(_ response: [Endpoint: (info: OnionRequestResponseInfoType, data: Codable)], isBackgroundPoll: Bool) { + private func handlePollResponse(_ response: [OpenGroupAPI.Endpoint: (info: OnionRequestResponseInfoType, data: Codable)], isBackgroundPoll: Bool) { let storage = SNMessagingKitConfiguration.shared.storage response.forEach { endpoint, response in switch endpoint { case .roomMessagesRecent(let roomToken), .roomMessagesBefore(let roomToken, _), .roomMessagesSince(let roomToken, _): - guard let responseData: [OpenGroupAPIV2.Message] = response.data as? [OpenGroupAPIV2.Message] else { + guard let responseData: [OpenGroupAPI.Message] = response.data as? [OpenGroupAPI.Message] else { //SNLog("Open group polling failed due to error: \(error).") return // TODO: Throw error? } @@ -77,7 +77,7 @@ public final class OpenGroupPollerV2 : NSObject { handleMessages(responseData, roomToken: roomToken, isBackgroundPoll: isBackgroundPoll, using: storage) case .roomPollInfo(let roomToken, _): - guard let responseData: OpenGroupAPIV2.RoomPollInfo = response.data as? OpenGroupAPIV2.RoomPollInfo else { + guard let responseData: OpenGroupAPI.RoomPollInfo = response.data as? OpenGroupAPI.RoomPollInfo else { //SNLog("Open group polling failed due to error: \(error).") return // TODO: Throw error? } @@ -92,10 +92,10 @@ public final class OpenGroupPollerV2 : NSObject { // MARK: - Custom response handling // TODO: Shift this logic to the OpenGroupManagerV2? (seems like the place it should belong?) - private func handleMessages(_ messages: [OpenGroupAPIV2.Message], roomToken: String, isBackgroundPoll: Bool, using storage: SessionMessagingKitStorageProtocol) { + private func handleMessages(_ messages: [OpenGroupAPI.Message], roomToken: String, isBackgroundPoll: Bool, using storage: SessionMessagingKitStorageProtocol) { // Sorting the messages by server ID before importing them fixes an issue where messages that quote older messages can't find those older messages let openGroupID = "\(server).\(roomToken)" - let sortedMessages: [OpenGroupAPIV2.Message] = messages + let sortedMessages: [OpenGroupAPI.Message] = messages .sorted { lhs, rhs in lhs.seqNo < rhs.seqNo } storage.write { transaction in @@ -140,18 +140,18 @@ public final class OpenGroupPollerV2 : NSObject { } } - private func handlePollInfo(_ pollInfo: OpenGroupAPIV2.RoomPollInfo, roomToken: String, isBackgroundPoll: Bool, using storage: SessionMessagingKitStorageProtocol) { + private func handlePollInfo(_ pollInfo: OpenGroupAPI.RoomPollInfo, roomToken: String, isBackgroundPoll: Bool, using storage: SessionMessagingKitStorageProtocol) { // TODO: Handle other properties??? // - Moderators - OpenGroupAPIV2.moderators[server] = (OpenGroupAPIV2.moderators[server] ?? [:]) + OpenGroupAPI.moderators[server] = (OpenGroupAPI.moderators[server] ?? [:]) .setting(roomToken, Set(pollInfo.moderators ?? [])) } // MARK: - Legacy Handling - private func handleCompactPollBody(_ body: OpenGroupAPIV2.LegacyCompactPollResponse.Result, isBackgroundPoll: Bool) { + private func handleCompactPollBody(_ body: OpenGroupAPI.LegacyCompactPollResponse.Result, isBackgroundPoll: Bool) { let storage = SNMessagingKitConfiguration.shared.storage // - Messages // Sorting the messages by server ID before importing them fixes an issue where messages that quote older messages can't find those older messages @@ -177,12 +177,12 @@ public final class OpenGroupPollerV2 : NSObject { } // - Moderators - if var x = OpenGroupAPIV2.moderators[server] { + if var x = OpenGroupAPI.moderators[server] { x[body.room] = Set(body.moderators ?? []) - OpenGroupAPIV2.moderators[server] = x + OpenGroupAPI.moderators[server] = x } else { - OpenGroupAPIV2.moderators[server] = [ body.room : Set(body.moderators ?? []) ] + OpenGroupAPI.moderators[server] = [ body.room : Set(body.moderators ?? []) ] } // - Deletions diff --git a/SessionMessagingKit/Utilities/Promise+Utilities.swift b/SessionMessagingKit/Utilities/Promise+Utilities.swift index 84e71cd1c..b59ebdbc2 100644 --- a/SessionMessagingKit/Utilities/Promise+Utilities.swift +++ b/SessionMessagingKit/Utilities/Promise+Utilities.swift @@ -16,7 +16,7 @@ extension Promise where T == (OnionRequestResponseInfoType, Data?) { func decoded(as type: R.Type, on queue: DispatchQueue? = nil, error: Error? = nil) -> Promise<(OnionRequestResponseInfoType, R)> { self.map(on: queue) { responseInfo, maybeData -> (OnionRequestResponseInfoType, R) in guard let data: Data = maybeData else { - throw OpenGroupAPIV2.Error.parsingFailed + throw OpenGroupAPI.Error.parsingFailed } return (responseInfo, try data.decoded(as: type, customError: error)) diff --git a/SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Convenience.swift b/SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Convenience.swift index d491b716f..15bade4d6 100644 --- a/SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Convenience.swift +++ b/SignalUtilitiesKit/Messaging/Sending & Receiving/MessageSender+Convenience.swift @@ -49,7 +49,7 @@ extension MessageSender { stream, using: { data in // TODO: Update to non-legacy version - OpenGroupAPIV2.legacyUpload( + OpenGroupAPI.legacyUpload( data, to: v2OpenGroup.room, on: v2OpenGroup.server @@ -96,7 +96,7 @@ extension MessageSender { stream, using: { data in // TODO: Update to non-legacy version - OpenGroupAPIV2.legacyUpload( + OpenGroupAPI.legacyUpload( data, to: v2OpenGroup.room, on: v2OpenGroup.server