PeerID 28/n: ChatViewModel.getShortIDForNoiseKey (#836)

This commit is contained in:
Islam
2025-10-19 20:30:10 +02:00
committed by GitHub
parent 880813f256
commit c3a1af7023
3 changed files with 18 additions and 32 deletions
+15 -15
View File
@@ -171,7 +171,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
if spid.isGeoChat || spid.isGeoDM {
let full = (nostrKeyMapping[spid] ?? spid.bare).lowercased()
return "nostr:" + full
} else if spid.id.count == 16, let full = getNoiseKeyForShortID(spid)?.lowercased() {
} else if spid.id.count == 16, let full = getNoiseKeyForShortID(spid)?.id.lowercased() {
return "noise:" + full
} else {
return "mesh:" + spid.id.lowercased()
@@ -328,16 +328,16 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
private var peerIDToPublicKeyFingerprint: [PeerID: String] = [:]
private var selectedPrivateChatFingerprint: String? = nil
// Map stable short peer IDs (16-hex) to full Noise public key hex (64-hex) for session continuity
private var shortIDToNoiseKey: [PeerID: String] = [:]
private var shortIDToNoiseKey: [PeerID: PeerID] = [:]
// Resolve full Noise key for a peer's short ID (used by UI header rendering)
@MainActor
private func getNoiseKeyForShortID(_ shortPeerID: PeerID) -> String? {
private func getNoiseKeyForShortID(_ shortPeerID: PeerID) -> PeerID? {
if let mapped = shortIDToNoiseKey[shortPeerID] { return mapped }
// Fallback: derive from active Noise session if available
if shortPeerID.id.count == 16,
let key = meshService.getNoiseService().getPeerPublicKeyData(shortPeerID) {
let stable = key.hexEncodedString()
let stable = PeerID(hexData: key)
shortIDToNoiseKey[shortPeerID] = stable
return stable
}
@@ -346,16 +346,17 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
// Resolve short mesh ID (16-hex) from a full Noise public key hex (64-hex)
@MainActor
func getShortIDForNoiseKey(_ fullNoiseKeyHex: String) -> PeerID? {
func getShortIDForNoiseKey(_ fullNoiseKeyHex: PeerID) -> PeerID {
guard fullNoiseKeyHex.id.count == 64 else { return fullNoiseKeyHex }
// Check known peers for a noise key match
if let match = allPeers.first(where: { $0.noisePublicKey.hexEncodedString() == fullNoiseKeyHex }) {
if let match = allPeers.first(where: { PeerID(hexData: $0.noisePublicKey) == fullNoiseKeyHex }) {
return match.peerID
}
// Also search cache mapping
if let pair = shortIDToNoiseKey.first(where: { $0.value == fullNoiseKeyHex }) {
return pair.key
}
return nil
return fullNoiseKeyHex
}
private var peerIndex: [PeerID: BitchatPeer] = [:]
@@ -4423,7 +4424,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
@MainActor
private func meshSeed(for peerID: PeerID) -> String {
if let full = getNoiseKeyForShortID(peerID)?.lowercased() {
if let full = getNoiseKeyForShortID(peerID)?.id.lowercased() {
return "noise:" + full
}
return peerID.id.lowercased()
@@ -4899,9 +4900,9 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
// Cache shortID -> full Noise key mapping as soon as session authenticates
if self.shortIDToNoiseKey[peerID] == nil,
let keyData = self.meshService.getNoiseService().getPeerPublicKeyData(peerID) {
let stable = keyData.hexEncodedString()
let stable = PeerID(hexData: keyData)
self.shortIDToNoiseKey[peerID] = stable
SecureLogger.debug("🗺️ Mapped short peerID to Noise key for header continuity: \(peerID) -> \(stable.prefix(8))", category: .session)
SecureLogger.debug("🗺️ Mapped short peerID to Noise key for header continuity: \(peerID) -> \(stable.id.prefix(8))", category: .session)
}
// If a QR verification is pending but not sent yet, send it now that session is authenticated
@@ -5166,7 +5167,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
// Cache mapping to full Noise key for session continuity on disconnect
if let peer = unifiedPeerService.getPeer(by: peerID) {
let noiseKeyHex = peer.noisePublicKey.hexEncodedString()
let noiseKeyHex = PeerID(hexData: peer.noisePublicKey)
shortIDToNoiseKey[peerID] = noiseKeyHex
}
@@ -5182,15 +5183,14 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
identityManager.removeEphemeralSession(peerID: peerID)
// If the open PM is tied to this short peer ID, switch UI context to the full Noise key (offline favorite)
var derivedStableKeyHex: String? = shortIDToNoiseKey[peerID]
var derivedStableKeyHex = shortIDToNoiseKey[peerID]
if derivedStableKeyHex == nil,
let key = meshService.getNoiseService().getPeerPublicKeyData(peerID) {
derivedStableKeyHex = key.hexEncodedString()
derivedStableKeyHex = PeerID(hexData: key)
shortIDToNoiseKey[peerID] = derivedStableKeyHex
}
if let current = selectedPrivateChatPeer, current == peerID,
let stableKeyHex = PeerID(str: derivedStableKeyHex) {
if let current = selectedPrivateChatPeer, current == peerID, let stableKeyHex = derivedStableKeyHex {
// Migrate messages view context to stable key so header shows favorite + Nostr globe
if let messages = privateChats[peerID] {
if privateChats[stableKeyHex] == nil { privateChats[stableKeyHex] = [] }
+2 -13
View File
@@ -1213,12 +1213,7 @@ struct ContentView: View {
.foregroundColor(textColor)
if !privatePeerID.isGeoDM {
let statusPeerID: PeerID = {
if privatePeerID.id.count == 64, let short = viewModel.getShortIDForNoiseKey(privatePeerID.id) {
return short
}
return context.headerPeerID
}()
let statusPeerID = viewModel.getShortIDForNoiseKey(privatePeerID)
let encryptionStatus = viewModel.getEncryptionStatus(for: statusPeerID)
if let icon = encryptionStatus.icon {
Image(systemName: icon)
@@ -1252,13 +1247,7 @@ struct ContentView: View {
}
private func makePrivateHeaderContext(for privatePeerID: PeerID) -> PrivateHeaderContext {
let headerPeerID: PeerID = {
if privatePeerID.id.count == 64, let short = viewModel.getShortIDForNoiseKey(privatePeerID.id) {
return short
}
return privatePeerID
}()
let headerPeerID = viewModel.getShortIDForNoiseKey(privatePeerID)
let peer = viewModel.getPeer(byID: headerPeerID)
let displayName: String = {
+1 -4
View File
@@ -65,10 +65,7 @@ struct FingerprintView: View {
VStack(alignment: .leading, spacing: 16) {
// Prefer short mesh ID for session/encryption status
let statusPeerID: PeerID = {
if peerID.id.count == 64, let short = viewModel.getShortIDForNoiseKey(peerID.id) { return short }
return peerID
}()
let statusPeerID = viewModel.getShortIDForNoiseKey(peerID)
// Resolve a friendly name
let peerNickname: String = {
if let p = viewModel.getPeer(byID: statusPeerID) { return p.displayName }