mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Refactor: Improve handling of encrypted data
This commit refactors the handling of encryption and decryption requests to provide better context and a clearer user interface. - **Introduce typed encrypted data models**: Replaces the generic `encryptDecryptResponse` string with specific data classes (`ClearTextEncryptedDataKind`, `EventEncryptedDataKind`, `TagArrayEncryptedDataKind`) to better represent the structure of the data being processed. - **Enhance UI for encryption/decryption**: The UI now displays more contextual information about the content being encrypted or decrypted, such as distinguishing between plain text, events (including sealed rumors), and tag arrays. - **Simplify intent handling**: Removes custom JSON serialization/deserialization for `AmberBunkerRequest` and streamlines intent processing logic. - **Refactor bunker request creation**: Updates the creation of `AmberBunkerRequest` to use the new typed data models, improving type safety and code clarity throughout the app.
This commit is contained in:
@@ -268,7 +268,7 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
override fun onResume() {
|
||||
Amber.instance.setMainActivity(this)
|
||||
mainViewModel.showBunkerRequests(callingPackage)
|
||||
mainViewModel.showBunkerRequests()
|
||||
@Suppress("KotlinConstantConditions")
|
||||
if (BuildConfig.FLAVOR != "offline") {
|
||||
val connectivityManager =
|
||||
|
||||
@@ -4,22 +4,18 @@ import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.core.net.toUri
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.NavHostController
|
||||
import com.greenart7c3.nostrsigner.models.IntentData
|
||||
import com.greenart7c3.nostrsigner.service.BunkerRequestUtils
|
||||
import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents.intents
|
||||
import com.greenart7c3.nostrsigner.ui.AccountStateViewModel
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import kotlin.text.isNotBlank
|
||||
import kotlin.text.startsWith
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -96,32 +92,13 @@ class MainViewModel(val context: Context) : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun showBunkerRequests(callingPackage: String?, accountStateViewModel: AccountStateViewModel? = null) {
|
||||
fun showBunkerRequests(accountStateViewModel: AccountStateViewModel? = null) {
|
||||
val requests =
|
||||
BunkerRequestUtils.getBunkerRequests().map {
|
||||
it.copy()
|
||||
}
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val account = LocalPreferences.loadFromEncryptedStorage(context)
|
||||
account?.let { acc ->
|
||||
requests.forEach {
|
||||
val contentIntent =
|
||||
Intent(Amber.instance, MainActivity::class.java).apply {
|
||||
data = "nostrsigner:".toUri()
|
||||
}
|
||||
contentIntent.putExtra("bunker", it.toJson())
|
||||
contentIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
val intentData = IntentUtils.getIntentData(context, contentIntent, callingPackage, Route.IncomingRequest.route, acc)
|
||||
contentIntent.putExtra("current_account", acc.npub)
|
||||
if (intentData != null) {
|
||||
if (intents.value.none { item -> item.id == intentData.id }) {
|
||||
intents.value += listOf(intentData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (requests.isNotEmpty()) {
|
||||
val npub = getAccount(null)
|
||||
val currentAccount = LocalPreferences.currentAccount(context)
|
||||
|
||||
@@ -69,8 +69,9 @@ class SignerProvider : ContentProvider() {
|
||||
} else {
|
||||
if (Hex.isHex(sortOrder)) {
|
||||
sortOrder
|
||||
} else {
|
||||
null
|
||||
}
|
||||
null
|
||||
}
|
||||
if (packageName == null) {
|
||||
Log.d(Amber.TAG, "No package name")
|
||||
|
||||
@@ -2,26 +2,10 @@ package com.greenart7c3.nostrsigner.models
|
||||
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.fasterxml.jackson.core.JsonGenerator
|
||||
import com.fasterxml.jackson.core.JsonParser
|
||||
import com.fasterxml.jackson.databind.DeserializationContext
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.JsonNode
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.SerializerProvider
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.ui.RememberType
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.JacksonMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequest
|
||||
import kotlin.collections.asIterable
|
||||
|
||||
enum class EncryptionType {
|
||||
NIP44,
|
||||
@@ -37,80 +21,8 @@ data class AmberBunkerRequest(
|
||||
val closeApplication: Boolean,
|
||||
val name: String,
|
||||
val signedEvent: Event?,
|
||||
val encryptDecryptResponse: String?,
|
||||
val encryptedData: EncryptedDataKind?,
|
||||
val checked: MutableState<Boolean> = mutableStateOf(true),
|
||||
val rememberType: MutableState<RememberType> = mutableStateOf(RememberType.NEVER),
|
||||
val encryptionType: EncryptionType,
|
||||
) {
|
||||
fun toJson(): String {
|
||||
return mapper.writeValueAsString(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val mapper: ObjectMapper =
|
||||
jacksonObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.registerModule(
|
||||
SimpleModule()
|
||||
.addDeserializer(AmberBunkerRequest::class.java, AmberBunkerRequestDeserializer())
|
||||
.addSerializer(AmberBunkerRequest::class.java, AmberBunkerRequestSerializer()),
|
||||
)
|
||||
|
||||
fun fromJson(jsonObject: JsonNode): AmberBunkerRequest {
|
||||
return AmberBunkerRequest(
|
||||
request = JacksonMapper.mapper.readValue(jsonObject.get("request").asText().intern()),
|
||||
localKey = jsonObject.get("localKey")?.asText()?.intern() ?: "",
|
||||
relays = jsonObject.get("relays")?.asIterable()?.toList()?.mapNotNull {
|
||||
RelayUrlNormalizer.normalizeOrNull(it.asText())
|
||||
} ?: Amber.instance.getSavedRelays().toList(),
|
||||
currentAccount = jsonObject.get("currentAccount")?.asText()?.intern() ?: "",
|
||||
nostrConnectSecret = jsonObject.get("nostrConnectSecret")?.asText()?.intern() ?: "",
|
||||
closeApplication = jsonObject.get("closeApplication")?.asBoolean() != false,
|
||||
name = jsonObject.get("name")?.asText()?.intern() ?: "",
|
||||
signedEvent = jsonObject.get("signedEvent")?.asText()?.intern()?.let {
|
||||
try {
|
||||
JacksonMapper.fromJson(it)
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
},
|
||||
encryptDecryptResponse = jsonObject.get("encryptDecryptResponse")?.asText()?.intern(),
|
||||
encryptionType = EncryptionType.valueOf(jsonObject.get("encryptionType")?.asText()?.intern() ?: "NIP44"),
|
||||
)
|
||||
}
|
||||
|
||||
private class AmberBunkerRequestDeserializer : StdDeserializer<AmberBunkerRequest>(AmberBunkerRequest::class.java) {
|
||||
override fun deserialize(
|
||||
jp: JsonParser,
|
||||
ctxt: DeserializationContext,
|
||||
): AmberBunkerRequest {
|
||||
return fromJson(jp.codec.readTree(jp))
|
||||
}
|
||||
}
|
||||
|
||||
private class AmberBunkerRequestSerializer : StdSerializer<AmberBunkerRequest>(AmberBunkerRequest::class.java) {
|
||||
override fun serialize(
|
||||
value: AmberBunkerRequest,
|
||||
gen: JsonGenerator,
|
||||
provider: SerializerProvider,
|
||||
) {
|
||||
gen.writeStartObject()
|
||||
gen.writeStringField("request", mapper.writeValueAsString(value.request))
|
||||
gen.writeStringField("localKey", value.localKey)
|
||||
gen.writeArrayFieldStart("relays")
|
||||
value.relays.forEach {
|
||||
gen.writeString(it.url)
|
||||
}
|
||||
gen.writeEndArray()
|
||||
gen.writeStringField("currentAccount", value.currentAccount)
|
||||
gen.writeStringField("nostrConnectSecret", value.nostrConnectSecret)
|
||||
gen.writeBooleanField("closeApplication", value.closeApplication)
|
||||
gen.writeStringField("name", value.name)
|
||||
gen.writeStringField("signedEvent", value.signedEvent?.toJson())
|
||||
gen.writeStringField("encryptDecryptResponse", value.encryptDecryptResponse)
|
||||
gen.writeStringField("encryptionType", value.encryptionType.name)
|
||||
gen.writeEndObject()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
+110
-13
@@ -36,9 +36,12 @@ import com.greenart7c3.nostrsigner.database.HistoryEntity
|
||||
import com.greenart7c3.nostrsigner.database.LogEntity
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.AmberBunkerRequest
|
||||
import com.greenart7c3.nostrsigner.models.ClearTextEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.models.EncryptionType
|
||||
import com.greenart7c3.nostrsigner.models.EventEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TagArrayEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.service.NotificationUtils.sendNotification
|
||||
import com.greenart7c3.nostrsigner.service.model.AmberEvent
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
@@ -56,6 +59,7 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.seals.SealedRumorEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import java.util.UUID
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -174,21 +178,114 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
null
|
||||
}
|
||||
|
||||
val encryptDecryptResponse = if (bunkerRequest is BunkerRequestNip44Decrypt) {
|
||||
acc.signer.signerSync.nip44Decrypt(bunkerRequest.ciphertext, bunkerRequest.pubKey)
|
||||
val encryptedDataKind = if (bunkerRequest is BunkerRequestNip44Decrypt) {
|
||||
val result = acc.signer.signerSync.nip44Decrypt(bunkerRequest.ciphertext, bunkerRequest.pubKey)
|
||||
|
||||
if (result.startsWith("{")) {
|
||||
val event = AmberEvent.fromJson(result)
|
||||
if (event.kind == SealedRumorEvent.KIND) {
|
||||
val decryptedSealData = acc.signer.signerSync.decrypt(event.content, acc.hexKey)
|
||||
if (decryptedSealData.startsWith("{")) {
|
||||
val sealEvent = AmberEvent.fromJson(decryptedSealData)
|
||||
EventEncryptedDataKind(event, EventEncryptedDataKind(sealEvent, null, decryptedSealData), result)
|
||||
} else if (decryptedSealData.startsWith("[")) {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(decryptedSealData)
|
||||
EventEncryptedDataKind(event, TagArrayEncryptedDataKind(tagArray, decryptedSealData), decryptedSealData)
|
||||
} else {
|
||||
EventEncryptedDataKind(event, ClearTextEncryptedDataKind(event.content, decryptedSealData), result)
|
||||
}
|
||||
} else {
|
||||
EventEncryptedDataKind(event, null, result)
|
||||
}
|
||||
} else if (result.startsWith("[")) {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(result)
|
||||
TagArrayEncryptedDataKind(tagArray, result)
|
||||
} else {
|
||||
ClearTextEncryptedDataKind(bunkerRequest.ciphertext, result)
|
||||
}
|
||||
} else if (bunkerRequest is BunkerRequestNip44Encrypt) {
|
||||
acc.signer.signerSync.nip44Encrypt(bunkerRequest.message, bunkerRequest.pubKey)
|
||||
val result = acc.signer.signerSync.nip44Encrypt(bunkerRequest.message, bunkerRequest.pubKey)
|
||||
if (bunkerRequest.message.startsWith("{")) {
|
||||
try {
|
||||
val event = AmberEvent.fromJson(bunkerRequest.message)
|
||||
if (event.kind == SealedRumorEvent.KIND) {
|
||||
val decryptedSealData = acc.signer.signerSync.decrypt(event.content, acc.hexKey)
|
||||
if (decryptedSealData.startsWith("{")) {
|
||||
val sealEvent = AmberEvent.fromJson(decryptedSealData)
|
||||
EventEncryptedDataKind(event, EventEncryptedDataKind(sealEvent, null, decryptedSealData), result)
|
||||
} else if (decryptedSealData.startsWith("[")) {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(decryptedSealData)
|
||||
EventEncryptedDataKind(event, TagArrayEncryptedDataKind(tagArray, decryptedSealData), decryptedSealData)
|
||||
} else {
|
||||
EventEncryptedDataKind(event, ClearTextEncryptedDataKind(event.content, decryptedSealData), result)
|
||||
}
|
||||
} else {
|
||||
EventEncryptedDataKind(event, null, result)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("IntentUtils", "Error parsing JSON: ${e.message}")
|
||||
ClearTextEncryptedDataKind(bunkerRequest.message, result)
|
||||
}
|
||||
} else if (bunkerRequest.message.startsWith("[")) {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(bunkerRequest.message)
|
||||
TagArrayEncryptedDataKind(tagArray, result)
|
||||
} else {
|
||||
ClearTextEncryptedDataKind(bunkerRequest.message, result)
|
||||
}
|
||||
} else if (bunkerRequest is BunkerRequestNip04Decrypt) {
|
||||
acc.signer.signerSync.nip04Decrypt(bunkerRequest.ciphertext, bunkerRequest.pubKey)
|
||||
val result = acc.signer.signerSync.nip04Decrypt(bunkerRequest.ciphertext, bunkerRequest.pubKey)
|
||||
|
||||
if (result.startsWith("{")) {
|
||||
val event = AmberEvent.fromJson(result)
|
||||
if (event.kind == SealedRumorEvent.KIND) {
|
||||
val decryptedSealData = acc.signer.signerSync.decrypt(event.content, acc.hexKey)
|
||||
if (decryptedSealData.startsWith("{")) {
|
||||
val sealEvent = AmberEvent.fromJson(decryptedSealData)
|
||||
EventEncryptedDataKind(event, EventEncryptedDataKind(sealEvent, null, decryptedSealData), result)
|
||||
} else if (decryptedSealData.startsWith("[")) {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(decryptedSealData)
|
||||
EventEncryptedDataKind(event, TagArrayEncryptedDataKind(tagArray, decryptedSealData), decryptedSealData)
|
||||
} else {
|
||||
EventEncryptedDataKind(event, ClearTextEncryptedDataKind(event.content, decryptedSealData), result)
|
||||
}
|
||||
} else {
|
||||
EventEncryptedDataKind(event, null, result)
|
||||
}
|
||||
} else if (result.startsWith("[")) {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(result)
|
||||
TagArrayEncryptedDataKind(tagArray, result)
|
||||
} else {
|
||||
ClearTextEncryptedDataKind(bunkerRequest.ciphertext, result)
|
||||
}
|
||||
} else if (bunkerRequest is BunkerRequestNip04Encrypt) {
|
||||
acc.signer.signerSync.nip04Encrypt(bunkerRequest.message, bunkerRequest.pubKey)
|
||||
} else if (bunkerRequest.method == "decrypt_zap_event") {
|
||||
AmberUtils.encryptOrDecryptData(
|
||||
bunkerRequest.params[1],
|
||||
SignerType.DECRYPT_ZAP_EVENT,
|
||||
acc,
|
||||
bunkerRequest.params.first(),
|
||||
)
|
||||
val result = acc.signer.signerSync.nip04Encrypt(bunkerRequest.message, bunkerRequest.pubKey)
|
||||
if (bunkerRequest.message.startsWith("{")) {
|
||||
try {
|
||||
val event = AmberEvent.fromJson(bunkerRequest.message)
|
||||
if (event.kind == SealedRumorEvent.KIND) {
|
||||
val decryptedSealData = acc.signer.signerSync.decrypt(event.content, acc.hexKey)
|
||||
if (decryptedSealData.startsWith("{")) {
|
||||
val sealEvent = AmberEvent.fromJson(decryptedSealData)
|
||||
EventEncryptedDataKind(event, EventEncryptedDataKind(sealEvent, null, decryptedSealData), result)
|
||||
} else if (decryptedSealData.startsWith("[")) {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(decryptedSealData)
|
||||
EventEncryptedDataKind(event, TagArrayEncryptedDataKind(tagArray, decryptedSealData), decryptedSealData)
|
||||
} else {
|
||||
EventEncryptedDataKind(event, ClearTextEncryptedDataKind(event.content, decryptedSealData), result)
|
||||
}
|
||||
} else {
|
||||
EventEncryptedDataKind(event, null, result)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("IntentUtils", "Error parsing JSON: ${e.message}")
|
||||
ClearTextEncryptedDataKind(bunkerRequest.message, result)
|
||||
}
|
||||
} else if (bunkerRequest.message.startsWith("[")) {
|
||||
val tagArray = JacksonMapper.fromJsonToTagArray(bunkerRequest.message)
|
||||
TagArrayEncryptedDataKind(tagArray, result)
|
||||
} else {
|
||||
ClearTextEncryptedDataKind(bunkerRequest.message, result)
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -217,7 +314,7 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
closeApplication = true,
|
||||
name = "",
|
||||
signedEvent = signedEvent,
|
||||
encryptDecryptResponse = encryptDecryptResponse,
|
||||
encryptedData = encryptedDataKind,
|
||||
encryptionType = encryptionType,
|
||||
)
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import com.greenart7c3.nostrsigner.database.ApplicationWithPermissions
|
||||
import com.greenart7c3.nostrsigner.database.HistoryEntity
|
||||
import com.greenart7c3.nostrsigner.database.LogEntity
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.AmberBunkerRequest
|
||||
import com.greenart7c3.nostrsigner.models.ClearTextEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.models.CompressionType
|
||||
import com.greenart7c3.nostrsigner.models.EventEncryptedDataKind
|
||||
@@ -595,22 +594,8 @@ object IntentUtils {
|
||||
return null
|
||||
}
|
||||
|
||||
val bunkerRequest =
|
||||
if (intent.getStringExtra("bunker") != null) {
|
||||
AmberBunkerRequest.mapper.readValue(
|
||||
intent.getStringExtra("bunker"),
|
||||
AmberBunkerRequest::class.java,
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
var localAccount = currentLoggedInAccount
|
||||
if (bunkerRequest != null) {
|
||||
LocalPreferences.loadFromEncryptedStorageSync(context, bunkerRequest.currentAccount)?.let {
|
||||
localAccount = it
|
||||
}
|
||||
} else if (intent.getStringExtra("current_user") != null) {
|
||||
if (intent.getStringExtra("current_user") != null) {
|
||||
var npub = intent.getStringExtra("current_user")
|
||||
if (npub != null) {
|
||||
npub = parsePubKey(npub)
|
||||
@@ -622,8 +607,6 @@ object IntentUtils {
|
||||
|
||||
if (intent.dataString?.startsWith("nostrconnect:") == true) {
|
||||
NostrConnectUtils.getIntentFromNostrConnect(intent, localAccount)
|
||||
} else if (bunkerRequest != null) {
|
||||
BunkerRequestUtils.addRequest(bunkerRequest)
|
||||
} else if (intent.extras?.getString(Browser.EXTRA_APPLICATION_ID) == null) {
|
||||
return getIntentDataFromIntent(context, intent, packageName, route, localAccount)
|
||||
} else {
|
||||
|
||||
@@ -124,7 +124,7 @@ object NostrConnectUtils {
|
||||
closeApplication = intent.getBooleanExtra("closeApplication", true),
|
||||
name = name,
|
||||
signedEvent = null,
|
||||
encryptDecryptResponse = null,
|
||||
encryptedData = null,
|
||||
encryptionType = EncryptionType.NIP44,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -183,7 +183,21 @@ fun SeeDetailsScreen(
|
||||
val event = bunkerRequest.signedEvent!!
|
||||
if (event.kind == 22242) AmberEvent.relay(event) else event.content
|
||||
} else {
|
||||
bunkerRequest.encryptDecryptResponse ?: BunkerRequestUtils.getDataFromBunker(bunkerRequest.request)
|
||||
if (type.name.contains("ENCRYPT") && bunkerRequest.encryptedData is ClearTextEncryptedDataKind) {
|
||||
bunkerRequest.encryptedData.text
|
||||
} else if (bunkerRequest.encryptedData is EventEncryptedDataKind) {
|
||||
if (bunkerRequest.encryptedData.sealEncryptedDataKind != null) {
|
||||
if (bunkerRequest.encryptedData.sealEncryptedDataKind is EventEncryptedDataKind) {
|
||||
bunkerRequest.encryptedData.sealEncryptedDataKind.event.content
|
||||
} else {
|
||||
bunkerRequest.encryptedData.sealEncryptedDataKind.result
|
||||
}
|
||||
} else {
|
||||
bunkerRequest.encryptedData.event.content
|
||||
}
|
||||
} else {
|
||||
bunkerRequest.encryptedData?.result ?: BunkerRequestUtils.getDataFromBunker(bunkerRequest.request)
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
|
||||
+11
-11
@@ -306,7 +306,7 @@ fun BunkerSingleEventHomeScreen(
|
||||
account = account,
|
||||
modifier = modifier,
|
||||
content = bunkerRequest.request.message,
|
||||
encryptedData = bunkerRequest.encryptDecryptResponse ?: "",
|
||||
encryptedData = bunkerRequest.encryptedData,
|
||||
shouldRunOnAccept = acceptOrReject,
|
||||
appName = appName,
|
||||
type = type,
|
||||
@@ -315,7 +315,7 @@ fun BunkerSingleEventHomeScreen(
|
||||
context = context,
|
||||
account = account,
|
||||
key = key,
|
||||
response = bunkerRequest.encryptDecryptResponse ?: "",
|
||||
response = bunkerRequest.encryptedData?.result ?: "",
|
||||
bunkerRequest = bunkerRequest,
|
||||
kind = null,
|
||||
onLoading = onLoading,
|
||||
@@ -371,12 +371,12 @@ fun BunkerSingleEventHomeScreen(
|
||||
account = account,
|
||||
modifier = modifier,
|
||||
content = bunkerRequest.request.ciphertext,
|
||||
encryptedData = bunkerRequest.encryptDecryptResponse ?: "",
|
||||
encryptedData = bunkerRequest.encryptedData,
|
||||
shouldRunOnAccept = acceptOrReject,
|
||||
appName = appName,
|
||||
type = type,
|
||||
onAccept = {
|
||||
val result = bunkerRequest.encryptDecryptResponse ?: ""
|
||||
val result = bunkerRequest.encryptedData?.result ?: ""
|
||||
|
||||
BunkerRequestUtils.sendResult(
|
||||
context = context,
|
||||
@@ -438,12 +438,12 @@ fun BunkerSingleEventHomeScreen(
|
||||
account = account,
|
||||
modifier = modifier,
|
||||
content = bunkerRequest.request.message,
|
||||
encryptedData = bunkerRequest.encryptDecryptResponse ?: "",
|
||||
encryptedData = bunkerRequest.encryptedData,
|
||||
shouldRunOnAccept = acceptOrReject,
|
||||
appName = appName,
|
||||
type = type,
|
||||
onAccept = {
|
||||
val result = bunkerRequest.encryptDecryptResponse ?: ""
|
||||
val result = bunkerRequest.encryptedData?.result ?: ""
|
||||
|
||||
BunkerRequestUtils.sendResult(
|
||||
context = context,
|
||||
@@ -505,12 +505,12 @@ fun BunkerSingleEventHomeScreen(
|
||||
account = account,
|
||||
modifier = modifier,
|
||||
content = bunkerRequest.request.ciphertext,
|
||||
encryptedData = bunkerRequest.encryptDecryptResponse ?: "",
|
||||
encryptedData = bunkerRequest.encryptedData,
|
||||
shouldRunOnAccept = acceptOrReject,
|
||||
appName = appName,
|
||||
type = type,
|
||||
onAccept = {
|
||||
val result = bunkerRequest.encryptDecryptResponse ?: ""
|
||||
val result = bunkerRequest.encryptedData?.result ?: ""
|
||||
|
||||
BunkerRequestUtils.sendResult(
|
||||
context = context,
|
||||
@@ -658,16 +658,16 @@ fun BunkerSingleEventHomeScreen(
|
||||
account = account,
|
||||
modifier = modifier,
|
||||
content = bunkerRequest.request.params[1],
|
||||
encryptedData = bunkerRequest.encryptDecryptResponse ?: "",
|
||||
encryptedData = bunkerRequest.encryptedData,
|
||||
shouldRunOnAccept = acceptOrReject,
|
||||
appName = appName,
|
||||
type = type,
|
||||
onAccept = {
|
||||
val result =
|
||||
if (bunkerRequest.encryptDecryptResponse == "Could not decrypt the message") {
|
||||
if (bunkerRequest.encryptedData?.result == "Could not decrypt the message") {
|
||||
""
|
||||
} else {
|
||||
bunkerRequest.encryptDecryptResponse ?: ""
|
||||
bunkerRequest.encryptedData?.result ?: ""
|
||||
}
|
||||
|
||||
BunkerRequestUtils.sendResult(
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package com.greenart7c3.nostrsigner.ui.components
|
||||
|
||||
import android.content.ClipData
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Card
|
||||
@@ -17,7 +14,6 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ClipEntry
|
||||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -27,7 +23,6 @@ import androidx.compose.ui.text.capitalize
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@@ -42,7 +37,6 @@ import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TagArrayEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.ui.RememberType
|
||||
import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun EncryptDecryptData(
|
||||
@@ -200,7 +194,7 @@ fun BunkerEncryptDecryptData(
|
||||
account: Account,
|
||||
modifier: Modifier,
|
||||
content: String,
|
||||
encryptedData: String,
|
||||
encryptedData: EncryptedDataKind?,
|
||||
shouldRunOnAccept: Boolean?,
|
||||
appName: String,
|
||||
type: SignerType,
|
||||
@@ -222,41 +216,91 @@ fun BunkerEncryptDecryptData(
|
||||
) {
|
||||
ProfilePicture(account)
|
||||
|
||||
val message =
|
||||
when (type) {
|
||||
SignerType.NIP44_ENCRYPT -> stringResource(R.string.encrypt_nip44)
|
||||
SignerType.NIP04_ENCRYPT -> stringResource(R.string.encrypt_nip04)
|
||||
SignerType.NIP44_DECRYPT -> stringResource(R.string.decrypt_nip44)
|
||||
SignerType.NIP04_DECRYPT -> stringResource(R.string.decrypt_nip04)
|
||||
SignerType.DECRYPT_ZAP_EVENT -> stringResource(R.string.decrypt_zap_event)
|
||||
else -> stringResource(R.string.encrypt_decrypt)
|
||||
}
|
||||
|
||||
Text(
|
||||
buildAnnotatedString {
|
||||
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(appName)
|
||||
}
|
||||
append(" requests $message")
|
||||
if (type.name.contains("ENCRYPT")) {
|
||||
when (encryptedData) {
|
||||
is EventEncryptedDataKind -> {
|
||||
val permission = Permission("sign_event", encryptedData.event.kind)
|
||||
append(stringResource(R.string.wants_to_encrypt_with, permission.toLocalizedString(Amber.instance), type.name.split("_").first()))
|
||||
}
|
||||
|
||||
is TagArrayEncryptedDataKind -> {
|
||||
append(stringResource(R.string.wants_to_encrypt_this_list_of_tags_with, type.name.split("_").first()))
|
||||
}
|
||||
|
||||
else -> append(stringResource(R.string.wants_to_encrypt_this_text_with, type.name.split("_").first()))
|
||||
}
|
||||
} else {
|
||||
when (encryptedData) {
|
||||
is EventEncryptedDataKind -> {
|
||||
val permission = Permission("sign_event", encryptedData.event.kind)
|
||||
append(stringResource(R.string.wants_to_read_from_encrypted_content, permission.toLocalizedString(Amber.instance), type.name.split("_").first()))
|
||||
}
|
||||
|
||||
is TagArrayEncryptedDataKind -> {
|
||||
append(stringResource(R.string.wants_to_read_this_list_of_tags_from_encrypted_content, type.name.split("_").first()))
|
||||
}
|
||||
|
||||
else -> append(stringResource(R.string.wants_to_read_this_text_from_encrypted_content, type.name.split("_").first()))
|
||||
}
|
||||
}
|
||||
},
|
||||
fontSize = 18.sp,
|
||||
)
|
||||
Spacer(Modifier.size(4.dp))
|
||||
if (!type.toString().contains("DECRYPT")) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Column(Modifier.padding(6.dp)) {
|
||||
Text(
|
||||
"Event content",
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Column(Modifier.padding(6.dp)) {
|
||||
Text(
|
||||
stringResource(R.string.content).capitalize(Locale.current),
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
|
||||
if (encryptedData is EventEncryptedDataKind) {
|
||||
if (encryptedData.sealEncryptedDataKind != null) {
|
||||
if (encryptedData.sealEncryptedDataKind is EventEncryptedDataKind) {
|
||||
val content = if (encryptedData.sealEncryptedDataKind.event.kind == 22242) encryptedData.sealEncryptedDataKind.event.relay() else encryptedData.sealEncryptedDataKind.event.content
|
||||
if (encryptedData.event.kind == ContactListEvent.KIND) {
|
||||
ContactListDetail(
|
||||
title = stringResource(R.string.following),
|
||||
text = "${encryptedData.event.verifiedFollowKeySet().size}",
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
content,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val content = if (encryptedData.event.kind == 22242) encryptedData.event.relay() else encryptedData.event.content
|
||||
if (encryptedData.event.kind == ContactListEvent.KIND) {
|
||||
ContactListDetail(
|
||||
title = stringResource(R.string.following),
|
||||
text = "${encryptedData.event.verifiedFollowKeySet().size}",
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
content,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val content = if (type.name.contains("ENCRYPT") && encryptedData is ClearTextEncryptedDataKind) encryptedData.text else encryptedData?.result ?: ""
|
||||
Text(
|
||||
content,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp),
|
||||
@@ -264,37 +308,8 @@ fun BunkerEncryptDecryptData(
|
||||
}
|
||||
}
|
||||
}
|
||||
RawJsonButton(
|
||||
onCLick = {
|
||||
showMore = !showMore
|
||||
},
|
||||
if (!showMore) stringResource(R.string.show_details) else stringResource(R.string.hide_details),
|
||||
)
|
||||
if (showMore) {
|
||||
RawJson(
|
||||
content,
|
||||
encryptedData,
|
||||
Modifier.height(200.dp),
|
||||
stringResource(R.string.encrypted_decrypted_data),
|
||||
type,
|
||||
) {
|
||||
coroutineScope.launch {
|
||||
clipboardManager.setClipEntry(
|
||||
ClipEntry(
|
||||
ClipData.newPlainText("", encryptedData),
|
||||
),
|
||||
)
|
||||
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.data_copied_to_the_clipboard),
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
RememberMyChoice(
|
||||
shouldRunOnAccept,
|
||||
|
||||
@@ -894,7 +894,7 @@ fun BunkerMultiEventHomeScreen(
|
||||
thisAccount.npub,
|
||||
)
|
||||
|
||||
val signature = request.encryptDecryptResponse ?: continue
|
||||
val signature = request.encryptedData?.result ?: continue
|
||||
val localBunkerRequest = request.copy()
|
||||
BunkerRequestUtils.remove(request.request.id)
|
||||
if (request.checked.value) {
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.greenart7c3.nostrsigner.models
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class AmberBunkerRequestTest {
|
||||
@Test
|
||||
fun `encryption type survives serialization`() {
|
||||
val relay = RelayUrlNormalizer.normalizeOrNull("wss://relay.example.com")
|
||||
requireNotNull(relay) { "Expected relay URL to normalize" }
|
||||
|
||||
val request =
|
||||
AmberBunkerRequest(
|
||||
request = BunkerRequestConnect(remoteKey = HEX_KEY, secret = "secret", permissions = null),
|
||||
localKey = HEX_KEY,
|
||||
relays = listOf(relay),
|
||||
currentAccount = "npub1test",
|
||||
nostrConnectSecret = "secret",
|
||||
closeApplication = true,
|
||||
name = "Test App",
|
||||
signedEvent = null,
|
||||
encryptDecryptResponse = null,
|
||||
encryptionType = EncryptionType.NIP04,
|
||||
)
|
||||
|
||||
val json = request.toJson()
|
||||
val roundTrip = AmberBunkerRequest.mapper.readValue(json, AmberBunkerRequest::class.java)
|
||||
|
||||
assertEquals(EncryptionType.NIP04, roundTrip.encryptionType)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val HEX_KEY = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user