This commit is contained in:
otsmr 2025-05-31 01:50:39 +02:00
parent ede9888515
commit af8aa8b915
4 changed files with 78 additions and 16 deletions

View file

@ -28,11 +28,16 @@ class NotificationService: UNNotificationServiceExtension {
let data = getPushNotificationData(pushDataJson: push_data) let data = getPushNotificationData(pushDataJson: push_data)
if data != nil { if data != nil {
if data!.title == "blocked" {
NSLog("Block message because user is blocked!")
// https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.usernotifications.filtering
return contentHandler(UNNotificationContent())
}
bestAttemptContent.title = data!.title; bestAttemptContent.title = data!.title;
bestAttemptContent.body = data!.body; bestAttemptContent.body = data!.body;
bestAttemptContent.threadIdentifier = String(format: "%d", data!.notificationId) bestAttemptContent.threadIdentifier = String(format: "%d", data!.notificationId)
} else { } else {
bestAttemptContent.title = "\(bestAttemptContent.title) [10]" bestAttemptContent.title = "\(bestAttemptContent.title)"
} }
contentHandler(bestAttemptContent) contentHandler(bestAttemptContent)
@ -81,6 +86,7 @@ func getPushNotificationData(pushDataJson: String) -> (title: String, body: Stri
var pushKind: PushKind? var pushKind: PushKind?
var displayName: String? var displayName: String?
var fromUserId: Int? var fromUserId: Int?
var blocked: Bool?
// Check the keyId // Check the keyId
if pushData.keyId == 0 { if pushData.keyId == 0 {
@ -96,6 +102,7 @@ func getPushNotificationData(pushDataJson: String) -> (title: String, body: Stri
if pushKind != nil { if pushKind != nil {
displayName = userKeys.displayName displayName = userKeys.displayName
fromUserId = userId fromUserId = userId
blocked = userKeys.blocked
break break
} }
} }
@ -108,6 +115,10 @@ func getPushNotificationData(pushDataJson: String) -> (title: String, body: Stri
} }
} }
if blocked == true {
return ("blocked", "blocked", 0)
}
// Handle the push notification based on the pushKind // Handle the push notification based on the pushKind
if let pushKind = pushKind { if let pushKind = pushKind {
@ -259,17 +270,19 @@ struct PushKeyMeta: Codable {
struct PushUser: Codable { struct PushUser: Codable {
let displayName: String let displayName: String
let keys: [PushKeyMeta] let keys: [PushKeyMeta]
let blocked: Bool?
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case displayName case displayName
case keys case keys
case blocked
} }
} }
func getPushKey() -> [Int: PushUser]? { func getPushKey() -> [Int: PushUser]? {
// Retrieve the data from secure storage (Keychain) // Retrieve the data from secure storage (Keychain)
guard let data = readFromKeychain(key: "receivingPushKeys") else { guard let data = readFromKeychain(key: "receivingPushKeys") else {
print("No data found for key: receivingPushKeys") NSLog("No data found for key: receivingPushKeys")
return nil return nil
} }
@ -290,7 +303,7 @@ func getPushKey() -> [Int: PushUser]? {
return pushKeys return pushKeys
} catch { } catch {
print("Error decoding JSON: \(error)") NSLog("Error decoding JSON: \(error)")
return nil return nil
} }
} }

View file

