From 2246a5d9ce01f52fefda7e51457f221f7d18782d Mon Sep 17 00:00:00 2001 From: 0x330a <92654767+0x330a@users.noreply.github.com> Date: Wed, 19 Apr 2023 23:07:36 +1000 Subject: [PATCH] feat: introduce new pns models and wire kotlinx serialization to apply in libsession --- app/build.gradle | 15 ------ .../securesms/ApplicationContext.java | 8 +-- ...nManager.kt => PushNotificationManager.kt} | 2 +- .../notifications/PushNotificationService.kt | 4 +- build.gradle | 4 +- libsession/build.gradle | 2 + .../sending_receiving/notifications/Models.kt | 52 +++++++++++++++++++ .../notifications/PushNotificationAPI.kt | 4 +- 8 files changed, 66 insertions(+), 25 deletions(-) rename app/src/main/java/org/thoughtcrime/securesms/notifications/{LokiPushNotificationManager.kt => PushNotificationManager.kt} (99%) create mode 100644 libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/Models.kt diff --git a/app/build.gradle b/app/build.gradle index b861220339..a2bb940922 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,18 +1,3 @@ -buildscript { - repositories { - google() - mavenCentral() - } - dependencies { - classpath "com.android.tools.build:gradle:$gradlePluginVersion" - classpath files('libs/gradle-witness.jar') - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" - classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion" - classpath "com.google.gms:google-services:$googleServicesVersion" - classpath "com.google.dagger:hilt-android-gradle-plugin:$daggerVersion" - } -} - apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'witness' diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index a605a84922..2fc53dc244 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -76,7 +76,7 @@ import org.thoughtcrime.securesms.logging.UncaughtExceptionLogger; import org.thoughtcrime.securesms.notifications.BackgroundPollWorker; import org.thoughtcrime.securesms.notifications.DefaultMessageNotifier; import org.thoughtcrime.securesms.notifications.FcmUtils; -import org.thoughtcrime.securesms.notifications.LokiPushNotificationManager; +import org.thoughtcrime.securesms.notifications.PushNotificationManager; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.OptimizedMessageNotifier; import org.thoughtcrime.securesms.providers.BlobProvider; @@ -455,9 +455,9 @@ public class ApplicationContext extends Application implements DefaultLifecycleO AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> { if (TextSecurePreferences.isUsingFCM(this)) { - LokiPushNotificationManager.register(token, userPublicKey, this, force); + PushNotificationManager.register(token, userPublicKey, this, force); } else { - LokiPushNotificationManager.unregister(token, this); + PushNotificationManager.unregister(token, this); } }); @@ -536,7 +536,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO public void clearAllData(boolean isMigratingToV2KeyPair) { String token = TextSecurePreferences.getFCMToken(this); if (token != null && !token.isEmpty()) { - LokiPushNotificationManager.unregister(token, this); + PushNotificationManager.unregister(token, this); } if (firebaseInstanceIdJob != null && firebaseInstanceIdJob.isActive()) { firebaseInstanceIdJob.cancel(null); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/LokiPushNotificationManager.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/PushNotificationManager.kt similarity index 99% rename from app/src/main/java/org/thoughtcrime/securesms/notifications/LokiPushNotificationManager.kt rename to app/src/main/java/org/thoughtcrime/securesms/notifications/PushNotificationManager.kt index adaec0e17a..5a53f7af22 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/LokiPushNotificationManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/PushNotificationManager.kt @@ -15,7 +15,7 @@ import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.retryIfNeeded import org.thoughtcrime.securesms.dependencies.DatabaseComponent -object LokiPushNotificationManager { +object PushNotificationManager { private val maxRetryCount = 4 private val tokenExpirationInterval = 12 * 60 * 60 * 1000 diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/PushNotificationService.kt b/app/src/main/java/org/thoughtcrime/securesms/notifications/PushNotificationService.kt index fc399d293e..b7a92e3b76 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/PushNotificationService.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/PushNotificationService.kt @@ -18,7 +18,7 @@ class PushNotificationService : FirebaseMessagingService() { super.onNewToken(token) Log.d("Loki", "New FCM token: $token.") val userPublicKey = TextSecurePreferences.getLocalNumber(this) ?: return - LokiPushNotificationManager.register(token, userPublicKey, this, false) + PushNotificationManager.register(token, userPublicKey, this, false) } override fun onMessageReceived(message: RemoteMessage) { @@ -53,6 +53,6 @@ class PushNotificationService : FirebaseMessagingService() { super.onDeletedMessages() val token = TextSecurePreferences.getFCMToken(this)!! val userPublicKey = TextSecurePreferences.getLocalNumber(this) ?: return - LokiPushNotificationManager.register(token, userPublicKey, this, true) + PushNotificationManager.register(token, userPublicKey, this, true) } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 7e7e14f00f..64a1fd4d02 100644 --- a/build.gradle +++ b/build.gradle @@ -5,9 +5,11 @@ buildscript { } dependencies { classpath "com.android.tools.build:gradle:$gradlePluginVersion" + classpath files('libs/gradle-witness.jar') classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" + classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion" classpath "com.google.gms:google-services:$googleServicesVersion" - classpath files('libs/gradle-witness.jar') + classpath "com.google.dagger:hilt-android-gradle-plugin:$daggerVersion" } } diff --git a/libsession/build.gradle b/libsession/build.gradle index dd8959958e..2241cfb3c5 100644 --- a/libsession/build.gradle +++ b/libsession/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.library' id 'kotlin-android' + id 'kotlinx-serialization' } android { @@ -41,6 +42,7 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxJsonVersion" implementation "nl.komponents.kovenant:kovenant:$kovenantVersion" testImplementation "junit:junit:$junitVersion" testImplementation 'org.assertj:assertj-core:3.11.1' diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/Models.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/Models.kt new file mode 100644 index 0000000000..e37b5b0b60 --- /dev/null +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/Models.kt @@ -0,0 +1,52 @@ +package org.session.libsession.messaging.sending_receiving.notifications + +import kotlinx.serialization.Serializable + +@Serializable +data class SubscriptionRequest( + /** the 33-byte account being subscribed to; typically a session ID */ + val pubkey: String, + /** when the pubkey starts with 05 (i.e. a session ID) this is the ed25519 32-byte pubkey associated with the session ID */ + val session_ed25519: String?, + /** 32-byte swarm authentication subkey; omitted (or null) when not using subkey auth (new closed groups) */ + val subkey_tag: String?, + /** array of integer namespaces to subscribe to, **must be sorted in ascending order** */ + val namespaces: List, + /** if provided and true then notifications will include the body of the message (as long as it isn't too large) */ + val data: Boolean, + /** the signature unix timestamp in seconds, not ms */ + val sig_ts: Long, + /** the 64-byte ed25519 signature */ + val signature: String, + /** the string identifying the notification service, "firebase" for android (currently) */ + val service: String, + /** dict of service-specific data, currently just "token" field with device-specific token but different services might have other requirements */ + val service_info: Map, + /** 32-byte encryption key; notification payloads sent to the device will be encrypted with XChaCha20-Poly1305 via libsodium using this key. + * persist it on device */ + val enc_key: String +) + +@Serializable +data class SubscriptionResponse( + val error: Int?, + val message: String?, + val success: Boolean?, + val added: Boolean?, + val updated: Boolean?, +) { + companion object { + /** invalid values, missing reuqired arguments etc, details in message */ + const val UNPARSEABLE_ERROR = 1 + /** the "service" value is not active / valid */ + const val SERVICE_NOT_AVAILABLE = 2 + /** something getting wrong internally talking to the backend */ + const val SERVICE_TIMEOUT = 3 + /** other error processing the subscription (details in the message) */ + const val GENERIC_ERROR = 4 + } + fun isSuccess() = success == true && error == null + fun errorInfo() = if (success == false && error != null) { + true to message + } else false to null +} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt index f793cd6e4b..e49375babe 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt @@ -16,8 +16,8 @@ import org.session.libsignal.utilities.Log @SuppressLint("StaticFieldLeak") object PushNotificationAPI { val context = MessagingModuleConfiguration.shared.context - val server = "https://live.apns.getsession.org" - val serverPublicKey = "642a6585919742e5a2d4dc51244964fbcd8bcab2b75612407de58b810740d049" + val server = "https://push.getsession.org" + val serverPublicKey: String = TODO("get the new server pubkey here") private val maxRetryCount = 4 private val tokenExpirationInterval = 12 * 60 * 60 * 1000