Files
fn_registry/dev/issues/0160-matrix-client-android-mini-webapps.md
egutierrez daef7ea190 feat(matrix): MAS migration helpers + 2 flows + 15 issues + capability group
Helper functions (matrix-mas capability group):
- mas_client_register_bash_infra: register/sync OAuth clients via mas-cli
- mas_syn2mas_migration_bash_infra: dry-run + apply user migration to MAS
- synapse_msc3861_enable_go_infra: edit homeserver.yaml MSC3861 block (with diff)
- wellknown_oidc_patch_go_infra: patch well-known JSON with msc2965.authentication
- synapse_login_flows_check_go_infra: health-check post-migration login flows

Flows + issues for custom Matrix clients (PC + Android):
- 0010 matrix-client-pc: Wails + React+Mantine (issues 0147-0153)
- 0011 matrix-client-android: Kotlin + Compose (issues 0154-0161)
- 0162 enable MAS as auth provider (Synapse delegate) — EXECUTED on VPS
- 0163 custom admin panel propio (sustituye synapse-admin)

Production state (organic-machine.com):
- Synapse migrated SQLite -> Postgres
- MSC3861 active, password_config disabled
- 21 users + 41 access_tokens migrated via syn2mas
- 4 MAS clients registered (element, matrix_pc, matrix_android, admin_panel)
- synapse-admin container removed + Coolify route deleted
- well-known patched with org.matrix.msc2965.authentication

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:53:33 +02:00

4.2 KiB

id, title, status, priority, created, related_flows, related_issues, dependencies, tags
id title status priority created related_flows related_issues dependencies tags
0160 matrix-client-android mini-webapps: WebView + Widget API v2 bridge pending medium 2026-05-24
0011
0159
0161
0159
matrix
android
webview
widgets
agents
sandbox

Objetivo

Host de widgets en Android equivalente al cliente PC (issue 0152). Mismo contrato Widget API v2. WebView con sandbox estricto + bridge JS-Kotlin implementa capabilities API. Widgets de los rooms operados por agentes (agents_and_robots) se ven embebidos: dashboard, formulario, kanban inline, control del agente.

Tareas

  1. ViewModel:
    • WidgetsViewModel(matrixClient, roomId):
      • Flow<List<Widget>> desde state events m.widget del room.
      • addWidget(widget), removeWidget(widgetId).
      • generateUrl(widget) -> String — substituye placeholders Matrix Widget API.
      • mintScopedToken(widgetId) -> String — token efimero scope room+widget.
  2. Compose:
    • WidgetsPanel (drawer lateral o bottom sheet en movil):
      • Tabs con widgets activos del room.
      • Cada tab = WidgetView que envuelve un WebView.
    • WidgetView composable:
      • WebView configurado:
        • settings.javaScriptEnabled = true.
        • settings.allowFileAccess = false.
        • settings.allowContentAccess = false.
        • settings.allowFileAccessFromFileURLs = false.
        • settings.allowUniversalAccessFromFileURLs = false.
        • settings.mixedContentMode = MIXED_CONTENT_NEVER_ALLOW.
        • webViewClient con CSP injection + URL allowlist.
      • addJavascriptInterface(WidgetBridge, "MatrixWidgetBridge") — bridge expone Widget API v2.
    • CapabilityConsentDialog Compose — pide consentimiento usuario para capabilities.
  3. WidgetBridge (Kotlin):
    • Implementa capabilities handshake postMessage (igual contrato que cliente PC):
      • read_events, send_event, send_to_device, get_openid, m.always_on_screen.
    • Audit log mensajes JS<->Kotlin en local DB.
    • Whitelist estricta de capabilities concedidas.
  4. Widgets internos primer batch (compartidos con cliente PC):
    • widget-agent-panel — control del agente.
    • widget-kanban — kanban inline.
    • widget-issue-tracker.
  5. Tests:
    • Instrumented WidgetCapabilitiesTest — dialog aparece + accept/decline funciona.
    • Instrumented WidgetSandboxTest — widget malicioso (intenta window.location='file:///etc/passwd') bloqueado.
    • Instrumented WidgetSendEventTest — widget con capability envia msg.

Funciones del registry a crear

  • WidgetView_kotlin_ui — Compose WebView wrapper sandboxed.
  • widget_bridge_kotlin_infra — JavascriptInterface implementando Widget API v2.
  • widget_url_template_kotlin_core — substituyente placeholders (puede compartirse logica con la Go version del PC, contrato identico).
  • CapabilityConsentDialog_kotlin_ui — Compose dialog.
  • widget_audit_log_kotlin_infra — append-only audit log en Room DB.

Acceptance

  • Widget publicado desde cliente PC se ve embebido en Android (mismo room).
  • Capability handshake: widget pide send_event -> dialog Compose -> accept -> widget envia msg.
  • Sandbox: widget intenta XMLHttpRequest a file:/// -> bloqueado.
  • Widget agent-panel funcional: muestra logs en vivo del agente + boton restart.
  • Audit log persiste en Room DB con timestamp + capability + accept/deny.

Notas

Critico:

  • Mismo contrato Widget API v2 que cliente PC. Widget HTML escrito una vez funciona en ambos.
  • WebView Android moderno (Chromium 100+) soporta WebRTC + WebGL + service workers. Suficiente para widgets ricos.

Gotcha:

  • WebView.addJavascriptInterface solo seguro en Android 4.2+ (API 17+, ya minSdk=28). Pero validar todo input desde JS — nunca confiar.
  • setAllowFileAccessFromFileURLs(false) solo aplica si la URL del widget es file://. Nuestros widgets son https:// -> hardcode CSP estricta.
  • Memory: WebView por tab + 5 widgets activos = ~200MB facil. Limitar a max 3 widgets simultaneos activos.

Roadmap post-DoD:

  • Widget marketplace catalog accesible via menu.
  • "Add to home screen" PWA mode para widgets favoritos (Android shortcut + launcher icon dedicado).