diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 42cfd56e0..56d09a555 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -272,7 +272,7 @@ class Account( return null } - if (note.event is ChatMessageEvent) { + if (note.event is ChatMessageEvent && signEvent) { val event = note.event as ChatMessageEvent val users = event.recipientsPubKey().plus(event.pubKey).toSet().toList() @@ -284,7 +284,7 @@ class Account( emojiUrl = emojiUrl, originalNote = it, to = users, - from = keyPair.privKey!! + from = keyPair ) broadcastPrivately(giftWraps) @@ -299,7 +299,7 @@ class Account( content = reaction, originalNote = it, to = users, - from = keyPair.privKey!! + from = keyPair ) broadcastPrivately(giftWraps) @@ -310,11 +310,11 @@ class Account( val emojiUrl = EmojiUrl.decode(reaction) if (emojiUrl != null) { note.event?.let { + val event = ReactionEvent.create(emojiUrl, it, keyPair) if (!signEvent) { - return ReactionEvent.create(emojiUrl, it, keyPair.pubKey.toHexKey()) + return event } - val event = ReactionEvent.create(emojiUrl, it, keyPair.privKey!!) Client.send(event) LocalCache.consume(event) } @@ -324,11 +324,10 @@ class Account( } note.event?.let { + val event = ReactionEvent.create(reaction, it, keyPair) if (!signEvent) { - return ReactionEvent.create(reaction, it, keyPair.pubKey.toHexKey()) + return event } - - val event = ReactionEvent.create(reaction, it, keyPair.privKey!!) Client.send(event) LocalCache.consume(event) } @@ -468,7 +467,7 @@ class Account( } fun report(note: Note, type: ReportEvent.ReportType, content: String = "") { - if (!isWriteable()) return + if (!isWriteable() && !loginWithAmber) return if (note.hasReacted(userProfile(), "⚠️")) { // has already liked this note @@ -476,27 +475,66 @@ class Account( } note.event?.let { - val event = ReactionEvent.createWarning(it, keyPair.privKey!!) + var event = ReactionEvent.createWarning(it, keyPair) + if (loginWithAmber) { + AmberUtils.content = "" + AmberUtils.openAmber(event) + if (AmberUtils.content.isBlank()) return + event = ReactionEvent( + event.id, + event.pubKey, + event.createdAt, + event.tags, + event.content, + AmberUtils.content + ) + } Client.send(event) LocalCache.consume(event) } note.event?.let { - val event = ReportEvent.create(it, type, keyPair.privKey!!, content = content) + var event = ReportEvent.create(it, type, keyPair, content = content) + if (loginWithAmber) { + AmberUtils.content = "" + AmberUtils.openAmber(event) + if (AmberUtils.content.isBlank()) return + event = ReportEvent( + event.id, + event.pubKey, + event.createdAt, + event.tags, + event.content, + AmberUtils.content + ) + } Client.send(event) LocalCache.consume(event, null) } } fun report(user: User, type: ReportEvent.ReportType) { - if (!isWriteable()) return + if (!isWriteable() && !loginWithAmber) return if (user.hasReport(userProfile(), type)) { // has already reported this note return } - val event = ReportEvent.create(user.pubkeyHex, type, keyPair.privKey!!) + var event = ReportEvent.create(user.pubkeyHex, type, keyPair) + if (loginWithAmber) { + AmberUtils.content = "" + AmberUtils.openAmber(event) + if (AmberUtils.content.isBlank()) return + event = ReportEvent( + event.id, + event.pubKey, + event.createdAt, + event.tags, + event.content, + AmberUtils.content + ) + } Client.send(event) LocalCache.consume(event, null) } @@ -1819,25 +1857,81 @@ class Account( fun hideUser(pubkeyHex: String) { val blockList = migrateHiddenUsersIfNeeded(getBlockList()) + if (loginWithAmber) { + val content = blockList?.content ?: "" + val encryptedContent = if (content.isBlank()) { + val privateTags = listOf(listOf("p", pubkeyHex)) + val msg = Event.mapper.writeValueAsString(privateTags) - val event = if (blockList != null) { - PeopleListEvent.addUser( - earlierVersion = blockList, - pubKeyHex = pubkeyHex, - isPrivate = true, - privateKey = keyPair.privKey!! + AmberUtils.content = "" + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) + if (AmberUtils.content.isBlank()) return + AmberUtils.content + } else { + AmberUtils.content = "" + AmberUtils.decrypt(content, keyPair.pubKey.toHexKey()) + if (AmberUtils.content.isBlank()) return + val decryptedContent = AmberUtils.content + AmberUtils.content = "" + val privateTags = blockList?.privateTagsOrEmpty(decryptedContent)?.plus(element = listOf("p", pubkeyHex)) + val msg = Event.mapper.writeValueAsString(privateTags) + AmberUtils.content = "" + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) + if (AmberUtils.content.isBlank()) return + AmberUtils.content + } + + var event = if (blockList != null) { + PeopleListEvent.addUser( + earlierVersion = blockList, + pubKeyHex = pubkeyHex, + isPrivate = true, + pubKey = keyPair.pubKey.toHexKey(), + encryptedContent + ) + } else { + PeopleListEvent.createListWithUser( + name = PeopleListEvent.blockList, + pubKeyHex = pubkeyHex, + isPrivate = true, + pubKey = keyPair.pubKey.toHexKey(), + encryptedContent + ) + } + + AmberUtils.content = "" + AmberUtils.openAmber(event) + event = PeopleListEvent( + event.id, + event.pubKey, + event.createdAt, + event.tags, + event.content, + AmberUtils.content ) + + Client.send(event) + LocalCache.consume(event) } else { - PeopleListEvent.createListWithUser( - name = PeopleListEvent.blockList, - pubKeyHex = pubkeyHex, - isPrivate = true, - privateKey = keyPair.privKey!! - ) - } + val event = if (blockList != null) { + PeopleListEvent.addUser( + earlierVersion = blockList, + pubKeyHex = pubkeyHex, + isPrivate = true, + privateKey = keyPair.privKey!! + ) + } else { + PeopleListEvent.createListWithUser( + name = PeopleListEvent.blockList, + pubKeyHex = pubkeyHex, + isPrivate = true, + privateKey = keyPair.privKey!! + ) + } - Client.send(event) - LocalCache.consume(event) + Client.send(event) + LocalCache.consume(event) + } live.invalidateData() saveable.invalidateData() diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP24Factory.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP24Factory.kt index cb7523351..d91e8bc40 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP24Factory.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/NIP24Factory.kt @@ -2,6 +2,7 @@ package com.vitorpamplona.quartz.events import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.KeyPair import com.vitorpamplona.quartz.encoders.HexKey class NIP24Factory { @@ -44,8 +45,8 @@ class NIP24Factory { } } - fun createReactionWithinGroup(content: String, originalNote: EventInterface, to: List, from: ByteArray): List { - val senderPublicKey = CryptoUtils.pubkeyCreate(from).toHexKey() + fun createReactionWithinGroup(content: String, originalNote: EventInterface, to: List, from: KeyPair): List { + val senderPublicKey = CryptoUtils.pubkeyCreate(from.privKey!!).toHexKey() val senderReaction = ReactionEvent.create( content, @@ -58,15 +59,15 @@ class NIP24Factory { event = SealedGossipEvent.create( event = senderReaction, encryptTo = it, - privateKey = from + privateKey = from.privKey ), recipientPubKey = it ) } } - fun createReactionWithinGroup(emojiUrl: EmojiUrl, originalNote: EventInterface, to: List, from: ByteArray): List { - val senderPublicKey = CryptoUtils.pubkeyCreate(from).toHexKey() + fun createReactionWithinGroup(emojiUrl: EmojiUrl, originalNote: EventInterface, to: List, from: KeyPair): List { + val senderPublicKey = CryptoUtils.pubkeyCreate(from.privKey!!).toHexKey() val senderReaction = ReactionEvent.create( emojiUrl, @@ -79,7 +80,7 @@ class NIP24Factory { event = SealedGossipEvent.create( event = senderReaction, encryptTo = it, - privateKey = from + privateKey = from.privKey ), recipientPubKey = it ) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt index 9f8ca146f..6218f9c73 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ReactionEvent.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.KeyPair import com.vitorpamplona.quartz.encoders.HexKey @Immutable @@ -22,39 +23,29 @@ class ReactionEvent( companion object { const val kind = 7 - fun createWarning(originalNote: EventInterface, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ReactionEvent { - return create("\u26A0\uFE0F", originalNote, privateKey, createdAt) + fun createWarning(originalNote: EventInterface, keyPair: KeyPair, createdAt: Long = TimeUtils.now()): ReactionEvent { + return create("\u26A0\uFE0F", originalNote, keyPair, createdAt) } - fun createLike(originalNote: EventInterface, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ReactionEvent { - return create("+", originalNote, privateKey, createdAt) + fun createLike(originalNote: EventInterface, keyPair: KeyPair, createdAt: Long = TimeUtils.now()): ReactionEvent { + return create("+", originalNote, keyPair, createdAt) } - fun create(content: String, originalNote: EventInterface, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ReactionEvent { - val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey() - + fun create(content: String, originalNote: EventInterface, keyPair: KeyPair, createdAt: Long = TimeUtils.now()): ReactionEvent { var tags = listOf(listOf("e", originalNote.id()), listOf("p", originalNote.pubKey())) if (originalNote is AddressableEvent) { tags = tags + listOf(listOf("a", originalNote.address().toTag())) } + val pubKey = keyPair.pubKey.toHexKey() val id = generateId(pubKey, createdAt, kind, tags, content) - val sig = CryptoUtils.sign(id, privateKey) - return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey()) + val sig = if (keyPair.privKey == null) null else CryptoUtils.sign(id, keyPair.privKey) + return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig?.toHexKey() ?: "") } - fun create(content: String, originalNote: EventInterface, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ReactionEvent { - var tags = listOf(listOf("e", originalNote.id()), listOf("p", originalNote.pubKey())) - if (originalNote is AddressableEvent) { - tags = tags + listOf(listOf("a", originalNote.address().toTag())) - } - - val id = generateId(pubKey, createdAt, kind, tags, content) - return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, "") - } - - fun create(emojiUrl: EmojiUrl, originalNote: EventInterface, pubKey: HexKey, createdAt: Long = TimeUtils.now()): ReactionEvent { + fun create(emojiUrl: EmojiUrl, originalNote: EventInterface, keyPair: KeyPair, createdAt: Long = TimeUtils.now()): ReactionEvent { val content = ":${emojiUrl.code}:" + val pubKey = keyPair.pubKey.toHexKey() var tags = listOf( listOf("e", originalNote.id()), @@ -67,26 +58,8 @@ class ReactionEvent( } val id = generateId(pubKey, createdAt, kind, tags, content) - return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, "") - } - - fun create(emojiUrl: EmojiUrl, originalNote: EventInterface, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ReactionEvent { - val content = ":${emojiUrl.code}:" - val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey() - - var tags = listOf( - listOf("e", originalNote.id()), - listOf("p", originalNote.pubKey()), - listOf("emoji", emojiUrl.code, emojiUrl.url) - ) - - if (originalNote is AddressableEvent) { - tags = tags + listOf(listOf("a", originalNote.address().toTag())) - } - - val id = generateId(pubKey, createdAt, kind, tags, content) - val sig = CryptoUtils.sign(id, privateKey) - return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey()) + val sig = if (keyPair.privKey == null) null else CryptoUtils.sign(id, keyPair.privKey) + return ReactionEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig?.toHexKey() ?: "") } } } diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt index 6cdaf0ee9..d4436db62 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/ReportEvent.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.utils.TimeUtils import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.crypto.KeyPair import com.vitorpamplona.quartz.encoders.HexKey @Immutable @@ -56,14 +57,14 @@ class ReportEvent( fun create( reportedPost: EventInterface, type: ReportType, - privateKey: ByteArray, + keyPair: KeyPair, content: String = "", createdAt: Long = TimeUtils.now() ): ReportEvent { val reportPostTag = listOf("e", reportedPost.id(), type.name.lowercase()) val reportAuthorTag = listOf("p", reportedPost.pubKey(), type.name.lowercase()) - val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey() + val pubKey = keyPair.pubKey.toHexKey() var tags: List> = listOf(reportPostTag, reportAuthorTag) if (reportedPost is AddressableEvent) { @@ -71,20 +72,20 @@ class ReportEvent( } val id = generateId(pubKey, createdAt, kind, tags, content) - val sig = CryptoUtils.sign(id, privateKey) - return ReportEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey()) + val sig = if (keyPair.privKey == null) null else CryptoUtils.sign(id, keyPair.privKey) + return ReportEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig?.toHexKey() ?: "") } - fun create(reportedUser: String, type: ReportType, privateKey: ByteArray, createdAt: Long = TimeUtils.now()): ReportEvent { + fun create(reportedUser: String, type: ReportType, keyPair: KeyPair, createdAt: Long = TimeUtils.now()): ReportEvent { val content = "" val reportAuthorTag = listOf("p", reportedUser, type.name.lowercase()) - val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey() + val pubKey = keyPair.pubKey.toHexKey() val tags: List> = listOf(reportAuthorTag) val id = generateId(pubKey, createdAt, kind, tags, content) - val sig = CryptoUtils.sign(id, privateKey) - return ReportEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig.toHexKey()) + val sig = if (keyPair.privKey == null) null else CryptoUtils.sign(id, keyPair.privKey) + return ReportEvent(id.toHexKey(), pubKey, createdAt, tags, content, sig?.toHexKey() ?: "") } }