mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-24 22:45:19 +00:00
Remove local logging functionality
- Delete LoggingService.swift - Remove all bitchatLog() function calls throughout the codebase - Update Xcode project to remove LoggingService references - Clean up debug logging statements from all services and views
This commit is contained in:
@@ -19,10 +19,8 @@
|
||||
4E778E5A414571ACAC2A0F01 /* MessageRetentionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67A85BFDDE65B4CD8BDF6DDB /* MessageRetentionService.swift */; };
|
||||
5D95F2BFBE257A1225998389 /* BatteryOptimizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED176FF3B274E35C2D827894 /* BatteryOptimizer.swift */; };
|
||||
61C81ED5F679D5E973EE0C07 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448F84BF86A42A3CC4A9379 /* NotificationService.swift */; };
|
||||
6A624D9359BCCAAE58CE0D64 /* LoggingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CDF6D0AF0F2052A6C7E634 /* LoggingService.swift */; };
|
||||
6DE056E1EE9850E9FBF50157 /* BitchatProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 229F17B68CFF7AB1BC91C847 /* BitchatProtocol.swift */; };
|
||||
6E7761E21C99F28AE2F9BE5F /* BitchatApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF625BB3AD919322C01A46B2 /* BitchatApp.swift */; };
|
||||
72BDC660D445E2D24AB90326 /* LoggingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96CDF6D0AF0F2052A6C7E634 /* LoggingService.swift */; };
|
||||
739429DFDE5C5829CF70DA7D /* EncryptionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC1563390A15C042D059CF9 /* EncryptionService.swift */; };
|
||||
749D8CF8A362B6CD0786782D /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3448F84BF86A42A3CC4A9379 /* NotificationService.swift */; };
|
||||
7576A357B278E5733E9D9F33 /* ChatViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6B8F7B7D55092C2540A7996 /* ChatViewModel.swift */; };
|
||||
@@ -85,7 +83,6 @@
|
||||
763E0DBA9492A654FC0CDCB9 /* AppInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInfoView.swift; sourceTree = "<group>"; };
|
||||
7EEBDA723E1CFD88758DA4AC /* bitchat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
8DE9CDF66D4E52D268851048 /* MessagePaddingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagePaddingTests.swift; sourceTree = "<group>"; };
|
||||
96CDF6D0AF0F2052A6C7E634 /* LoggingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingService.swift; sourceTree = "<group>"; };
|
||||
997D512074C64904D75DDD40 /* bitchat.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = bitchat.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
A08E03AA0C63E97C91749AEC /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||
A2136C3E22D02D4A8DBE7EAB /* BinaryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BinaryProtocol.swift; sourceTree = "<group>"; };
|
||||
@@ -192,7 +189,6 @@
|
||||
D5C3D880FF8AE1673B20E1E3 /* BluetoothMeshService.swift */,
|
||||
6DC1563390A15C042D059CF9 /* EncryptionService.swift */,
|
||||
136696FC4436A02D98CE6A77 /* KeychainManager.swift */,
|
||||
96CDF6D0AF0F2052A6C7E634 /* LoggingService.swift */,
|
||||
67A85BFDDE65B4CD8BDF6DDB /* MessageRetentionService.swift */,
|
||||
AA4D7595A613F7ED3B386132 /* MessageRetryService.swift */,
|
||||
3448F84BF86A42A3CC4A9379 /* NotificationService.swift */,
|
||||
@@ -349,7 +345,6 @@
|
||||
92D34E7A07C990C8A815B0CE /* ContentView.swift in Sources */,
|
||||
739429DFDE5C5829CF70DA7D /* EncryptionService.swift in Sources */,
|
||||
FB8819B4C84FAFEF5C36B216 /* KeychainManager.swift in Sources */,
|
||||
72BDC660D445E2D24AB90326 /* LoggingService.swift in Sources */,
|
||||
4E778E5A414571ACAC2A0F01 /* MessageRetentionService.swift in Sources */,
|
||||
C99763A4761567F587D21688 /* MessageRetryService.swift in Sources */,
|
||||
749D8CF8A362B6CD0786782D /* NotificationService.swift in Sources */,
|
||||
@@ -372,7 +367,6 @@
|
||||
1D9674FA5F998503831DC281 /* ContentView.swift in Sources */,
|
||||
DDA1DFAB1FF7AADE52DC0F53 /* EncryptionService.swift in Sources */,
|
||||
8F737CE0435792CC2AD65FCB /* KeychainManager.swift in Sources */,
|
||||
6A624D9359BCCAAE58CE0D64 /* LoggingService.swift in Sources */,
|
||||
4274B6016F755946FBF2513E /* MessageRetentionService.swift in Sources */,
|
||||
CEAE115C9C3EB3C4ED82F128 /* MessageRetryService.swift in Sources */,
|
||||
61C81ED5F679D5E973EE0C07 /* NotificationService.swift in Sources */,
|
||||
|
||||
@@ -662,7 +662,6 @@ class BluetoothMeshService: NSObject {
|
||||
ttl: 3 // Short TTL for leave notifications
|
||||
)
|
||||
|
||||
bitchatLog("Sending room leave notification for \(room)", category: "room")
|
||||
self.broadcastPacket(packet)
|
||||
}
|
||||
}
|
||||
@@ -687,7 +686,6 @@ class BluetoothMeshService: NSObject {
|
||||
ttl: 5 // Allow wider propagation for room announcements
|
||||
)
|
||||
|
||||
bitchatLog("Announcing room \(room) protection status: \(isProtected)", category: "room")
|
||||
self.broadcastPacket(packet)
|
||||
}
|
||||
}
|
||||
@@ -710,7 +708,6 @@ class BluetoothMeshService: NSObject {
|
||||
ttl: 5 // Allow wider propagation for room announcements
|
||||
)
|
||||
|
||||
bitchatLog("Announcing room \(room) retention status: \(enabled)", category: "room")
|
||||
self.broadcastPacket(packet)
|
||||
}
|
||||
}
|
||||
@@ -727,12 +724,10 @@ class BluetoothMeshService: NSObject {
|
||||
|
||||
// Debug logging
|
||||
let keyData = roomKey.withUnsafeBytes { Data($0) }
|
||||
bitchatLog("Encrypting message for room \(room) with key hash: \(keyData.prefix(8).hexEncodedString())", category: "crypto")
|
||||
|
||||
do {
|
||||
let sealedBox = try AES.GCM.seal(contentData, using: roomKey)
|
||||
let encryptedData = sealedBox.combined!
|
||||
bitchatLog("Successfully encrypted message, size: \(encryptedData.count) bytes", category: "crypto")
|
||||
|
||||
// Create message with encrypted content
|
||||
let message = BitchatMessage(
|
||||
@@ -770,10 +765,8 @@ class BluetoothMeshService: NSObject {
|
||||
)
|
||||
|
||||
self.broadcastPacket(packet)
|
||||
bitchatLog("Sent encrypted message to room \(room)", category: "room")
|
||||
}
|
||||
} catch {
|
||||
bitchatLog("Failed to encrypt room message: \(error)", category: "crypto")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1253,7 +1246,6 @@ class BluetoothMeshService: NSObject {
|
||||
recipientNickname: message.recipientNickname,
|
||||
roomKey: roomKeyData
|
||||
)
|
||||
bitchatLog("No peers available, added message to retry queue", category: "mesh")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1370,15 +1362,12 @@ class BluetoothMeshService: NSObject {
|
||||
// Handle encrypted room messages
|
||||
var finalContent = message.content
|
||||
if message.isEncrypted, let room = message.room, let encryptedData = message.encryptedContent {
|
||||
bitchatLog("Processing encrypted message in room \(room), encrypted data size: \(encryptedData.count)", category: "crypto")
|
||||
// Try to decrypt the content
|
||||
if let decryptedContent = self.delegate?.decryptRoomMessage(encryptedData, room: room) {
|
||||
finalContent = decryptedContent
|
||||
bitchatLog("Successfully decrypted message in room \(room): \(decryptedContent.prefix(20))...", category: "crypto")
|
||||
} else {
|
||||
// Unable to decrypt - show placeholder
|
||||
finalContent = "[Encrypted message - password required]"
|
||||
bitchatLog("Failed to decrypt message in room \(room) - will pass to ChatViewModel for re-attempt", category: "crypto")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1780,7 +1769,6 @@ class BluetoothMeshService: NSObject {
|
||||
if let room = String(data: packet.payload, encoding: .utf8),
|
||||
room.hasPrefix("#") {
|
||||
// Room leave notification
|
||||
bitchatLog("Received room leave notification from \(senderID) for room \(room)", category: "room")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.didReceiveRoomLeave(room, from: senderID)
|
||||
@@ -1844,7 +1832,6 @@ class BluetoothMeshService: NSObject {
|
||||
let creatorID = components[2]
|
||||
let keyCommitment = components.count >= 4 ? components[3] : nil
|
||||
|
||||
bitchatLog("Received room announcement: \(room) is \(isProtected ? "protected" : "public") by \(creatorID)" + (keyCommitment != nil ? " with commitment" : ""), category: "room")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.didReceivePasswordProtectedRoomAnnouncement(room, isProtected: isProtected, creatorID: creatorID, keyCommitment: keyCommitment)
|
||||
@@ -1868,7 +1855,6 @@ class BluetoothMeshService: NSObject {
|
||||
let enabled = components[1] == "1"
|
||||
let creatorID = components[2]
|
||||
|
||||
bitchatLog("Received room retention announcement: \(room) retention \(enabled ? "enabled" : "disabled") by \(creatorID)", category: "room")
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.didReceiveRoomRetentionAnnouncement(room, enabled: enabled, creatorID: creatorID)
|
||||
@@ -2701,4 +2687,4 @@ extension BluetoothMeshService: CBPeripheralManagerDelegate {
|
||||
private func updatePeerLastSeen(_ peerID: String) {
|
||||
peerLastSeenTimestamps[peerID] = Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
//
|
||||
// LoggingService.swift
|
||||
// bitchat
|
||||
//
|
||||
// This is free and unencumbered software released into the public domain.
|
||||
// For more information, see <https://unlicense.org>
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import os
|
||||
|
||||
class LoggingService {
|
||||
static let shared = LoggingService()
|
||||
|
||||
private let logger = Logger(subsystem: "com.bitchat", category: "general")
|
||||
private let fileURL: URL
|
||||
private let dateFormatter: DateFormatter
|
||||
private let queue = DispatchQueue(label: "bitchat.logging", qos: .background)
|
||||
|
||||
private init() {
|
||||
// Set up date formatter
|
||||
dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
|
||||
|
||||
#if os(macOS)
|
||||
// Only create log files on macOS
|
||||
// Get documents directory
|
||||
let documentsPath = FileManager.default.urls(for: .documentDirectory,
|
||||
in: .userDomainMask).first!
|
||||
|
||||
// Create logs directory
|
||||
let logsDirectory = documentsPath.appendingPathComponent("Logs")
|
||||
try? FileManager.default.createDirectory(at: logsDirectory,
|
||||
withIntermediateDirectories: true)
|
||||
|
||||
// Create log file with today's date
|
||||
let dateString = DateFormatter.localizedString(from: Date(),
|
||||
dateStyle: .short,
|
||||
timeStyle: .none)
|
||||
.replacingOccurrences(of: "/", with: "-")
|
||||
fileURL = logsDirectory.appendingPathComponent("bitchat-\(dateString).log")
|
||||
|
||||
// Create file if it doesn't exist
|
||||
if !FileManager.default.fileExists(atPath: fileURL.path) {
|
||||
FileManager.default.createFile(atPath: fileURL.path, contents: nil)
|
||||
}
|
||||
|
||||
log("=== BitChat Started ===")
|
||||
log("Log file: \(fileURL.path)")
|
||||
#else
|
||||
// On iOS, just create a dummy URL since we won't write to disk
|
||||
fileURL = URL(fileURLWithPath: "/dev/null")
|
||||
#endif
|
||||
}
|
||||
|
||||
func log(_ message: String, category: String = "general") {
|
||||
let timestamp = dateFormatter.string(from: Date())
|
||||
let logLine = "[\(timestamp)] [\(category)] \(message)\n"
|
||||
|
||||
// Log to console for debugging
|
||||
print(logLine.trimmingCharacters(in: .newlines))
|
||||
|
||||
// Log to system logger
|
||||
logger.log("\(message, privacy: .public)")
|
||||
|
||||
// Write to file asynchronously
|
||||
queue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
if let data = logLine.data(using: .utf8) {
|
||||
do {
|
||||
let fileHandle = try FileHandle(forWritingTo: self.fileURL)
|
||||
fileHandle.seekToEndOfFile()
|
||||
fileHandle.write(data)
|
||||
fileHandle.closeFile()
|
||||
} catch {
|
||||
print("Failed to write to log file: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getLogFileURL() -> URL {
|
||||
return fileURL
|
||||
}
|
||||
|
||||
func clearLogs() {
|
||||
queue.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
try? "".write(to: self.fileURL, atomically: true, encoding: .utf8)
|
||||
self.log("=== Logs Cleared ===")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Global logging function for convenience
|
||||
func bitchatLog(_ message: String, category: String = "general") {
|
||||
LoggingService.shared.log(message, category: category)
|
||||
}
|
||||
@@ -135,7 +135,6 @@ class MessageRetentionService {
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
bitchatLog("Failed to load messages for room \(room): \(error)", category: "retention")
|
||||
}
|
||||
|
||||
return messages.sorted { $0.timestamp < $1.timestamp }
|
||||
@@ -148,7 +147,6 @@ class MessageRetentionService {
|
||||
let sealedBox = try AES.GCM.seal(data, using: encryptionKey)
|
||||
return sealedBox.combined
|
||||
} catch {
|
||||
bitchatLog("Failed to encrypt message: \(error)", category: "retention")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -158,7 +156,6 @@ class MessageRetentionService {
|
||||
let sealedBox = try AES.GCM.SealedBox(combined: data)
|
||||
return try AES.GCM.open(sealedBox, using: encryptionKey)
|
||||
} catch {
|
||||
bitchatLog("Failed to decrypt message: \(error)", category: "retention")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -179,7 +176,6 @@ class MessageRetentionService {
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
bitchatLog("Failed to cleanup old messages: \(error)", category: "retention")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +188,6 @@ class MessageRetentionService {
|
||||
try? FileManager.default.removeItem(at: fileURL)
|
||||
}
|
||||
} catch {
|
||||
bitchatLog("Failed to delete messages for room \(room): \(error)", category: "retention")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,10 +198,9 @@ class MessageRetentionService {
|
||||
try? FileManager.default.removeItem(at: fileURL)
|
||||
}
|
||||
} catch {
|
||||
bitchatLog("Failed to delete all stored messages: \(error)", category: "retention")
|
||||
}
|
||||
|
||||
// Clear favorite rooms
|
||||
UserDefaults.standard.removeObject(forKey: favoriteRoomsKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ class MessageRetryService {
|
||||
) {
|
||||
// Don't queue if we're at capacity
|
||||
guard retryQueue.count < maxQueueSize else {
|
||||
bitchatLog("Retry queue full, dropping message", category: "retry")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -77,7 +76,6 @@ class MessageRetryService {
|
||||
)
|
||||
|
||||
retryQueue.append(retryMessage)
|
||||
bitchatLog("Added message to retry queue: \(content.prefix(20))...", category: "retry")
|
||||
}
|
||||
|
||||
private func processRetryQueue() {
|
||||
@@ -100,7 +98,6 @@ class MessageRetryService {
|
||||
for message in messagesToRetry {
|
||||
// Check if we should still retry
|
||||
if message.retryCount >= message.maxRetries {
|
||||
bitchatLog("Max retries reached for message: \(message.content.prefix(20))...", category: "retry")
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -118,7 +115,6 @@ class MessageRetryService {
|
||||
to: recipientID,
|
||||
recipientNickname: message.recipientNickname ?? "unknown"
|
||||
)
|
||||
bitchatLog("Retried private message to \(recipientID)", category: "retry")
|
||||
} else {
|
||||
// Recipient not connected, keep in queue with updated retry time
|
||||
var updatedMessage = message
|
||||
@@ -147,7 +143,6 @@ class MessageRetryService {
|
||||
room: room,
|
||||
roomKey: roomKey
|
||||
)
|
||||
bitchatLog("Retried encrypted room message to \(room)", category: "retry")
|
||||
} else {
|
||||
// No peers connected, keep in queue
|
||||
var updatedMessage = message
|
||||
@@ -173,7 +168,6 @@ class MessageRetryService {
|
||||
mentions: message.mentions ?? [],
|
||||
room: message.room
|
||||
)
|
||||
bitchatLog("Retried regular message", category: "retry")
|
||||
} else {
|
||||
// No peers connected, keep in queue
|
||||
var updatedMessage = message
|
||||
@@ -197,10 +191,9 @@ class MessageRetryService {
|
||||
|
||||
func clearRetryQueue() {
|
||||
retryQueue.removeAll()
|
||||
bitchatLog("Cleared retry queue", category: "retry")
|
||||
}
|
||||
|
||||
func getRetryQueueCount() -> Int {
|
||||
return retryQueue.count
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,8 +78,6 @@ class ChatViewModel: ObservableObject {
|
||||
meshService.delegate = self
|
||||
|
||||
// Log startup info
|
||||
bitchatLog("ChatViewModel initialized", category: "startup")
|
||||
bitchatLog("Nickname: \(nickname)", category: "startup")
|
||||
|
||||
// Start mesh service immediately
|
||||
meshService.startServices()
|
||||
@@ -136,7 +134,6 @@ class ChatViewModel: ObservableObject {
|
||||
let savedMessages = MessageRetentionService.shared.loadMessagesForRoom(room)
|
||||
if !savedMessages.isEmpty {
|
||||
roomMessages[room] = savedMessages
|
||||
bitchatLog("Loaded \(savedMessages.count) saved messages for room \(room) on startup", category: "retention")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,7 +191,6 @@ class ChatViewModel: ObservableObject {
|
||||
// Ensure room starts with #
|
||||
let roomTag = room.hasPrefix("#") ? room : "#\(room)"
|
||||
|
||||
bitchatLog("joinRoom called for \(roomTag), password provided: \(password != nil), is protected: \(passwordProtectedRooms.contains(roomTag)), has key: \(roomKeys[roomTag] != nil)", category: "room")
|
||||
|
||||
// Check if room is already joined and we can access it
|
||||
if joinedRooms.contains(roomTag) {
|
||||
@@ -202,7 +198,6 @@ class ChatViewModel: ObservableObject {
|
||||
if passwordProtectedRooms.contains(roomTag) && roomKeys[roomTag] == nil {
|
||||
if let password = password {
|
||||
// User provided password for already-joined room - verify it
|
||||
bitchatLog("Verifying password for already-joined room \(roomTag)", category: "room")
|
||||
|
||||
// Derive key and try to verify
|
||||
let key = deriveRoomKey(from: password, roomName: roomTag)
|
||||
@@ -211,10 +206,8 @@ class ChatViewModel: ObservableObject {
|
||||
if let expectedCommitment = roomKeyCommitments[roomTag] {
|
||||
let actualCommitment = computeKeyCommitment(for: key)
|
||||
if actualCommitment != expectedCommitment {
|
||||
bitchatLog("Password verification failed - key commitment mismatch for already-joined room \(roomTag)", category: "room")
|
||||
return false
|
||||
}
|
||||
bitchatLog("Password verified via key commitment for already-joined room \(roomTag)", category: "room")
|
||||
}
|
||||
|
||||
// Check if we have messages to verify against
|
||||
@@ -224,10 +217,8 @@ class ChatViewModel: ObservableObject {
|
||||
let encryptedData = encryptedMsg.encryptedContent {
|
||||
let testDecrypted = decryptRoomMessage(encryptedData, room: roomTag, testKey: key)
|
||||
if testDecrypted == nil {
|
||||
bitchatLog("Password verification failed for already-joined room", category: "room")
|
||||
return false
|
||||
}
|
||||
bitchatLog("Password verified for already-joined room", category: "room")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +233,6 @@ class ChatViewModel: ObservableObject {
|
||||
// Need password to access
|
||||
passwordPromptRoom = roomTag
|
||||
showPasswordPrompt = true
|
||||
bitchatLog("Room \(roomTag) already joined but needs password, showing prompt", category: "room")
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -255,7 +245,6 @@ class ChatViewModel: ObservableObject {
|
||||
if passwordProtectedRooms.contains(roomTag) && roomKeys[roomTag] == nil {
|
||||
// Allow room creator to bypass password check
|
||||
if roomCreators[roomTag] == meshService.myPeerID {
|
||||
bitchatLog("Room creator bypassing password check for room \(roomTag)", category: "room")
|
||||
// Room creator should already have the key set when they created the password
|
||||
// This is a failsafe - just proceed without password
|
||||
} else if let password = password {
|
||||
@@ -266,11 +255,8 @@ class ChatViewModel: ObservableObject {
|
||||
if let expectedCommitment = roomKeyCommitments[roomTag] {
|
||||
let actualCommitment = computeKeyCommitment(for: key)
|
||||
if actualCommitment != expectedCommitment {
|
||||
bitchatLog("Password verification failed - key commitment mismatch for room \(roomTag)", category: "room")
|
||||
bitchatLog("Expected: \(expectedCommitment), Got: \(actualCommitment)", category: "room")
|
||||
return false
|
||||
}
|
||||
bitchatLog("Password verified via key commitment for room \(roomTag)", category: "room")
|
||||
}
|
||||
|
||||
// Try to verify password if there are existing encrypted messages
|
||||
@@ -280,24 +266,19 @@ class ChatViewModel: ObservableObject {
|
||||
if let roomMsgs = roomMessages[roomTag], !roomMsgs.isEmpty {
|
||||
// Look for encrypted messages to verify against
|
||||
let encryptedMessages = roomMsgs.filter { $0.isEncrypted && $0.encryptedContent != nil }
|
||||
bitchatLog("Found \(encryptedMessages.count) encrypted messages in room \(roomTag) to verify against", category: "room")
|
||||
|
||||
if let encryptedMsg = encryptedMessages.first,
|
||||
let encryptedData = encryptedMsg.encryptedContent {
|
||||
// Test decryption with the derived key
|
||||
bitchatLog("Testing password by decrypting message from \(encryptedMsg.sender)", category: "room")
|
||||
let testDecrypted = decryptRoomMessage(encryptedData, room: roomTag, testKey: key)
|
||||
if testDecrypted == nil {
|
||||
// Password is wrong, can't decrypt
|
||||
bitchatLog("WRONG PASSWORD - decryption failed for room \(roomTag)", category: "room")
|
||||
shouldProceed = false
|
||||
} else {
|
||||
bitchatLog("Password VERIFIED - successfully decrypted message: \(testDecrypted?.prefix(20) ?? "")", category: "room")
|
||||
passwordVerified = true
|
||||
}
|
||||
} else {
|
||||
// No encrypted messages yet - accept tentatively
|
||||
bitchatLog("No encrypted messages to verify password for room \(roomTag) - accepting tentatively", category: "room")
|
||||
|
||||
// Add warning message
|
||||
let warningMsg = BitchatMessage(
|
||||
@@ -310,7 +291,6 @@ class ChatViewModel: ObservableObject {
|
||||
}
|
||||
} else {
|
||||
// Empty room - accept tentatively
|
||||
bitchatLog("Room \(roomTag) is empty - accepting password tentatively", category: "room")
|
||||
|
||||
// Add info message
|
||||
let infoMsg = BitchatMessage(
|
||||
@@ -334,21 +314,17 @@ class ChatViewModel: ObservableObject {
|
||||
_ = KeychainManager.shared.saveRoomPassword(password, for: roomTag)
|
||||
|
||||
if passwordVerified {
|
||||
bitchatLog("Password stored for room \(roomTag) - verified", category: "room")
|
||||
} else {
|
||||
bitchatLog("Password stored for room \(roomTag) - tentative, awaiting verification", category: "room")
|
||||
}
|
||||
} else {
|
||||
// Show password prompt and return early - don't join the room yet
|
||||
passwordPromptRoom = roomTag
|
||||
showPasswordPrompt = true
|
||||
bitchatLog("Room \(roomTag) is password protected, showing prompt", category: "room")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, room is either not password protected or we don't know yet
|
||||
bitchatLog("Joining room \(roomTag) - not known to be password protected or have key", category: "room")
|
||||
|
||||
joinedRooms.insert(roomTag)
|
||||
saveJoinedRooms()
|
||||
@@ -358,7 +334,6 @@ class ChatViewModel: ObservableObject {
|
||||
if roomCreators[roomTag] == nil && !passwordProtectedRooms.contains(roomTag) {
|
||||
roomCreators[roomTag] = meshService.myPeerID
|
||||
saveRoomData()
|
||||
bitchatLog("Set room creator for new room \(roomTag) to \(meshService.myPeerID)", category: "room")
|
||||
}
|
||||
|
||||
// Add ourselves as a member
|
||||
@@ -393,7 +368,6 @@ class ChatViewModel: ObservableObject {
|
||||
}
|
||||
// Sort by timestamp
|
||||
roomMessages[roomTag]?.sort { $0.timestamp < $1.timestamp }
|
||||
bitchatLog("Loaded \(savedMessages.count) saved messages for favorite room \(roomTag)", category: "retention")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,13 +406,11 @@ class ChatViewModel: ObservableObject {
|
||||
|
||||
// Check if room already has a creator
|
||||
if let existingCreator = roomCreators[room], existingCreator != meshService.myPeerID {
|
||||
bitchatLog("Cannot set password - room \(room) already has creator: \(existingCreator)", category: "room")
|
||||
return
|
||||
}
|
||||
|
||||
// If room is already password protected by someone else, we can't claim it
|
||||
if passwordProtectedRooms.contains(room) && roomCreators[room] != meshService.myPeerID {
|
||||
bitchatLog("Cannot set password - room \(room) is already password protected by another user", category: "room")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -482,13 +454,11 @@ class ChatViewModel: ObservableObject {
|
||||
let initMessage = "🔐 Room \(room) initialized | Protected room created by \(nickname) | Metadata: \(metadataStr)"
|
||||
meshService.sendEncryptedRoomMessage(initMessage, mentions: [], room: room, roomKey: key)
|
||||
|
||||
bitchatLog("Set password for room \(room) and sent init message", category: "room")
|
||||
}
|
||||
|
||||
func removeRoomPassword(for room: String) {
|
||||
// Only room creator can remove password
|
||||
guard roomCreators[room] == meshService.myPeerID else {
|
||||
bitchatLog("Only room creator can remove password", category: "room")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -505,7 +475,6 @@ class ChatViewModel: ObservableObject {
|
||||
// Announce that this room is no longer password protected
|
||||
meshService.announcePasswordProtectedRoom(room, isProtected: false, creatorID: meshService.myPeerID)
|
||||
|
||||
bitchatLog("Removed password for room \(room)", category: "room")
|
||||
}
|
||||
|
||||
// Transfer room ownership to another user
|
||||
@@ -576,7 +545,6 @@ class ChatViewModel: ObservableObject {
|
||||
meshService.sendMessage(transferMsg.content, mentions: [targetNick])
|
||||
}
|
||||
|
||||
bitchatLog("Transferred ownership of room \(currentRoom) to \(targetPeerID)", category: "room")
|
||||
}
|
||||
|
||||
// Change password for current room
|
||||
@@ -667,7 +635,6 @@ class ChatViewModel: ObservableObject {
|
||||
)
|
||||
messages.append(successMsg)
|
||||
|
||||
bitchatLog("Changed password for room \(currentRoom)", category: "room")
|
||||
}
|
||||
|
||||
// Compute SHA256 hash of the derived key for public verification
|
||||
@@ -683,7 +650,6 @@ class ChatViewModel: ObservableObject {
|
||||
let keyData = pbkdf2(password: password, salt: salt, iterations: 100000, keyLength: 32)
|
||||
|
||||
// Debug logging
|
||||
bitchatLog("Derived key for room \(roomName) with password '\(password)' - key hash: \(keyData.prefix(8).hexEncodedString())", category: "crypto")
|
||||
|
||||
return SymmetricKey(data: keyData)
|
||||
}
|
||||
@@ -848,7 +814,6 @@ class ChatViewModel: ObservableObject {
|
||||
roomMembers[room] = Set()
|
||||
}
|
||||
roomMembers[room]?.insert(meshService.myPeerID)
|
||||
bitchatLog("Added self \(meshService.myPeerID) to room \(room), total members: \(roomMembers[room]?.count ?? 0)", category: "room")
|
||||
} else {
|
||||
// Add to main messages
|
||||
messages.append(message)
|
||||
@@ -990,7 +955,6 @@ class ChatViewModel: ObservableObject {
|
||||
// Force UI update
|
||||
objectWillChange.send()
|
||||
|
||||
bitchatLog("PANIC: All data cleared for safety", category: "security")
|
||||
}
|
||||
|
||||
|
||||
@@ -1274,7 +1238,6 @@ extension ChatViewModel: BitchatDelegate {
|
||||
// Remove peer from room members
|
||||
if roomMembers[room] != nil {
|
||||
roomMembers[room]?.remove(peerID)
|
||||
bitchatLog("Removed peer \(peerID) from room \(room) members", category: "room")
|
||||
|
||||
// Force UI update
|
||||
objectWillChange.send()
|
||||
@@ -1293,12 +1256,10 @@ extension ChatViewModel: BitchatDelegate {
|
||||
// Store the key commitment if provided
|
||||
if let commitment = keyCommitment {
|
||||
roomKeyCommitments[room] = commitment
|
||||
bitchatLog("Stored key commitment for room \(room): \(commitment)", category: "room")
|
||||
}
|
||||
|
||||
// If we just learned this room is protected and we're in it without a key, prompt for password
|
||||
if !wasAlreadyProtected && joinedRooms.contains(room) && roomKeys[room] == nil {
|
||||
bitchatLog("Just learned room \(room) is password protected, need to prompt for password", category: "room")
|
||||
|
||||
// Add system message
|
||||
let systemMessage = BitchatMessage(
|
||||
@@ -1326,41 +1287,34 @@ extension ChatViewModel: BitchatDelegate {
|
||||
// Save updated room data
|
||||
saveRoomData()
|
||||
|
||||
bitchatLog("Room \(room) is now \(isProtected ? "password protected" : "public")", category: "room")
|
||||
}
|
||||
|
||||
func decryptRoomMessage(_ encryptedContent: Data, room: String, testKey: SymmetricKey? = nil) -> String? {
|
||||
let key = testKey ?? roomKeys[room]
|
||||
guard let key = key else {
|
||||
bitchatLog("No key available for encrypted room \(room)", category: "room")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Debug logging
|
||||
let keyData = key.withUnsafeBytes { Data($0) }
|
||||
bitchatLog("Attempting to decrypt with key hash: \(keyData.prefix(8).hexEncodedString()) for room \(room)", category: "crypto")
|
||||
|
||||
do {
|
||||
let sealedBox = try AES.GCM.SealedBox(combined: encryptedContent)
|
||||
let decryptedData = try AES.GCM.open(sealedBox, using: key)
|
||||
let decryptedString = String(data: decryptedData, encoding: .utf8)
|
||||
bitchatLog("Successfully decrypted message: \(decryptedString?.prefix(20) ?? "nil")", category: "crypto")
|
||||
return decryptedString
|
||||
} catch {
|
||||
bitchatLog("Failed to decrypt room message: \(error)", category: "crypto")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func didReceiveRoomRetentionAnnouncement(_ room: String, enabled: Bool, creatorID: String?) {
|
||||
bitchatLog("Received retention announcement for room \(room): \(enabled ? "enabled" : "disabled") by \(creatorID ?? "unknown")", category: "room")
|
||||
|
||||
// Only process if we're a member of this room
|
||||
guard joinedRooms.contains(room) else { return }
|
||||
|
||||
// Verify the announcement is from the room owner
|
||||
if let creatorID = creatorID, roomCreators[room] != creatorID {
|
||||
bitchatLog("Ignoring retention announcement from non-owner \(creatorID) for room \(room)", category: "room")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1658,15 +1612,12 @@ extension ChatViewModel: BitchatDelegate {
|
||||
if let room = currentRoom {
|
||||
// Clear room messages
|
||||
roomMessages[room]?.removeAll()
|
||||
bitchatLog("cleared messages in room \(room)", category: "chat")
|
||||
} else if let peerID = selectedPrivateChatPeer {
|
||||
// Clear private chat
|
||||
privateChats[peerID]?.removeAll()
|
||||
bitchatLog("cleared private chat with \(peerID)", category: "chat")
|
||||
} else {
|
||||
// Clear main messages
|
||||
messages.removeAll()
|
||||
bitchatLog("cleared main chat", category: "chat")
|
||||
}
|
||||
case "/save":
|
||||
// Toggle retention for current room (owner only)
|
||||
@@ -1766,7 +1717,6 @@ extension ChatViewModel: BitchatDelegate {
|
||||
}
|
||||
|
||||
func didReceiveMessage(_ message: BitchatMessage) {
|
||||
bitchatLog("Received message from \(message.sender), room: \(message.room ?? "nil"), senderPeerID: \(message.senderPeerID ?? "nil")", category: "message")
|
||||
|
||||
if message.isPrivate {
|
||||
// Handle private message
|
||||
@@ -1812,7 +1762,6 @@ extension ChatViewModel: BitchatDelegate {
|
||||
if wasNewlyDiscovered {
|
||||
passwordProtectedRooms.insert(room)
|
||||
saveRoomData()
|
||||
bitchatLog("Discovered room \(room) is password protected from encrypted message", category: "room")
|
||||
|
||||
// Add a system message to indicate the room is password protected (only once)
|
||||
let systemMessage = BitchatMessage(
|
||||
@@ -1831,11 +1780,9 @@ extension ChatViewModel: BitchatDelegate {
|
||||
if currentRoom == room {
|
||||
passwordPromptRoom = room
|
||||
showPasswordPrompt = true
|
||||
bitchatLog("Showing password prompt for encrypted message in current room \(room)", category: "room")
|
||||
}
|
||||
} else if message.isEncrypted && roomKeys[room] != nil && message.content == "[Encrypted message - password required]" {
|
||||
// We have a key but the message shows as encrypted - try to decrypt it again
|
||||
bitchatLog("Received encrypted message placeholder but we have a key - attempting re-decryption", category: "room")
|
||||
|
||||
// Check if this is the first encrypted message in the room (password verification opportunity)
|
||||
let isFirstEncryptedMessage = roomMessages[room]?.filter { $0.isEncrypted }.isEmpty ?? true
|
||||
@@ -1843,10 +1790,8 @@ extension ChatViewModel: BitchatDelegate {
|
||||
if let encryptedData = message.encryptedContent {
|
||||
if let decryptedContent = decryptRoomMessage(encryptedData, room: room) {
|
||||
// Successfully decrypted - update the message content
|
||||
bitchatLog("Re-decryption successful! Content: \(decryptedContent.prefix(20))", category: "room")
|
||||
|
||||
if isFirstEncryptedMessage {
|
||||
bitchatLog("First encrypted message successfully decrypted - password VERIFIED for room \(room)", category: "room")
|
||||
|
||||
// Add success message
|
||||
let verifiedMsg = BitchatMessage(
|
||||
@@ -1878,7 +1823,6 @@ extension ChatViewModel: BitchatDelegate {
|
||||
messageToAdd = decryptedMessage
|
||||
} else {
|
||||
// Decryption really failed - wrong password
|
||||
bitchatLog("Re-decryption failed - password is actually wrong", category: "room")
|
||||
|
||||
// Clear the wrong password
|
||||
roomKeys.removeValue(forKey: room)
|
||||
@@ -1886,7 +1830,6 @@ extension ChatViewModel: BitchatDelegate {
|
||||
|
||||
// If this was the first encrypted message, we need to kick the user out
|
||||
if isFirstEncryptedMessage {
|
||||
bitchatLog("First encrypted message failed to decrypt - WRONG PASSWORD, removing user from room", category: "room")
|
||||
|
||||
// Leave the room
|
||||
joinedRooms.remove(room)
|
||||
@@ -1951,9 +1894,7 @@ extension ChatViewModel: BitchatDelegate {
|
||||
}
|
||||
if let senderPeerID = message.senderPeerID {
|
||||
roomMembers[room]?.insert(senderPeerID)
|
||||
bitchatLog("Added member \(senderPeerID) to room \(room), total members: \(roomMembers[room]?.count ?? 0)", category: "room")
|
||||
} else {
|
||||
bitchatLog("No senderPeerID for message in room \(room)", category: "room")
|
||||
}
|
||||
|
||||
// Update unread count if not currently viewing this room
|
||||
@@ -1962,7 +1903,6 @@ extension ChatViewModel: BitchatDelegate {
|
||||
}
|
||||
} else {
|
||||
// We're not in this room, ignore the message
|
||||
bitchatLog("Ignoring message for room \(room) - not joined", category: "room")
|
||||
}
|
||||
} else {
|
||||
// Regular public message (main chat)
|
||||
@@ -2094,4 +2034,4 @@ extension ChatViewModel: BitchatDelegate {
|
||||
return favoritePeers.contains(fingerprint)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -840,9 +840,6 @@ struct ContentView: View {
|
||||
if let currentRoom = viewModel.currentRoom,
|
||||
let roomMemberIDs = viewModel.roomMembers[currentRoom] {
|
||||
// Show only peers who have sent messages to this room (including self)
|
||||
bitchatLog("Room \(currentRoom) has members: \(roomMemberIDs)", category: "view")
|
||||
bitchatLog("Connected peers: \(viewModel.connectedPeers)", category: "view")
|
||||
bitchatLog("My peer ID: \(myPeerID)", category: "view")
|
||||
|
||||
// Start with room members who are also connected
|
||||
var memberPeers = viewModel.connectedPeers.filter { roomMemberIDs.contains($0) }
|
||||
@@ -852,7 +849,6 @@ struct ContentView: View {
|
||||
memberPeers.append(myPeerID)
|
||||
}
|
||||
|
||||
bitchatLog("Peers to show in room: \(memberPeers)", category: "view")
|
||||
return memberPeers
|
||||
} else {
|
||||
// Show all connected peers in main chat
|
||||
@@ -1064,4 +1060,4 @@ struct MessageContentView: View {
|
||||
|
||||
return segments
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user