Š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:
Julius Joska
2026-07-11 17:06:39 +02:00
commit 8081d98c67
309 changed files with 44102 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
/// Nativní APNs most pro iOS (bez Firebase).
///
/// Komunikuje s AppDelegate.swift přes MethodChannel `cz.sepot.sepot/apns`:
/// Dart → native: register (registerForRemoteNotifications), getToken
/// native → Dart: onToken (APNs device token hex), onWake (tichý budíček)
///
/// APNs token se pošle relayi jako PLATFORM_APNS; relay pak posílá tichý
/// background budíček přímo přes Apple, žádný Google v cestě.
library;
import 'dart:io' show Platform;
import 'package:flutter/services.dart';
class ApnsBridge {
ApnsBridge._();
static const _channel = MethodChannel('cz.sepot.sepot/apns');
static bool _handlerSet = false;
/// Callback při vydání/změně APNs tokenu (hex string).
static void Function(String token)? onToken;
/// Callback při tichém budíčku (probudit WS a vylít frontu).
static void Function()? onWake;
static bool get isSupported => Platform.isIOS;
/// Zaregistruje příjem native → Dart callbacků. Idempotentní; volat
/// při startu (i killed-state, aby onWake fungoval po probuzení pushem).
static void ensureHandler() {
if (_handlerSet || !isSupported) return;
_handlerSet = true;
_channel.setMethodCallHandler((call) async {
switch (call.method) {
case 'onToken':
final token = call.arguments as String?;
if (token != null) onToken?.call(token);
case 'onWake':
onWake?.call();
}
return null;
});
}
/// Spustí nativní APNs registraci (systém se případně zeptá na povolení
/// notifikací). Token dorazí asynchronně přes [onToken].
static Future<void> register() async {
if (!isSupported) return;
ensureHandler();
await _channel.invokeMethod<void>('register');
}
/// Už vydaný token (null, pokud APNs ještě neodpověděl).
static Future<String?> currentToken() async {
if (!isSupported) return null;
return _channel.invokeMethod<String>('getToken');
}
}