@ -1,6 +1,7 @@
import 'package:drift/drift.dart'; import 'package:drift/drift.dart';
import 'package:twonly/src/database/tables/contacts_table.dart'; import 'package:twonly/src/database/tables/contacts_table.dart';
import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/services/notification.service.dart';
part 'contacts_dao.g.dart'; part 'contacts_dao.g.dart';
@ -97,9 +98,17 @@ class ContactsDao extends DatabaseAccessor<TwonlyDatabase>
return (delete(contacts)..where((t) => t.userId.equals(userId))).go(); return (delete(contacts)..where((t) => t.userId.equals(userId))).go();
} }
Future updateContact(int userId, ContactsCompanion updatedValues) { Future updateContact(int userId, ContactsCompanion updatedValues) async {
return (update(contacts)..where((c) => c.userId.equals(userId))) await ((update(contacts)..where((c) => c.userId.equals(userId)))
.write(updatedValues); .write(updatedValues));
if (updatedValues.blocked.present ||
updatedValues.displayName.present ||
updatedValues.nickName.present) {
final contact = await getContactByUserId(userId).getSingleOrNull();
if (contact != null) {
await updatePushUser(contact);
}
}
} }
Future newMessageExchange(int userId) { Future newMessageExchange(int userId) {

View file

@ -16,13 +16,16 @@ import 'package:twonly/src/database/tables/messages_table.dart';
import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/model/json/message.dart' as my; import 'package:twonly/src/model/json/message.dart' as my;
import 'package:twonly/src/services/api/messages.dart'; import 'package:twonly/src/services/api/messages.dart';
import 'package:twonly/src/utils/log.dart';
class PushUser { class PushUser {
String displayName; String displayName;
bool blocked;
List<PushKeyMeta> keys; List<PushKeyMeta> keys;
PushUser({ PushUser({
required this.displayName, required this.displayName,
required this.blocked,
required this.keys, required this.keys,
}); });
@ -30,6 +33,7 @@ class PushUser {
factory PushUser.fromJson(Map<String, dynamic> json) { factory PushUser.fromJson(Map<String, dynamic> json) {
return PushUser( return PushUser(
displayName: json['displayName'], displayName: json['displayName'],
blocked: json['blocked'] ?? false,
keys: (json['keys'] as List) keys: (json['keys'] as List)
.map((keyJson) => PushKeyMeta.fromJson(keyJson)) .map((keyJson) => PushKeyMeta.fromJson(keyJson))
.toList(), .toList(),
@ -40,6 +44,7 @@ class PushUser {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
'displayName': displayName, 'displayName': displayName,
'blocked': blocked,
'keys': keys.map((key) => key.toJson()).toList(), 'keys': keys.map((key) => key.toJson()).toList(),
}; };
} }
@ -111,6 +116,7 @@ Future setupNotificationWithUsers({bool force = false}) async {
await sendNewPushKey(contact.userId, pushKey); await sendNewPushKey(contact.userId, pushKey);
final pushUser = PushUser( final pushUser = PushUser(
displayName: getContactDisplayName(contact), displayName: getContactDisplayName(contact),
blocked: contact.blocked,
keys: [pushKey], keys: [pushKey],
); );
pushKeys[contact.userId] = pushUser; pushKeys[contact.userId] = pushUser;
@ -135,11 +141,29 @@ Future sendNewPushKey(int userId, PushKeyMeta pushKey) async {
); );
} }
Future updatePushUser(Contact contact) async {
var receivingPushKeys = await getPushKeys("receivingPushKeys");
if (receivingPushKeys[contact.userId] == null) {
receivingPushKeys[contact.userId] = PushUser(
displayName: getContactDisplayName(contact),
keys: [],
blocked: contact.blocked,
);
} else {
receivingPushKeys[contact.userId]!.displayName =
getContactDisplayName(contact);
receivingPushKeys[contact.userId]!.blocked = contact.blocked;
}
await setPushKeys("receivingPushKeys", receivingPushKeys);
}
Future handleNewPushKey(int fromUserId, my.PushKeyContent pushKey) async { Future handleNewPushKey(int fromUserId, my.PushKeyContent pushKey) async {
var pushKeys = await getPushKeys("sendingPushKeys"); var pushKeys = await getPushKeys("sendingPushKeys");
if (pushKeys[fromUserId] == null) { if (pushKeys[fromUserId] == null) {
pushKeys[fromUserId] = PushUser(displayName: "-", keys: []); pushKeys[fromUserId] = PushUser(displayName: "-", keys: [], blocked: false);
} }
// only store the newest key... // only store the newest key...
@ -355,7 +379,14 @@ Future setPushKeys(String storageKey, Map<int, PushUser> pushKeys) async {
jsonToSend[key.toString()] = value.toJson(); jsonToSend[key.toString()] = value.toJson();
}); });
await storage.delete(key: storageKey); await storage.delete(
key: storageKey,
iOptions: IOSOptions(
groupId: "CN332ZUGRP.eu.twonly.shared",
synchronizable: false,
accessibility: KeychainAccessibility.first_unlock,
),
);
String jsonString = jsonEncode(jsonToSend); String jsonString = jsonEncode(jsonToSend);
await storage.write( await storage.write(
@ -433,6 +464,12 @@ Future showLocalPushNotification(
if (user == null) return; if (user == null) return;
// do not show notification for blocked users...
if (user.blocked) {
Log.info("Blocked a message from a blocked user!");
return;
}
title = getContactDisplayName(user); title = getContactDisplayName(user);
body = getPushNotificationText(pushKind); body = getPushNotificationText(pushKind);
if (body == "") { if (body == "") {

View file

@ -33,8 +33,11 @@ class NotificationView extends StatelessWidget {
if (storedToken == null) { if (storedToken == null) {
final platform = Platform.isAndroid ? "Google's" : "Apple's"; final platform = Platform.isAndroid ? "Google's" : "Apple's";
showAlertDialog(context, "Problem detected", showAlertDialog(
"twonly is not able to register your app to $platform push server infrastrukture. For Android that can happen when you do not have the Google Play Services installed. If you theses installed and want to help us to fix the issue please send us your debug log in Settings > Help > Debug log."); context,
"Problem detected",
"twonly is not able to register your app to $platform push server infrastructure. For Android that can happen when you do not have the Google Play Services installed. If you theses installed and want to help us to fix the issue please send us your debug log in Settings > Help > Debug log.",
);
} else { } else {
final run = await showAlertDialog( final run = await showAlertDialog(
context, context,