decrypt private bookmark

This commit is contained in:
greenart7c3 2023-08-25 06:56:49 -03:00
parent 4f4d689f5a
commit 46571a6029
7 changed files with 103 additions and 10 deletions

View File

@ -83,7 +83,7 @@ object LocalPreferences {
private var _currentAccount: String? = null
private fun currentAccount(): String? {
fun currentAccount(): String? {
if (_currentAccount == null) {
_currentAccount = encryptedPreferences().getString(PrefKeys.CURRENT_ACCOUNT, null)
}

View File

@ -3,14 +3,17 @@ package com.vitorpamplona.amethyst.model
import android.util.Log
import androidx.compose.runtime.Stable
import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.LocalPreferences
import com.vitorpamplona.amethyst.service.checkNotInMainThread
import com.vitorpamplona.amethyst.service.relays.Relay
import com.vitorpamplona.amethyst.ui.components.BundledInsert
import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter
import com.vitorpamplona.quartz.encoders.ATag
import com.vitorpamplona.quartz.encoders.Hex
import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.encoders.HexValidator
import com.vitorpamplona.quartz.encoders.Nip19
import com.vitorpamplona.quartz.encoders.bechToBytes
import com.vitorpamplona.quartz.encoders.decodePublicKeyAsHexOrNull
import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.events.*
@ -199,6 +202,14 @@ object LocalCache {
val user = getOrCreateUser(event.pubKey)
if (user.latestBookmarkList == null || event.createdAt > user.latestBookmarkList!!.createdAt) {
if (event.dTag() == "bookmark") {
val loggedInUser = LocalPreferences.currentAccount()
val hexKey = loggedInUser?.bechToBytes()
if (hexKey != null) {
val pubKey = Hex.encode(hexKey)
if (pubKey == event.pubKey) {
BookmarkPrivateFeedFilter.content = ""
}
}
user.updateBookmark(event)
}
// Log.d("MT", "New User Metadata ${oldUser.pubkeyDisplayHex} ${oldUser.toBestDisplayName()}")

View File

@ -6,4 +6,5 @@ import androidx.activity.result.ActivityResultLauncher
object IntentUtils {
lateinit var activityResultLauncher: ActivityResultLauncher<Intent>
lateinit var authActivityResultLauncher: ActivityResultLauncher<Intent>
lateinit var decryptActivityResultLauncher: ActivityResultLauncher<Intent>
}

View File

@ -32,6 +32,7 @@ import com.vitorpamplona.amethyst.service.notifications.RegisterAccounts
import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.ui.components.DefaultMutedSetting
import com.vitorpamplona.amethyst.ui.components.keepPlayingMutex
import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter
import com.vitorpamplona.amethyst.ui.navigation.Route
import com.vitorpamplona.amethyst.ui.navigation.debugState
import com.vitorpamplona.amethyst.ui.note.Nip47
@ -110,6 +111,26 @@ class MainActivity : AppCompatActivity() {
ServiceManager.shouldPauseService = true
}
IntentUtils.decryptActivityResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode != Activity.RESULT_OK) {
GlobalScope.launch(Dispatchers.Main) {
Toast.makeText(
Amethyst.instance,
"Sign request rejected",
Toast.LENGTH_SHORT
).show()
}
BookmarkPrivateFeedFilter.isActivityRunning = false
return@registerForActivityResult
}
val event = it.data?.getStringExtra("signature") ?: ""
BookmarkPrivateFeedFilter.content = event
BookmarkPrivateFeedFilter.isActivityRunning = false
}
super.onCreate(savedInstanceState)
LocalPreferences.migrateSingleUserPrefs()

View File

@ -3,27 +3,57 @@ package com.vitorpamplona.amethyst.ui.dal
import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.service.IntentUtils
import com.vitorpamplona.amethyst.ui.actions.SignerType
import com.vitorpamplona.amethyst.ui.actions.openAmber
import com.vitorpamplona.quartz.encoders.toHexKey
object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
lateinit var account: Account
var content: String = ""
var isActivityRunning: Boolean = false
override fun feedKey(): String {
return account.userProfile().latestBookmarkList?.id ?: ""
}
override fun feed(): List<Note> {
val privKey = account.keyPair.privKey ?: return emptyList()
val bookmarks = account.userProfile().latestBookmarkList
val notes = bookmarks?.privateTaggedEvents(privKey)
?.mapNotNull { LocalCache.checkGetOrCreateNote(it) } ?: emptyList()
if (account.loginWithAmber) {
if (content.isBlank()) {
isActivityRunning = true
openAmber(
bookmarks?.content ?: "",
SignerType.NIP04_DECRYPT,
IntentUtils.decryptActivityResultLauncher,
account.keyPair.pubKey.toHexKey()
)
while (isActivityRunning) {
Thread.sleep(250)
}
}
val addresses = bookmarks?.privateTaggedAddresses(privKey)
?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList()
val notes = bookmarks?.privateTaggedEvents(content)
?.mapNotNull { LocalCache.checkGetOrCreateNote(it) } ?: emptyList()
val addresses = bookmarks?.privateTaggedAddresses(content)
?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList()
return notes.plus(addresses).toSet()
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed()
return notes.plus(addresses).toSet()
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed()
} else {
val privKey = account.keyPair.privKey ?: return emptyList()
val notes = bookmarks?.privateTaggedEvents(privKey)
?.mapNotNull { LocalCache.checkGetOrCreateNote(it) } ?: emptyList()
val addresses = bookmarks?.privateTaggedAddresses(privKey)
?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList()
return notes.plus(addresses).toSet()
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed()
}
}
}

View File

@ -11,6 +11,7 @@ import androidx.compose.material.Tab
import androidx.compose.material.TabRow
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
@ -91,5 +92,11 @@ fun BookmarkListScreen(accountViewModel: AccountViewModel, nav: (String) -> Unit
}
}
}
DisposableEffect(Unit) {
onDispose {
BookmarkPrivateFeedFilter.content = ""
}
}
}
}

