mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 02:25:20 +00:00
Remove noise service exposure; single-owner selection state
Transport callers no longer reach the raw NoiseEncryptionService: getNoiseService() is deleted in favor of narrow purpose-named Transport methods (session public key, identity fingerprint, static/signing keys, sign/verify, callback installation). VerificationService now reaches crypto through the transport, so it can no longer pin a stale service across a panic reset. myPeerID/myNickname become private(set); the existing setNickname mutator is the sole nickname path. ConversationStore is now the sole owner of private-chat selection: PrivateChatManager.selectedPeer is a published read-only mirror, and startChat/endChat mutate through the store intent. The bridge method and its five call sites are deleted, removing a latent bug where a stale manager selection pushed back into the store could resurrect a just-removed conversation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,7 +66,6 @@ private final class MockChatPeerIdentityContext: ChatPeerIdentityContext {
|
||||
private(set) var consolidatedPeers: [(peerID: PeerID, peerNickname: String)] = []
|
||||
private(set) var syncedReadReceiptPeers: [PeerID] = []
|
||||
private(set) var begunChatSessions: [PeerID] = []
|
||||
private(set) var selectionStoreSyncCount = 0
|
||||
private(set) var markedReadPeers: [PeerID] = []
|
||||
|
||||
@discardableResult
|
||||
@@ -83,7 +82,6 @@ private final class MockChatPeerIdentityContext: ChatPeerIdentityContext {
|
||||
begunChatSessions.append(peerID)
|
||||
}
|
||||
|
||||
func synchronizeConversationSelectionStore() { selectionStoreSyncCount += 1 }
|
||||
func markPrivateMessagesAsRead(from peerID: PeerID) { markedReadPeers.append(peerID) }
|
||||
|
||||
// Unified peer service
|
||||
@@ -283,7 +281,6 @@ struct ChatPeerIdentityCoordinatorContextTests {
|
||||
#expect(context.storedFingerprints.map(\.fingerprint) == ["fp-alice"])
|
||||
#expect(context.selectedPrivateChatFingerprint == "fp-alice")
|
||||
#expect(context.begunChatSessions == [peerID])
|
||||
#expect(context.selectionStoreSyncCount == 1)
|
||||
#expect(context.markedReadPeers == [peerID])
|
||||
|
||||
// Established session: no second handshake.
|
||||
|
||||
@@ -34,9 +34,7 @@ final class MockBLEService: NSObject {
|
||||
weak var delegate: BitchatDelegate?
|
||||
var myPeerID = PeerID(str: "MOCK1234")
|
||||
var myNickname: String = "MockUser"
|
||||
|
||||
private let mockKeychain = MockKeychain()
|
||||
|
||||
|
||||
// Test-specific properties
|
||||
var sentMessages: [(message: BitchatMessage, packet: BitchatPacket)] = []
|
||||
var sentPackets: [BitchatPacket] = []
|
||||
@@ -240,10 +238,6 @@ final class MockBLEService: NSObject {
|
||||
delegate?.didUpdatePeerList([])
|
||||
}
|
||||
|
||||
func getNoiseService() -> NoiseEncryptionService {
|
||||
return NoiseEncryptionService(keychain: mockKeychain)
|
||||
}
|
||||
|
||||
func getFingerprint(for peerID: String) -> String? {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -109,8 +109,34 @@ final class MockTransport: Transport {
|
||||
triggeredHandshakes.append(peerID)
|
||||
}
|
||||
|
||||
func getNoiseService() -> NoiseEncryptionService {
|
||||
NoiseEncryptionService(keychain: mockKeychain)
|
||||
// Noise identity wrappers backed by a mock-keychain encryption service
|
||||
// (mirrors the previous `getNoiseService()` placeholder behavior: a real
|
||||
// identity, but no peer sessions). Exposed so tests can assert against
|
||||
// the same identity the wrappers use.
|
||||
private(set) lazy var mockNoiseService = NoiseEncryptionService(keychain: mockKeychain)
|
||||
|
||||
func noiseSessionPublicKeyData(for peerID: PeerID) -> Data? {
|
||||
mockNoiseService.getPeerPublicKeyData(peerID)
|
||||
}
|
||||
|
||||
func noiseIdentityFingerprint() -> String {
|
||||
mockNoiseService.getIdentityFingerprint()
|
||||
}
|
||||
|
||||
func noiseStaticPublicKeyData() -> Data {
|
||||
mockNoiseService.getStaticPublicKeyData()
|
||||
}
|
||||
|
||||
func noiseSigningPublicKeyData() -> Data {
|
||||
mockNoiseService.getSigningPublicKeyData()
|
||||
}
|
||||
|
||||
func noiseSignData(_ data: Data) -> Data? {
|
||||
mockNoiseService.signData(data)
|
||||
}
|
||||
|
||||
func noiseVerifySignature(_ signature: Data, for data: Data, publicKey: Data) -> Bool {
|
||||
mockNoiseService.verifySignature(signature, for: data, publicKey: publicKey)
|
||||
}
|
||||
|
||||
// MARK: - Messaging
|
||||
|
||||
@@ -21,7 +21,6 @@ private final class DefaultTransportProbe: Transport {
|
||||
let subject = CurrentValueSubject<[TransportPeerSnapshot], Never>([])
|
||||
let myPeerID = PeerID(str: "0011223344556677")
|
||||
var myNickname = "Tester"
|
||||
private let keychain = MockKeychain()
|
||||
private(set) var sentMessages: [(content: String, mentions: [String])] = []
|
||||
|
||||
var peerSnapshotPublisher: AnyPublisher<[TransportPeerSnapshot], Never> {
|
||||
@@ -40,7 +39,6 @@ private final class DefaultTransportProbe: Transport {
|
||||
func getFingerprint(for peerID: PeerID) -> String? { nil }
|
||||
func getNoiseSessionState(for peerID: PeerID) -> LazyHandshakeState { .none }
|
||||
func triggerHandshake(with peerID: PeerID) {}
|
||||
func getNoiseService() -> NoiseEncryptionService { NoiseEncryptionService(keychain: keychain) }
|
||||
func sendMessage(_ content: String, mentions: [String]) { sentMessages.append((content, mentions)) }
|
||||
func sendPrivateMessage(_ content: String, to peerID: PeerID, recipientNickname: String, messageID: String) {}
|
||||
func sendReadReceipt(_ receipt: ReadReceipt, to peerID: PeerID) {}
|
||||
|
||||
@@ -98,10 +98,13 @@ final class VerificationServiceTests: XCTestCase {
|
||||
}
|
||||
|
||||
private func makeService() -> (VerificationService, NoiseEncryptionService) {
|
||||
let noise = NoiseEncryptionService(keychain: MockKeychain())
|
||||
// The service consumes Noise identity operations through the
|
||||
// Transport's narrow noise* wrappers; the mock transport's backing
|
||||
// encryption service is returned for direct assertions.
|
||||
let transport = MockTransport()
|
||||
let service = VerificationService()
|
||||
service.configure(with: noise)
|
||||
return (service, noise)
|
||||
service.configure(with: transport)
|
||||
return (service, transport.mockNoiseService)
|
||||
}
|
||||
|
||||
private func makeSignedQR(
|
||||
|
||||
Reference in New Issue
Block a user