From 3f642ab62f10c646ecf2a5c4caf5ca740bf2d46f Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 29 May 2024 13:07:31 -0300 Subject: [PATCH] Add support for the Sign message type in the content provider and MultiEventHomeScreen --- .../greenart7c3/nostrsigner/SignerProvider.kt | 71 +++++++++++++++++++ .../ui/components/MultiEventHomeScreen.kt | 65 +++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/SignerProvider.kt b/app/src/main/java/com/greenart7c3/nostrsigner/SignerProvider.kt index cc42ee7f..e17768de 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/SignerProvider.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/SignerProvider.kt @@ -9,6 +9,8 @@ import com.greenart7c3.nostrsigner.database.HistoryEntity import com.greenart7c3.nostrsigner.models.SignerType import com.greenart7c3.nostrsigner.models.TimeUtils import com.greenart7c3.nostrsigner.service.AmberUtils +import com.vitorpamplona.quartz.crypto.CryptoUtils +import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.encoders.toNpub import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.LnZapRequestEvent @@ -46,6 +48,75 @@ class SignerProvider : ContentProvider() { ): Cursor? { val appId = BuildConfig.APPLICATION_ID return when (uri.toString()) { + "content://$appId.SIGN" -> { + val packageName = callingPackage ?: return null + val message = projection?.first() ?: return null + if (!LocalPreferences.containsAccount(projection[2])) return null + val account = LocalPreferences.loadFromEncryptedStorage(projection[2]) ?: return null + val currentSelection = selection ?: "0" + val database = NostrSigner.instance.getDatabase(account.keyPair.pubKey.toNpub()) + val permission = + database + .applicationDao() + .getPermission( + sortOrder ?: packageName, + "SIGN", + null, + ) + if (currentSelection == "1") { + val isRemembered = permission?.acceptable ?: return null + if (!isRemembered) { + val cursor = + MatrixCursor(arrayOf("rejected")).also { + it.addRow(arrayOf("true")) + } + database.applicationDao().addHistory( + HistoryEntity( + 0, + sortOrder ?: packageName, + uri.toString().replace("content://$appId.", ""), + null, + TimeUtils.now(), + false, + ), + ) + return cursor + } + } else { + val isRemembered = permission?.acceptable ?: false + if (!isRemembered) { + database.applicationDao().addHistory( + HistoryEntity( + 0, + sortOrder ?: packageName, + uri.toString().replace("content://$appId.", ""), + null, + TimeUtils.now(), + false, + ), + ) + return null + } + } + + val result = CryptoUtils.signString(message, account.keyPair.privKey!!).toHexKey() + database.applicationDao().addHistory( + HistoryEntity( + 0, + sortOrder ?: packageName, + "SIGN", + null, + TimeUtils.now(), + true, + ), + ) + + val localCursor = MatrixCursor(arrayOf("signature", "event")).also { + it.addRow(arrayOf(result, result)) + } + + return localCursor + } "content://$appId.SIGN_EVENT" -> { val packageName = callingPackage ?: return null val json = projection?.first() ?: return null diff --git a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MultiEventHomeScreen.kt b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MultiEventHomeScreen.kt index 68244a61..0b4b4294 100644 --- a/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MultiEventHomeScreen.kt +++ b/app/src/main/java/com/greenart7c3/nostrsigner/ui/components/MultiEventHomeScreen.kt @@ -70,6 +70,7 @@ import com.greenart7c3.nostrsigner.service.model.AmberEvent import com.greenart7c3.nostrsigner.service.toShortenHex import com.greenart7c3.nostrsigner.ui.Result import com.greenart7c3.nostrsigner.ui.theme.ButtonBorder +import com.vitorpamplona.quartz.crypto.CryptoUtils import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.events.LnZapRequestEvent import kotlinx.coroutines.Dispatchers @@ -241,6 +242,70 @@ fun MultiEventHomeScreen( ), ) } + } else if (intentData.type == SignerType.SIGN) { + if (intentData.rememberMyChoice.value) { + AmberUtils.acceptOrRejectPermission( + key, + intentData, + null, + intentData.rememberMyChoice.value, + applicationEntity?.application?.name?.ifBlank { applicationEntity.application.key.toShortenHex() } ?: "", + localAccount, + database, + ) + } + + val application = + database + .applicationDao() + .getByKey(key) ?: ApplicationWithPermissions( + application = ApplicationEntity( + key, + applicationEntity?.application?.name?.ifBlank { applicationEntity.application.key.toShortenHex() } ?: "", + listOf(), + "", + "", + "", + localAccount.keyPair.pubKey.toHexKey(), + true, + intentData.bunkerRequest?.secret ?: "", + intentData.bunkerRequest?.secret != null, + ), + permissions = mutableListOf(), + ) + + database.applicationDao().insertApplicationWithPermissions(application) + + database.applicationDao().addHistory( + HistoryEntity( + 0, + key, + intentData.type.toString(), + null, + TimeUtils.now(), + true, + ), + ) + + val signedMessage = CryptoUtils.signString(intentData.data, localAccount.keyPair.privKey!!).toHexKey() + + if (intentData.bunkerRequest != null) { + IntentUtils.sendBunkerResponse( + localAccount, + intentData.bunkerRequest.localKey, + BunkerResponse(intentData.bunkerRequest.id, signedMessage, null), + applicationEntity?.application?.relays?.map { url -> Relay(url) } ?: emptyList(), + onLoading = {}, + ) { } + } else { + results.add( + Result( + null, + signedMessage, + intentData.id, + ), + ) + } } else { if (intentData.rememberMyChoice.value) { AmberUtils.acceptOrRejectPermission(