feat(extensions): complete signed-session grants from help dialog

Add a platform bridge to finish session grants on Android and iOS with
JSON success validation, let users paste callback URLs from the
clipboard, and auto-dismiss the verification help dialog after grant.
This commit is contained in:
zarzet
2026-07-05 01:50:42 +07:00
parent edb241faf7
commit 6b30eba947
4 changed files with 284 additions and 59 deletions
@@ -2115,6 +2115,9 @@ class MainActivity: FlutterFragmentActivity() {
Gobackend.setExtensionAuthCodeByID(extId, code)
Gobackend.invokeExtensionActionJSON(extId, "completeSpotifyLogin")
}
if (isSessionGrant) {
requireSuccessfulExtensionAction(extId, "completeGrant", json)
}
android.util.Log.i("SpotiFLAC", "Extension callback complete for $extId: $json")
if (isSessionGrant) {
withContext(Dispatchers.Main) {
@@ -2132,6 +2135,23 @@ class MainActivity: FlutterFragmentActivity() {
}
}
private fun requireSuccessfulExtensionAction(extensionId: String, actionName: String, response: String) {
val obj = try {
JSONObject(response)
} catch (e: Exception) {
throw IllegalStateException(
"Extension $actionName for $extensionId returned invalid JSON: ${response.take(240)}"
)
}
if (obj.optBoolean("success", false)) {
return
}
val error = obj.optString("error")
.ifBlank { obj.optString("message") }
.ifBlank { response.take(240) }
throw IllegalStateException("Extension $actionName failed for $extensionId: $error")
}
private fun notifySessionGrantCompleted(extensionId: String, success: Boolean) {
val payload = mapOf(
"extension_id" to extensionId,
@@ -3340,6 +3360,16 @@ class MainActivity: FlutterFragmentActivity() {
}
result.success(null)
}
"completeExtensionSessionGrant" -> {
val extensionId = call.argument<String>("extension_id") ?: ""
val grant = call.argument<String>("grant") ?: ""
withContext(Dispatchers.IO) {
Gobackend.setExtensionSessionGrantByID(extensionId, grant)
val json = Gobackend.invokeExtensionActionJSON(extensionId, "completeGrant")
requireSuccessfulExtensionAction(extensionId, "completeGrant", json)
}
result.success(true)
}
"setExtensionTokens" -> {
val extensionId = call.argument<String>("extension_id") ?: ""
val accessToken = call.argument<String>("access_token") ?: ""