Refactor v1 and v2

This commit is contained in:
andrew 2023-06-21 10:01:35 +09:30
parent 0e0ab9151e
commit 42cfce0c3e
8 changed files with 215 additions and 148 deletions

View File

@ -18,7 +18,7 @@ import nl.komponents.kovenant.functional.map
import okhttp3.MediaType import okhttp3.MediaType
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import org.session.libsession.messaging.sending_receiving.notifications.LegacyGroupsPushManager 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.PushNotificationMetadata
import org.session.libsession.messaging.sending_receiving.notifications.Response import org.session.libsession.messaging.sending_receiving.notifications.Response
import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionRequest import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionRequest
@ -43,52 +43,18 @@ import org.thoughtcrime.securesms.crypto.KeyPairUtilities
private const val TAG = "FirebasePushManager" private const val TAG = "FirebasePushManager"
class FirebasePushManager (private val context: Context): PushManager { class FirebasePushManager(
private val context: Context
): PushManager {
private val pushManagerV2 = PushManagerV2(context)
companion object { companion object {
private const val maxRetryCount = 4 const val maxRetryCount = 4
} }
private val tokenManager = FcmTokenManager(context, ExpiryManager(context)) private val tokenManager = FcmTokenManager(context, ExpiryManager(context))
private var firebaseInstanceIdJob: Job? = null private var firebaseInstanceIdJob: Job? = null
private val sodium = LazySodiumAndroid(SodiumAndroid())
private fun getOrCreateNotificationKey(): Key {
if (IdentityKeyUtil.retrieve(context, IdentityKeyUtil.NOTIFICATION_KEY) == null) {
// generate the key and store it
val key = sodium.keygen(AEAD.Method.XCHACHA20_POLY1305_IETF)
IdentityKeyUtil.save(context, IdentityKeyUtil.NOTIFICATION_KEY, key.asHexString)
}
return Key.fromHexString(IdentityKeyUtil.retrieve(context, IdentityKeyUtil.NOTIFICATION_KEY))
}
fun decrypt(encPayload: ByteArray): ByteArray? {
Log.d(TAG, "decrypt() called")
val encKey = getOrCreateNotificationKey()
val nonce = encPayload.take(AEAD.XCHACHA20POLY1305_IETF_NPUBBYTES).toByteArray()
val payload = encPayload.drop(AEAD.XCHACHA20POLY1305_IETF_NPUBBYTES).toByteArray()
val padded = SodiumUtilities.decrypt(payload, encKey.asBytes, nonce)
?: error("Failed to decrypt push notification")
val decrypted = padded.dropLastWhile { it.toInt() == 0 }.toByteArray()
val bencoded = Bencode.Decoder(decrypted)
val expectedList = (bencoded.decode() as? BencodeList)?.values
?: error("Failed to decode bencoded list from payload")
val metadataJson = (expectedList[0] as? BencodeString)?.value ?: error("no metadata")
val metadata: PushNotificationMetadata = Json.decodeFromString(String(metadataJson))
val content: ByteArray? = if (expectedList.size >= 2) (expectedList[1] as? BencodeString)?.value else null
// null content is valid only if we got a "data_too_long" flag
if (content == null)
check(metadata.data_too_long) { "missing message data, but no too-long flag" }
else
check(metadata.data_len == content.size) { "wrong message data size" }
Log.d(TAG, "Received push for ${metadata.account}/${metadata.namespace}, msg ${metadata.msg_hash}, ${metadata.data_len}B")
return content
}
@Synchronized @Synchronized
override fun refresh(force: Boolean) { override fun refresh(force: Boolean) {
@ -143,12 +109,12 @@ class FirebasePushManager (private val context: Context): PushManager {
publicKey: String, publicKey: String,
userEd25519Key: KeyPair, userEd25519Key: KeyPair,
namespaces: List<Int> = listOf(Namespace.DEFAULT) namespaces: List<Int> = listOf(Namespace.DEFAULT)
): Promise<*, Exception> = LegacyGroupsPushManager.register(token, publicKey) and getSubscription( ): Promise<*, Exception> = PushManagerV1.register(token, publicKey) and pushManagerV2.register(
token, publicKey, userEd25519Key, namespaces token, publicKey, userEd25519Key, namespaces
) fail { ) fail {
Log.e(TAG, "Couldn't register for FCM due to error: $it.", it) Log.e(TAG, "Couldn't register for FCM due to error: $it.", it)
} success { } success {
Log.d(TAG, "register() success!!") Log.d(TAG, "register() success... saving token!!")
tokenManager.fcmToken = token tokenManager.fcmToken = token
} }
@ -156,82 +122,13 @@ class FirebasePushManager (private val context: Context): PushManager {
token: String, token: String,
userPublicKey: String, userPublicKey: String,
userEdKey: KeyPair userEdKey: KeyPair
): Promise<*, Exception> = LegacyGroupsPushManager.unregister() and getUnsubscription( ): Promise<*, Exception> = PushManagerV1.unregister() and pushManagerV2.unregister(
token, userPublicKey, userEdKey token, userPublicKey, userEdKey
) fail { ) fail {
Log.e(TAG, "Couldn't unregister for FCM due to error: ${it}.", it) Log.e(TAG, "Couldn't unregister for FCM due to error: $it.", it)
} success { } success {
tokenManager.fcmToken = null tokenManager.fcmToken = null
} }
private fun getSubscription( fun decrypt(decode: ByteArray) = pushManagerV2.decrypt(decode)
token: String,
publicKey: String,
userEd25519Key: KeyPair,
namespaces: List<Int>
): Promise<SubscriptionResponse, Exception> {
val pnKey = getOrCreateNotificationKey()
val timestamp = SnodeAPI.nowWithOffset / 1000 // get timestamp in ms -> s
// if we want to support passing namespace list, here is the place to do it
val sigData = "MONITOR${publicKey}${timestamp}1${namespaces.joinToString(separator = ",")}".encodeToByteArray()
val signature = ByteArray(Sign.BYTES)
sodium.cryptoSignDetached(signature, sigData, sigData.size.toLong(), userEd25519Key.secretKey.asBytes)
val requestParameters = SubscriptionRequest(
pubkey = publicKey,
session_ed25519 = userEd25519Key.publicKey.asHexString,
namespaces = listOf(Namespace.DEFAULT),
data = true, // only permit data subscription for now (?)
service = "firebase",
sig_ts = timestamp,
signature = Base64.encodeBytes(signature),
service_info = mapOf("token" to token),
enc_key = pnKey.asHexString,
).let(Json::encodeToString)
return retryResponseBody("subscribe", requestParameters)
}
private fun getUnsubscription(
token: String,
userPublicKey: String,
userEdKey: KeyPair
): Promise<UnsubscribeResponse, Exception> {
val timestamp = SnodeAPI.nowWithOffset / 1000 // get timestamp in ms -> s
// if we want to support passing namespace list, here is the place to do it
val sigData = "UNSUBSCRIBE${userPublicKey}${timestamp}".encodeToByteArray()
val signature = ByteArray(Sign.BYTES)
sodium.cryptoSignDetached(signature, sigData, sigData.size.toLong(), userEdKey.secretKey.asBytes)
val requestParameters = UnsubscriptionRequest(
pubkey = userPublicKey,
session_ed25519 = userEdKey.publicKey.asHexString,
service = "firebase",
sig_ts = timestamp,
signature = Base64.encodeBytes(signature),
service_info = mapOf("token" to token),
).let(Json::encodeToString)
return retryResponseBody("unsubscribe", requestParameters)
}
private inline fun <reified T: Response> retryResponseBody(path: String, requestParameters: String): Promise<T, Exception> =
retryIfNeeded(maxRetryCount) { getResponseBody(path, requestParameters) }
private inline fun <reified T: Response> getResponseBody(path: String, requestParameters: String): Promise<T, Exception> {
val url = "${LegacyGroupsPushManager.server}/$path"
val body = RequestBody.create(MediaType.get("application/json"), requestParameters)
val request = Request.Builder().url(url).post(body).build()
return OnionRequestAPI.sendOnionRequest(
request,
LegacyGroupsPushManager.server,
LegacyGroupsPushManager.serverPublicKey,
Version.V4
).map { response ->
response.body!!.inputStream()
.let { Json.decodeFromStream<T>(it) }
.also { if (it.isFailure()) throw Exception("error: ${it.message}.") }
}
}
} }

