Relabel private Nostr envelopes honestly

This commit is contained in:
jack
2026-07-10 17:22:24 -04:00
parent 733098bb63
commit cc32f0b596
28 changed files with 1161 additions and 474 deletions
+33 -28
View File
@@ -393,20 +393,25 @@ struct ChatViewModelNostrExtensionTests {
}
@Test @MainActor
func subscribeGiftWrap_rejectsOversizedEmbeddedPacket() async throws {
func privateEnvelope_rejectsOversizedEmbeddedPacketBeforePublication() async throws {
let (viewModel, _) = makeTestableViewModel()
let sender = try NostrIdentity.generate()
let recipient = try NostrIdentity.generate()
let oversized = Data(repeating: 0x41, count: FileTransferLimits.maxFramedFileBytes + 1)
let content = "bitchat1:" + base64URLEncode(oversized)
let giftWrap = try NostrProtocol.createPrivateMessage(
content: content,
recipientPubkey: recipient.publicKeyHex,
senderIdentity: sender
)
viewModel.subscribeGiftWrap(giftWrap, id: recipient)
do {
_ = try NostrProtocol.createPrivateEnvelope(
content: content,
recipientPubkey: recipient.publicKeyHex,
senderIdentity: sender
)
Issue.record("Expected oversized private-envelope plaintext to be rejected")
} catch NostrError.invalidCiphertext {
// Rejected before encryption/publication, as intended.
} catch {
Issue.record("Expected NostrError.invalidCiphertext, got \(error)")
}
try? await Task.sleep(nanoseconds: 100_000_000)
#expect(viewModel.privateChats.isEmpty)
@@ -451,7 +456,7 @@ struct ChatViewModelNostrExtensionTests {
}
@Test @MainActor
func subscribeGiftWrap_deliveredAckUpdatesExistingMessage() async throws {
func subscribePrivateEnvelope_deliveredAckUpdatesExistingMessage() async throws {
let (viewModel, _) = makeTestableViewModel()
let sender = try NostrIdentity.generate()
let recipient = try NostrIdentity.generate()
@@ -473,13 +478,13 @@ struct ChatViewModelNostrExtensionTests {
], for: convKey)
let content = try ackContent(type: .delivered, messageID: messageID, senderPeerID: PeerID(str: "0123456789abcdef"))
let giftWrap = try NostrProtocol.createPrivateMessage(
let envelope = try NostrProtocol.createPrivateEnvelope(
content: content,
recipientPubkey: recipient.publicKeyHex,
senderIdentity: sender
)
viewModel.subscribeGiftWrap(giftWrap, id: recipient)
viewModel.subscribePrivateEnvelope(envelope, id: recipient)
let didUpdate = await TestHelpers.waitUntil(
{ isDelivered(status: deliveryStatus(in: viewModel, peerID: convKey, messageID: messageID)) },
@@ -489,7 +494,7 @@ struct ChatViewModelNostrExtensionTests {
}
@Test @MainActor
func subscribeGiftWrap_readAckUpdatesExistingMessage() async throws {
func subscribePrivateEnvelope_readAckUpdatesExistingMessage() async throws {
let (viewModel, _) = makeTestableViewModel()
let sender = try NostrIdentity.generate()
let recipient = try NostrIdentity.generate()
@@ -511,13 +516,13 @@ struct ChatViewModelNostrExtensionTests {
], for: convKey)
let content = try ackContent(type: .readReceipt, messageID: messageID, senderPeerID: PeerID(str: "0123456789abcdef"))
let giftWrap = try NostrProtocol.createPrivateMessage(
let envelope = try NostrProtocol.createPrivateEnvelope(
content: content,
recipientPubkey: recipient.publicKeyHex,
senderIdentity: sender
)
viewModel.subscribeGiftWrap(giftWrap, id: recipient)
viewModel.subscribePrivateEnvelope(envelope, id: recipient)
let didUpdate = await TestHelpers.waitUntil(
{ isRead(status: deliveryStatus(in: viewModel, peerID: convKey, messageID: messageID)) },
@@ -527,28 +532,28 @@ struct ChatViewModelNostrExtensionTests {
}
@Test @MainActor
func handleGiftWrap_privateMessageStoresConversationAndMapping() async throws {
func handlePrivateEnvelope_privateMessageStoresConversationAndMapping() async throws {
let (viewModel, _) = makeTestableViewModel()
let sender = try NostrIdentity.generate()
let recipient = try NostrIdentity.generate()
let messageID = "gift-private"
let messageID = "envelope-private"
let convKey = PeerID(nostr_: sender.publicKeyHex)
let content = try privateMessageContent(
text: "Hello from gift wrap",
text: "Hello from private envelope",
messageID: messageID,
senderPeerID: PeerID(str: "0123456789abcdef")
)
let giftWrap = try NostrProtocol.createPrivateMessage(
let envelope = try NostrProtocol.createPrivateEnvelope(
content: content,
recipientPubkey: recipient.publicKeyHex,
senderIdentity: sender
)
viewModel.handleGiftWrap(giftWrap, id: recipient)
viewModel.handlePrivateEnvelope(envelope, id: recipient)
let didStore = await TestHelpers.waitUntil(
{ viewModel.privateChats[convKey]?.first?.content == "Hello from gift wrap" },
{ viewModel.privateChats[convKey]?.first?.content == "Hello from private envelope" },
timeout: 5.0
)
#expect(didStore)
@@ -557,11 +562,11 @@ struct ChatViewModelNostrExtensionTests {
}
@Test @MainActor
func handleGiftWrap_blockedSenderSkipsMessageStorage() async throws {
func handlePrivateEnvelope_blockedSenderSkipsMessageStorage() async throws {
let (viewModel, _) = makeTestableViewModel()
let sender = try NostrIdentity.generate()
let recipient = try NostrIdentity.generate()
let messageID = "gift-blocked"
let messageID = "envelope-blocked"
let convKey = PeerID(nostr_: sender.publicKeyHex)
viewModel.identityManager.setNostrBlocked(sender.publicKeyHex, isBlocked: true)
@@ -571,13 +576,13 @@ struct ChatViewModelNostrExtensionTests {
messageID: messageID,
senderPeerID: PeerID(str: "0123456789abcdef")
)
let giftWrap = try NostrProtocol.createPrivateMessage(
let envelope = try NostrProtocol.createPrivateEnvelope(
content: content,
recipientPubkey: recipient.publicKeyHex,
senderIdentity: sender
)
viewModel.handleGiftWrap(giftWrap, id: recipient)
viewModel.handlePrivateEnvelope(envelope, id: recipient)
try? await Task.sleep(nanoseconds: 50_000_000)
#expect(viewModel.privateChats[convKey] == nil)
@@ -585,12 +590,12 @@ struct ChatViewModelNostrExtensionTests {
}
@Test @MainActor
func handleGiftWrap_deliveredAckUpdatesExistingMessage() async throws {
func handlePrivateEnvelope_deliveredAckUpdatesExistingMessage() async throws {
let (viewModel, _) = makeTestableViewModel()
let sender = try NostrIdentity.generate()
let recipient = try NostrIdentity.generate()
let convKey = PeerID(nostr_: sender.publicKeyHex)
let messageID = "gift-delivered"
let messageID = "envelope-delivered"
viewModel.seedPrivateChat([
BitchatMessage(
@@ -607,13 +612,13 @@ struct ChatViewModelNostrExtensionTests {
], for: convKey)
let content = try ackContent(type: .delivered, messageID: messageID, senderPeerID: PeerID(str: "0123456789abcdef"))
let giftWrap = try NostrProtocol.createPrivateMessage(
let envelope = try NostrProtocol.createPrivateEnvelope(
content: content,
recipientPubkey: recipient.publicKeyHex,
senderIdentity: sender
)
viewModel.handleGiftWrap(giftWrap, id: recipient)
viewModel.handlePrivateEnvelope(envelope, id: recipient)
let didUpdate = await TestHelpers.waitUntil(
{ isDelivered(status: deliveryStatus(in: viewModel, peerID: convKey, messageID: messageID)) },