mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-24 15:58:22 +00:00
feat: add background group creation and placeholder spinny progress
This commit is contained in:
@@ -23,6 +23,7 @@ import org.session.libsignal.utilities.Log
|
||||
import org.session.libsignal.utilities.Namespace
|
||||
import org.session.libsignal.utilities.SessionId
|
||||
import org.session.libsignal.utilities.Snode
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
class ClosedGroupPoller(private val executor: CoroutineScope,
|
||||
private val closedGroupSessionId: SessionId,
|
||||
@@ -97,6 +98,12 @@ class ClosedGroupPoller(private val executor: CoroutineScope,
|
||||
val members = configFactoryProtocol.getGroupMemberConfig(closedGroupSessionId) ?: return null
|
||||
val keys = configFactoryProtocol.getGroupKeysConfig(closedGroupSessionId) ?: return null
|
||||
|
||||
val hashesToExtend = mutableSetOf<String>()
|
||||
|
||||
hashesToExtend += info.currentHashes()
|
||||
hashesToExtend += members.currentHashes()
|
||||
hashesToExtend += keys.currentHashes()
|
||||
|
||||
val keysIndex = 0
|
||||
val infoIndex = 1
|
||||
val membersIndex = 2
|
||||
@@ -133,14 +140,26 @@ class ClosedGroupPoller(private val executor: CoroutineScope,
|
||||
group.signingKey()
|
||||
) ?: return null
|
||||
|
||||
val requests = mutableListOf(keysPoll, infoPoll, membersPoll, messagePoll)
|
||||
|
||||
if (hashesToExtend.isNotEmpty()) {
|
||||
SnodeAPI.buildAuthenticatedAlterTtlBatchRequest(
|
||||
messageHashes = hashesToExtend.toList(),
|
||||
publicKey = closedGroupSessionId.hexString(),
|
||||
signingKey = group.signingKey(),
|
||||
newExpiry = SnodeAPI.nowWithOffset + 14.days.inWholeMilliseconds,
|
||||
extend = true
|
||||
)?.let { extensionRequest ->
|
||||
requests += extensionRequest
|
||||
}
|
||||
}
|
||||
|
||||
val pollResult = SnodeAPI.getRawBatchResponse(
|
||||
snode,
|
||||
closedGroupSessionId.hexString(),
|
||||
listOf(keysPoll, infoPoll, membersPoll, messagePoll)
|
||||
requests
|
||||
).get()
|
||||
|
||||
// TODO: add the extend duration TTLs for known hashes here
|
||||
|
||||
// if poll result body is null here we don't have any things ig
|
||||
if (ENABLE_LOGGING) Log.d("ClosedGroupPoller", "Poll results @${SnodeAPI.nowWithOffset}:")
|
||||
(pollResult["results"] as List<RawResponse>).forEachIndexed { index, response ->
|
||||
|
@@ -525,9 +525,11 @@ object SnodeAPI {
|
||||
messageHashes: List<String>,
|
||||
newExpiry: Long,
|
||||
publicKey: String,
|
||||
signingKey: ByteArray,
|
||||
pubKeyEd25519: String? = null,
|
||||
shorten: Boolean = false,
|
||||
extend: Boolean = false): SnodeBatchRequestInfo? {
|
||||
val params = buildAlterTtlParams(messageHashes, newExpiry, publicKey, extend, shorten) ?: return null
|
||||
val params = buildAlterTtlParams(messageHashes, newExpiry, publicKey, signingKey, pubKeyEd25519, extend, shorten) ?: return null
|
||||
return SnodeBatchRequestInfo(
|
||||
Snode.Method.Expire.rawValue,
|
||||
params,
|
||||
@@ -535,6 +537,28 @@ object SnodeAPI {
|
||||
)
|
||||
}
|
||||
|
||||
fun buildAuthenticatedAlterTtlBatchRequest(
|
||||
messageHashes: List<String>,
|
||||
newExpiry: Long,
|
||||
publicKey: String,
|
||||
shorten: Boolean = false,
|
||||
extend: Boolean = false): SnodeBatchRequestInfo? {
|
||||
val userEd25519KeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair() ?: return null
|
||||
val signingKey = userEd25519KeyPair.secretKey.asBytes
|
||||
val pubKeyEd25519 = userEd25519KeyPair.publicKey.asHexString
|
||||
return buildAuthenticatedAlterTtlBatchRequest(
|
||||
messageHashes,
|
||||
newExpiry,
|
||||
publicKey,
|
||||
signingKey,
|
||||
pubKeyEd25519,
|
||||
shorten,
|
||||
extend
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun getRawBatchResponse(snode: Snode, publicKey: String, requests: List<SnodeBatchRequestInfo>, sequence: Boolean = false): RawResponsePromise {
|
||||
val parameters = mutableMapOf<String, Any>(
|
||||
"requests" to requests
|
||||
@@ -587,9 +611,18 @@ object SnodeAPI {
|
||||
}
|
||||
}
|
||||
|
||||
fun alterTtl(messageHashes: List<String>, newExpiry: Long, publicKey: String, extend: Boolean = false, shorten: Boolean = false): RawResponsePromise {
|
||||
fun alterTtl(messageHashes: List<String>,
|
||||
newExpiry: Long,
|
||||
publicKey: String,
|
||||
extend: Boolean = false,
|
||||
shorten: Boolean = false): RawResponsePromise {
|
||||
return retryIfNeeded(maxRetryCount) {
|
||||
val params = buildAlterTtlParams(messageHashes, newExpiry, publicKey, extend, shorten)
|
||||
val userEd25519KeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair() ?: return@retryIfNeeded Promise.ofFail(
|
||||
Exception("No user key pair to sign alter ttl message")
|
||||
)
|
||||
val signingKey = userEd25519KeyPair.secretKey.asBytes
|
||||
val pubKeyEd25519 = userEd25519KeyPair.publicKey.asHexString
|
||||
val params = buildAlterTtlParams(messageHashes, newExpiry, publicKey, signingKey, pubKeyEd25519, extend, shorten)
|
||||
?: return@retryIfNeeded Promise.ofFail(
|
||||
Exception("Couldn't build signed params for alterTtl request for newExpiry=$newExpiry, extend=$extend, shorten=$shorten")
|
||||
)
|
||||
@@ -599,13 +632,15 @@ object SnodeAPI {
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildAlterTtlParams( // TODO: in future this will probably need to use the closed group subkeys / admin keys for group swarms
|
||||
private fun buildAlterTtlParams(
|
||||
messageHashes: List<String>,
|
||||
newExpiry: Long,
|
||||
publicKey: String,
|
||||
signingKey: ByteArray,
|
||||
pubKeyEd25519: String? = null,
|
||||
extend: Boolean = false,
|
||||
shorten: Boolean = false): Map<String, Any>? {
|
||||
val userEd25519KeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair() ?: return null
|
||||
|
||||
val params = mutableMapOf(
|
||||
"expiry" to newExpiry,
|
||||
"messages" to messageHashes,
|
||||
@@ -619,21 +654,23 @@ object SnodeAPI {
|
||||
|
||||
val signData = "${Snode.Method.Expire.rawValue}$shortenOrExtend$newExpiry${messageHashes.joinToString(separator = "")}".toByteArray()
|
||||
|
||||
val ed25519PublicKey = userEd25519KeyPair.publicKey.asHexString
|
||||
val signature = ByteArray(Sign.BYTES)
|
||||
try {
|
||||
sodium.cryptoSignDetached(
|
||||
signature,
|
||||
signData,
|
||||
signData.size.toLong(),
|
||||
userEd25519KeyPair.secretKey.asBytes
|
||||
signingKey
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Log.e("Loki", "Signing data failed with user secret key", e)
|
||||
return null
|
||||
}
|
||||
params["pubkey"] = publicKey
|
||||
params["pubkey_ed25519"] = ed25519PublicKey
|
||||
if (pubKeyEd25519 != null) {
|
||||
params["pubkey_ed25519"] = pubKeyEd25519
|
||||
}
|
||||
|
||||
params["signature"] = Base64.encodeBytes(signature)
|
||||
|
||||
return params
|
||||
|
Reference in New Issue
Block a user