2022-04-21 08:42:35 +02:00
|
|
|
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
2020-11-07 23:00:10 +01:00
|
|
|
|
2022-04-21 08:42:35 +02:00
|
|
|
import Foundation
|
|
|
|
import GRDB
|
2022-12-02 04:00:10 +01:00
|
|
|
import SessionSnodeKit
|
2022-04-21 08:42:35 +02:00
|
|
|
import SessionUtilitiesKit
|
2020-11-07 23:00:10 +01:00
|
|
|
|
2022-04-21 08:42:35 +02:00
|
|
|
public extension Message {
|
|
|
|
enum Destination: Codable {
|
2022-12-02 04:00:10 +01:00
|
|
|
case contact(
|
|
|
|
publicKey: String,
|
|
|
|
namespace: SnodeAPI.Namespace
|
|
|
|
)
|
|
|
|
case closedGroup(
|
|
|
|
groupPublicKey: String,
|
|
|
|
namespace: SnodeAPI.Namespace
|
|
|
|
)
|
2022-02-11 06:48:16 +01:00
|
|
|
case openGroup(
|
|
|
|
roomToken: String,
|
|
|
|
server: String,
|
|
|
|
whisperTo: String? = nil,
|
|
|
|
whisperMods: Bool = false,
|
2022-03-04 06:17:03 +01:00
|
|
|
fileIds: [String]? = nil
|
2022-02-11 06:48:16 +01:00
|
|
|
)
|
2022-02-25 01:59:29 +01:00
|
|
|
case openGroupInbox(server: String, openGroupPublicKey: String, blindedPublicKey: String)
|
2020-11-25 06:15:16 +01:00
|
|
|
|
2022-12-08 04:21:38 +01:00
|
|
|
var namespace: SnodeAPI.Namespace {
|
|
|
|
switch self {
|
|
|
|
case .contact(_, let namespace), .closedGroup(_, let namespace): return namespace
|
|
|
|
default: preconditionFailure("Attepted to retrieve namespace for invalid destination")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-27 22:32:32 +01:00
|
|
|
public static func from(
|
2022-06-08 06:29:51 +02:00
|
|
|
_ db: Database,
|
|
|
|
thread: SessionThread,
|
|
|
|
fileIds: [String]? = nil
|
|
|
|
) throws -> Message.Destination {
|
2022-04-21 08:42:35 +02:00
|
|
|
switch thread.variant {
|
2022-06-08 06:29:51 +02:00
|
|
|
case .contact:
|
2022-06-09 10:37:44 +02:00
|
|
|
if SessionId.Prefix(from: thread.id) == .blinded {
|
|
|
|
guard let lookup: BlindedIdLookup = try? BlindedIdLookup.fetchOne(db, id: thread.id) else {
|
2022-06-08 06:29:51 +02:00
|
|
|
preconditionFailure("Attempting to send message to blinded id without the Open Group information")
|
|
|
|
}
|
|
|
|
|
|
|
|
return .openGroupInbox(
|
2022-06-09 10:37:44 +02:00
|
|
|
server: lookup.openGroupServer,
|
|
|
|
openGroupPublicKey: lookup.openGroupPublicKey,
|
2022-06-08 06:29:51 +02:00
|
|
|
blindedPublicKey: thread.id
|
|
|
|
)
|
2022-02-25 01:59:29 +01:00
|
|
|
}
|
|
|
|
|
2022-12-02 04:00:10 +01:00
|
|
|
return .contact(publicKey: thread.id, namespace: .default)
|
2022-02-25 01:59:29 +01:00
|
|
|
|
2022-06-08 06:29:51 +02:00
|
|
|
case .closedGroup:
|
2022-12-02 04:00:10 +01:00
|
|
|
return .closedGroup(groupPublicKey: thread.id, namespace: .legacyClosedGroup)
|
2022-02-11 06:48:16 +01:00
|
|
|
|
2022-04-21 08:42:35 +02:00
|
|
|
case .openGroup:
|
|
|
|
guard let openGroup: OpenGroup = try thread.openGroup.fetchOne(db) else {
|
2022-05-30 05:04:26 +02:00
|
|
|
throw StorageError.objectNotFound
|
2022-04-21 08:42:35 +02:00
|
|
|
}
|
|
|
|
|
2022-06-09 10:37:44 +02:00
|
|
|
return .openGroup(roomToken: openGroup.roomToken, server: openGroup.server, fileIds: fileIds)
|
2020-11-25 06:15:16 +01:00
|
|
|
}
|
|
|
|
}
|
2022-07-25 09:03:09 +02:00
|
|
|
|
|
|
|
func with(fileIds: [String]) -> Message.Destination {
|
|
|
|
// Only Open Group messages support receiving the 'fileIds'
|
|
|
|
switch self {
|
|
|
|
case .openGroup(let roomToken, let server, let whisperTo, let whisperMods, _):
|
|
|
|
return .openGroup(
|
|
|
|
roomToken: roomToken,
|
|
|
|
server: server,
|
|
|
|
whisperTo: whisperTo,
|
|
|
|
whisperMods: whisperMods,
|
|
|
|
fileIds: fileIds
|
|
|
|
)
|
|
|
|
|
|
|
|
default: return self
|
|
|
|
}
|
|
|
|
}
|
2022-12-02 04:00:10 +01:00
|
|
|
|
|
|
|
// MARK: - Codable
|
|
|
|
|
|
|
|
// FIXME: Remove this custom implementation after enough time has passed (added the 'namespace' properties)
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
|
|
let container: KeyedDecodingContainer<CodingKeys> = try decoder.container(keyedBy: CodingKeys.self)
|
|
|
|
|
|
|
|
// Should only have a single root key so we can just switch on it to have cleaner code
|
|
|
|
switch container.allKeys.first {
|
|
|
|
case .contact:
|
|
|
|
let childContainer: KeyedDecodingContainer<ContactCodingKeys> = try container.nestedContainer(keyedBy: ContactCodingKeys.self, forKey: .contact)
|
|
|
|
|
|
|
|
self = .contact(
|
|
|
|
publicKey: try childContainer.decode(String.self, forKey: .publicKey),
|
|
|
|
namespace: (
|
|
|
|
(try? childContainer.decode(SnodeAPI.Namespace.self, forKey: .namespace)) ??
|
|
|
|
.default
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
case .closedGroup:
|
|
|
|
let childContainer: KeyedDecodingContainer<ClosedGroupCodingKeys> = try container.nestedContainer(keyedBy: ClosedGroupCodingKeys.self, forKey: .closedGroup)
|
|
|
|
|
|
|
|
self = .closedGroup(
|
|
|
|
groupPublicKey: try childContainer.decode(String.self, forKey: .groupPublicKey),
|
|
|
|
namespace: (
|
|
|
|
(try? childContainer.decode(SnodeAPI.Namespace.self, forKey: .namespace)) ??
|
|
|
|
.legacyClosedGroup
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
case .openGroup:
|
|
|
|
let childContainer: KeyedDecodingContainer<OpenGroupCodingKeys> = try container.nestedContainer(keyedBy: OpenGroupCodingKeys.self, forKey: .openGroup)
|
|
|
|
|
|
|
|
self = .openGroup(
|
|
|
|
roomToken: try childContainer.decode(String.self, forKey: .roomToken),
|
|
|
|
server: try childContainer.decode(String.self, forKey: .server),
|
|
|
|
whisperTo: try? childContainer.decode(String.self, forKey: .whisperTo),
|
|
|
|
whisperMods: try childContainer.decode(Bool.self, forKey: .whisperMods),
|
|
|
|
fileIds: try? childContainer.decode([String].self, forKey: .fileIds)
|
|
|
|
)
|
|
|
|
|
|
|
|
case .openGroupInbox:
|
|
|
|
let childContainer: KeyedDecodingContainer<OpenGroupInboxCodingKeys> = try container.nestedContainer(keyedBy: OpenGroupInboxCodingKeys.self, forKey: .openGroupInbox)
|
|
|
|
|
|
|
|
self = .openGroupInbox(
|
|
|
|
server: try childContainer.decode(String.self, forKey: .server),
|
|
|
|
openGroupPublicKey: try childContainer.decode(String.self, forKey: .openGroupPublicKey),
|
|
|
|
blindedPublicKey: try childContainer.decode(String.self, forKey: .blindedPublicKey)
|
|
|
|
)
|
|
|
|
|
|
|
|
default: throw MessageReceiverError.invalidMessage
|
|
|
|
}
|
|
|
|
}
|
2020-11-07 23:00:10 +01:00
|
|
|
}
|
|
|
|
}
|