Renamed OpenGroupAPIV2 to OpenGroupAPI

Added the inbox endpoints
This commit is contained in:
Morgan Pretty 2022-02-15 16:30:11 +11:00
parent 4963a84ddd
commit 63e6cdd9ec
53 changed files with 490 additions and 392 deletions

View File

@ -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 = "<group>"; };
B886B4A62398B23E00211ABE /* QRCodeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeVC.swift; sourceTree = "<group>"; };
B886B4A82398BA1500211ABE /* QRCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCode.swift; sourceTree = "<group>"; };
B88FA7B726045D100049422F /* OpenGroupAPIV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupAPIV2.swift; sourceTree = "<group>"; };
B88FA7B726045D100049422F /* OpenGroupAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupAPI.swift; sourceTree = "<group>"; };
B88FA7F1260C3EB10049422F /* OpenGroupSuggestionGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupSuggestionGrid.swift; sourceTree = "<group>"; };
B88FA7FA26114EA70049422F /* Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hex.swift; sourceTree = "<group>"; };
B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQRCodeWrapperVC.swift; sourceTree = "<group>"; };
@ -1859,7 +1861,7 @@
C3DAB3232480CB2A00725F25 /* SRCopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRCopyableLabel.swift; sourceTree = "<group>"; };
C3DB66AB260ACA42001EFC55 /* OpenGroupManagerV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupManagerV2.swift; sourceTree = "<group>"; };
C3DB66C2260ACCE6001EFC55 /* OpenGroupPollerV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupPollerV2.swift; sourceTree = "<group>"; };
C3DB66CB260AF1F3001EFC55 /* OpenGroupAPIV2+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenGroupAPIV2+ObjC.swift"; sourceTree = "<group>"; };
C3DB66CB260AF1F3001EFC55 /* OpenGroupAPI+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OpenGroupAPI+ObjC.swift"; sourceTree = "<group>"; };
C3DFFAC523E96F0D0058DAF8 /* Sheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sheet.swift; sourceTree = "<group>"; };
C3E5C2F9251DBABB0040DFFC /* EditClosedGroupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditClosedGroupVC.swift; sourceTree = "<group>"; };
C3E7134E251C867C009649BB /* Sodium+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sodium+Utilities.swift"; sourceTree = "<group>"; };
@ -1974,6 +1976,8 @@
FDC438BC27BB2AB400C60D73 /* Mockable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mockable.swift; sourceTree = "<group>"; };
FDC438C027BB4E6800C60D73 /* Dependencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dependencies.swift; sourceTree = "<group>"; };
FDC438C227BB512200C60D73 /* SodiumProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SodiumProtocols.swift; sourceTree = "<group>"; };
FDC438C627BB6DF000C60D73 /* DirectMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DirectMessage.swift; sourceTree = "<group>"; };
FDC438C827BB706500C60D73 /* SendDirectMessageRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendDirectMessageRequest.swift; sourceTree = "<group>"; };
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 = "<group>"; };
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 = "<group>"; };
/* 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 */,

View File

@ -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)

View File

@ -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()
}
}

View File

@ -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];
}
}

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -383,7 +383,7 @@ static NSTimeInterval launchStartedAt;
}
if (CurrentAppContext().isMainApp) {
[SNOpenGroupAPIV2 legacyGetDefaultRoomsIfNeeded];
[SNOpenGroupAPI legacyGetDefaultRoomsIfNeeded];
}
[[SNSnodeAPI getSnodePool] retainUntilComplete];

View File

@ -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() {

View File

@ -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)
}

View File

@ -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)

View File

@ -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,

View File

@ -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<CodingKeys> = 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
)

View File

