Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utilise new Push Notification endpoint for 1-on-1 conversations. #1249

Merged
merged 22 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2246a5d
feat: introduce new pns models and wire kotlinx serialization to appl…
0x330a Apr 19, 2023
8d4f244
feat: add support for firebase and split out google services as a dep…
0x330a Apr 20, 2023
7762d53
feat: add no op push manager for de-googled
0x330a Apr 20, 2023
d2e80c3
feat: re-add bencode utility and fix tests to use bytearray instead o…
0x330a Oct 28, 2022
46acd78
New SPNS subscription and notifications
jagerman May 18, 2023
95bb9ee
refactor: remove some unnecessary code for legacy PN registration
0x330a May 24, 2023
ba6eca2
Add FirebasePushManager#unregister
bemusementpark Jun 9, 2023
3f6229f
Remove PushNotificationManager
bemusementpark Jun 9, 2023
01d80ae
cleanup PushNotificationAPI
bemusementpark Jun 9, 2023
be4d742
Unregister v1 push
bemusementpark Jun 9, 2023
b2a1b5f
Add token to FCM logs
bemusementpark Jun 10, 2023
288b70b
Store legacy fcm token to reduce unregister api calls
bemusementpark Jun 13, 2023
153aa4c
Reinstate push v1
bemusementpark Jun 14, 2023
667af27
Utilise TokenManager and ExpiryManager
bemusementpark Jun 16, 2023
5c9dc36
Merge branch 'dev' into add-unregister
bemusementpark Jun 20, 2023
0e0ab91
cleanup
bemusementpark Jun 20, 2023
42cfce0
Refactor v1 and v2
bemusementpark Jun 21, 2023
e3f60eb
Fix individual group subs
bemusementpark Jun 21, 2023
dc7602a
Check fcm is enabled before modifying group sub
bemusementpark Jun 21, 2023
8be088a
Reinstate v1 PNServerJob
bemusementpark Jun 23, 2023
002793b
Merge branch 'dev' into add-unregister
bemusementpark Jul 21, 2023
58cda9b
Fix website
bemusementpark Jul 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class FirebasePushManager(

firebaseInstanceIdJob = getFcmInstanceId { task ->
when {
task.isSuccessful -> try { task.result?.token?.let { refresh(it, force).get() } } catch(e: Exception) { Log.d(TAG, "refresh() failed", e) }
task.isSuccessful -> try { task.result?.token?.let { refresh(it, force).get() } } catch(e: Exception) { Log.e(TAG, "refresh() failed", e) }
else -> Log.w(TAG, "getFcmInstanceId failed." + task.exception)
}
}
Expand Down Expand Up @@ -115,9 +115,9 @@ class FirebasePushManager(
) and pushManagerV2.register(
token, publicKey, userEd25519Key, namespaces
) fail {
Log.e(TAG, "Couldn't register for FCM due to error: $it.", it)
Log.e(TAG, "registerBoth failed", it)
} success {
Log.d(TAG, "register() success... saving token!!")
Log.d(TAG, "registerBoth success... saving token!!")
tokenManager.fcmToken = token
}

Expand All @@ -128,7 +128,7 @@ class FirebasePushManager(
): Promise<*, Exception> = PushManagerV1.unregister() and pushManagerV2.unregister(
token, userPublicKey, userEdKey
) fail {
Log.e(TAG, "Couldn't unregister for FCM due to error: $it.", it)
Log.e(TAG, "unregisterBoth failed", it)
} success {
tokenManager.fcmToken = null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import okhttp3.RequestBody
import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationMetadata
import org.session.libsession.messaging.sending_receiving.notifications.Response
import org.session.libsession.messaging.sending_receiving.notifications.Server
import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionRequest
import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionResponse
import org.session.libsession.messaging.sending_receiving.notifications.UnsubscribeResponse
Expand Down Expand Up @@ -67,7 +68,7 @@ class PushManagerV2(private val context: Context) {
).let(Json::encodeToString)

return retryResponseBody<SubscriptionResponse>("subscribe", requestParameters) success {
Log.d(TAG, "register() success!!")
Log.d(TAG, "registerV2 success")
}
}

Expand All @@ -92,22 +93,23 @@ class PushManagerV2(private val context: Context) {
).let(Json::encodeToString)

return retryResponseBody<UnsubscribeResponse>("unsubscribe", requestParameters) success {
Log.d(TAG, "unregister() success!!")
Log.d(TAG, "unregisterV2 success")
}
}

