diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index aaf93751a..04ff884a5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -3111,10 +3111,14 @@ class Account( val innerEvent = com.vitorpamplona.quartz.nip01Core.core.Event .fromJson(json) - // MIP-03 inner events are unsigned rumors - // (empty sig); pass wasVerified=true so - // LocalCache skips the Nostr secp256k1 check - // that would silently reject them. + // wasVerified=true: MIP-03 inner events are + // unsigned rumors (empty sig), authenticated + // via the MLS credential-identity check in + // GroupEventHandler when first decrypted. + // Running Nostr sig verify here (justVerify + // via wasVerified=false) would silently drop + // kind:7 reactions / kind:5 deletions since + // they never carry a Schnorr signature. val isNew = cache.justConsume(innerEvent, null, true) val innerNote = cache.getOrCreateNote(innerEvent.id) if (isNew) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DecryptAndIndexProcessor.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DecryptAndIndexProcessor.kt index ef3894539..b2a5d834d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DecryptAndIndexProcessor.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DecryptAndIndexProcessor.kt @@ -592,28 +592,28 @@ class GroupEventHandler( "GroupEventHandler.add: ApplicationMessage decrypted innerKind=${innerEvent.kind} " + "innerId=${innerEvent.id.take(8)}… author=${innerEvent.pubKey.take(8)}…" } - // Treat the inner event as pre-verified. MLS already - // authenticated the sender: MarmotInboundProcessor. - // processPrivateMessage rejects any inner event whose - // `pubkey` field doesn't match the MLS sender's - // credential identity. Running Nostr sig verify again - // here is a redundant gate — and one that silently - // dropped wn-signed inner events (wn's kind:9 rumors - // don't always round-trip Amethyst's `event.verify()`, - // e.g. because of JSON canonicalization differences). - // Without this, justConsume returned false, the chatroom - // never got the message, and the operator saw nothing - // but a misleading "inner event already in cache" log. + // wasVerified=true: MIP-03 inner events are unsigned + // rumors (empty sig); LocalCache.justVerify would reject + // every one on Schnorr verification. Authenticity is + // already guaranteed by MLS — MarmotInboundProcessor + // enforces innerEvent.pubKey == MLS sender's credential + // identity before returning ApplicationMessage. Without + // this, wn-signed kind:9 chat messages, kind:7 reactions, + // and kind:5 deletions would all silently drop here. + // + // Always call marmotGroupList.addMessage regardless of + // justConsume's return value. `addMessageSync` dedupes + // by Note identity, so a duplicate is a cheap no-op — + // but a previous-session persist that hydrated the + // cache at startup without populating the chatroom + // needs this path to surface the note (otherwise the + // operator saw nothing but a misleading "inner event + // already in cache" log and the message never rendered). val isNew = cache.justConsume(innerEvent, null, true) val innerNote = cache.getOrCreateNote(innerEvent.id) - if (!isNew) { - // Legit duplicate: a prior session persisted the - // inner JSON and the startup restore loop hydrated - // the cache before this kind:445 arrived. The - // chatroom may still not have it (restore order / - // chatroom snapshot drop), so `addMessage` runs - // unconditionally — `MarmotGroupChatroom.addMessageSync` - // dedupes by Note identity if it was already there. + if (isNew) { + innerNote.event = innerEvent + } else { Log.d("MarmotDbg") { "GroupEventHandler.add: inner event already in cache — surfacing in chatroom anyway" } diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 6032853ab..2715c23f5 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -1690,7 +1690,7 @@ Niektóre akcje nie powiodły się Wszystkie akcje udane Wszystkie akcje nieudane - Reakcja + Reakcję Wiadomość głosowa Odpowiedź głosowa Czas zakończenia głosowania diff --git a/amethyst/src/main/res/values-zh-rCN/strings.xml b/amethyst/src/main/res/values-zh-rCN/strings.xml index 6af34ef7a..4faad6e55 100644 --- a/amethyst/src/main/res/values-zh-rCN/strings.xml +++ b/amethyst/src/main/res/values-zh-rCN/strings.xml @@ -458,6 +458,11 @@ 公共聊天 关注包 直播 + 音频室 + 阶段 + 观众 + 举手 + 放下手 视频 文章 私人书签 @@ -818,6 +823,16 @@ 服务器 URL 用户名 凭证 + 保持与收件箱中继的连接以便接收实时通知 + Amethyst 通知活跃 + 已连接到 %1$d 个收件箱中继 + 正在连接到收件箱中继\u2026 + 暂停 + 始终开启通知服务 + 保持与收件箱中继的持续连接以便即时发送通知。 显示正在进行的通知。使用更多电量,但确保您永远不会错过消息。 + 电池优化已启用 + Android 可能会限制后台中继连接。禁用针对Amethyst电池优化以确保可靠的通知。 + 立即修复 通知: 加入对话 用户或群组 ID