View File

@ -52,6 +52,20 @@ abstract class GeneralListEvent(
return privateTagsCache
}
fun privateTags(content: String): List<List<String>>? {
if (privateTagsCache != null) {
return privateTagsCache
}
privateTagsCache = try {
content.let { mapper.readValue<List<List<String>>>(it) }
} catch (e: Throwable) {
Log.w("GeneralList", "Error parsing the JSON ${e.message}")
null
}
return privateTagsCache
}
fun privateTagsOrEmpty(privKey: ByteArray): List<List<String>> {
return privateTags(privKey) ?: emptyList()
}
@ -61,6 +75,8 @@ abstract class GeneralListEvent(
fun privateHashtags(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "t" }?.map { it[1] }
fun privateGeohashes(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "g" }?.map { it[1] }
fun privateTaggedEvents(privKey: ByteArray) = privateTags(privKey)?.filter { it.size > 1 && it[0] == "e" }?.map { it[1] }
fun privateTaggedEvents(content: String) = privateTags(content)?.filter { it.size > 1 && it[0] == "e" }?.map { it[1] }
fun privateTaggedAddresses(privKey: ByteArray) = privateTags(privKey)?.filter { it.firstOrNull() == "a" }?.mapNotNull {
val aTagValue = it.getOrNull(1)
val relay = it.getOrNull(2)
@ -68,6 +84,13 @@ abstract class GeneralListEvent(
if (aTagValue != null) ATag.parse(aTagValue, relay) else null
}
fun privateTaggedAddresses(content: String) = privateTags(content)?.filter { it.firstOrNull() == "a" }?.mapNotNull {
val aTagValue = it.getOrNull(1)
val relay = it.getOrNull(2)
if (aTagValue != null) ATag.parse(aTagValue, relay) else null
}
companion object {
fun createPrivateTags(
privEvents: List<String>? = null,