Fix encryption key exchange and add persistent identity for favorites

- Implement three-tier key system: ephemeral encryption, ephemeral signing, persistent identity
- Fix signature verification by properly separating KeyAgreement and Signing keys
- Add persistent identity key for favorites that survives app restarts
- Fix Data subscript crashes by converting to byte arrays
- Add proper error handling for key exchange
- Private messages remain fully encrypted with ephemeral keys
This commit is contained in:
jack
2025-07-04 01:43:16 +02:00
parent 34e51b3d9a
commit fe986ed397
12 changed files with 679 additions and 929 deletions
+55
View File
@@ -1,17 +1,72 @@
import SwiftUI
import UserNotifications
@main
struct BitchatApp: App {
@StateObject private var chatViewModel = ChatViewModel()
#if os(iOS)
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
#endif
init() {
UNUserNotificationCenter.current().delegate = NotificationDelegate.shared
}
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(chatViewModel)
.onAppear {
NotificationDelegate.shared.chatViewModel = chatViewModel
}
}
#if os(macOS)
.windowStyle(.hiddenTitleBar)
.windowResizability(.contentSize)
#endif
}
}
#if os(iOS)
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
return true
}
}
#endif
class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
static let shared = NotificationDelegate()
weak var chatViewModel: ChatViewModel?
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let identifier = response.notification.request.identifier
// Check if this is a private message notification
if identifier.hasPrefix("private-") {
// Extract sender from notification title
let title = response.notification.request.content.title
if let senderName = title.replacingOccurrences(of: "Private message from ", with: "").nilIfEmpty {
// Find peer ID and open chat
if let peerID = chatViewModel?.getPeerIDForNickname(senderName) {
DispatchQueue.main.async {
self.chatViewModel?.startPrivateChat(with: peerID)
}
}
}
}
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// Show notification even when app is in foreground (for testing)
completionHandler([.banner, .sound])
}
}
extension String {
var nilIfEmpty: String? {
self.isEmpty ? nil : self
}
}