Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,18 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper)
return messageDB.getMessageIDs(serverIds, threadId)
}

override fun getUserMessageHashes(threadId: Long, userPubKey: String): List<String> {
val component = DatabaseComponent.get(context)
val messages = component.mmsSmsDatabase().getUserMessages(threadId, userPubKey)
val messageDatabase = component.lokiMessageDatabase()
return messages.mapNotNull {
messageDatabase.getMessageServerHash(
messageID = it.id,
mms = it.isMms
)
}
}

override fun deleteMessage(messageID: Long, isSms: Boolean) {
val messagingDatabase: MessagingDatabase = if (isSms) DatabaseComponent.get(context).smsDatabase()
else DatabaseComponent.get(context).mmsDatabase()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1012,15 +1012,18 @@ class GroupManagerV2Impl @Inject constructor(
}
}

// Delete from swarm if we are admin
val adminKey = configFactory.getGroup(groupId)?.adminKey
if (!senderIsVerifiedAdmin && adminKey != null && hashes.isNotEmpty()) {
// If the deletion request comes from a non-admin, and we as an admin, will also delete
// the content from the swarm, provided that the messages are actually sent by that user
if (storage.ensureMessageHashesAreSender(
hashes.toSet(),
sender.hexString,
groupId.hexString
)
if (adminKey != null) {

// If hashes are given, these are the messages to delete. To be able to delete these
// messages from the swarm, the deletion request must be sent by an admin, or the messages
// belong to the requester.
if (hashes.isNotEmpty() && (
senderIsVerifiedAdmin || storage.ensureMessageHashesAreSender(
hashes = hashes.toSet(),
sender = sender.hexString,
closedGroupId = groupId.hexString))
) {
SnodeAPI.deleteMessage(
groupId.hexString,
Expand All @@ -1029,8 +1032,21 @@ class GroupManagerV2Impl @Inject constructor(
)
}

// The non-admin user shouldn't be able to delete other user's messages so we will
// ignore the memberIds in the message
// If memberIds are given, all messages belong to these members will be deleted on the
// swarm. These requests must be sent by an admin.
if (memberIds.isNotEmpty() && senderIsVerifiedAdmin) {
val userMessageHashes = memberIds.flatMap { memberId ->
messageDataProvider.getUserMessageHashes(threadId, memberId)
}

if (userMessageHashes.isNotEmpty()) {
SnodeAPI.deleteMessage(
groupId.hexString,
OwnedSwarmAuth.ofClosedGroup(groupId, adminKey),
userMessageHashes
)
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface MessageDataProvider {
*/
fun getMessageID(serverId: Long, threadId: Long): Pair<Long, Boolean>?
fun getMessageIDs(serverIDs: List<Long>, threadID: Long): Pair<List<Long>, List<Long>>
fun getUserMessageHashes(threadId: Long, userPubKey: String): List<String>
fun deleteMessage(messageID: Long, isSms: Boolean)
fun deleteMessages(messageIDs: List<Long>, threadId: Long, isSms: Boolean)
fun markMessageAsDeleted(timestamp: Long, author: String, displayedMessage: String)
Expand Down