View File

@ -0,0 +1,155 @@
package org.thoughtcrime.securesms.notifications
import android.content.Context
import com.goterl.lazysodium.LazySodiumAndroid
import com.goterl.lazysodium.SodiumAndroid
import com.goterl.lazysodium.interfaces.AEAD
import com.goterl.lazysodium.interfaces.Sign
import com.goterl.lazysodium.utils.Key
import com.goterl.lazysodium.utils.KeyPair
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
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.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.SubscriptionRequest
import org.session.libsession.messaging.sending_receiving.notifications.SubscriptionResponse
import org.session.libsession.messaging.sending_receiving.notifications.UnsubscribeResponse
import org.session.libsession.messaging.sending_receiving.notifications.UnsubscriptionRequest
import org.session.libsession.messaging.utilities.SodiumUtilities
import org.session.libsession.snode.OnionRequestAPI
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.snode.Version
import org.session.libsession.utilities.bencode.Bencode
import org.session.libsession.utilities.bencode.BencodeList
import org.session.libsession.utilities.bencode.BencodeString
import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.Log
import org.session.libsignal.utilities.Namespace
import org.session.libsignal.utilities.retryIfNeeded
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
private const val TAG = "PushManagerV2"
class PushManagerV2(private val context: Context) {
private val sodium = LazySodiumAndroid(SodiumAndroid())
fun register(
token: String,
publicKey: String,
userEd25519Key: KeyPair,
namespaces: List<Int>
): Promise<SubscriptionResponse, Exception> {
val pnKey = getOrCreateNotificationKey()
val timestamp = SnodeAPI.nowWithOffset / 1000 // get timestamp in ms -> s
// if we want to support passing namespace list, here is the place to do it
val sigData = "MONITOR${publicKey}${timestamp}1${namespaces.joinToString(separator = ",")}".encodeToByteArray()
val signature = ByteArray(Sign.BYTES)
sodium.cryptoSignDetached(signature, sigData, sigData.size.toLong(), userEd25519Key.secretKey.asBytes)
val requestParameters = SubscriptionRequest(
pubkey = publicKey,
session_ed25519 = userEd25519Key.publicKey.asHexString,
namespaces = listOf(Namespace.DEFAULT),
data = true, // only permit data subscription for now (?)
service = "firebase",
sig_ts = timestamp,
signature = Base64.encodeBytes(signature),
service_info = mapOf("token" to token),
enc_key = pnKey.asHexString,
).let(Json::encodeToString)
return retryResponseBody<SubscriptionResponse>("subscribe", requestParameters) success {
Log.d(TAG, "register() success!!")
}
}
fun unregister(
token: String,
userPublicKey: String,
userEdKey: KeyPair
): Promise<UnsubscribeResponse, Exception> {
val timestamp = SnodeAPI.nowWithOffset / 1000 // get timestamp in ms -> s
// if we want to support passing namespace list, here is the place to do it
val sigData = "UNSUBSCRIBE${userPublicKey}${timestamp}".encodeToByteArray()
val signature = ByteArray(Sign.BYTES)
sodium.cryptoSignDetached(signature, sigData, sigData.size.toLong(), userEdKey.secretKey.asBytes)
val requestParameters = UnsubscriptionRequest(
pubkey = userPublicKey,
session_ed25519 = userEdKey.publicKey.asHexString,
service = "firebase",
sig_ts = timestamp,
signature = Base64.encodeBytes(signature),
service_info = mapOf("token" to token),
).let(Json::encodeToString)
return retryResponseBody<UnsubscribeResponse>("unsubscribe", requestParameters) success {
Log.d(TAG, "unregister() 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 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,
Version.V4
).map { response ->
response.body!!.inputStream()
.let { Json.decodeFromStream<T>(it) }
.also { if (it.isFailure()) throw Exception("error: ${it.message}.") }
}
}
private fun getOrCreateNotificationKey(): Key {
if (IdentityKeyUtil.retrieve(context, IdentityKeyUtil.NOTIFICATION_KEY) == null) {
// generate the key and store it
val key = sodium.keygen(AEAD.Method.XCHACHA20_POLY1305_IETF)
IdentityKeyUtil.save(context, IdentityKeyUtil.NOTIFICATION_KEY, key.asHexString)
}
return Key.fromHexString(IdentityKeyUtil.retrieve(context, IdentityKeyUtil.NOTIFICATION_KEY))
}
fun decrypt(encPayload: ByteArray): ByteArray? {
Log.d(TAG, "decrypt() called")
val encKey = getOrCreateNotificationKey()
val nonce = encPayload.take(AEAD.XCHACHA20POLY1305_IETF_NPUBBYTES).toByteArray()
val payload = encPayload.drop(AEAD.XCHACHA20POLY1305_IETF_NPUBBYTES).toByteArray()
val padded = SodiumUtilities.decrypt(payload, encKey.asBytes, nonce)
?: error("Failed to decrypt push notification")
val decrypted = padded.dropLastWhile { it.toInt() == 0 }.toByteArray()
val bencoded = Bencode.Decoder(decrypted)
val expectedList = (bencoded.decode() as? BencodeList)?.values
?: error("Failed to decode bencoded list from payload")
val metadataJson = (expectedList[0] as? BencodeString)?.value ?: error("no metadata")
val metadata: PushNotificationMetadata = Json.decodeFromString(String(metadataJson))
val content: ByteArray? = if (expectedList.size >= 2) (expectedList[1] as? BencodeString)?.value else null
// null content is valid only if we got a "data_too_long" flag
if (content == null)
check(metadata.data_too_long) { "missing message data, but no too-long flag" }
else
check(metadata.data_len == content.size) { "wrong message data size" }
Log.d(TAG, "Received push for ${metadata.account}/${metadata.namespace}, msg ${metadata.msg_hash}, ${metadata.data_len}B")
return content
}
}

View File

@ -8,7 +8,7 @@ import dagger.hilt.android.AndroidEntryPoint
import org.session.libsession.messaging.jobs.BatchMessageReceiveJob import org.session.libsession.messaging.jobs.BatchMessageReceiveJob
import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.JobQueue
import org.session.libsession.messaging.jobs.MessageReceiveParameters import org.session.libsession.messaging.jobs.MessageReceiveParameters
import org.session.libsession.messaging.sending_receiving.notifications.LegacyGroupsPushManager import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.messaging.utilities.MessageWrapper
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.Base64
@ -69,6 +69,6 @@ class PushNotificationService : FirebaseMessagingService() {
override fun onDeletedMessages() { override fun onDeletedMessages() {
Log.d(TAG, "Called onDeletedMessages.") Log.d(TAG, "Called onDeletedMessages.")
super.onDeletedMessages() super.onDeletedMessages()
LegacyGroupsPushManager.register() PushManagerV1.register()
} }
} }

