implemented an E2E-encrypted Nextcloud push-v2 notification system with support for RSA decryption and signature verification; introduced an iOS Notification Service Extension and native AppDelegate handlers for Talk actions (inline reply and mark-as-read); replaced the legacy notification registration with a new lifecycle managing app passwords and secure keypair storage; added background message handling with tray synchronization and a test notification utility in the settings.

This commit is contained in:
2026-07-04 22:50:18 +02:00
parent 32f7c311bc
commit 74a2ddd17f
56 changed files with 2987 additions and 285 deletions
+28 -29
View File
@@ -1,5 +1,9 @@
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import '../push/push_actions.dart';
import '../push/push_renderer.dart';
import '../push/push_tap_router.dart';
class NotificationService {
static final NotificationService _instance = NotificationService._internal();
@@ -15,7 +19,27 @@ class NotificationService {
'@mipmap/ic_launcher',
);
final iosSettings = DarwinInitializationSettings();
// iOS Talk category mirrors the Android inline reply + mark-as-read actions
// so both platforms expose the same quick actions. The actual delivery of
// these while the app is terminated is handled by the (Phase 3) NSE.
final iosSettings = DarwinInitializationSettings(
notificationCategories: [
DarwinNotificationCategory(
PushRenderer.iosTalkCategory,
actions: [
DarwinNotificationAction.text(
kTalkReplyActionId,
'Antworten',
buttonTitle: 'Senden',
options: const {
DarwinNotificationActionOption.authenticationRequired,
},
),
DarwinNotificationAction.plain(kTalkMarkReadActionId, 'Gelesen'),
],
),
],
);
final initializationSettings = InitializationSettings(
android: androidSettings,
@@ -24,34 +48,9 @@ class NotificationService {
await flutterLocalNotificationsPlugin.initialize(
settings: initializationSettings,
);
}
Future<void> showNotification({
required String title,
required String body,
required int badgeCount,
}) async {
const androidPlatformChannelSpecifics = AndroidNotificationDetails(
'marmobile',
'Marianum Fulda',
importance: Importance.defaultImportance,
priority: Priority.defaultPriority,
ticker: 'Marianum Fulda',
);
const iosPlatformChannelSpecifics = DarwinNotificationDetails();
const platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iosPlatformChannelSpecifics,
);
await flutterLocalNotificationsPlugin.show(
id: 0,
title: title,
body: body,
notificationDetails: platformChannelSpecifics,
onDidReceiveNotificationResponse: PushTapRouter.handleResponse,
onDidReceiveBackgroundNotificationResponse:
PushActions.handleBackgroundResponse,
);
}
}