Merge pull request #785 from RyanRory/fix-quoting-in-community-chats

Fix quoting in community chats
pull/793/head
RyanZhao 1 year ago committed by GitHub
commit ae6f609b41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -461,10 +461,17 @@ extension ConversationVC:
.filter(id: threadId)
.updateAll(db, SessionThread.Columns.shouldBeVisible.set(to: true))
let authorId: String = {
if let blindedId = self?.viewModel.threadData.currentUserBlindedPublicKey {
return blindedId
}
return self?.viewModel.threadData.currentUserPublicKey ?? getUserHexEncodedPublicKey(db)
}()
// Create the interaction
let interaction: Interaction = try Interaction(
threadId: threadId,
authorId: getUserHexEncodedPublicKey(db),
authorId: authorId,
variant: .standardOutgoing,
body: text,
timestampMs: sentTimestampMs,

@ -82,7 +82,11 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
// distinct stutter)
self.pagedDataObserver = self.setupPagedObserver(
for: threadId,
userPublicKey: getUserHexEncodedPublicKey()
userPublicKey: getUserHexEncodedPublicKey(),
blindedPublicKey: SessionThread.getUserHexEncodedBlindedKey(
threadId: threadId,
threadVariant: threadVariant
)
)
// Run the initial query on a background thread so we don't block the push transition
@ -172,7 +176,7 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
}
}
private func setupPagedObserver(for threadId: String, userPublicKey: String) -> PagedDatabaseObserver<Interaction, MessageViewModel> {
private func setupPagedObserver(for threadId: String, userPublicKey: String, blindedPublicKey: String?) -> PagedDatabaseObserver<Interaction, MessageViewModel> {
return PagedDatabaseObserver(
pagedTable: Interaction.self,
pageSize: ConversationViewModel.pageSize,
@ -220,6 +224,7 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
orderSQL: MessageViewModel.orderSQL,
dataQuery: MessageViewModel.baseQuery(
userPublicKey: userPublicKey,
blindedPublicKey: blindedPublicKey,
orderSQL: MessageViewModel.orderSQL,
groupSQL: MessageViewModel.groupSQL
),
@ -458,7 +463,8 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
self.observableThreadData = self.setupObservableThreadData(for: updatedThreadId)
self.pagedDataObserver = self.setupPagedObserver(
for: updatedThreadId,
userPublicKey: getUserHexEncodedPublicKey()
userPublicKey: getUserHexEncodedPublicKey(),
blindedPublicKey: nil
)
// Try load everything up to the initial visible message, fallback to just the initial page of messages

@ -322,18 +322,31 @@ public extension SessionThread {
) -> String? {
guard
threadVariant == .openGroup,
let blindingInfo: (edkeyPair: Box.KeyPair?, publicKey: String?) = Storage.shared.read({ db in
let blindingInfo: (edkeyPair: Box.KeyPair?, publicKey: String?, capabilities: Set<Capability.Variant>) = Storage.shared.read({ db in
struct OpenGroupInfo: Decodable, FetchableRecord {
let publicKey: String?
let server: String?
}
let openGroupInfo: OpenGroupInfo? = try OpenGroup
.filter(id: threadId)
.select(.publicKey, .server)
.asRequest(of: OpenGroupInfo.self)
.fetchOne(db)
return (
Identity.fetchUserEd25519KeyPair(db),
try OpenGroup
.filter(id: threadId)
.select(.publicKey)
.asRequest(of: String.self)
.fetchOne(db)
openGroupInfo?.publicKey,
(try? Capability
.select(.variant)
.filter(Capability.Columns.openGroupServer == openGroupInfo?.server?.lowercased())
.asRequest(of: Capability.Variant.self)
.fetchSet(db))
.defaulting(to: [])
)
}),
let userEdKeyPair: Box.KeyPair = blindingInfo.edkeyPair,
let publicKey: String = blindingInfo.publicKey
let publicKey: String = blindingInfo.publicKey,
blindingInfo.capabilities.isEmpty || blindingInfo.capabilities.contains(.blind)
else { return nil }
let sodium: Sodium = Sodium()

@ -44,6 +44,7 @@ public final class VisibleMessage: Message {
// MARK: - Initialization
public init(
sender: String? = nil,
sentTimestamp: UInt64? = nil,
recipient: String? = nil,
groupPublicKey: String? = nil,
@ -68,6 +69,7 @@ public final class VisibleMessage: Message {
super.init(
sentTimestamp: sentTimestamp,
recipient: recipient,
sender: sender,
groupPublicKey: groupPublicKey
)
}
@ -228,6 +230,7 @@ public extension VisibleMessage {
let linkPreview: LinkPreview? = try? interaction.linkPreview.fetchOne(db)
return VisibleMessage(
sender: interaction.authorId,
sentTimestamp: UInt64(interaction.timestampMs),
recipient: (try? interaction.recipientStates.fetchOne(db))?.recipientId,
groupPublicKey: try? interaction.thread

@ -318,7 +318,6 @@ public final class MessageSender {
dependencies: SMKDependencies = SMKDependencies()
) -> Promise<Void> {
let (promise, seal) = Promise<Void>.pending()
let threadId: String
// Set the timestamp, sender and recipient
if message.sentTimestamp == nil { // Visible messages will already have their sent timestamp set
@ -328,7 +327,6 @@ public final class MessageSender {
switch destination {
case .contact, .closedGroup, .openGroupInbox: preconditionFailure()
case .openGroup(let roomToken, let server, let whisperTo, let whisperMods, _):
threadId = OpenGroup.idFor(roomToken: roomToken, server: server)
message.recipient = [
server,
roomToken,
@ -343,34 +341,12 @@ public final class MessageSender {
// which would go into this case, so rather than handling it as an invalid state we just want to
// error in a non-retryable way
guard
let openGroup: OpenGroup = try? OpenGroup.fetchOne(db, id: threadId),
let userEdKeyPair: Box.KeyPair = Identity.fetchUserEd25519KeyPair(db),
case .openGroup(let roomToken, let server, let whisperTo, let whisperMods, let fileIds) = destination
else {
seal.reject(MessageSenderError.invalidMessage)
return promise
}
message.sender = {
let capabilities: [Capability.Variant] = (try? Capability
.select(.variant)
.filter(Capability.Columns.openGroupServer == server)
.filter(Capability.Columns.isMissing == false)
.asRequest(of: Capability.Variant.self)
.fetchAll(db))
.defaulting(to: [])
// If the server doesn't support blinding then go with an unblinded id
guard capabilities.isEmpty || capabilities.contains(.blind) else {
return SessionId(.unblinded, publicKey: userEdKeyPair.publicKey).hexString
}
guard let blindedKeyPair: Box.KeyPair = dependencies.sodium.blindedKeyPair(serverPublicKey: openGroup.publicKey, edKeyPair: userEdKeyPair, genericHash: dependencies.genericHash) else {
preconditionFailure()
}
return SessionId(.blinded, publicKey: blindedKeyPair.publicKey).hexString
}()
// Set the failure handler (need it here already for precondition failure handling)
func handleFailure(_ db: Database, with error: MessageSenderError) {
MessageSender.handleFailedMessageSend(db, message: message, with: error, interactionId: interactionId)
@ -467,7 +443,6 @@ public final class MessageSender {
dependencies: SMKDependencies = SMKDependencies()
) -> Promise<Void> {
let (promise, seal) = Promise<Void>.pending()
let currentUserPublicKey: String = getUserHexEncodedPublicKey(db, dependencies: dependencies)
guard case .openGroupInbox(let server, let openGroupPublicKey, let recipientBlindedPublicKey) = destination else {
preconditionFailure()
@ -478,7 +453,6 @@ public final class MessageSender {
message.sentTimestamp = UInt64(SnodeAPI.currentOffsetTimestampMs())
}
message.sender = currentUserPublicKey
message.recipient = recipientBlindedPublicKey
// Set the failure handler (need it here already for precondition failure handling)
@ -628,7 +602,6 @@ public final class MessageSender {
// real message has no use when we delete a message. It is OK to let it be.
try interaction.with(
serverHash: message.serverHash,
// Track the open group server message ID and update server timestamp (use server
// timestamp for open group messages otherwise the quote messages may not be able
// to be found by the timestamp on other devices

@ -629,6 +629,7 @@ public extension MessageViewModel {
static func baseQuery(
userPublicKey: String,
blindedPublicKey: String?,
orderSQL: SQL,
groupSQL: SQL?
) -> (([Int64]) -> AdaptedFetchRequest<SQLRequest<MessageViewModel>>) {
@ -726,7 +727,12 @@ public extension MessageViewModel {
\(interactionAttachment[.attachmentId]) AS \(Quote.Columns.attachmentId)
FROM \(Quote.self)
LEFT JOIN \(Interaction.self) ON (
\(quote[.authorId]) = \(interaction[.authorId]) AND
(
\(quote[.authorId]) = \(interaction[.authorId]) OR (
\(quote[.authorId]) = \(blindedPublicKey ?? "") AND
\(userPublicKey) = \(interaction[.authorId])
)
) AND
\(quote[.timestampMs]) = \(interaction[.timestampMs])
)
LEFT JOIN \(InteractionAttachment.self) ON \(interaction[.id]) = \(interactionAttachment[.interactionId])

Loading…
Cancel
Save