@@ -64,6 +64,7 @@ import io.muun.apollo.presentation.ui.view.TextInputWithBackHandling
6464import newop.EnterAmountState
6565import newop.EnterDescriptionState
6666import newop.PaymentIntent
67+ import timber.log.Timber
6768import javax.inject.Inject
6869import javax.money.MonetaryAmount
6970
@@ -225,36 +226,52 @@ class NewOperationActivity : SingleFragmentActivity<NewOperationPresenter>(),
225226 override fun onCreate (savedInstanceState : Bundle ? ) {
226227 super .onCreate(savedInstanceState)
227228
229+ // TODO: add timber.i() for intent.getAction() and intent.getData().getScheme() iff not null
230+
228231 if (intent.flags and Intent .FLAG_ACTIVITY_CLEAR_TOP == 0 ) {
229232 // HACK ALERT
230233 // This Activity was not launched with the CLEAR_TOP flag, because it started from
231234 // an <intent-filter> defined in the manifest. Flags cannot be specified for these
232235 // Intents (pff), and we really need CLEAR_TOP, so... well, this:
233236 intent.addFlags(Intent .FLAG_ACTIVITY_CLEAR_TOP )
234237
238+ // We log penalties but don't throw and exception for it because it could happen that
239+ // there are non supported args but the uri can still be usable
240+ val penalties = mutableListOf<String >()
241+
235242 // Sanitize the intent before restarting to prevent UnsafeIntentLaunch
236243 val sanitizedIntent = IntentSanitizer .Builder ()
237244 .allowComponent(ComponentName (this , NewOperationActivity ::class .java))
238- .allowData { uri -> uri.scheme in listOf (" bitcoin" , " lightning" , " lnurl " ) }
245+ .allowData { uri -> uri.scheme in listOf (" bitcoin" , " lightning" , " muun " ) }
239246 .allowExtra(OPERATION_URI , String ::class .java)
240247 .allowExtra(ORIGIN , String ::class .java)
241248 .allowFlags(Intent .FLAG_ACTIVITY_CLEAR_TOP )
242249 .build()
243- .sanitizeByFiltering(intent)
250+ .sanitize(intent) { error ->
251+ penalties.add(error)
252+ }
253+
254+ if (penalties.isNotEmpty()) {
255+ Timber .e(" Invalid NewOp Intent uri: %s" , penalties.toString())
256+
257+ // Add 1 breadcrumb per penalty, strings are long and will be cutoff otherwise
258+ penalties.forEach { penalty ->
259+ Timber .i(" NewOp Intent Penalty: %s" , penalty)
260+ }
261+ }
244262
245263 startActivity(sanitizedIntent)
246264 finishActivity()
265+ return
247266 }
248267
249268 val newOpOrigin = getOrigin(intent)
250- val uri = getValidIntentUri(intent)
251- val operationUri = try {
252- OperationUri .fromString(uri)
253- } catch (e: Exception ) {
254- null
255- }
269+ Timber .i(" NewOp Origin: %s" , newOpOrigin)
256270
257- if (operationUri != null ) {
271+ try {
272+ val uri = getValidIntentUri(intent)
273+
274+ val operationUri: OperationUri = OperationUri .fromString(uri)
258275 when {
259276 operationUri.isLn ->
260277 presenter.startForInvoice(operationUri.lnInvoice.get(), newOpOrigin)
@@ -269,9 +286,12 @@ class NewOperationActivity : SingleFragmentActivity<NewOperationPresenter>(),
269286 presenter.startForBitcoinUri(uri, operationUri, newOpOrigin)
270287 }
271288
272- } else {
289+ } catch (e: Exception ) {
290+
291+ Timber .e(e)
292+
273293 showTextToast(getString(R .string.error_no_valid_payment_details_provided))
274- finishActivity( )
294+ presenter.handleError(e, newOpOrigin )
275295 }
276296 }
277297
@@ -328,9 +348,11 @@ class NewOperationActivity : SingleFragmentActivity<NewOperationPresenter>(),
328348 }
329349
330350 private fun getValidIntentUri (intent : Intent ): String {
331- return intent.getStringExtra(OPERATION_URI ) // from startActivity
332- ? : intent.dataString // deeplink
333- ? : throw IllegalStateException (" Invalid New Op Intent" ) // should not happen
351+ return intent.getStringExtra(OPERATION_URI ) // from startActivity
352+ ? : intent.dataString // deeplink
353+ ? : throw InvalidOperationUriException (
354+ " Invalid NewOp Intent uri"
355+ ) // uri is not valid for our scheme
334356 }
335357
336358 override fun setLoading (isLoading : Boolean ) {
0 commit comments