tauri-plugin-auth-session 0.2.2

Tauri v2 plugin for in-app OAuth authentication on Apple and Android platforms
Documentation
package app.tauri.auth_session

import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.browser.customtabs.CustomTabsIntent

/**
 * Transparent bridge activity that launches Chrome Custom Tabs for OAuth
 * and captures the callback URL via intent filter.
 *
 * Consumer apps must declare an intent filter on this Activity in their
 * AndroidManifest.xml with their app-specific callback scheme.
 */
class AuthSessionActivity : Activity() {
    private var resumed = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Process was killed during auth — can't resume, ask user to retry
        if (savedInstanceState != null) {
            setResult(RESULT_CANCELED)
            finish()
            return
        }

        val authUrl = intent.getStringExtra(EXTRA_AUTH_URL)
        if (authUrl == null) {
            returnError("Missing auth URL")
            return
        }

        try {
            val customTabsIntent = CustomTabsIntent.Builder().build()
            customTabsIntent.launchUrl(this, Uri.parse(authUrl))
        } catch (_: ActivityNotFoundException) {
            returnError("No browser available to handle authentication")
        }
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)

        // Reset flag so onResume doesn't cancel
        resumed = false

        val callbackUrl = intent.data?.toString()
        if (callbackUrl != null) {
            val result = Intent().apply {
                putExtra(EXTRA_CALLBACK_URL, callbackUrl)
            }
            setResult(RESULT_OK, result)
        } else {
            setResult(RESULT_CANCELED)
        }
        finish()
    }

    override fun onResume() {
        super.onResume()

        if (resumed) {
            // Second resume without onNewIntent = user pressed back
            setResult(RESULT_CANCELED)
            finish()
            return
        }
        resumed = true
    }

    private fun returnError(message: String) {
        val result = Intent().apply {
            putExtra(EXTRA_ERROR, message)
        }
        setResult(RESULT_FIRST_USER, result)
        finish()
    }

    companion object {
        const val EXTRA_AUTH_URL = "auth_url"
        const val EXTRA_CALLBACK_URL = "callback_url"
        const val EXTRA_ERROR = "error"
    }
}