|
|
@@ -0,0 +1,232 @@
|
|
|
+# Configuración de Jitsi Meet con JWT
|
|
|
+
|
|
|
+## ✅ Completado en la aplicación
|
|
|
+
|
|
|
+La aplicación Next.js ya está configurada para usar tu instancia de Jitsi Meet con autenticación JWT:
|
|
|
+
|
|
|
+- ✅ Configuración agregada a [src/lib/config.ts](src/lib/config.ts)
|
|
|
+- ✅ Utilidad JWT creada en [src/lib/jitsi-jwt.ts](src/lib/jitsi-jwt.ts)
|
|
|
+- ✅ Endpoint API en [src/app/api/appointments/[id]/jitsi-token/route.ts](src/app/api/appointments/[id]/jitsi-token/route.ts)
|
|
|
+- ✅ Página de meet actualizada en [src/app/appointments/[id]/meet/page.tsx](src/app/appointments/[id]/meet/page.tsx)
|
|
|
+- ✅ Variables de entorno configuradas en [.env](.env)
|
|
|
+
|
|
|
+## 🔧 Configuración requerida en tu servidor Jitsi
|
|
|
+
|
|
|
+### 1. Actualizar tu archivo `.env` de Docker de Jitsi
|
|
|
+
|
|
|
+Basado en la configuración que ya tienes, actualiza las líneas comentadas:
|
|
|
+
|
|
|
+```env
|
|
|
+# JWT authentication
|
|
|
+AUTH_TYPE=jwt
|
|
|
+
|
|
|
+# Application identifier
|
|
|
+JWT_APP_ID=reuniones_utb
|
|
|
+
|
|
|
+# Application secret known only to your token generator
|
|
|
+JWT_APP_SECRET=theystolemyfuckingmoney
|
|
|
+
|
|
|
+# (Recomendado) Set asap_accepted_issuers as a comma separated list
|
|
|
+JWT_ACCEPTED_ISSUERS=reuniones_utb
|
|
|
+
|
|
|
+# (Recomendado) Set asap_accepted_audiences as a comma separated list
|
|
|
+JWT_ACCEPTED_AUDIENCES=reuniones_utb
|
|
|
+
|
|
|
+# (Opcional) Permitir invitados sin autenticación
|
|
|
+# Si quieres que solo usuarios autenticados puedan unirse, déjalo comentado
|
|
|
+# ENABLE_GUESTS=1
|
|
|
+```
|
|
|
+
|
|
|
+### 2. Reiniciar los contenedores de Jitsi
|
|
|
+
|
|
|
+Después de actualizar el `.env`, reinicia los servicios:
|
|
|
+
|
|
|
+```bash
|
|
|
+cd /ruta/a/tu/jitsi-docker
|
|
|
+docker compose down
|
|
|
+docker compose up -d
|
|
|
+```
|
|
|
+
|
|
|
+### 3. Verificar la configuración
|
|
|
+
|
|
|
+Verifica que los contenedores estén corriendo correctamente:
|
|
|
+
|
|
|
+```bash
|
|
|
+docker compose ps
|
|
|
+docker compose logs -f web
|
|
|
+```
|
|
|
+
|
|
|
+## 🔐 Cómo funciona la autenticación JWT
|
|
|
+
|
|
|
+### Flujo de autenticación:
|
|
|
+
|
|
|
+1. **Usuario accede a una cita aprobada** → [/appointments/[id]/meet](src/app/appointments/[id]/meet/page.tsx)
|
|
|
+
|
|
|
+2. **Frontend solicita JWT token** → `GET /api/appointments/[id]/jitsi-token`
|
|
|
+ - Valida que el usuario sea PATIENT, DOCTOR o ADMIN
|
|
|
+ - Valida que la cita esté aprobada
|
|
|
+ - Valida el tiempo (15 min antes hasta 1 hora después)
|
|
|
+
|
|
|
+3. **Backend genera JWT token** usando [src/lib/jitsi-jwt.ts](src/lib/jitsi-jwt.ts):
|
|
|
+ ```javascript
|
|
|
+ {
|
|
|
+ "iss": "reuniones_utb", // JWT_APP_ID
|
|
|
+ "aud": "reuniones_utb", // JWT_APP_ID
|
|
|
+ "sub": "meet.checkthis.space", // Tu dominio
|
|
|
+ "room": "appointment-123", // Sala específica
|
|
|
+ "context": {
|
|
|
+ "user": {
|
|
|
+ "id": "user-id",
|
|
|
+ "name": "Juan Pérez",
|
|
|
+ "email": "juan@example.com",
|
|
|
+ "avatar": "https://..."
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "moderator": true, // true para DOCTOR/ADMIN
|
|
|
+ "exp": 1699123456 // 2 horas de expiración
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+4. **Frontend inicializa Jitsi** con el token JWT:
|
|
|
+ ```javascript
|
|
|
+ new JitsiMeetExternalAPI("meet.checkthis.space", {
|
|
|
+ roomName: "appointment-123",
|
|
|
+ jwt: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
|
+ // ... otras opciones
|
|
|
+ })
|
|
|
+ ```
|
|
|
+
|
|
|
+5. **Jitsi valida el token** usando `JWT_APP_SECRET`:
|
|
|
+ - Verifica la firma del token
|
|
|
+ - Verifica que `iss` esté en `JWT_ACCEPTED_ISSUERS`
|
|
|
+ - Verifica que `aud` esté en `JWT_ACCEPTED_AUDIENCES`
|
|
|
+ - Verifica que el token no haya expirado
|
|
|
+
|
|
|
+## 👥 Roles y permisos
|
|
|
+
|
|
|
+### DOCTOR y ADMIN (moderadores):
|
|
|
+- ✅ Pueden grabar la reunión
|
|
|
+- ✅ Pueden hacer streaming
|
|
|
+- ✅ Pueden expulsar participantes
|
|
|
+- ✅ Pueden silenciar a otros participantes
|
|
|
+- ✅ Pueden finalizar la reunión para todos
|
|
|
+
|
|
|
+### PATIENT (participantes):
|
|
|
+- ✅ Pueden unirse a la reunión
|
|
|
+- ✅ Pueden compartir audio/video
|
|
|
+- ✅ Pueden usar el chat
|
|
|
+- ❌ No pueden expulsar a otros
|
|
|
+- ❌ No pueden grabar
|
|
|
+
|
|
|
+## 🔑 Variables de entorno en tu aplicación
|
|
|
+
|
|
|
+Tu archivo [.env](.env) ya está configurado con:
|
|
|
+
|
|
|
+```env
|
|
|
+JITSI_DOMAIN="meet.checkthis.space"
|
|
|
+JITSI_APP_ID="reuniones_utb"
|
|
|
+JITSI_APP_SECRET="theystolemyfuckingmoney"
|
|
|
+JITSI_USE_JWT="true"
|
|
|
+```
|
|
|
+
|
|
|
+**⚠️ IMPORTANTE:**
|
|
|
+- `JITSI_APP_ID` debe coincidir con `JWT_APP_ID` en Jitsi
|
|
|
+- `JITSI_APP_SECRET` debe coincidir con `JWT_APP_SECRET` en Jitsi
|
|
|
+- Estos valores deben ser EXACTAMENTE iguales
|
|
|
+
|
|
|
+## 🧪 Testing
|
|
|
+
|
|
|
+### 1. Verificar que el servidor esté accesible:
|
|
|
+
|
|
|
+```bash
|
|
|
+curl https://meet.checkthis.space/
|
|
|
+```
|
|
|
+
|
|
|
+### 2. Crear una cita de prueba y probar el flujo completo:
|
|
|
+
|
|
|
+1. Crear una cita como PATIENT
|
|
|
+2. Aprobarla como DOCTOR
|
|
|
+3. Ambos usuarios intentar unirse a la videollamada
|
|
|
+4. Verificar que:
|
|
|
+ - El token JWT se genera correctamente
|
|
|
+ - Jitsi acepta el token
|
|
|
+ - Los permisos de moderador funcionan correctamente
|
|
|
+
|
|
|
+### 3. Verificar logs del backend:
|
|
|
+
|
|
|
+```bash
|
|
|
+npm run dev
|
|
|
+```
|
|
|
+
|
|
|
+Deberías ver en la consola:
|
|
|
+```
|
|
|
+🎥 Jitsi Meet:
|
|
|
+ Domain: meet.checkthis.space
|
|
|
+ App ID: ✅ Configurado
|
|
|
+ App Secret: ✅ Configurado
|
|
|
+ Use JWT: ✅ Habilitado
|
|
|
+```
|
|
|
+
|
|
|
+## 🐛 Troubleshooting
|
|
|
+
|
|
|
+### Problema: "No se pudo conectar con el servidor de videollamadas"
|
|
|
+
|
|
|
+**Solución:**
|
|
|
+- Verifica que `meet.checkthis.space` sea accesible desde el navegador
|
|
|
+- Verifica que el certificado SSL sea válido
|
|
|
+- Verifica que el script `https://meet.checkthis.space/external_api.js` cargue correctamente
|
|
|
+
|
|
|
+### Problema: "Invalid JWT token"
|
|
|
+
|
|
|
+**Solución:**
|
|
|
+1. Verifica que `JITSI_APP_ID` y `JWT_APP_ID` coincidan exactamente
|
|
|
+2. Verifica que `JITSI_APP_SECRET` y `JWT_APP_SECRET` coincidan exactamente
|
|
|
+3. Verifica que `JWT_ACCEPTED_ISSUERS` incluya el valor de `JWT_APP_ID`
|
|
|
+4. Verifica que `JWT_ACCEPTED_AUDIENCES` incluya el valor de `JWT_APP_ID`
|
|
|
+5. Revisa los logs de Jitsi: `docker compose logs -f prosody`
|
|
|
+
|
|
|
+### Problema: Token expirado
|
|
|
+
|
|
|
+**Solución:**
|
|
|
+- El token expira después de 2 horas por defecto
|
|
|
+- Si necesitas más tiempo, modifica el parámetro `expiresInSeconds` en [src/app/api/appointments/[id]/jitsi-token/route.ts:146](src/app/api/appointments/[id]/jitsi-token/route.ts#L146)
|
|
|
+
|
|
|
+### Problema: Usuario no tiene permisos de moderador
|
|
|
+
|
|
|
+**Solución:**
|
|
|
+- Solo usuarios con rol `DOCTOR` o `ADMIN` son moderadores
|
|
|
+- Verifica el rol del usuario en la base de datos
|
|
|
+- El campo `isModerator` se calcula en [src/app/api/appointments/[id]/jitsi-token/route.ts:138](src/app/api/appointments/[id]/jitsi-token/route.ts#L138)
|
|
|
+
|
|
|
+## 📚 Referencias
|
|
|
+
|
|
|
+- [Jitsi JWT Authentication](https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker/#authentication)
|
|
|
+- [JWT.io Debugger](https://jwt.io/) - Para debugging de tokens
|
|
|
+- [Jitsi Meet API](https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-iframe)
|
|
|
+
|
|
|
+## 🔒 Seguridad
|
|
|
+
|
|
|
+**IMPORTANTE:** En producción:
|
|
|
+
|
|
|
+1. ✅ Cambia `JWT_APP_SECRET` por un valor secreto y seguro
|
|
|
+2. ✅ Usa HTTPS para todo (tu dominio y tu app)
|
|
|
+3. ✅ No expongas `JITSI_APP_SECRET` en el frontend
|
|
|
+4. ✅ Los tokens se generan en el backend (ya implementado)
|
|
|
+5. ✅ Configura `JWT_ACCEPTED_ISSUERS` y `JWT_ACCEPTED_AUDIENCES`
|
|
|
+
|
|
|
+## 🎯 Próximos pasos opcionales
|
|
|
+
|
|
|
+### Configuración adicional de Jitsi:
|
|
|
+
|
|
|
+- **Grabar reuniones:** Configurar Jibri para grabación
|
|
|
+- **Transcripción:** Configurar Jigasi para transcripción
|
|
|
+- **TURN server:** Para mejorar conectividad detrás de firewalls
|
|
|
+- **Límites de sala:** Limitar número de participantes por sala
|
|
|
+- **Branding:** Personalizar logo y colores de Jitsi
|
|
|
+
|
|
|
+### Mejoras en la aplicación:
|
|
|
+
|
|
|
+- Agregar notificaciones cuando un participante se une
|
|
|
+- Guardar duración de la videollamada en la base de datos
|
|
|
+- Agregar grabación automática para citas específicas
|
|
|
+- Implementar espera virtual (waiting room)
|