View File

@ -8,8 +8,8 @@ import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import org.session.libsession.messaging.jobs.Job.Companion.MAX_BUFFER_SIZE import org.session.libsession.messaging.jobs.Job.Companion.MAX_BUFFER_SIZE
import org.session.libsession.messaging.sending_receiving.notifications.LegacyGroupsPushManager import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
import org.session.libsession.messaging.sending_receiving.notifications.LegacyGroupsPushManager.server import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1.server
import org.session.libsession.messaging.utilities.Data import org.session.libsession.messaging.utilities.Data
import org.session.libsession.snode.SnodeMessage import org.session.libsession.snode.SnodeMessage
import org.session.libsession.snode.OnionRequestAPI import org.session.libsession.snode.OnionRequestAPI
@ -41,7 +41,7 @@ class NotifyPNServerJob(val message: SnodeMessage) : Job {
OnionRequestAPI.sendOnionRequest( OnionRequestAPI.sendOnionRequest(
request, request,
server, server,
LegacyGroupsPushManager.serverPublicKey, PushManagerV1.serverPublicKey,
Version.V2 Version.V2
) success { response -> ) success { response ->
when (response.info["code"]) { when (response.info["code"]) {

View File

@ -8,7 +8,7 @@ import nl.komponents.kovenant.deferred
import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage
import org.session.libsession.messaging.sending_receiving.MessageSender.Error import org.session.libsession.messaging.sending_receiving.MessageSender.Error
import org.session.libsession.messaging.sending_receiving.notifications.LegacyGroupsPushManager import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2 import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2
import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address
@ -83,7 +83,7 @@ fun MessageSender.create(name: String, members: Collection<String>): Promise<Str
} }
// Notify the PN server // Notify the PN server
LegacyGroupsPushManager.register(publicKey = userPublicKey) PushManagerV1.register(publicKey = userPublicKey)
// Start polling // Start polling
ClosedGroupPollerV2.shared.startPolling(groupPublicKey) ClosedGroupPollerV2.shared.startPolling(groupPublicKey)
// Fulfill the promise // Fulfill the promise

View File

@ -23,7 +23,7 @@ import org.session.libsession.messaging.open_groups.OpenGroupApi
import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment
import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
import org.session.libsession.messaging.sending_receiving.notifications.LegacyGroupsPushManager import org.session.libsession.messaging.sending_receiving.notifications.PushManagerV1
import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2 import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPollerV2
import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel
import org.session.libsession.messaging.utilities.SessionId import org.session.libsession.messaging.utilities.SessionId
@ -479,7 +479,7 @@ private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPubli
// Set expiration timer // Set expiration timer
storage.setExpirationTimer(groupID, expireTimer) storage.setExpirationTimer(groupID, expireTimer)
// Notify the PN server // Notify the PN server
LegacyGroupsPushManager.register(publicKey = userPublicKey) PushManagerV1.register(publicKey = userPublicKey)
// Notify the user // Notify the user
if (userPublicKey == sender && !groupExists) { if (userPublicKey == sender && !groupExists) {
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID)) val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(groupID))
@ -772,7 +772,7 @@ fun MessageReceiver.disableLocalGroupAndUnsubscribe(groupPublicKey: String, grou
storage.setActive(groupID, false) storage.setActive(groupID, false)
storage.removeMember(groupID, Address.fromSerialized(userPublicKey)) storage.removeMember(groupID, Address.fromSerialized(userPublicKey))
// Notify the PN server // Notify the PN server
LegacyGroupsPushManager.register(publicKey = userPublicKey) PushManagerV1.register(publicKey = userPublicKey)
// Stop polling // Stop polling
ClosedGroupPollerV2.shared.stopPolling(groupPublicKey) ClosedGroupPollerV2.shared.stopPolling(groupPublicKey)
} }

View File

@ -2,7 +2,6 @@ package org.session.libsession.messaging.sending_receiving.notifications
import android.annotation.SuppressLint import android.annotation.SuppressLint
import nl.komponents.kovenant.Promise import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.all
import nl.komponents.kovenant.functional.map import nl.komponents.kovenant.functional.map
import okhttp3.MediaType import okhttp3.MediaType
import okhttp3.Request import okhttp3.Request
@ -17,8 +16,8 @@ import org.session.libsignal.utilities.emptyPromise
import org.session.libsignal.utilities.retryIfNeeded import org.session.libsignal.utilities.retryIfNeeded
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
object LegacyGroupsPushManager { object PushManagerV1 {
private const val TAG = "LegacyGroupsPushManager" private const val TAG = "PushManagerV1"
val context = MessagingModuleConfiguration.shared.context val context = MessagingModuleConfiguration.shared.context
const val server = "https://push.getsession.org" const val server = "https://push.getsession.org"
@ -31,29 +30,46 @@ object LegacyGroupsPushManager {
token: String? = TextSecurePreferences.getFCMToken(context), token: String? = TextSecurePreferences.getFCMToken(context),
publicKey: String? = TextSecurePreferences.getLocalNumber(context), publicKey: String? = TextSecurePreferences.getLocalNumber(context),
legacyGroupPublicKeys: Collection<String> = MessagingModuleConfiguration.shared.storage.getAllClosedGroupPublicKeys() legacyGroupPublicKeys: Collection<String> = MessagingModuleConfiguration.shared.storage.getAllClosedGroupPublicKeys()
): Promise<Unit, Exception> = ): Promise<*, Exception> =
retryIfNeeded(maxRetryCount) { retryIfNeeded(maxRetryCount) {
Log.d(TAG, "register() called") doRegister(token, publicKey, legacyGroupPublicKeys)
val parameters = mapOf(
"token" to token!!,
"pubKey" to publicKey!!,
"legacyGroupPublicKeys" to legacyGroupPublicKeys.takeIf { it.isNotEmpty() }!!
)
val url = "$legacyServer/register_legacy_groups_only"
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).map { response ->
when (response.info["code"]) {
null, 0 -> throw Exception("error: ${response.info["message"]}.")
else -> Log.d(TAG, "register() success!!")
}
}
} fail { exception -> } fail { exception ->
Log.d(TAG, "Couldn't register for FCM due to error: ${exception}.") Log.d(TAG, "Couldn't register for FCM due to error: ${exception}.")
} success {
Log.d(TAG, "register success!!")
} }
private fun doRegister(token: String?, publicKey: String?, legacyGroupPublicKeys: Collection<String>): Promise<*, Exception> {
Log.d(TAG, "doRegister() called $token, $publicKey, $legacyGroupPublicKeys")
token ?: return emptyPromise()
publicKey ?: return emptyPromise()
legacyGroupPublicKeys.takeIf { it.isNotEmpty() } ?: return emptyPromise()
Log.d(TAG, "actually registering...")
val parameters = mapOf(
"token" to token,
"pubKey" to publicKey,
"legacyGroupPublicKeys" to legacyGroupPublicKeys
)
val url = "$legacyServer/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, "register() success!!")
}
} success {
Log.d(TAG, "onion request success")
} fail {
Log.d(TAG, "onion fail: $it")
}
}
/** /**
* Unregister push notifications for 1-1 conversations as this is now done in FirebasePushManager. * Unregister push notifications for 1-1 conversations as this is now done in FirebasePushManager.
*/ */
@ -74,7 +90,7 @@ object LegacyGroupsPushManager {
legacyServerPublicKey, legacyServerPublicKey,
Version.V2 Version.V2
) success { ) success {
android.util.Log.d(TAG, "unregister() success!!") Log.d(TAG, "unregister() success!!")
when (it.info["code"]) { when (it.info["code"]) {
null, 0 -> throw Exception("error: ${it.info["message"]}.") null, 0 -> throw Exception("error: ${it.info["message"]}.")

View File

@ -28,4 +28,3 @@ fun <V, T : Promise<V, Exception>> retryIfNeeded(maxRetryCount: Int, retryInterv
retryIfNeeded() retryIfNeeded()
return deferred.promise return deferred.promise
} }