fix(marmot): route reply button on MLS messages to the encrypted group
Tapping reply on a Marmot/MLS (kind:445) message in the Notifications screen previously fell through routeReplyTo()'s `else` branch and opened the generic public-comment composer (Route.GenericCommentPost). Sending it would publish a plaintext kind:1111 that references the encrypted inner event id, leaking that the user has decrypted that group message. Mirror the NIP-17 pattern (Route.Room carries replyId, draftId, draftMessage; the same chat screen renders the "replying to" quote above the input) for MLS: - routeReplyTo() now detects MarmotGroupChatroom in note.inGatherers, matching how routeFor() at line 67 already finds the parent group, and returns Route.MarmotGroupChat(groupId, replyId = note.idHex). - Route.MarmotGroupChat gains message/replyId/draftId fields. - MarmotGroupChatView resolves the replyId into a Note, shows DisplayReplyingToNote above the composer, wires onWantsToReply for in-chat replies, and threads the parent inner event through AccountViewModel.sendMarmotGroupMessage into MarmotManager.buildTextMessage, which now adds a NIP-18 q-tag on the inner kind:9 (the same convention ChatEvent.reply() uses). Push notifications: notifyGroupMessage previously passed chatroomMembers=null, so the inline Reply action was never attached for MLS group notifications. Add a parallel MARMOT_REPLY_ACTION wired with the group id + parent inner event id; NotificationReplyReceiver loads the account, rebuilds the parent inner event from LocalCache (or sends unthreaded if the cache was pruned), and publishes the reply through the same MarmotManager path — so the inline notification reply stays encrypted inside the group instead of taking the NIP-17 PTag fallback.
This commit is contained in:
+17
-1
@@ -46,6 +46,8 @@ import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.QEventTag
|
||||
import com.vitorpamplona.quartz.nip18Reposts.quotes.quote
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
@@ -182,11 +184,25 @@ class MarmotManager(
|
||||
suspend fun buildTextMessage(
|
||||
nostrGroupId: HexKey,
|
||||
text: String,
|
||||
replyTo: Event? = null,
|
||||
persistOwn: Boolean = true,
|
||||
): TextMessageBundle {
|
||||
val template =
|
||||
com.vitorpamplona.quartz.nip01Core.signers
|
||||
.eventTemplate<Event>(kind = 9, description = text)
|
||||
.eventTemplate<Event>(kind = 9, description = text) {
|
||||
if (replyTo != null) {
|
||||
// Mirror ChatEvent.reply(): NIP-18 q-tag references the
|
||||
// parent inner kind:9 by id (+ author, no relay hint —
|
||||
// the inner rumor never hits a relay directly).
|
||||
quote(
|
||||
QEventTag(
|
||||
eventId = replyTo.id,
|
||||
relayHint = null,
|
||||
authorPubKeyHex = replyTo.pubKey,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
val innerEvent =
|
||||
com.vitorpamplona.quartz.nip59Giftwrap.rumors.RumorAssembler
|
||||
.assembleRumor<Event>(signer.pubKey, template)
|
||||
|
||||
Reference in New Issue
Block a user