@ -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<OpenGroupAPIV2.BatchResponse> {
self.map(on: queue) { responseInfo, maybeData -> OpenGroupAPIV2.BatchResponse in
func decoded(as types: OpenGroupAPI.BatchResponseTypes, on queue: DispatchQueue? = nil, error: Error) -> Promise<OpenGroupAPI.BatchResponse> {
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)

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct Capabilities: Codable {
public enum Capability: CaseIterable, Codable {
public static var allCases: [Capability] {

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct DeletedMessagesResponse: Codable {
enum CodingKeys: String, CodingKey {
case deletions = "ids"

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct Deletion: Codable {
enum CodingKeys: String, CodingKey {
case id

View File

@ -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
}
}

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct FileResponse: Codable {
enum CodingKeys: String, CodingKey {
case fileName = "filename"

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct LegacyCompactPollBody: Codable {
struct Room: Codable {
enum CodingKeys: String, CodingKey {

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct LegacyCompactPollResponse: Codable {
public struct Result: Codable {
enum CodingKeys: String, CodingKey {

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct LegacyGetInfoResponse: Codable {
let room: LegacyRoomInfo
}

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct LegacyRoomInfo: Codable {
enum CodingKeys: String, CodingKey {
case id

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct LegacyRoomsResponse: Codable {
let rooms: [LegacyRoomInfo]
}

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct MemberCountResponse: Codable {
enum CodingKeys: String, CodingKey {
case memberCount = "member_count"

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct ModeratorsResponse: Codable {
let moderators: [String]
}

View File

@ -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<CodingKeys> = 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),

View File

@ -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(

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct PinnedMessage: Codable {
enum CodingKeys: String, CodingKey {
case id

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct PublicKeyBody: Codable {
enum CodingKeys: String, CodingKey {
case publicKey = "public_key"

View File

@ -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<CodingKeys> = 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),

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
/// This only contains ephemeral data
public struct RoomPollInfo: Codable {
enum CodingKeys: String, CodingKey {

View File

@ -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<CodingKeys> = encoder.container(keyedBy: CodingKeys.self)
try container.encode(data.base64EncodedString(), forKey: .data)
try container.encode(signature.base64EncodedString(), forKey: .signature)
}
}
}

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct SendMessageRequest: Codable {
enum CodingKeys: String, CodingKey {
case data

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct UserBanRequest: Codable {
let rooms: [String]?
let global: Bool?

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct UserDeleteMessagesRequest: Codable {
let rooms: [String]?
let global: Bool?

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct UserDeleteMessagesResponse: Codable {
enum CodingKeys: String, CodingKey {
case id

View File

@ -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.
///

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct UserPermissionsRequest: Codable {
let rooms: [String]
let timeout: TimeInterval

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct UserUnbanRequest: Codable {
let rooms: [String]?
let global: Bool?

View File

@ -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))
}

View File

@ -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<String>]> = 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<String>]] = [:] // Server URL to room ID to set of moderator IDs
public static var defaultRoomsPromise: Promise<[Room]>?
public static var groupImagePromises: [String: Promise<Data>] = [:]
@ -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<LegacyCompactPollResponse> {
let storage: SessionMessagingKitStorageProtocol = SNMessagingKitConfiguration.shared.storage
let rooms: [String] = storage.getAllV2OpenGroups().values
public static func compactPoll(_ server: String, using dependencies: Dependencies = Dependencies()) -> Promise<LegacyCompactPollResponse> {
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<LegacyCompactPollResponse> in
return send(request, using: dependencies)
.then(on: OpenGroupAPI.workQueue) { _, maybeData -> Promise<LegacyCompactPollResponse> 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<Data> {
// 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<Data> = 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<String> = legacyRequestNewAuthToken(for: room, on: server)
.then(on: OpenGroupAPIV2.workQueue) { legacyClaimAuthToken($0, for: room, on: server) }
.then(on: OpenGroupAPIV2.workQueue) { authToken -> Promise<String> in
.then(on: OpenGroupAPI.workQueue) { legacyClaimAuthToken($0, for: room, on: server) }
.then(on: OpenGroupAPI.workQueue) { authToken -> Promise<String> in
let (promise, seal) = Promise<String>.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<String>](getAuthTokenPromises.values))
.then(on: OpenGroupAPIV2.workQueue) { _ -> Promise<LegacyCompactPollResponse> in
.then(on: OpenGroupAPI.workQueue) { _ -> Promise<LegacyCompactPollResponse> 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<LegacyCompactPollResponse> in
.then(on: OpenGroupAPI.workQueue) { _, maybeData -> Promise<LegacyCompactPollResponse> 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<Data> = legacySend(request).map(on: OpenGroupAPIV2.workQueue) { _, maybeData in
let promise: Promise<Data> = 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<Data> {
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<Void> {
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

View File

@ -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)

View File

@ -4,7 +4,7 @@ import Foundation
import Sodium
import SessionSnodeKit
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public struct Dependencies {
let api: OnionRequestAPIType.Type
let storage: SessionMessagingKitStorageProtocol

View File

@ -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
}
}
}
}

View File

@ -2,7 +2,7 @@
import Foundation
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public enum Error: LocalizedError {
case generic
case parsingFailed

View File

@ -10,7 +10,7 @@ extension NonceGenerator16ByteType {
}
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
public class NonceGenerator16Byte: NonceGenerator, NonceGenerator16ByteType {
public var NonceBytes: Int { 16 }

View File

@ -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"

View File

@ -3,7 +3,7 @@
import Foundation
import SessionUtilitiesKit
extension OpenGroupAPIV2 {
extension OpenGroupAPI {
struct Request {
let method: HTTP.Verb
let server: String

View File

@ -373,7 +373,7 @@ public final class MessageSender : NSObject {
preconditionFailure()
}
OpenGroupAPIV2
OpenGroupAPI
.send(
plaintext,
to: room,

View File

@ -48,13 +48,13 @@ public final class OpenGroupPollerV2 : NSObject {
let (promise, seal) = Promise<Void>.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

View File

@ -16,7 +16,7 @@ extension Promise where T == (OnionRequestResponseInfoType, Data?) {
func decoded<R: Decodable>(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))

View File

@ -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