mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Fix some racing conditions when using bunker
This commit is contained in:
+1
@@ -1,6 +1,7 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="AndroidLintUnsafeImplicitIntentLaunch" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="composableFile" value="true" />
|
||||
<option name="previewFile" value="true" />
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.greenart7c3.nostrsigner.models.BunkerResponse
|
||||
import com.greenart7c3.nostrsigner.models.IntentData
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.kindToNip
|
||||
import com.greenart7c3.nostrsigner.ui.IntentResultType
|
||||
import com.vitorpamplona.ammolite.relays.RelaySetupInfo
|
||||
import com.vitorpamplona.quartz.crypto.CryptoUtils
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
@@ -127,7 +128,7 @@ object AmberUtils {
|
||||
relays: List<RelaySetupInfo>,
|
||||
context: Context,
|
||||
closeApplication: Boolean,
|
||||
onRemoveIntentData: (IntentData) -> Unit,
|
||||
onRemoveIntentData: (IntentData, IntentResultType) -> Unit,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
@@ -137,11 +138,15 @@ object AmberUtils {
|
||||
BunkerResponse(bunkerRequest.id, "", "user rejected"),
|
||||
relays,
|
||||
onLoading = onLoading,
|
||||
onDone = {
|
||||
onRemoveIntentData(intentData)
|
||||
context.getAppCompatActivity()?.intent = null
|
||||
if (closeApplication) {
|
||||
context.getAppCompatActivity()?.finish()
|
||||
onDone = { result ->
|
||||
if (!result) {
|
||||
onLoading(false)
|
||||
} else {
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
context.getAppCompatActivity()?.intent = null
|
||||
if (closeApplication) {
|
||||
context.getAppCompatActivity()?.finish()
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -135,7 +135,19 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
BunkerResponse(bunkerRequest.id, bunkerRequest.nostrConnectSecret.ifBlank { "ack" }, null),
|
||||
permission.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
onDone = {
|
||||
if (!it) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
applicationContext,
|
||||
acc,
|
||||
bunkerRequest,
|
||||
BunkerResponse(bunkerRequest.id, bunkerRequest.nostrConnectSecret.ifBlank { "ack" }, null),
|
||||
permission.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {},
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -169,7 +181,19 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
BunkerResponse(bunkerRequest.id, "", message),
|
||||
applicationWithSecret?.application?.relays ?: NostrSigner.getInstance().getSavedRelays().toList(),
|
||||
onLoading = { },
|
||||
onDone = { },
|
||||
onDone = {
|
||||
if (!it) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
applicationContext,
|
||||
acc,
|
||||
bunkerRequest,
|
||||
BunkerResponse(bunkerRequest.id, "", message),
|
||||
applicationWithSecret?.application?.relays ?: NostrSigner.getInstance().getSavedRelays().toList(),
|
||||
onLoading = { },
|
||||
onDone = { },
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -218,7 +242,19 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
BunkerResponse(bunkerRequest.id, "", "no permission"),
|
||||
relays,
|
||||
onLoading = { },
|
||||
onDone = {},
|
||||
onDone = {
|
||||
if (!it) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
applicationContext,
|
||||
acc,
|
||||
bunkerRequest,
|
||||
BunkerResponse(bunkerRequest.id, "", "no permission"),
|
||||
relays,
|
||||
onLoading = { },
|
||||
onDone = {},
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -245,7 +281,19 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
BunkerResponse(bunkerRequest.id, "", "user rejected"),
|
||||
relays,
|
||||
onLoading = { },
|
||||
onDone = { },
|
||||
onDone = {
|
||||
if (!it) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
applicationContext,
|
||||
acc,
|
||||
bunkerRequest,
|
||||
BunkerResponse(bunkerRequest.id, "", "user rejected"),
|
||||
relays,
|
||||
onLoading = { },
|
||||
onDone = { },
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
} else {
|
||||
var index = localCursor.getColumnIndex("event")
|
||||
@@ -261,7 +309,19 @@ class EventNotificationConsumer(private val applicationContext: Context) {
|
||||
BunkerResponse(bunkerRequest.id, result, null),
|
||||
relays,
|
||||
onLoading = { },
|
||||
onDone = { },
|
||||
onDone = {
|
||||
if (!it) {
|
||||
IntentUtils.sendBunkerResponse(
|
||||
applicationContext,
|
||||
acc,
|
||||
bunkerRequest,
|
||||
BunkerResponse(bunkerRequest.id, result, null),
|
||||
relays,
|
||||
onLoading = { },
|
||||
onDone = { },
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -322,7 +322,7 @@ object IntentUtils {
|
||||
bunkerResponse: BunkerResponse,
|
||||
relays: List<RelaySetupInfo>,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
onDone: () -> Unit,
|
||||
onDone: (Boolean) -> Unit,
|
||||
) {
|
||||
AmberListenerSingleton.getListener()?.let {
|
||||
Client.unsubscribe(it)
|
||||
@@ -379,7 +379,7 @@ object IntentUtils {
|
||||
encryptedContent: String,
|
||||
relays: List<RelaySetupInfo>,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
onDone: () -> Unit,
|
||||
onDone: (Boolean) -> Unit,
|
||||
) {
|
||||
account.signer.sign<Event>(
|
||||
TimeUtils.now(),
|
||||
@@ -399,8 +399,9 @@ object IntentUtils {
|
||||
val success = Client.sendAndWaitForResponse(it, relayList = relays)
|
||||
if (success) {
|
||||
Log.d("IntentUtils", "Success response to relays ${relays.map { it.url }} type ${bunkerRequest?.method}")
|
||||
onDone()
|
||||
onDone(true)
|
||||
} else {
|
||||
onDone(false)
|
||||
Log.d("IntentUtils", "Failed response to relays ${relays.map { it.url }} type ${bunkerRequest?.method}")
|
||||
}
|
||||
AmberListenerSingleton.getListener()?.let {
|
||||
|
||||
@@ -92,7 +92,7 @@ object NotificationUtils {
|
||||
bunkerRequest: BunkerRequest,
|
||||
) {
|
||||
val notId = id.hashCode()
|
||||
val notifications: Array<StatusBarNotification> = getActiveNotifications()
|
||||
val notifications: Array<StatusBarNotification> = activeNotifications
|
||||
for (notification in notifications) {
|
||||
if (notification.id == notId) {
|
||||
return
|
||||
|
||||
@@ -140,9 +140,17 @@ fun AccountScreen(
|
||||
database,
|
||||
navController,
|
||||
storageHelper,
|
||||
onRemoveIntentData = {
|
||||
onRemoveIntentData = { intentData, type ->
|
||||
val oldIntents = intents.toMutableList()
|
||||
oldIntents.remove(it)
|
||||
when (type) {
|
||||
IntentResultType.ADD -> {
|
||||
oldIntents.add(intentData)
|
||||
}
|
||||
IntentResultType.REMOVE -> {
|
||||
oldIntents.remove(intentData)
|
||||
}
|
||||
}
|
||||
|
||||
flow.value = oldIntents
|
||||
},
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ fun IncomingRequestScreen(
|
||||
account: Account,
|
||||
database: AppDatabase,
|
||||
navController: NavController,
|
||||
onRemoveIntentData: (IntentData) -> Unit,
|
||||
onRemoveIntentData: (IntentData, IntentResultType) -> Unit,
|
||||
) {
|
||||
var loading by remember { mutableStateOf(false) }
|
||||
val context = LocalContext.current
|
||||
|
||||
@@ -140,7 +140,7 @@ fun sendResult(
|
||||
permissions: List<Permission>? = null,
|
||||
appName: String? = null,
|
||||
signPolicy: Int? = null,
|
||||
onRemoveIntentData: (IntentData) -> Unit,
|
||||
onRemoveIntentData: (IntentData, IntentResultType) -> Unit,
|
||||
) {
|
||||
onLoading(true)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
@@ -254,7 +254,10 @@ fun sendResult(
|
||||
)
|
||||
}
|
||||
|
||||
if (intentData.bunkerRequest == null && intentData.type == SignerType.GET_PUBLIC_KEY) {
|
||||
if (intentData.type == SignerType.CONNECT) {
|
||||
database.applicationDao().deletePermissions(key)
|
||||
}
|
||||
if ((intentData.bunkerRequest == null && intentData.type == SignerType.GET_PUBLIC_KEY) || (intentData.bunkerRequest != null && intentData.type == SignerType.CONNECT)) {
|
||||
if (!application.permissions.any { it.type == SignerType.GET_PUBLIC_KEY.toString() }) {
|
||||
application.permissions.add(
|
||||
ApplicationPermissionsEntity(
|
||||
@@ -269,6 +272,25 @@ fun sendResult(
|
||||
}
|
||||
|
||||
if (intentData.bunkerRequest != null) {
|
||||
val localIntentData = intentData.copy()
|
||||
|
||||
// assume that everything worked and try to revert it if it fails
|
||||
EventNotificationConsumer(context).notificationManager().cancelAll()
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
kind,
|
||||
TimeUtils.now(),
|
||||
true,
|
||||
),
|
||||
)
|
||||
|
||||
EventNotificationConsumer(context).notificationManager().cancelAll()
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
|
||||
IntentUtils.sendBunkerResponse(
|
||||
context,
|
||||
account,
|
||||
@@ -277,27 +299,21 @@ fun sendResult(
|
||||
application.application.relays.ifEmpty { relays },
|
||||
onLoading,
|
||||
onDone = {
|
||||
EventNotificationConsumer(context).notificationManager().cancelAll()
|
||||
if (intentData.type == SignerType.CONNECT) {
|
||||
database.applicationDao().deletePermissions(key)
|
||||
}
|
||||
database.applicationDao().insertApplicationWithPermissions(application)
|
||||
database.applicationDao().addHistory(
|
||||
HistoryEntity(
|
||||
0,
|
||||
key,
|
||||
intentData.type.toString(),
|
||||
kind,
|
||||
TimeUtils.now(),
|
||||
true,
|
||||
),
|
||||
)
|
||||
|
||||
EventNotificationConsumer(context).notificationManager().cancelAll()
|
||||
onRemoveIntentData(intentData)
|
||||
activity?.intent = null
|
||||
if (application.application.closeApplication || intentData.bunkerRequest.closeApplication) {
|
||||
activity?.finish()
|
||||
if (!it) {
|
||||
if (intentData.type == SignerType.SIGN_EVENT) {
|
||||
kind?.let {
|
||||
database.applicationDao().deletePermissions(key, intentData.type.toString(), kind)
|
||||
}
|
||||
} else {
|
||||
database.applicationDao().deletePermissions(key, intentData.type.toString())
|
||||
}
|
||||
onLoading(false)
|
||||
onRemoveIntentData(localIntentData, IntentResultType.ADD)
|
||||
} else {
|
||||
activity?.intent = null
|
||||
if (application.application.closeApplication || intentData.bunkerRequest.closeApplication) {
|
||||
activity?.finish()
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -323,7 +339,7 @@ fun sendResult(
|
||||
intent.putExtra("package", BuildConfig.APPLICATION_ID)
|
||||
}
|
||||
activity?.setResult(RESULT_OK, intent)
|
||||
onRemoveIntentData(intentData)
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
activity?.intent = null
|
||||
activity?.finish()
|
||||
} else if (!intentData.callBackUrl.isNullOrBlank()) {
|
||||
@@ -351,7 +367,7 @@ fun sendResult(
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
onRemoveIntentData(intentData)
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
activity?.intent = null
|
||||
activity?.finish()
|
||||
} else {
|
||||
@@ -377,7 +393,7 @@ fun sendResult(
|
||||
Toast.LENGTH_SHORT,
|
||||
).show()
|
||||
}
|
||||
onRemoveIntentData(intentData)
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
activity?.intent = null
|
||||
activity?.finish()
|
||||
}
|
||||
@@ -445,6 +461,11 @@ fun Color.Companion.fromHex(colorString: String) = try {
|
||||
Unspecified
|
||||
}
|
||||
|
||||
enum class IntentResultType {
|
||||
REMOVE,
|
||||
ADD,
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MainScreen(
|
||||
@@ -457,7 +478,7 @@ fun MainScreen(
|
||||
database: AppDatabase,
|
||||
navController: NavHostController,
|
||||
storageHelper: SimpleStorageHelper,
|
||||
onRemoveIntentData: (IntentData) -> Unit,
|
||||
onRemoveIntentData: (IntentData, IntentResultType) -> Unit,
|
||||
) {
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val destinationRoute = navBackStackEntry?.destination?.route ?: ""
|
||||
|
||||
+11
-4
@@ -67,6 +67,7 @@ import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents
|
||||
import com.greenart7c3.nostrsigner.service.getAppCompatActivity
|
||||
import com.greenart7c3.nostrsigner.service.toShortenHex
|
||||
import com.greenart7c3.nostrsigner.ui.IntentResultType
|
||||
import com.greenart7c3.nostrsigner.ui.Result
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
import com.greenart7c3.nostrsigner.ui.theme.orange
|
||||
@@ -84,7 +85,7 @@ fun MultiEventHomeScreen(
|
||||
packageName: String?,
|
||||
accountParam: Account,
|
||||
navController: NavController,
|
||||
onRemoveIntentData: (IntentData) -> Unit,
|
||||
onRemoveIntentData: (IntentData, IntentResultType) -> Unit,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
@@ -254,7 +255,9 @@ fun MultiEventHomeScreen(
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {
|
||||
onRemoveIntentData(intentData)
|
||||
if (it) {
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
}
|
||||
},
|
||||
)
|
||||
} else {
|
||||
@@ -333,7 +336,9 @@ fun MultiEventHomeScreen(
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {
|
||||
onRemoveIntentData(intentData)
|
||||
if (it) {
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
}
|
||||
},
|
||||
)
|
||||
} else {
|
||||
@@ -397,7 +402,9 @@ fun MultiEventHomeScreen(
|
||||
application.application.relays,
|
||||
onLoading = {},
|
||||
onDone = {
|
||||
onRemoveIntentData(intentData)
|
||||
if (it) {
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
}
|
||||
},
|
||||
)
|
||||
} else {
|
||||
|
||||
+6
-5
@@ -37,6 +37,7 @@ import com.greenart7c3.nostrsigner.models.kindToNip
|
||||
import com.greenart7c3.nostrsigner.service.AmberUtils
|
||||
import com.greenart7c3.nostrsigner.service.getAppCompatActivity
|
||||
import com.greenart7c3.nostrsigner.service.toShortenHex
|
||||
import com.greenart7c3.nostrsigner.ui.IntentResultType
|
||||
import com.greenart7c3.nostrsigner.ui.sendResult
|
||||
import com.vitorpamplona.quartz.crypto.CryptoUtils
|
||||
import com.vitorpamplona.quartz.encoders.bechToBytes
|
||||
@@ -55,7 +56,7 @@ fun SingleEventHomeScreen(
|
||||
intentData: IntentData,
|
||||
account: Account,
|
||||
database: AppDatabase,
|
||||
onRemoveIntentData: (IntentData) -> Unit,
|
||||
onRemoveIntentData: (IntentData, IntentResultType) -> Unit,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
var applicationEntity by remember {
|
||||
@@ -158,7 +159,7 @@ fun SingleEventHomeScreen(
|
||||
)
|
||||
}
|
||||
} else {
|
||||
onRemoveIntentData(intentData)
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
context.getAppCompatActivity()?.intent = null
|
||||
context.getAppCompatActivity()?.finish()
|
||||
}
|
||||
@@ -284,7 +285,7 @@ fun SingleEventHomeScreen(
|
||||
onRemoveIntentData = onRemoveIntentData,
|
||||
)
|
||||
} else {
|
||||
onRemoveIntentData(intentData)
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
context.getAppCompatActivity()?.intent = null
|
||||
if (application.application.closeApplication) {
|
||||
context.getAppCompatActivity()?.finish()
|
||||
@@ -428,7 +429,7 @@ fun SingleEventHomeScreen(
|
||||
onLoading,
|
||||
)
|
||||
} else {
|
||||
onRemoveIntentData(intentData)
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
context.getAppCompatActivity()?.intent = null
|
||||
if (application.application.closeApplication) {
|
||||
context.getAppCompatActivity()?.finish()
|
||||
@@ -597,7 +598,7 @@ fun SingleEventHomeScreen(
|
||||
onRemoveIntentData = onRemoveIntentData,
|
||||
)
|
||||
} else {
|
||||
onRemoveIntentData(intentData)
|
||||
onRemoveIntentData(intentData, IntentResultType.REMOVE)
|
||||
context.getAppCompatActivity()?.intent = null
|
||||
if (application.application.closeApplication) {
|
||||
context.getAppCompatActivity()?.finish()
|
||||
|
||||
Reference in New Issue
Block a user