mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-04 14:17:44 +00:00
Merge branch 'dev' of https://github.com/loki-project/session-android into data-extraction-2
This commit is contained in:
commit
5f297835fa
@ -41,6 +41,11 @@ import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities
|
|||||||
import org.thoughtcrime.securesms.loki.utilities.get
|
import org.thoughtcrime.securesms.loki.utilities.get
|
||||||
import org.thoughtcrime.securesms.loki.utilities.getString
|
import org.thoughtcrime.securesms.loki.utilities.getString
|
||||||
import org.thoughtcrime.securesms.mms.PartAuthority
|
import org.thoughtcrime.securesms.mms.PartAuthority
|
||||||
|
import org.session.libsession.messaging.messages.signal.IncomingGroupMessage
|
||||||
|
import org.session.libsession.messaging.messages.signal.IncomingTextMessage
|
||||||
|
import org.session.libsession.messaging.messages.signal.OutgoingTextMessage
|
||||||
|
import org.session.libsession.utilities.preferences.ProfileKeyUtil
|
||||||
|
import org.session.libsignal.service.loki.utilities.prettifiedDescription
|
||||||
|
|
||||||
class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), StorageProtocol {
|
class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), StorageProtocol {
|
||||||
override fun getUserPublicKey(): String? {
|
override fun getUserPublicKey(): String? {
|
||||||
@ -370,6 +375,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context,
|
|||||||
val smsDatabase = DatabaseFactory.getSmsDatabase(context)
|
val smsDatabase = DatabaseFactory.getSmsDatabase(context)
|
||||||
smsDatabase.markAsSentFailed(messageRecord.getId())
|
smsDatabase.markAsSentFailed(messageRecord.getId())
|
||||||
}
|
}
|
||||||
|
if (error.localizedMessage != null) {
|
||||||
|
DatabaseFactory.getLokiMessageDatabase(context).setErrorMessage(messageRecord.getId(), error.localizedMessage!!)
|
||||||
|
} else {
|
||||||
|
DatabaseFactory.getLokiMessageDatabase(context).setErrorMessage(messageRecord.getId(), error.javaClass.simpleName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGroup(groupID: String): GroupRecord? {
|
override fun getGroup(groupID: String): GroupRecord? {
|
||||||
|
@ -30,6 +30,7 @@ import org.session.libsession.messaging.sending_receiving.MessageSender
|
|||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
|
import org.session.libsession.messaging.jobs.JobQueue
|
||||||
import org.session.libsession.utilities.*
|
import org.session.libsession.utilities.*
|
||||||
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager
|
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager
|
||||||
import org.session.libsignal.service.loki.utilities.toHexString
|
import org.session.libsignal.service.loki.utilities.toHexString
|
||||||
@ -139,6 +140,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
|
|||||||
if (userPublicKey != null) {
|
if (userPublicKey != null) {
|
||||||
MentionsManager.configureIfNeeded(userPublicKey, threadDB, userDB)
|
MentionsManager.configureIfNeeded(userPublicKey, threadDB, userDB)
|
||||||
application.publicChatManager.startPollersIfNeeded()
|
application.publicChatManager.startPollersIfNeeded()
|
||||||
|
JobQueue.shared.resumePendingJobs()
|
||||||
}
|
}
|
||||||
IP2Country.configureIfNeeded(this)
|
IP2Country.configureIfNeeded(this)
|
||||||
application.registerForFCMIfNeeded(false)
|
application.registerForFCMIfNeeded(false)
|
||||||
|
@ -12,11 +12,11 @@ import org.thoughtcrime.securesms.loki.utilities.*
|
|||||||
class SessionJobDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) {
|
class SessionJobDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val sessionJobTable = "session_job_database"
|
private const val sessionJobTable = "session_job_database"
|
||||||
val jobID = "job_id"
|
const val jobID = "job_id"
|
||||||
val jobType = "job_type"
|
const val jobType = "job_type"
|
||||||
val failureCount = "failure_count"
|
const val failureCount = "failure_count"
|
||||||
val serializedData = "serialized_data"
|
const val serializedData = "serialized_data"
|
||||||
@JvmStatic val createSessionJobTableCommand = "CREATE TABLE $sessionJobTable ($jobID INTEGER PRIMARY KEY, $jobType STRING, $failureCount INTEGER DEFAULT 0, $serializedData TEXT);"
|
@JvmStatic val createSessionJobTableCommand = "CREATE TABLE $sessionJobTable ($jobID INTEGER PRIMARY KEY, $jobType STRING, $failureCount INTEGER DEFAULT 0, $serializedData TEXT);"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,10 +85,7 @@ class SessionJobDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SessionJobHelper() {
|
object SessionJobHelper {
|
||||||
|
val dataSerializer: Data.Serializer = JsonDataSerializer()
|
||||||
companion object {
|
val sessionJobInstantiator: SessionJobInstantiator = SessionJobInstantiator(SessionJobManagerFactories.getSessionJobFactories())
|
||||||
val dataSerializer: Data.Serializer = JsonDataSerializer()
|
|
||||||
val sessionJobInstantiator: SessionJobInstantiator = SessionJobInstantiator(SessionJobManagerFactories.getSessionJobFactories())
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -17,7 +17,7 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long)
|
|||||||
private val MAX_ATTACHMENT_SIZE = 10 * 1024 * 1024
|
private val MAX_ATTACHMENT_SIZE = 10 * 1024 * 1024
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
internal sealed class Error(val description: String) : Exception() {
|
internal sealed class Error(val description: String) : Exception(description) {
|
||||||
object NoAttachment : Error("No such attachment.")
|
object NoAttachment : Error("No such attachment.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess
|
|||||||
override var failureCount: Int = 0
|
override var failureCount: Int = 0
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
internal sealed class Error(val description: String) : Exception() {
|
internal sealed class Error(val description: String) : Exception(description) {
|
||||||
object NoAttachment : Error("No such attachment.")
|
object NoAttachment : Error("No such attachment.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
|||||||
class MemberLeft() : Kind()
|
class MemberLeft() : Kind()
|
||||||
class EncryptionKeyPairRequest(): Kind()
|
class EncryptionKeyPairRequest(): Kind()
|
||||||
|
|
||||||
val description: String = run {
|
val description: String =
|
||||||
when(this) {
|
when(this) {
|
||||||
is New -> "new"
|
is New -> "new"
|
||||||
is Update -> "update"
|
is Update -> "update"
|
||||||
@ -66,7 +66,6 @@ class ClosedGroupControlMessage() : ControlMessage() {
|
|||||||
is MemberLeft -> "memberLeft"
|
is MemberLeft -> "memberLeft"
|
||||||
is EncryptionKeyPairRequest -> "encryptionKeyPairRequest"
|
is EncryptionKeyPairRequest -> "encryptionKeyPairRequest"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -14,12 +14,11 @@ class DataExtractionNotification(): ControlMessage() {
|
|||||||
class Screenshot() : Kind()
|
class Screenshot() : Kind()
|
||||||
class MediaSaved(val timestamp: Long) : Kind()
|
class MediaSaved(val timestamp: Long) : Kind()
|
||||||
|
|
||||||
val description: String = run {
|
val description: String =
|
||||||
when(this) {
|
when(this) {
|
||||||
is Screenshot -> "screenshot"
|
is Screenshot -> "screenshot"
|
||||||
is MediaSaved -> "mediaSaved"
|
is MediaSaved -> "mediaSaved"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -27,12 +26,11 @@ class DataExtractionNotification(): ControlMessage() {
|
|||||||
|
|
||||||
fun fromProto(proto: SignalServiceProtos.Content): DataExtractionNotification? {
|
fun fromProto(proto: SignalServiceProtos.Content): DataExtractionNotification? {
|
||||||
val dataExtractionNotification = proto.dataExtractionNotification ?: return null
|
val dataExtractionNotification = proto.dataExtractionNotification ?: return null
|
||||||
val kind: Kind
|
val kind: Kind = when(dataExtractionNotification.type) {
|
||||||
when(dataExtractionNotification.type) {
|
SignalServiceProtos.DataExtractionNotification.Type.SCREENSHOT -> Kind.Screenshot()
|
||||||
SignalServiceProtos.DataExtractionNotification.Type.SCREENSHOT -> kind = Kind.Screenshot()
|
|
||||||
SignalServiceProtos.DataExtractionNotification.Type.MEDIA_SAVED -> {
|
SignalServiceProtos.DataExtractionNotification.Type.MEDIA_SAVED -> {
|
||||||
val timestamp = if (dataExtractionNotification.hasTimestamp()) dataExtractionNotification.timestamp else 0
|
val timestamp = if (dataExtractionNotification.hasTimestamp()) dataExtractionNotification.timestamp else return null
|
||||||
kind = Kind.MediaSaved(timestamp)
|
Kind.MediaSaved(timestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return DataExtractionNotification(kind)
|
return DataExtractionNotification(kind)
|
||||||
|
@ -35,7 +35,7 @@ class ReadReceipt() : ControlMessage() {
|
|||||||
override fun toProto(): SignalServiceProtos.Content? {
|
override fun toProto(): SignalServiceProtos.Content? {
|
||||||
val timestamps = timestamps
|
val timestamps = timestamps
|
||||||
if (timestamps == null) {
|
if (timestamps == null) {
|
||||||
Log.w(ExpirationTimerUpdate.TAG, "Couldn't construct read receipt proto from: $this")
|
Log.w(TAG, "Couldn't construct read receipt proto from: $this")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
val receiptProto = SignalServiceProtos.ReceiptMessage.newBuilder()
|
val receiptProto = SignalServiceProtos.ReceiptMessage.newBuilder()
|
||||||
@ -46,7 +46,7 @@ class ReadReceipt() : ControlMessage() {
|
|||||||
contentProto.receiptMessage = receiptProto.build()
|
contentProto.receiptMessage = receiptProto.build()
|
||||||
return contentProto.build()
|
return contentProto.build()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.w(ExpirationTimerUpdate.TAG, "Couldn't construct read receipt proto from: $this")
|
Log.w(TAG, "Couldn't construct read receipt proto from: $this")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ object MessageReceiver {
|
|||||||
|
|
||||||
private val lastEncryptionKeyPairRequest = mutableMapOf<String, Long>()
|
private val lastEncryptionKeyPairRequest = mutableMapOf<String, Long>()
|
||||||
|
|
||||||
internal sealed class Error(val description: String) : Exception() {
|
internal sealed class Error(val description: String) : Exception(description) {
|
||||||
object DuplicateMessage: Error("Duplicate message.")
|
object DuplicateMessage: Error("Duplicate message.")
|
||||||
object InvalidMessage: Error("Invalid message.")
|
object InvalidMessage: Error("Invalid message.")
|
||||||
object UnknownMessage: Error("Unknown message type.")
|
object UnknownMessage: Error("Unknown message type.")
|
||||||
|
@ -35,7 +35,7 @@ import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel as S
|
|||||||
object MessageSender {
|
object MessageSender {
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
sealed class Error(val description: String) : Exception() {
|
sealed class Error(val description: String) : Exception(description) {
|
||||||
object InvalidMessage : Error("Invalid message.")
|
object InvalidMessage : Error("Invalid message.")
|
||||||
object ProtoConversionFailed : Error("Couldn't convert message to proto.")
|
object ProtoConversionFailed : Error("Couldn't convert message to proto.")
|
||||||
object ProofOfWorkCalculationFailed : Error("Proof of work calculation failed.")
|
object ProofOfWorkCalculationFailed : Error("Proof of work calculation failed.")
|
||||||
@ -50,6 +50,9 @@ object MessageSender {
|
|||||||
object NoPrivateKey : Error("Couldn't find a private key associated with the given group public key.")
|
object NoPrivateKey : Error("Couldn't find a private key associated with the given group public key.")
|
||||||
object InvalidClosedGroupUpdate : Error("Invalid group update.")
|
object InvalidClosedGroupUpdate : Error("Invalid group update.")
|
||||||
|
|
||||||
|
// Precondition
|
||||||
|
class PreconditionFailure(val reason: String): Error(reason)
|
||||||
|
|
||||||
internal val isRetryable: Boolean = when (this) {
|
internal val isRetryable: Boolean = when (this) {
|
||||||
is InvalidMessage -> false
|
is InvalidMessage -> false
|
||||||
is ProtoConversionFailed -> false
|
is ProtoConversionFailed -> false
|
||||||
@ -73,7 +76,6 @@ object MessageSender {
|
|||||||
val promise = deferred.promise
|
val promise = deferred.promise
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
val userPublicKey = storage.getUserPublicKey()
|
val userPublicKey = storage.getUserPublicKey()
|
||||||
val preconditionFailure = Exception("Destination should not be open groups!")
|
|
||||||
// Set the timestamp, sender and recipient
|
// Set the timestamp, sender and recipient
|
||||||
message.sentTimestamp ?: run { message.sentTimestamp = System.currentTimeMillis() } /* Visible messages will already have their sent timestamp set */
|
message.sentTimestamp ?: run { message.sentTimestamp = System.currentTimeMillis() } /* Visible messages will already have their sent timestamp set */
|
||||||
message.sender = userPublicKey
|
message.sender = userPublicKey
|
||||||
@ -90,7 +92,7 @@ object MessageSender {
|
|||||||
when (destination) {
|
when (destination) {
|
||||||
is Destination.Contact -> message.recipient = destination.publicKey
|
is Destination.Contact -> message.recipient = destination.publicKey
|
||||||
is Destination.ClosedGroup -> message.recipient = destination.groupPublicKey
|
is Destination.ClosedGroup -> message.recipient = destination.groupPublicKey
|
||||||
is Destination.OpenGroup -> throw preconditionFailure
|
is Destination.OpenGroup -> throw Error.PreconditionFailure("Destination should not be open groups!")
|
||||||
}
|
}
|
||||||
// Validate the message
|
// Validate the message
|
||||||
if (!message.isValid()) { throw Error.InvalidMessage }
|
if (!message.isValid()) { throw Error.InvalidMessage }
|
||||||
@ -128,7 +130,7 @@ object MessageSender {
|
|||||||
val encryptionKeyPair = MessagingConfiguration.shared.storage.getLatestClosedGroupEncryptionKeyPair(destination.groupPublicKey)!!
|
val encryptionKeyPair = MessagingConfiguration.shared.storage.getLatestClosedGroupEncryptionKeyPair(destination.groupPublicKey)!!
|
||||||
ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, encryptionKeyPair.hexEncodedPublicKey)
|
ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, encryptionKeyPair.hexEncodedPublicKey)
|
||||||
}
|
}
|
||||||
is Destination.OpenGroup -> throw preconditionFailure
|
is Destination.OpenGroup -> throw Error.PreconditionFailure("Destination should not be open groups!")
|
||||||
}
|
}
|
||||||
// Wrap the result
|
// Wrap the result
|
||||||
val kind: SignalServiceProtos.Envelope.Type
|
val kind: SignalServiceProtos.Envelope.Type
|
||||||
@ -142,7 +144,7 @@ object MessageSender {
|
|||||||
kind = SignalServiceProtos.Envelope.Type.CLOSED_GROUP_CIPHERTEXT
|
kind = SignalServiceProtos.Envelope.Type.CLOSED_GROUP_CIPHERTEXT
|
||||||
senderPublicKey = destination.groupPublicKey
|
senderPublicKey = destination.groupPublicKey
|
||||||
}
|
}
|
||||||
is Destination.OpenGroup -> throw preconditionFailure
|
is Destination.OpenGroup -> throw Error.PreconditionFailure("Destination should not be open groups!")
|
||||||
}
|
}
|
||||||
val wrappedMessage = MessageWrapper.wrap(kind, message.sentTimestamp!!, senderPublicKey, ciphertext)
|
val wrappedMessage = MessageWrapper.wrap(kind, message.sentTimestamp!!, senderPublicKey, ciphertext)
|
||||||
// Calculate proof of work
|
// Calculate proof of work
|
||||||
@ -200,34 +202,31 @@ object MessageSender {
|
|||||||
private fun sendToOpenGroupDestination(destination: Destination, message: Message): Promise<Unit, Exception> {
|
private fun sendToOpenGroupDestination(destination: Destination, message: Message): Promise<Unit, Exception> {
|
||||||
val deferred = deferred<Unit, Exception>()
|
val deferred = deferred<Unit, Exception>()
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
val preconditionFailure = Exception("Destination should not be contacts or closed groups!")
|
|
||||||
message.sentTimestamp ?: run { message.sentTimestamp = System.currentTimeMillis() }
|
message.sentTimestamp ?: run { message.sentTimestamp = System.currentTimeMillis() }
|
||||||
message.sender = storage.getUserPublicKey()
|
message.sender = storage.getUserPublicKey()
|
||||||
|
// Set the failure handler (need it here already for precondition failure handling)
|
||||||
|
fun handleFailure(error: Exception) {
|
||||||
|
handleFailedMessageSend(message, error)
|
||||||
|
deferred.reject(error)
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
val server: String
|
val server: String
|
||||||
val channel: Long
|
val channel: Long
|
||||||
when (destination) {
|
when (destination) {
|
||||||
is Destination.Contact -> throw preconditionFailure
|
is Destination.Contact -> throw Error.PreconditionFailure("Destination should not be contacts!")
|
||||||
is Destination.ClosedGroup -> throw preconditionFailure
|
is Destination.ClosedGroup -> throw Error.PreconditionFailure("Destination should not be closed groups!")
|
||||||
is Destination.OpenGroup -> {
|
is Destination.OpenGroup -> {
|
||||||
message.recipient = "${destination.server}.${destination.channel}"
|
message.recipient = "${destination.server}.${destination.channel}"
|
||||||
server = destination.server
|
server = destination.server
|
||||||
channel = destination.channel
|
channel = destination.channel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set the failure handler (need it here already for precondition failure handling)
|
|
||||||
fun handleFailure(error: Exception) {
|
|
||||||
handleFailedMessageSend(message, error)
|
|
||||||
deferred.reject(error)
|
|
||||||
}
|
|
||||||
// Validate the message
|
// Validate the message
|
||||||
if (message !is VisibleMessage || !message.isValid()) {
|
if (message !is VisibleMessage || !message.isValid()) {
|
||||||
handleFailure(Error.InvalidMessage)
|
|
||||||
throw Error.InvalidMessage
|
throw Error.InvalidMessage
|
||||||
}
|
}
|
||||||
// Convert the message to an open group message
|
// Convert the message to an open group message
|
||||||
val openGroupMessage = OpenGroupMessage.from(message, server) ?: kotlin.run {
|
val openGroupMessage = OpenGroupMessage.from(message, server) ?: kotlin.run {
|
||||||
handleFailure(Error.InvalidMessage)
|
|
||||||
throw Error.InvalidMessage
|
throw Error.InvalidMessage
|
||||||
}
|
}
|
||||||
// Send the result
|
// Send the result
|
||||||
@ -239,7 +238,7 @@ object MessageSender {
|
|||||||
handleFailure(it)
|
handleFailure(it)
|
||||||
}
|
}
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
deferred.reject(exception)
|
handleFailure(exception)
|
||||||
}
|
}
|
||||||
return deferred.promise
|
return deferred.promise
|
||||||
}
|
}
|
||||||
@ -247,7 +246,8 @@ object MessageSender {
|
|||||||
// Result Handling
|
// Result Handling
|
||||||
fun handleSuccessfulMessageSend(message: Message, destination: Destination, isSyncMessage: Boolean = false) {
|
fun handleSuccessfulMessageSend(message: Message, destination: Destination, isSyncMessage: Boolean = false) {
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
val messageId = storage.getMessageIdInDatabase(message.sentTimestamp!!, message.sender!!) ?: return
|
val userPublicKey = storage.getUserPublicKey()!!
|
||||||
|
val messageId = storage.getMessageIdInDatabase(message.sentTimestamp!!, message.sender?:userPublicKey) ?: return
|
||||||
// Ignore future self-sends
|
// Ignore future self-sends
|
||||||
storage.addReceivedMessageTimestamp(message.sentTimestamp!!)
|
storage.addReceivedMessageTimestamp(message.sentTimestamp!!)
|
||||||
// Track the open group server message ID
|
// Track the open group server message ID
|
||||||
@ -255,17 +255,16 @@ object MessageSender {
|
|||||||
storage.setOpenGroupServerMessageID(messageId, message.openGroupServerMessageID!!)
|
storage.setOpenGroupServerMessageID(messageId, message.openGroupServerMessageID!!)
|
||||||
}
|
}
|
||||||
// Mark the message as sent
|
// Mark the message as sent
|
||||||
storage.markAsSent(message.sentTimestamp!!, message.sender!!)
|
storage.markAsSent(message.sentTimestamp!!, message.sender?:userPublicKey)
|
||||||
storage.markUnidentified(message.sentTimestamp!!, message.sender!!)
|
storage.markUnidentified(message.sentTimestamp!!, message.sender?:userPublicKey)
|
||||||
// Start the disappearing messages timer if needed
|
// Start the disappearing messages timer if needed
|
||||||
if (message is VisibleMessage && !isSyncMessage) {
|
if (message is VisibleMessage && !isSyncMessage) {
|
||||||
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(message.sentTimestamp!!, message.sender!!)
|
SSKEnvironment.shared.messageExpirationManager.startAnyExpiration(message.sentTimestamp!!, message.sender?:userPublicKey)
|
||||||
}
|
}
|
||||||
// Sync the message if:
|
// Sync the message if:
|
||||||
// • it's a visible message
|
// • it's a visible message
|
||||||
// • the destination was a contact
|
// • the destination was a contact
|
||||||
// • we didn't sync it already
|
// • we didn't sync it already
|
||||||
val userPublicKey = storage.getUserPublicKey()!!
|
|
||||||
if (destination is Destination.Contact && !isSyncMessage) {
|
if (destination is Destination.Contact && !isSyncMessage) {
|
||||||
if (message is VisibleMessage) { message.syncTarget = destination.publicKey }
|
if (message is VisibleMessage) { message.syncTarget = destination.publicKey }
|
||||||
if (message is ExpirationTimerUpdate) { message.syncTarget = destination.publicKey }
|
if (message is ExpirationTimerUpdate) { message.syncTarget = destination.publicKey }
|
||||||
@ -275,7 +274,8 @@ object MessageSender {
|
|||||||
|
|
||||||
fun handleFailedMessageSend(message: Message, error: Exception) {
|
fun handleFailedMessageSend(message: Message, error: Exception) {
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
storage.setErrorMessage(message.sentTimestamp!!, message.sender!!, error)
|
val userPublicKey = storage.getUserPublicKey()!!
|
||||||
|
storage.setErrorMessage(message.sentTimestamp!!, message.sender?:userPublicKey, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience
|
// Convenience
|
||||||
|
@ -42,7 +42,7 @@ open class DotNetAPI {
|
|||||||
internal enum class HTTPVerb { GET, PUT, POST, DELETE, PATCH }
|
internal enum class HTTPVerb { GET, PUT, POST, DELETE, PATCH }
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
internal sealed class Error(val description: String) : Exception() {
|
internal sealed class Error(val description: String) : Exception(description) {
|
||||||
object Generic : Error("An error occurred.")
|
object Generic : Error("An error occurred.")
|
||||||
object InvalidURL : Error("Invalid URL.")
|
object InvalidURL : Error("Invalid URL.")
|
||||||
object ParsingFailed : Error("Invalid file server response.")
|
object ParsingFailed : Error("Invalid file server response.")
|
||||||
|
@ -10,7 +10,7 @@ import java.security.SecureRandom
|
|||||||
object MessageWrapper {
|
object MessageWrapper {
|
||||||
|
|
||||||
// region Types
|
// region Types
|
||||||
sealed class Error(val description: String) : Exception() {
|
sealed class Error(val description: String) : Exception(description) {
|
||||||
object FailedToWrapData : Error("Failed to wrap data.")
|
object FailedToWrapData : Error("Failed to wrap data.")
|
||||||
object FailedToWrapMessageInEnvelope : Error("Failed to wrap message in envelope.")
|
object FailedToWrapMessageInEnvelope : Error("Failed to wrap message in envelope.")
|
||||||
object FailedToWrapEnvelopeInWebSocketMessage : Error("Failed to wrap envelope in web socket message.")
|
object FailedToWrapEnvelopeInWebSocketMessage : Error("Failed to wrap envelope in web socket message.")
|
||||||
|
@ -45,7 +45,7 @@ object SnodeAPI {
|
|||||||
internal var powDifficulty = 1
|
internal var powDifficulty = 1
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
internal sealed class Error(val description: String) : Exception() {
|
internal sealed class Error(val description: String) : Exception(description) {
|
||||||
object Generic : Error("An error occurred.")
|
object Generic : Error("An error occurred.")
|
||||||
object ClockOutOfSync : Error("The user's clock is out of sync with the service node network.")
|
object ClockOutOfSync : Error("The user's clock is out of sync with the service node network.")
|
||||||
object RandomSnodePoolUpdatingFailed : Error("Failed to update random service node pool.")
|
object RandomSnodePoolUpdatingFailed : Error("Failed to update random service node pool.")
|
||||||
|
@ -50,7 +50,7 @@ class MnemonicCodec(private val loadFileContents: (String) -> String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class DecodingError(val description: String) : Exception() {
|
sealed class DecodingError(val description: String) : Exception(description) {
|
||||||
object Generic : DecodingError("Something went wrong. Please check your mnemonic and try again.")
|
object Generic : DecodingError("Something went wrong. Please check your mnemonic and try again.")
|
||||||
object InputTooShort : DecodingError("Looks like you didn't enter enough words. Please check your mnemonic and try again.")
|
object InputTooShort : DecodingError("Looks like you didn't enter enough words. Please check your mnemonic and try again.")
|
||||||
object MissingLastWord : DecodingError("You seem to be missing the last word of your mnemonic. Please check what you entered and try again.")
|
object MissingLastWord : DecodingError("You seem to be missing the last word of your mnemonic. Please check what you entered and try again.")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user