diff --git a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 86b4f9cd2d..2dc877906d 100644 --- a/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/src/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -84,8 +84,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { private static final int lokiV8 = 29; private static final int lokiV9 = 30; private static final int lokiV10 = 31; + private static final int lokiV11 = 32; - private static final int DATABASE_VERSION = lokiV10; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes + private static final int DATABASE_VERSION = lokiV11; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -146,6 +147,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { db.execSQL(LokiAPIDatabase.getCreateSessionRequestTimestampCacheCommand()); db.execSQL(LokiAPIDatabase.getCreateSessionRequestSentTimestampCacheCommand()); db.execSQL(LokiAPIDatabase.getCreateSessionRequestProcessedTimestampCacheCommand()); + db.execSQL(LokiAPIDatabase.getCreateOpenGroupPublicKeyDBCommand()); db.execSQL(LokiPreKeyBundleDatabase.getCreateTableCommand()); db.execSQL(LokiPreKeyRecordDatabase.getCreateTableCommand()); db.execSQL(LokiMessageDatabase.getCreateMessageIDTableCommand()); @@ -597,6 +599,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { db.execSQL(LokiAPIDatabase.getCreateSessionRequestProcessedTimestampCacheCommand()); } + if (oldVersion < lokiV11) { + db.execSQL(LokiAPIDatabase.getCreateOpenGroupPublicKeyDBCommand()); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/src/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt b/src/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt index 0e2522b323..a5a6fabd90 100644 --- a/src/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt +++ b/src/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt @@ -14,8 +14,8 @@ class PushNotificationService : FirebaseMessagingService() { override fun onNewToken(token: String) { super.onNewToken(token) Log.d("Loki", "New FCM token: $token.") - val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this) ?: return - LokiPushNotificationManager.register(token, userHexEncodedPublicKey, this, false) + val userPublicKey = TextSecurePreferences.getLocalNumber(this) ?: return + LokiPushNotificationManager.register(token, userPublicKey, this, false) } override fun onMessageReceived(message: RemoteMessage) { diff --git a/src/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt b/src/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt index da2356bcc2..c12df05ad1 100644 --- a/src/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt @@ -79,12 +79,15 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( // Session request processed timestamp cache private val sessionRequestProcessedTimestampCache = "session_request_processed_timestamp_cache" @JvmStatic val createSessionRequestProcessedTimestampCacheCommand = "CREATE TABLE $sessionRequestProcessedTimestampCache ($publicKey STRING PRIMARY KEY, $timestamp INTEGER DEFAULT 0);" + // Open group public keys + private val openGroupPublicKeyDB = "open_group_public_keys" + @JvmStatic val createOpenGroupPublicKeyDBCommand = "CREATE TABLE $openGroupPublicKeyDB ($server STRING PRIMARY KEY, $publicKey INTEGER DEFAULT 0);" // region Deprecated private val sessionRequestTimestampCache = "session_request_timestamp_cache" - @JvmStatic val createSessionRequestTimestampCacheCommand = "CREATE TABLE $sessionRequestTimestampCache ($publicKey STRING PRIMARY KEY, $timestamp INTEGER DEFAULT 0);" + @JvmStatic val createSessionRequestTimestampCacheCommand = "CREATE TABLE $sessionRequestTimestampCache ($publicKey STRING PRIMARY KEY, $timestamp STRING);" // endregion } @@ -327,10 +330,10 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( }?.toInt() } - override fun setUserCount(userCount: Int, group: Long, server: String) { + override fun setUserCount(group: Long, server: String, newValue: Int) { val database = databaseHelper.writableDatabase val index = "$server.$group" - val row = wrap(mapOf(publicChatID to index, Companion.userCount to userCount.toString())) + val row = wrap(mapOf(publicChatID to index, Companion.userCount to newValue.toString())) database.insertOrUpdate(userCountCache, row, "$publicChatID = ?", wrap(index)) } @@ -341,9 +344,9 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( }?.toLong() } - override fun setSessionRequestSentTimestamp(publicKey: String, timestamp: Long) { + override fun setSessionRequestSentTimestamp(publicKey: String, newValue: Long) { val database = databaseHelper.writableDatabase - val row = wrap(mapOf(LokiAPIDatabase.publicKey to publicKey, LokiAPIDatabase.timestamp to timestamp.toString())) + val row = wrap(mapOf(LokiAPIDatabase.publicKey to publicKey, LokiAPIDatabase.timestamp to newValue.toString())) database.insertOrUpdate(sessionRequestSentTimestampCache, row, "${LokiAPIDatabase.publicKey} = ?", wrap(publicKey)) } @@ -354,11 +357,24 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( }?.toLong() } - override fun setSessionRequestProcessedTimestamp(publicKey: String, timestamp: Long) { + override fun setSessionRequestProcessedTimestamp(publicKey: String, newValue: Long) { val database = databaseHelper.writableDatabase - val row = wrap(mapOf(LokiAPIDatabase.publicKey to publicKey, LokiAPIDatabase.timestamp to timestamp.toString())) + val row = wrap(mapOf(LokiAPIDatabase.publicKey to publicKey, LokiAPIDatabase.timestamp to newValue.toString())) database.insertOrUpdate(sessionRequestProcessedTimestampCache, row, "${LokiAPIDatabase.publicKey} = ?", wrap(publicKey)) } + + override fun getOpenGroupPublicKey(server: String): String? { + val database = databaseHelper.readableDatabase + return database.get(openGroupPublicKeyDB, "${LokiAPIDatabase.server} = ?", wrap(server)) { cursor -> + cursor.getString(LokiAPIDatabase.publicKey) + } + } + + override fun setOpenGroupPublicKey(server: String, newValue: String) { + val database = databaseHelper.writableDatabase + val row = wrap(mapOf(LokiAPIDatabase.server to server, LokiAPIDatabase.publicKey to publicKey)) + database.insertOrUpdate(openGroupPublicKeyDB, row, "${LokiAPIDatabase.server} = ?", wrap(server)) + } } // region Convenience diff --git a/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt b/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt deleted file mode 100644 index 2e93f96039..0000000000 --- a/src/org/thoughtcrime/securesms/loki/shelved/LokiRSSFeedPoller.kt +++ /dev/null @@ -1,76 +0,0 @@ -package org.thoughtcrime.securesms.loki.shelved - -import android.content.Context -import android.os.Handler -import android.text.Html -import android.util.Log -import com.prof.rssparser.engine.XMLParser -import kotlinx.coroutines.Job -import kotlinx.coroutines.Runnable -import org.thoughtcrime.securesms.jobs.PushDecryptJob -import org.thoughtcrime.securesms.loki.utilities.successBackground -import org.whispersystems.libsignal.util.guava.Optional -import org.whispersystems.signalservice.api.messages.SignalServiceContent -import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage -import org.whispersystems.signalservice.api.messages.SignalServiceGroup -import org.whispersystems.signalservice.api.push.SignalServiceAddress -import org.whispersystems.signalservice.loki.api.shelved.rssfeeds.LokiRSSFeed -import org.whispersystems.signalservice.loki.api.shelved.rssfeeds.LokiRSSFeedProxy -import java.text.SimpleDateFormat -import java.util.regex.Pattern - -class LokiRSSFeedPoller(private val context: Context, private val feed: LokiRSSFeed) { - private val handler = Handler() - private val job = Job() - private var hasStarted = false - - private val task = object : Runnable { - - override fun run() { - poll() - handler.postDelayed(this, interval) - } - } - - companion object { - private val interval: Long = 8 * 60 * 1000 - } - - fun startIfNeeded() { - if (hasStarted) return - task.run() - hasStarted = true - } - - fun stop() { - handler.removeCallbacks(task) - job.cancel() - hasStarted = false - } - - private fun poll() { - LokiRSSFeedProxy.fetch(feed.url).successBackground { xml -> - val items = XMLParser(xml).call() - items.reversed().forEach { item -> - val title = item.title ?: return@forEach - val description = item.description ?: return@forEach - val dateAsString = item.pubDate ?: return@forEach - val formatter = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z") // e.g. Tue, 27 Aug 2019 03:52:05 +0000 - val date = formatter.parse(dateAsString) - val timestamp = date.time - var bodyAsHTML = "$title
$description" - val urlRegex = Pattern.compile("]*?\\s+)?href=\"([^\"]*)\".*?>(.*?)<.*?\\/a>") - val matcher = urlRegex.matcher(bodyAsHTML) - bodyAsHTML = matcher.replaceAll("$2 ($1)") - val body = Html.fromHtml(bodyAsHTML).toString().trim() - val id = feed.id.toByteArray() - val x1 = SignalServiceGroup(SignalServiceGroup.Type.UPDATE, id, SignalServiceGroup.GroupType.RSS_FEED, null, null, null, null) - val x2 = SignalServiceDataMessage(timestamp, x1, null, body) - val x3 = SignalServiceContent(x2, "Loki", SignalServiceAddress.DEFAULT_DEVICE_ID, timestamp, false, false) - PushDecryptJob(context).handleTextMessage(x3, x2, Optional.absent(), Optional.absent()) - } - }.fail { exception -> - Log.d("Loki", "Couldn't update RSS feed with ID: $feed.id due to exception: $exception.") - } - } -} \ No newline at end of file