private inline fun <reified T: Response> retryResponseBody(path: String, requestParameters: String): Promise<T, Exception> =
retryIfNeeded(FirebasePushManager.maxRetryCount) { getResponseBody(path, requestParameters) }

private inline fun <reified T: Response> getResponseBody(path: String, requestParameters: String): Promise<T, Exception> {
val url = "${PushManagerV1.server}/$path"
val server = Server.LATEST
val url = "${server.url}/$path"
val body = RequestBody.create(MediaType.get("application/json"), requestParameters)
val request = Request.Builder().url(url).post(body).build()

return OnionRequestAPI.sendOnionRequest(
request,
PushManagerV1.server,
PushManagerV1.serverPublicKey,
server.url,
server.publicKey,
Version.V4
).map { response ->
response.body!!.inputStream()
Expand Down Expand Up @@ -152,4 +154,4 @@ class PushManagerV2(private val context: Context) {

return content
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import okhttp3.Request
import okhttp3.RequestBody
import org.session.libsession.messaging.jobs.Job.Companion.MAX_BUFFER_SIZE

import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1.server
import org.session.libsession.messaging.sending_receiving.notifications.Server
import org.session.libsession.messaging.utilities.Data
import org.session.libsession.snode.SnodeMessage
import org.session.libsession.snode.OnionRequestAPI
Expand All @@ -33,26 +32,27 @@ class NotifyPNServerJob(val message: SnodeMessage) : Job {
}

override fun execute(dispatcherName: String) {
val server = Server.LEGACY
val parameters = mapOf( "data" to message.data, "send_to" to message.recipient )
val url = "${server}/notify"
val url = "${server.url}/notify"
val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters))
val request = Request.Builder().url(url).post(body).build()
retryIfNeeded(4) {
OnionRequestAPI.sendOnionRequest(
request,
server,
PushManagerV1.serverPublicKey,
server.url,
server.publicKey,
Version.V2
) success { response ->
when (response.info["code"]) {
null, 0 -> Log.d("Loki", "Couldn't notify PN server due to error: ${response.info["message"]}.")
when (response.code) {
null, 0 -> Log.d("NotifyPNServerJob", "Couldn't notify PN server due to error: ${response.message}.")
}
} fail { exception ->
Log.d("Loki", "Couldn't notify PN server due to error: $exception.")
Log.d("NotifyPNServerJob", "Couldn't notify PN server due to error: $exception.")
}
}.success {
} success {
handleSuccess(dispatcherName)
}. fail {
} fail {
handleFailure(dispatcherName, it)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package org.session.libsession.messaging.sending_receiving.notifications

import android.annotation.SuppressLint
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.functional.map
import okhttp3.MediaType
import okhttp3.Request
import okhttp3.RequestBody
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.snode.OnionRequestAPI
import org.session.libsession.snode.OnionResponse
import org.session.libsession.snode.Version
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.utilities.JsonUtil
Expand All @@ -21,12 +21,10 @@ object PushManagerV1 {
private const val TAG = "PushManagerV1"

val context = MessagingModuleConfiguration.shared.context
const val server = "https://push.getsession.org"
const val serverPublicKey: String = "d7557fe563e2610de876c0ac7341b62f3c82d5eea4b62c702392ea4368f51b3b"
private const val legacyServer = "https://dev.apns.getsession.org"
private const val legacyServerPublicKey = "642a6585919742e5a2d4dc51244964fbcd8bcab2b75612407de58b810740d049"
private const val maxRetryCount = 4

private val server = Server.LEGACY

fun register(
isUsingFCM: Boolean = TextSecurePreferences.isUsingFCM(context),
token: String? = TextSecurePreferences.getFCMToken(context),
Expand All @@ -38,58 +36,51 @@ object PushManagerV1 {
} else retryIfNeeded(maxRetryCount) {
doRegister(token, publicKey, legacyGroupPublicKeys)
} fail { exception ->
Log.d(TAG, "Couldn't register for FCM due to error: ${exception}.")
} success {
Log.d(TAG, "register success")
Log.d(TAG, "Couldn't register for FCM due to error: $exception.")
}

private fun doRegister(token: String?, publicKey: String?, legacyGroupPublicKeys: Collection<String>): Promise<*, Exception> {
Log.d(TAG, "doRegister() called")
Log.d(TAG, "registerV1 requested")

token ?: return emptyPromise()
publicKey ?: return emptyPromise()
legacyGroupPublicKeys.takeIf { it.isNotEmpty() } ?: return unregister()

val parameters = mapOf(
"token" to token,
"pubKey" to publicKey,
"legacyGroupPublicKeys" to legacyGroupPublicKeys
)

val url = "$legacyServer/register_legacy_groups_only"
val url = "${server.url}/register_legacy_groups_only"
val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters))
val request = Request.Builder().url(url).post(body).build()

return OnionRequestAPI.sendOnionRequest(request, legacyServer, legacyServerPublicKey, Version.V2).map { response ->
when (response.info["code"]) {
null, 0 -> throw Exception("error: ${response.info["message"]}.")
else -> Log.d(TAG, "doRegister success")
return sendOnionRequest(request) sideEffect { response ->
when (response.code) {
null, 0 -> throw Exception("error: ${response.message}.")
}
} success {
Log.d(TAG, "registerV1 success")
}
}

/**
* Unregister push notifications for 1-1 conversations as this is now done in FirebasePushManager.
*/
fun unregister(): Promise<*, Exception> {
Log.d(TAG, "unregister() called")
Log.d(TAG, "unregisterV1 requested")

val token = TextSecurePreferences.getFCMToken(context) ?: emptyPromise()

return retryIfNeeded(maxRetryCount) {
val parameters = mapOf( "token" to token )
val url = "$legacyServer/unregister"
val url = "${server.url}/unregister"
val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters))
val request = Request.Builder().url(url).post(body).build()

OnionRequestAPI.sendOnionRequest(
request,
legacyServer,
legacyServerPublicKey,
Version.V2
) success {
when (it.info["code"]) {
null, 0 -> throw Exception("error: ${it.info["message"]}.")
sendOnionRequest(request) success {
when (it.code) {
null, 0 -> throw Exception("error: ${it.message}.")
else -> Log.d(TAG, "unregisterV1 success")
}
}
Expand Down Expand Up @@ -120,21 +111,23 @@ object PushManagerV1 {
publicKey: String
): Promise<*, Exception> {
val parameters = mapOf( "closedGroupPublicKey" to closedGroupPublicKey, "pubKey" to publicKey )
val url = "$legacyServer/$operation"
val url = "${server.url}/$operation"
val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters))
val request = Request.Builder().url(url).post(body).build()

return retryIfNeeded(maxRetryCount) {
OnionRequestAPI.sendOnionRequest(
request,
legacyServer,
legacyServerPublicKey,
Version.V2
) sideEffect {
when (it.info["code"]) {
0, null -> throw Exception("${it.info["message"]}")
sendOnionRequest(request) sideEffect {
when (it.code) {
0, null -> throw Exception(it.message)
}
}
}
}

private fun sendOnionRequest(request: Request): Promise<OnionResponse, Exception> = OnionRequestAPI.sendOnionRequest(
request,
server.url,
server.publicKey,
Version.V2
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.session.libsession.messaging.sending_receiving.notifications

enum class Server(val url: String, val publicKey: String) {
LATEST("https://push.getsession.org", "d7557fe563e2610de876c0ac7341b62f3c82d5eea4b62c702392ea4368f51b3b"),
LEGACY("https://dev.apns.getsession.org", "642a6585919742e5a2d4dc51244964fbcd8bcab2b75612407de58b810740d049")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this one still be dev or we are just testing it for now?

}
Original file line number Diff line number Diff line change
Expand Up @@ -684,4 +684,7 @@ enum class Version(val value: String) {
data class OnionResponse(
val info: Map<*, *>,
val body: ByteArray? = null
)
) {
val code: Int? get() = info["code"] as? Int
val message: String? get() = info["message"] as? String
}