Šepot — end-to-end encrypted messenger
Initial public release. Anonymous on-device identity (no phone number, e-mail, or password), Signal-protocol cryptography (X3DH + PQXDH, Double Ratchet, sealed sender) via libsignal, a metadata-minimizing relay, group chats, disappearing messages, encrypted local storage, optional Tor transport, and a UI localized into Czech, English, German, Russian, and Italian. Monorepo: Flutter client (app/), Rust relay + wire types (rust/), protobuf definitions (proto/), self-host deploy (deploy/). Licensed under AGPL-3.0 with an app-store distribution exception (§7).
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import Flutter
|
||||
import UIKit
|
||||
|
||||
@main
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
private var apnsChannel: FlutterMethodChannel?
|
||||
// Token dorazí asynchronně z APNs; když si o něj Dart řekne dřív, podržíme ho.
|
||||
private var pendingToken: String?
|
||||
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
let controller = window?.rootViewController as! FlutterViewController
|
||||
let channel = FlutterMethodChannel(
|
||||
name: "cz.sepot.sepot/apns", binaryMessenger: controller.binaryMessenger)
|
||||
channel.setMethodCallHandler { [weak self] call, result in
|
||||
switch call.method {
|
||||
case "register":
|
||||
// Nativní APNs registrace (bez Firebase) — token přijde v callbacku
|
||||
application.registerForRemoteNotifications()
|
||||
result(nil)
|
||||
case "getToken":
|
||||
result(self?.pendingToken)
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
}
|
||||
}
|
||||
apnsChannel = channel
|
||||
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
|
||||
// APNs vydal device token → předáme Dartu (ten ho pošle relayi).
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
|
||||
) {
|
||||
let token = deviceToken.map { String(format: "%02x", $0) }.joined()
|
||||
pendingToken = token
|
||||
apnsChannel?.invokeMethod("onToken", arguments: token)
|
||||
}
|
||||
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFailToRegisterForRemoteNotificationsWithError error: Error
|
||||
) {
|
||||
NSLog("APNs registrace selhala: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
// Tichý „background" budíček z relaye (content-available:1). Probudí Dart,
|
||||
// ať se připojí na WS a vyleje frontu. Obsah nikdy neneseme.
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
|
||||
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
|
||||
) {
|
||||
apnsChannel?.invokeMethod("onWake", arguments: nil)
|
||||
// Dej WS chvíli na doručení; iOS background okno je krátké.
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 8) {
|
||||
completionHandler(.newData)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user