diff --git a/signalc/src/main/kotlin/info/signalboost/signalc/db/DeviceRecord.kt b/signalc/src/main/kotlin/info/signalboost/signalc/db/DeviceRecord.kt index 24aa4f9bc40005bdd806c3b160b94da4898104f0..80cc7a9bcc416f766f62bf1dc14225ac2dda0641 100644 --- a/signalc/src/main/kotlin/info/signalboost/signalc/db/DeviceRecord.kt +++ b/signalc/src/main/kotlin/info/signalboost/signalc/db/DeviceRecord.kt @@ -1,21 +1,29 @@ package info.signalboost.signalc.db +import info.signalboost.signalc.store.ProtocolStore +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.ObsoleteCoroutinesApi import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.statements.UpdateStatement import org.whispersystems.libsignal.SignalProtocolAddress +import kotlin.io.path.ExperimentalPathApi +import kotlin.time.ExperimentalTime +@ObsoleteCoroutinesApi +@ExperimentalCoroutinesApi +@ExperimentalTime +@ExperimentalPathApi interface DeviceRecord: FieldSet { val accountId: Column<String> val contactId: Column<String> val deviceId: Column<Int> companion object { - fun DeviceRecord.findByAddress(accountId: String, address: SignalProtocolAddress): ResultRow? { val table = this return table.select { (table.accountId eq accountId) - .and(table.contactId eq address.name) + .and(table.contactId eq ProtocolStore.resolveId(address.name)) .and(table.deviceId eq address.deviceId) }.singleOrNull() } @@ -28,7 +36,7 @@ interface DeviceRecord: FieldSet { val table = this return (table as Table).update ({ (table.accountId eq accountId) - .and(table.contactId eq address.name) + .and(table.contactId eq ProtocolStore.resolveId(address.name)) .and(table.deviceId eq address.deviceId) }, null, updateStatement) } @@ -37,7 +45,7 @@ interface DeviceRecord: FieldSet { val table = this return (table as Table).deleteWhere { (table.accountId eq accountId) - .and(table.contactId eq address.name) + .and(table.contactId eq ProtocolStore.resolveId(address.name)) .and(table.deviceId eq address.deviceId) } } diff --git a/signalc/src/main/kotlin/info/signalboost/signalc/db/Identities.kt b/signalc/src/main/kotlin/info/signalboost/signalc/db/Identities.kt index b2d585daf03edd4453156de119b18a69dbb8e85e..dee5fb24ecb59594390f332166c480499e2a21ff 100644 --- a/signalc/src/main/kotlin/info/signalboost/signalc/db/Identities.kt +++ b/signalc/src/main/kotlin/info/signalboost/signalc/db/Identities.kt @@ -1,7 +1,15 @@ package info.signalboost.signalc.db +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.ObsoleteCoroutinesApi import org.jetbrains.exposed.sql.Table +import kotlin.io.path.ExperimentalPathApi +import kotlin.time.ExperimentalTime +@ObsoleteCoroutinesApi +@ExperimentalCoroutinesApi +@ExperimentalTime +@ExperimentalPathApi object Identities: Table(), DeviceRecord { private const val IDENTITY_KEY_BYTE_ARRAY_LENGTH = 33 diff --git a/signalc/src/main/kotlin/info/signalboost/signalc/db/Sessions.kt b/signalc/src/main/kotlin/info/signalboost/signalc/db/Sessions.kt index 2331dafce69b7968f3391ca2b7fcd83ab9709729..7ffa30ad0a343d535703489b505794dbee544c50 100644 --- a/signalc/src/main/kotlin/info/signalboost/signalc/db/Sessions.kt +++ b/signalc/src/main/kotlin/info/signalboost/signalc/db/Sessions.kt @@ -1,9 +1,16 @@ package info.signalboost.signalc.db +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.ObsoleteCoroutinesApi import org.jetbrains.exposed.sql.Table +import kotlin.io.path.ExperimentalPathApi +import kotlin.time.ExperimentalTime - +@ObsoleteCoroutinesApi +@ExperimentalCoroutinesApi +@ExperimentalTime +@ExperimentalPathApi object Sessions: Table(), DeviceRecord { private const val SESSION_BYTE_ARRAY_LENGTH = 32 diff --git a/signalc/src/main/kotlin/info/signalboost/signalc/model/SignalcAddress.kt b/signalc/src/main/kotlin/info/signalboost/signalc/model/SignalcAddress.kt index a3601ac0806bc0f784805b96d08b68457fb00f7c..5ee3bf540c46cc88b61714343edd7bdc0f2c2101 100644 --- a/signalc/src/main/kotlin/info/signalboost/signalc/model/SignalcAddress.kt +++ b/signalc/src/main/kotlin/info/signalboost/signalc/model/SignalcAddress.kt @@ -22,7 +22,7 @@ data class SignalcAddress( ) fun SignalServiceEnvelope.asSignalcAddress() = SignalcAddress( - number = sourceE164.orNull(), + number = sourceE164.orNull()?.let{ if(it.isEmpty()) null else it}, uuid = sourceUuid.orNull()?.let{ if(it.isEmpty()) null else UUID.fromString (it) }, ).also { if (it.number == null && it.uuid == null) { diff --git a/signalc/src/main/kotlin/info/signalboost/signalc/store/ProtocolStore.kt b/signalc/src/main/kotlin/info/signalboost/signalc/store/ProtocolStore.kt index 4539ddeddcd407834f78aeb3c9d6333b7e404042..e3ee4cf0601e7f62dd98c4275114d11fefe6b94a 100644 --- a/signalc/src/main/kotlin/info/signalboost/signalc/store/ProtocolStore.kt +++ b/signalc/src/main/kotlin/info/signalboost/signalc/store/ProtocolStore.kt @@ -15,6 +15,7 @@ import org.whispersystems.libsignal.state.* import org.whispersystems.signalservice.api.SignalServiceProtocolStore import org.whispersystems.signalservice.api.SignalServiceSessionStore import org.whispersystems.signalservice.api.push.SignalServiceAddress +import java.util.* import kotlin.io.path.ExperimentalPathApi import kotlin.time.ExperimentalTime @@ -30,6 +31,40 @@ class ProtocolStore(app: Application) { fun countOwnIdentities(): Long = transaction(db) { OwnIdentities.selectAll().count() } + companion object { + fun resolveId(contactId: String): String { + return when { + isUUID(contactId) -> { + when (contactId) { + "362feb8e-17a0-402b-92d8-773df1b38a74" -> "+16154804259" + "1b2f2a81-38ee-49db-8be4-b450f83bfcf9" -> "+18319176400" + else -> throw Exception("oh noes! don't know this UUID: $contactId") + } + } + isE164(contactId) -> { + contactId + } + else -> { + throw Exception("what the h*** is this? don't know this contact id type, contact id: $contactId") + } + } + } + + private fun isE164(contactId: String): Boolean { + val regex = """^\+\d{9,15}$""".toRegex() + return regex.matches(contactId) + } + + private fun isUUID(contactId: String): Boolean { + return try { + UUID.fromString(contactId) + true + } catch (e: Throwable) { + false + } + } + } + class AccountProtocolStore( private val db: Database, private val accountId: String, diff --git a/signalc/src/main/kotlin/info/signalboost/signalc/store/protocol/SignalcIdentityStore.kt b/signalc/src/main/kotlin/info/signalboost/signalc/store/protocol/SignalcIdentityStore.kt index 1cbf65ee2ae26e82261abeb49e02288e6411e93f..1a00457696b80b0400d350e9eed40483f9df3045 100644 --- a/signalc/src/main/kotlin/info/signalboost/signalc/store/protocol/SignalcIdentityStore.kt +++ b/signalc/src/main/kotlin/info/signalboost/signalc/store/protocol/SignalcIdentityStore.kt @@ -10,6 +10,8 @@ import info.signalboost.signalc.db.Identities.contactId import info.signalboost.signalc.db.OwnIdentities import info.signalboost.signalc.db.PreKeys import info.signalboost.signalc.util.KeyUtil +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.ObsoleteCoroutinesApi import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.transactions.transaction import org.whispersystems.libsignal.IdentityKey @@ -17,8 +19,14 @@ import org.whispersystems.libsignal.IdentityKeyPair import org.whispersystems.libsignal.SignalProtocolAddress import org.whispersystems.libsignal.state.IdentityKeyStore import org.whispersystems.signalservice.api.push.SignalServiceAddress +import kotlin.io.path.ExperimentalPathApi +import kotlin.time.ExperimentalTime +@ObsoleteCoroutinesApi +@ExperimentalCoroutinesApi +@ExperimentalTime +@ExperimentalPathApi class SignalcIdentityStore( val db: Database, val accountId: String, diff --git a/signalc/src/main/kotlin/info/signalboost/signalc/store/protocol/SignalcSessionStore.kt b/signalc/src/main/kotlin/info/signalboost/signalc/store/protocol/SignalcSessionStore.kt index 5fc527b8635399d6fb017ffab7b2cafec326e01a..0a143cf984764794d06c91b3304a982abb8953d4 100644 --- a/signalc/src/main/kotlin/info/signalboost/signalc/store/protocol/SignalcSessionStore.kt +++ b/signalc/src/main/kotlin/info/signalboost/signalc/store/protocol/SignalcSessionStore.kt @@ -5,12 +5,22 @@ import info.signalboost.signalc.db.DeviceRecord.Companion.deleteByAddress import info.signalboost.signalc.db.DeviceRecord.Companion.findByAddress import info.signalboost.signalc.db.DeviceRecord.Companion.updateByAddress import info.signalboost.signalc.db.Sessions.sessionBytes +import info.signalboost.signalc.store.ProtocolStore.Companion.resolveId +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.ObsoleteCoroutinesApi import org.jetbrains.exposed.sql.* import org.whispersystems.libsignal.SignalProtocolAddress import org.whispersystems.libsignal.protocol.CiphertextMessage import org.whispersystems.libsignal.state.* import org.whispersystems.signalservice.api.SignalServiceSessionStore +import java.util.* +import kotlin.io.path.ExperimentalPathApi +import kotlin.time.ExperimentalTime +@ObsoleteCoroutinesApi +@ExperimentalCoroutinesApi +@ExperimentalTime +@ExperimentalPathApi class SignalcSessionStore( val db: Database, val accountId: String, @@ -27,7 +37,7 @@ class SignalcSessionStore( override fun getSubDeviceSessions(name: String): MutableList<Int> = lock.acquireForTransaction(db) { Sessions.select { - Sessions.accountId eq accountId and (Sessions.contactId eq name) + Sessions.accountId eq accountId and (Sessions.contactId eq resolveId(name)) }.mapTo(mutableListOf()) { it[Sessions.deviceId] } } @@ -40,7 +50,7 @@ class SignalcSessionStore( if (numUpdated == 0) { Sessions.insert { it[accountId] = this@SignalcSessionStore.accountId - it[contactId] = address.name + it[contactId] = resolveId(address.name) it[deviceId] = address.deviceId it[sessionBytes] = record.serialize() } @@ -70,7 +80,7 @@ class SignalcSessionStore( override fun deleteAllSessions(name: String) { lock.acquireForTransaction(db) { Sessions.deleteWhere { - Sessions.accountId eq accountId and (Sessions.contactId eq name) + Sessions.accountId eq accountId and (Sessions.contactId eq resolveId(name)) } } }