bd9f0d8437
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>
4.2 KiB
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 |
|
|
|
|
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
- ViewModel:
WidgetsViewModel(matrixClient, roomId):Flow<List<Widget>>desde state eventsm.widgetdel room.addWidget(widget),removeWidget(widgetId).generateUrl(widget) -> String— substituye placeholders Matrix Widget API.mintScopedToken(widgetId) -> String— token efimero scope room+widget.
- Compose:
WidgetsPanel(drawer lateral o bottom sheet en movil):- Tabs con widgets activos del room.
- Cada tab =
WidgetViewque envuelve unWebView.
WidgetViewcomposable:WebViewconfigurado:settings.javaScriptEnabled = true.settings.allowFileAccess = false.settings.allowContentAccess = false.settings.allowFileAccessFromFileURLs = false.settings.allowUniversalAccessFromFileURLs = false.settings.mixedContentMode = MIXED_CONTENT_NEVER_ALLOW.webViewClientcon CSP injection + URL allowlist.
addJavascriptInterface(WidgetBridge, "MatrixWidgetBridge")— bridge expone Widget API v2.
CapabilityConsentDialogCompose — pide consentimiento usuario para capabilities.
- 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.
- Implementa capabilities handshake postMessage (igual contrato que cliente PC):
- Widgets internos primer batch (compartidos con cliente PC):
widget-agent-panel— control del agente.widget-kanban— kanban inline.widget-issue-tracker.
- Tests:
- Instrumented
WidgetCapabilitiesTest— dialog aparece + accept/decline funciona. - Instrumented
WidgetSandboxTest— widget malicioso (intentawindow.location='file:///etc/passwd') bloqueado. - Instrumented
WidgetSendEventTest— widget con capability envia msg.
- Instrumented
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
XMLHttpRequestafile:///-> 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.addJavascriptInterfacesolo 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 esfile://. Nuestros widgets sonhttps://-> 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).