Files
fn_registry/dev/issues/0152-matrix-client-pc-mini-webapps.md
T
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.9 KiB

id, title, status, priority, created, related_flows, related_issues, dependencies, tags
id title status priority created related_flows related_issues dependencies tags
0152 matrix-client-pc mini-webapps embebidas: Matrix Widget API v2 pending high 2026-05-24
0010
0151
0153
0151
matrix
widgets
webapps
iframe
sandbox
agents
postmessage

Objetivo

Implementar host de widgets segun Matrix Widget API v2 (MSC2762, MSC2871, MSC2974). Cada room puede tener widgets activos publicados como state events m.widget. Los widgets son URLs cargadas en iframes sandboxed con bridge postMessage que da capabilities controladas (leer eventos del room, enviar eventos, mostrar UI overlay, etc.). Agentes de agents_and_robots pueden publicar widgets en sus rooms (ej. dashboard telemetria, formulario, kanban inline, panel de control del agente).

Tareas

  1. Backend Go:
    • MatrixService.ListWidgets(roomID) -> []Widget — lee state events m.widget del room.
    • MatrixService.AddWidget(roomID, widget Widget) — publica state event.
    • MatrixService.RemoveWidget(roomID, widgetID).
    • MatrixService.GenerateWidgetURL(widget Widget, userID) -> string — substituye $matrix_user_id, $matrix_room_id, $matrix_display_name, $matrix_avatar_url, $matrix_widget_id, $theme en la URL del widget.
    • Slash command /widget <url> handler en composer (issue 0149) que crea state event con widget temporal.
    • MatrixService.MintWidgetScopedToken(widgetID, userID) -> string — token efimero con scope reducido (solo el room donde esta el widget).
  2. Frontend React:
    • Hook useWidgets(roomID) — lista widgets activos.
    • Componente WidgetPanel:
      • Tabs por widget activo + boton "+" para anadir.
      • Cada widget en iframe con sandbox="allow-scripts allow-same-origin allow-forms allow-popups-to-escape-sandbox".
      • iframe.referrerpolicy="no-referrer".
      • CSP: frame-src https: data: blob:.
    • WidgetBridge — clase JS que escucha postMessage del iframe e implementa Widget API v2:
      • capabilities handshake: el widget declara que necesita, el host pide consentimiento usuario (dialog Mantine).
      • read_events, send_event, send_to_device, get_openid, m.always_on_screen, etc.
      • Whitelist estricta de capabilities concedidas. Audit log de mensajes en store.db.
    • Layout: widgets se abren en panel lateral derecho (toggleable) o en modal fullscreen.
  3. Widgets internos primer batch (proof of concept):
    • widget-jitsi-fallback — si LiveKit falla, fallback a Jitsi via widget (URL config).
    • widget-agent-panel — panel de control de agente: estado, ultima ejecucion, restart, view logs. Servido por agents_and_robots HTTP API (issue 0113 ya creando agent runner API).
    • widget-kanban — kanban inline embebido para tasks del room. Reusa apps/kanban (Go) servido en LAN.
    • widget-issue-tracker — widget que abre issue API (0109m).
  4. Tests:
    • e2e/test_widget_capabilities.sh — widget pide capability, dialog aparece, deniega/acepta funciona.
    • e2e/test_widget_send_event.sh — widget con capability send_event envia msg al room.
    • e2e/test_widget_sandbox.sh — widget malicioso (intenta top.location =) es bloqueado por sandbox.

Funciones del registry a crear

  • matrix_widget_state_go_infra — CRUD state events m.widget.
  • widget_url_template_go_core — substituye placeholders en URL.
  • widget_token_mint_go_infra — token scoped a un widget+room+user.
  • WidgetBridge_ts_ui — clase postMessage bridge Widget API v2 completa.
  • WidgetPanel_ts_ui — UI tabs + iframes + permisos.
  • CapabilityConsentDialog_ts_ui — dialog Mantine para consentimiento.

Acceptance

  • /widget https://my.app crea state event y abre iframe.
  • Widget declara capability m.send_event -> dialog Mantine pide consentimiento.
  • Widget concedido envia msg al room que aparece en timeline.
  • Widget malicioso <script>top.location='evil.com'</script> bloqueado por sandbox.
  • agents_and_robots publica widget panel y se ve embebido en el room del agente.
  • Widget kanban inline funciona: drag&drop card persiste en DB del kanban.

Notas

Anti-criterios:

  • NO permitir javascript: ni data:text/html URLs (XSS).
  • NO conceder capabilities sin consentimiento explicito del usuario (auditable).
  • NO compartir el access_token Matrix del usuario al widget — usar siempre tokens scoped efimeros.

Decisiones:

  • Widget API v2 (no v1) — soporta capabilities + tokens scoped.
  • iframe sandbox sin allow-top-navigation (previene escape).
  • CSP frame-src https: + permitir data:/blob: solo para widgets internos firmados.

Roadmap post-DoD:

  • Widget marketplace interno: widget-catalog en agents_and_robots con widgets internos descubribles.
  • Widget templates: un agente publica un widget HTML estatico subido al room (mxc://) y el cliente lo renderiza desde la URL mxc -> http.
  • Cross-room widgets: widget que persiste entre rooms (TBD, requiere MSC propio).