relaycorp / awala-endpoint-android

High-level library for Android apps implementing Awala endpoints
Apache License 2.0
2 stars 1 forks source link

App is notified about incoming parcels for 1st party endpoints from a previous instance of the app #338

Closed gnarea closed 1 year ago

gnarea commented 1 year ago

If the app is reinstalled or its data is cleared, the Awala app will notify it about incoming parcels for the old first-party endpoints, which would cause the app to crash with the following:

2023-09-18 16:49:27.455 13238-13266 AndroidRuntime          tech.relaycorp.letro                 E  FATAL EXCEPTION: DefaultDispatcher-worker-2
                                                                                                    Process: tech.relaycorp.letro, PID: 13238
                                                                                                    tech.relaycorp.relaynet.bindings.pdc.NonceSignerException: At least one nonce signer must be specified
                                                                                                        at tech.relaycorp.poweb.PoWebClient$collectParcels$2.invokeSuspend(PoWebClient.kt:191)
                                                                                                        at tech.relaycorp.poweb.PoWebClient$collectParcels$2.invoke(Unknown Source:8)
                                                                                                        at tech.relaycorp.poweb.PoWebClient$collectParcels$2.invoke(Unknown Source:4)
                                                                                                        at kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:61)
                                                                                                        at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:230)
                                                                                                        at tech.relaycorp.awaladroid.messaging.ReceiveMessages$collectParcels$$inlined$mapNotNull$1.collect(SafeCollector.common.kt:114)
                                                                                                        at kotlinx.coroutines.flow.FlowKt__EmittersKt$onCompletion$$inlined$unsafeFlow$1.collect(SafeCollector.common.kt:115)
                                                                                                        at kotlinx.coroutines.flow.FlowKt__CollectKt.emitAll(Collect.kt:109)
                                                                                                        at kotlinx.coroutines.flow.FlowKt.emitAll(Unknown Source:1)
                                                                                                        at tech.relaycorp.awaladroid.messaging.ReceiveMessages$receive$$inlined$flatMapLatest$1.invokeSuspend(Merge.kt:193)
                                                                                                        at tech.relaycorp.awaladroid.messaging.ReceiveMessages$receive$$inlined$flatMapLatest$1.invoke(Unknown Source:13)
                                                                                                        at tech.relaycorp.awaladroid.messaging.ReceiveMessages$receive$$inlined$flatMapLatest$1.invoke(Unknown Source:4)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3$1$2.invokeSuspend(Merge.kt:34)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3$1$2.invoke(Unknown Source:8)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3$1$2.invoke(Unknown Source:4)
                                                                                                        at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:44)
                                                                                                        at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:112)
                                                                                                        at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
                                                                                                        at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
                                                                                                        at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
                                                                                                        at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
                                                                                                        at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3$1.emit(Merge.kt:33)
                                                                                                        at kotlinx.coroutines.flow.FlowKt__BuildersKt$asFlow$$inlined$unsafeFlow$2.collect(SafeCollector.common.kt:114)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invokeSuspend(Merge.kt:27)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invoke(Unknown Source:8)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest$flowCollect$3.invoke(Unknown Source:4)
                                                                                                        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:78)
                                                                                                        at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:264)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowTransformLatest.flowCollect(Merge.kt:25)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collectTo$suspendImpl(ChannelFlow.kt:157)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlowOperator.collectTo(Unknown Source:0)
                                                                                                        at kotlinx.coroutines.flow.internal.ChannelFlow$collectToFun$1.invokeSuspend(ChannelFlow.kt:60)
                                                                                                        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
                                                                                                        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
                                                                                                        at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:115)
                                                                                                        at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:103)
                                                                                                        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:584)
                                                                                                        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:793)
                                                                                                        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:697)
                                                                                                        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:684)

One fix could be to alter the following broadcast receiver to only call checkForNewMessages() when there's at least one first-party endpoint.

https://github.com/relaycorp/awala-endpoint-android/blob/4504c6c934a123b384fc7469d63e8ca9f4710833/lib/src/main/java/tech/relaycorp/awaladroid/background/IncomingParcelBroadcastReceiver.kt#L16-L20

gnarea commented 1 year ago

A more reliable, but more expensive, solution would be to create a new intent that the app sends to Awala to report when it's running for the first time ever.

Awala could then store the date, so that any incoming parcel whose PDA was created before this date is automatically ignored.

github-actions[bot] commented 1 year ago

:tada: This issue has been resolved in version 1.13.23 :tada:

The release is available on GitHub release

Your semantic-release bot :package::rocket: