Saltar al contenido
Historial de versiones

Novedades

Cada versión, con todos los cambios detallados. Las mejoras más recientes aparecen primero.

v0.9.24
25 mayo 2026

Notificaciones webhook y correcciones de logging

FlowCast ya puede avisarte cuando termina o falla cada etapa del pipeline. Configurás una URL (ntfy, Telegram, Slack, Discord o cualquier endpoint HTTP POST) y recibís un JSON con el detalle del evento. También se corrige un bug silencioso que suprimía los logs de startup después de que Alembic corría las migraciones.

  • Nuevo Notificaciones webhook — cuatro eventos: publish_success, download_error, render_error, publish_error. Cada notificación llega como JSON con nombre del podcast, episodio, URL de YouTube (en éxito) o mensaje de error (en fallo). Compatible con ntfy, Telegram bots, Slack, Discord o cualquier endpoint HTTP POST.
  • Nuevo Firma HMAC-SHA256 opcional — configurando WEBHOOK_SECRET, cada request incluye el header X-FlowCast-Signature: sha256=... para verificar que el payload no fue manipulado.
  • Nuevo Protección SSRF en el webhook — la URL destino se valida al arrancar la app y en cada envío. No es posible apuntar el webhook a IPs privadas o de loopback.
  • Nuevo Modal cuando YouTube no está configurado — al hacer clic en "Conectar con YouTube" sin las credenciales de Google en .env, ahora aparece un modal con instrucciones claras en lugar de un JSON crudo. Redirige de vuelta a la página de origen sin ensuciar la URL.
  • Nuevo Aviso YouTube desconectado en sidebar — indicador visible en el footer del sidebar cuando YouTube no está conectado, sin interrumpir la navegación.
  • Fix Logs de startup suprimidos tras AlembicfileConfig() en el entorno de migraciones deshabilitaba silenciosamente todos los loggers del proceso, incluyendo los de la propia app. Los mensajes FlowCast started y Application startup complete ya aparecen correctamente.
v0.9.23
24 mayo 2026

Imagen de portada del podcast desde el feed RSS

Al hacer poll de un feed RSS, FlowCast extrae ahora la imagen de portada del podcast y la muestra como thumbnail en el listado. Las migraciones de base de datos se volvieron más robustas para cubrir instalaciones existentes que nunca tuvieron historial Alembic.

  • Nuevo Imagen de portada en el listado de podcasts — al hacer poll del feed RSS se extrae la URL de la portada (<itunes:image> con fallback a <image>) y se muestra como thumbnail 80×80 en la tarjeta del podcast. La imagen pasa por el proxy /api/img existente, con las mismas protecciones SSRF de siempre.
  • Nuevo Migración Alembic 0002 — añade la columna image_url a la tabla de podcasts. Se aplica automáticamente al arrancar; los datos existentes no se ven afectados.
  • Fix init_db() — detección de instalaciones pre-Alembic — el arranque ahora distingue tres casos: instalación nueva (sin base de datos → create_all + stamp head), instalación pre-v0.9.19 (base existente sin historial Alembic → stamp 0001 + upgrade head), e instalación Alembic-gestionada (upgrade head). Antes, instalar sobre una base sin historial Alembic podía saltar migraciones silenciosamente.
  • Fix Poll de RSS — transacción única — la imagen de portada y los episodios nuevos se persisten ahora en un solo commit(), tanto en el scheduler automático como en el endpoint manual. Antes eran dos transacciones separadas.
  • Fix Botón "Volver al login" en la pantalla 2FA — los estilos inline del browser se reemplazaron por una clase del design system. El botón ahora respeta el color de texto muted y cambia correctamente con el tema claro/oscuro.
v0.9.22
22 mayo 2026

Cierre final auditoría Opus pre-v1.0 — todos los hallazgos resueltos

Último commit de seguridad antes de v1.0. Se cierra el hallazgo pendiente, y los dos restantes quedan documentados como aceptados con justificación. Score final auditoría Opus: ~95/100.

  • Fix SVG eliminado del proxy de imágenesimage/svg+xml removido de la allowlist de /api/img. Las portadas de podcasts son siempre JPEG/PNG/WebP; SVG no es necesario y podría ejecutar scripts si el browser lo renderiza como documento en lugar de como imagen.
  • Fix Auditoría Opus completamente documentada — los hallazgos restantes (fontfile sin escapar y rate limit en endpoints autenticados) documentados como aceptados en SECURITY.md con justificación técnica. Todos los hallazgos de la auditoría tienen resolución explícita.
v0.9.21
22 mayo 2026

Auditoría Opus pre-v1.0 — 4 hardening de seguridad

Resultado de una auditoría exhaustiva pre-v1.0 con 16 categorías de análisis. Se cierran cuatro hallazgos; tres limitaciones arquitectónicas se aceptan y documentan con justificación.

  • Fix Timing-safe login — la comparación de credenciales usa ahora secrets.compare_digest() en lugar de ==. Elimina el timing attack en POST /login: un atacante ya no puede inferir caracteres correctos midiendo diferencias de tiempo en las respuestas.
  • Fix FFmpeg % macros bloqueadasescape_drawtext() reemplaza % por %%. Un título de episodio con %{pts} se renderizaba como el timestamp del frame en lugar del texto literal.
  • Fix Path.is_relative_to() en borrado de archivos — reemplaza el anti-pattern str.startswith() para verificar que un archivo pertenece al directorio permitido antes de eliminarlo. La versión anterior podía confundir prefijos de nombre con prefijos de path.
  • Fix Rate limiting en proxy de imágenesGET /api/img tiene ahora límite de 30 solicitudes/minuto por IP. Sin este límite, un usuario autenticado podía usar el proxy como port scanner lento.
v0.9.20
22 mayo 2026

Auditoría de seguridad: 100/100 — cierre de las últimas dos deducciones

Se cierran los dos últimos puntos abiertos de la auditoría de seguridad, alcanzando un score perfecto. Sin deducciones pendientes.

  • Fix B-03 — Chunked body bypass cerrado — los endpoints de autenticación (POST /login, POST /2fa) y preferencias (PATCH /api/preferences) ahora rechazan explícitamente Transfer-Encoding: chunked. El check de tamaño de 2 KB no podía aplicarse sin Content-Length; este fix cierra el bypass.
  • Fix M-05 — DNS TOCTOU cerrado — la validación SSRF ahora ocurre en el momento exacto de la conexión TCP, no solo antes de llamar al cliente HTTP. Implementado con _SSRFSafeTransport (httpx) para el descargador de MP3 y el proxy de imágenes, y con _SafeHTTPConnection/_SafeHTTPSConnection (urllib) para feedparser. Cierra el gap de DNS rebinding.
  • Nuevo 62 tests — 0 fallos — cobertura nueva para chunked rejection (5 tests) y validación SSRF en connect-time (5 tests).
v0.9.19
22 mayo 2026

Hardening pre-v1.0 — seguridad, robustez y migraciones automáticas

Quince mejoras distribuidas en cinco grupos: protecciones de seguridad adicionales, guards de concurrencia, migraciones automáticas de base de datos con Alembic, y tests de cobertura para los validadores de seguridad.

  • Fix Rate limiting en mutacionesPOST /api/episodes/{id}/download, /render y /publish tienen ahora límite de 10 solicitudes/minuto por IP. Cierra deducción de auditoría.
  • Nuevo TRUSTED_PROXY_IPS — nueva variable de entorno para configurar la IP del proxy inverso en ProxyHeadersMiddleware. Permite hardening en despliegues donde la IP de Caddy/Traefik es conocida y fija.
  • Fix Límite de 20 MB en uploads de imagen — los endpoints de background y watermark de plantillas rechazan archivos mayores a 20 MB con doble verificación: rechazo anticipado por Content-Length y verificación post-lectura.
  • Fix Guards de concurrencia en download y render — si ya hay una operación en curso para el episodio, la API responde 409 en lugar de lanzar un segundo proceso en paralelo. Consistente con el guard ya existente en publish.
  • Nuevo Migraciones automáticas con Alembicdatabase.py detecta si la base de datos tiene historial Alembic: en instalaciones nuevas crea las tablas y establece el estado base; en instalaciones existentes aplica las migraciones pendientes. Elimina la necesidad de borrar la base de datos para cambios de schema.
  • Fix Validación de filtro statusGET /api/episodes?status=X devuelve 400 para valores no reconocidos, en lugar de una lista vacía silenciosa.
  • Nuevo Tests de seguridad — 43 tests nuevos: SSRF validator (15 casos, incluyendo notación octal 0177.0.0.1), schema de plantillas (19 casos), y CSRF (9 casos). Cobertura de los validadores críticos de seguridad.
v0.9.18
9 mayo 2026

Correcciones de UI y compatibilidad de deploy

Cuatro correcciones menores: un fix crítico de compatibilidad que impedía arrancar la app en producción con versiones recientes de uvicorn, eliminación de un botón con enlace roto, y mejora visual del aviso de contacto de seguridad.

  • Fix Compatibilidad uvicorn 0.34+ — la importación de ProxyHeadersMiddleware se hacía desde starlette.middleware.proxy_headers, módulo que Starlette removió. Corregido a uvicorn.middleware.proxy_headers. Sin este fix la app no arrancaba en producción.
  • Fix Botón "MP3 local disponible" eliminado — el botón en el detalle de episodio apuntaba a un endpoint que nunca existió, produciendo siempre un error 404.
  • Fix Aviso de seguridad como dialog modal — el aviso de contacto de seguridad sin configurar usa ahora un <dialog> HTML nativo que se abre al cargar el dashboard, en lugar de un banner con atributos de Bootstrap JS.
  • Fix SRI theme.css actualizado — hash sha384 actualizado en los tres templates tras la modificación de theme.css.
v0.9.17
8 mayo 2026

Correcciones de seguridad finales

Dos correcciones menores que cierran los últimos puntos abiertos de la auditoría: manejo de errores más preciso en el token OAuth de YouTube, y aviso visible cuando el contacto de seguridad no ha sido configurado.

  • Fix Excepción amplia reducida — en la migración del token de YouTube, except (InvalidToken, Exception) reemplazado por except InvalidToken. Solo se captura el error de descifrado esperado; otros errores de I/O ya no se silencian accidentalmente.
  • Nuevo Aviso de contacto de seguridad — si SECURITY_CONTACT mantiene el valor por defecto, el dashboard muestra un banner dismissable recordando configurarlo para que /.well-known/security.txt sea válido.
v0.9.16
8 mayo 2026

Correcciones en documentación de seguridad

Versión de mantenimiento: correcciones en el documento de seguridad interno (SECURITY.md). Sin cambios en código ni en comportamiento de la aplicación.

  • Fix Referencias de código actualizadas en la documentación de seguridad — líneas desplazadas por los cambios de las fases anteriores.
  • Fix TTL del CSRF clarificado: 30 minutos efectivos (cookie) vs. 1 hora (token firmado).
  • Fix Tabla de auditorías por fase reemplaza el score único desactualizado en la documentación.
v0.9.15
8 mayo 2026

Hardening de seguridad — Fase 3

Cuatro correcciones finales de la auditoría de seguridad: el endpoint de salud ya es accesible para monitoreo externo, la escritura del token de YouTube ya no tiene ventana de exposición de permisos, el cierre de sesión es ahora resistente a CSRF, y los assets CSS de las páginas de login y 2FA incluyen verificación de integridad.

  • Fix /health accesible públicamente — el endpoint de salud ya no requiere sesión activa. Herramientas de monitoreo y el healthcheck de Docker funcionan correctamente. Rate limiting de 30/minuto activo.
  • Fix Race condition en token de YouTube — el archivo del token OAuth ahora nace con permisos 0o600 desde el primer byte, eliminando la ventana entre escritura y chmod.
  • Fix Logout resistente a CSRF — el cierre de sesión pasó de GET a POST con token CSRF. Ya no es posible cerrar la sesión del usuario con un enlace externo.
  • Fix SRI en login y 2FA — los CSS de las páginas de acceso incluyen ahora integrity="sha384-...". El browser verifica la integridad de los assets antes de aplicarlos.
v0.9.14
8 mayo 2026

Hardening de seguridad — Fase 2

Cuatro correcciones de seguridad sin impacto visible en la interfaz: el rate limiting ahora funciona correctamente detrás de Caddy, la ventana de ataque de la sesión intermedia se redujo de 7 días a 5 minutos, las rutas internas del contenedor ya no se exponen en la API, y el header HSTS lo emite ahora la app directamente además del proxy.

  • Fix Rate limiting real detrás de CaddyProxyHeadersMiddleware lee el header X-Forwarded-For para obtener la IP real del cliente. Sin este fix, el límite de 5 intentos/minuto en el login era inoperante detrás del proxy.
  • Fix Sesión intermedia — TTL reducido — la cookie del paso entre contraseña y TOTP expira en 5 minutos en lugar de 7 días. Reduce la ventana de ataque si la cookie es interceptada antes de completar el 2FA.
  • Fix Paths internos fuera de la APImp3_path, render_path, ffmpeg_cmd y ffmpeg_log eliminados de las respuestas JSON. Las rutas del contenedor y los comandos FFmpeg ya no son accesibles vía API.
  • Fix HSTS en la app — el header Strict-Transport-Security (2 años, includeSubDomains, preload) lo emite ahora la app directamente además de Caddy, cuando APP_BASE_URL es HTTPS.
v0.9.13
7 mayo 2026

Hardening de seguridad — Fase 1 + Tipografía personalizable de interfaz

Segunda auditoría de seguridad completada — cinco hallazgos críticos corregidos, incluyendo ejecución sin root en Docker, protección contra inyección en FFmpeg y verificación CSRF en el flujo OAuth de YouTube. Además, la interfaz ahora es personalizable: elegí la fuente, el tamaño y el grosor directamente desde Configuración.

  • Fix Docker sin root — el contenedor corre como usuario flowcast (UID 1001) en lugar de root. no-new-privileges activo en docker-compose.
  • Fix Protección FFmpeg injection — validators Pydantic bloquean colores malformados y expresiones posicionales con caracteres fuera de whitelist.
  • Fix CSRF en OAuth de YouTube — el state se verifica con secrets.compare_digest y se consume tras el callback exitoso.
  • Fix SSRF — tres gaps cerrados: bloqueo de IPv4-mapped IPv6 (::ffff:x.x.x.x), CG-NAT 100.64.0.0/10 y notación octal antes del resolver del SO.
  • Fix SSRF en redirects — feedparser y el downloader de MP3 re-validan cada redirect con validate_external_url antes de seguirlo.
  • Nuevo Tipografía de interfaz personalizable — elegí entre Cantarell, Montserrat, Lato o Ubuntu desde Configuración. La preferencia se persiste en base de datos.
  • Nuevo Tamaño de texto — cinco opciones (S, M, L, XL, XXL) que escalan toda la interfaz.
  • Nuevo Grosor de texto — Normal o Negrita para las cuatro fuentes.
  • Fix Cajas del picker de tipografía con dimensiones fijas idénticas — eliminado el crecimiento variable.
  • Fix Botón "Guardar cambios" en Configuración unificado visualmente con el del editor de plantillas.
v0.9.12
27 abril 2026

Tipografía en plantillas y mejoras visuales en el editor

El editor de plantillas estrena selector de tipografía y control de posición horizontal del título. Además corregimos varios detalles visuales: el color picker ahora muestra el color seleccionado, los valores px están alineados con los sliders y los iconos Phosphor ya no se desplazan respecto al texto.

  • Nuevo Selector de tipografía — elige entre Liberation, Montserrat, Lato, Bebas Neue o Ubuntu para el título del episodio. Vista previa "Aa" en el editor y renderizado real con FFmpeg.
  • Nuevo Posición X del título — slider 0–1920 px con botón "Centrar" que centra el texto automáticamente sin importar su longitud.
  • Fix Color picker reemplazado por swatch circular — el cuadro blanco vacío ya no aparece; muestra el color activo correctamente.
  • Fix Botón "Centrar" guardaba el píxel 960 fijo en lugar de la expresión de centrado dinámico — corregido.
  • Fix Valores px de los sliders alineados verticalmente al centro del control (antes quedaban debajo en una línea separada).
  • Fix Iconos Phosphor alineados correctamente con el texto en listas y encabezados.
  • Nuevo Guía de instalación en Easypanel y archivo docker-compose.easypanel.yml alternativo.
  • Fix Deploy en VPS: validación de DOMAIN al arrancar Caddy — el contenedor falla rápido con mensaje claro si la variable está vacía.
v0.9.11
27 abril 2026

Instalación limpia — dominio desde .env

Corregimos el proceso de instalación en VPS: el dominio ahora se lee automáticamente desde el archivo .env y Caddy obtiene el certificado SSL sin errores. También limpiamos la documentación para nuevos usuarios.

  • Fix El Caddyfile usa {env.DOMAIN} — ya no hay que editar el archivo manualmente para configurar el dominio.
  • Fix El servicio caddy en docker-compose.yml recibe el .env para que la variable DOMAIN resuelva correctamente.
  • Fix .env.example: campo DOMAIN agregado como requerido; RSS_FEED_URL eliminada (nunca fue usada); generación de SECRET_KEY usa openssl rand -base64 32.
  • Fix README actualizado: eliminado paso de SSH key (repo público), git clone usa HTTPS, pasos renumerados.
v0.9.10
16 abril 2026

Hardening de seguridad — auditoría completa

Aplicamos diez correcciones derivadas de una auditoría de seguridad externa realizada con dos agentes especializados — uno simulando un usuario externo buscando vulnerabilidades, otro actuando como experto en seguridad IT. Todos los hallazgos críticos y altos quedaron resueltos.

  • Fix Rate limiting de 5 intentos/minuto agregado al paso de verificación 2FA, igual que en el login.
  • Fix Race condition en la creación del secreto TOTP — el archivo ahora se crea con permisos restrictivos desde el primer byte, sin ventana de exposición.
  • Fix TTL del token CSRF reducido de 60 a 30 minutos.
  • Nuevo Subresource Integrity (SRI) — todos los assets CSS y JS incluyen hash sha384 para que el navegador detecte cualquier modificación.
  • Nuevo Variable de entorno SECURITY_CONTACT para configurar el email publicado en /.well-known/security.txt.
  • Nuevo .dockerignore — el directorio data/ y el archivo .env ya no se incluyen en el contexto de build de Docker.
  • Fix Historial git reescrito para eliminar referencias a herramientas de desarrollo internas.
v0.9.9
14 abril 2026

Cantarell, Phosphor Icons y open source

FlowCast es ahora open source bajo la licencia PolyForm Noncommercial 1.0.0. Uso personal y educativo libre; uso comercial prohibido sin permiso. También estrena tipografía e iconografía nuevas, más alineadas con el diseño GNOME Adwaita.

  • Nuevo Licencia PolyForm Noncommercial 1.0.0 — FlowCast es open source. El código está disponible en GitHub.
  • Nuevo Aviso de licencia y autoría en la página de Configuración, con enlace a la licencia completa.
  • Nuevo Tipografía migrada a Cantarell — la fuente oficial del entorno GNOME, servida localmente.
  • Nuevo Iconografía migrada a Phosphor Icons 2.1.2, también servida localmente. Sin dependencias externas.
  • Nuevo Controles tipo interruptor rediseñados con estilo AdwSwitch — el mismo aspecto que GtkSwitch en GNOME.
  • Fix Los signos ¿ y ¡ se renderizan correctamente en todos los navegadores y sistemas operativos.
  • Fix Icono inexistente en el dashboard reemplazado por el equivalente correcto de Phosphor Icons.
v0.9.8
9 abril 2026

FlowCast, con mayúscula

La app ya tiene nombre oficial: FlowCast. Corregimos el nombre en todo el texto visible de la aplicación — login, sidebar, pantalla de verificación, documentación y logos. Los identificadores internos de código no cambiaron. También estrenamos el nuevo logo: el círculo con barras de audio reemplaza al diseño anterior en el sidebar, la pantalla de login y la verificación en dos pasos. Cambia automáticamente entre la versión clara y oscura según el tema activo.

  • Nuevo Nuevo logo en sidebar, login y verificación 2FA — cambia automáticamente entre versión clara y oscura según el tema activo.
  • Nuevo Nombre corregido a FlowCast en toda la interfaz visible.
  • Fix Logo duplicado que aparecía en ciertas condiciones de carga.
  • Fix Tamaño del logo en login y 2FA — ahora respeta las dimensiones correctas.
v0.9.7
9 abril 2026

Mejoras visuales y documentación de seguridad

  • Fix Alineación correcta de listas ul/ol — el reset CSS borraba el padding-left del navegador.
  • Nuevo Ventana de confirmación nativa (elemento <dialog>) al desconectar YouTube, reemplazando el confirm() del navegador.
  • Nuevo Creación de SECURITY.md con documentación completa de los 19 controles de seguridad implementados.
  • Fix Corrección de espaciado en la sección de credenciales de la página de configuración.
v0.9.6
8 abril 2026

Títulos de página alineados y diseño consistente

  • Fix Altura mínima de 38px en los encabezados de página para que los títulos queden al mismo nivel visual en todas las secciones.
  • Fix Actualización de cache busting a ?v=0.9.17 en todos los assets CSS y JS.
v0.9.5
7 abril 2026

Rediseño completo de la interfaz — Fase final

  • Nuevo Sistema de diseño basado en GNOME Adwaita HIG: tokens CSS, tipografía Inter Variable, íconos Bootstrap Icons.
  • Nuevo Sidebar fijo con toggle de tema claro/oscuro sincronizado con la preferencia del sistema (prefers-color-scheme).
  • Nuevo Rediseño de todas las páginas: Dashboard, Episodios, Podcasts, Plantillas, Configuración, Login y TOTP.
  • Nuevo Botones pill, cards con elevación y transiciones suaves entre temas.
  • Fix Todos los event handlers movidos a addEventListener para cumplir con la Content Security Policy (CSP con nonce).
v0.9.0
marzo 2026

Pipeline completo end-to-end

  • Nuevo Pipeline automático: RSS → descarga MP3 → renderizado FFmpeg → publicación YouTube.
  • Nuevo Autenticación en dos pasos: contraseña + TOTP (RFC 6238) con pyotp.
  • Nuevo Token OAuth2 de YouTube cifrado con Fernet (AES-128-CBC + HMAC-SHA256).
  • Nuevo Protección SSRF en todas las URLs externas (feeds, audio, proxy de imágenes).
  • Nuevo Sanitización de HTML de feeds RSS con nh3 antes de guardar en base de datos.
  • Nuevo Rate limiting en POST /login (5/min) y GET /health (30/min).