daef7ea190
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.9 KiB
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 |
|
|
|
|
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
- Backend Go:
MatrixService.ListWidgets(roomID) -> []Widget— lee state eventsm.widgetdel 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,$themeen 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).
- 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 escuchapostMessagedel iframe e implementa Widget API v2:capabilitieshandshake: 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.
- Hook
- 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 poragents_and_robotsHTTP API (issue 0113 ya creando agent runner API).widget-kanban— kanban inline embebido para tasks del room. Reusaapps/kanban(Go) servido en LAN.widget-issue-tracker— widget que abre issue API (0109m).
- Tests:
e2e/test_widget_capabilities.sh— widget pide capability, dialog aparece, deniega/acepta funciona.e2e/test_widget_send_event.sh— widget con capabilitysend_eventenvia msg al room.e2e/test_widget_sandbox.sh— widget malicioso (intentatop.location =) es bloqueado por sandbox.
Funciones del registry a crear
matrix_widget_state_go_infra— CRUD state eventsm.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.appcrea 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_robotspublica 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:nidata:text/htmlURLs (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:+ permitirdata:/blob:solo para widgets internos firmados.
Roadmap post-DoD:
- Widget marketplace interno:
widget-catalogenagents_and_robotscon widgets internos descubribles. - Widget templates: un agente publica un widget HTML estatico subido al room (
mxc://) y el cliente lo renderiza desde la URLmxc -> http. - Cross-room widgets: widget que persiste entre rooms (TBD, requiere MSC propio).