bdc62403f4
El usuario solicita el cambio desde Mi cuenta (correo nuevo + clave actual). Lo aprueba un admin/superadmin (colaboradores), solo un superadmin (admins) o el propio superadmin mediante enlace a su correo actual. Tras aprobar se envia confirmacion al correo nuevo y aviso al actual; al confirmar se aplica el cambio y se cierran todas las sesiones. Todo el proceso queda en auditoria. Migracion 035. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
71 lines
5.4 KiB
Markdown
71 lines
5.4 KiB
Markdown
# Sesión, retorno al contexto y borradores
|
|
|
|
Solución compartida para toda la app (frontend). Los proyectos y comentarios también verifican
|
|
la versión en el backend (migración `029_optimistic_versions.sql`).
|
|
|
|
## Piezas
|
|
|
|
| Archivo | Qué hace |
|
|
|---|---|
|
|
| `utils/jwt.js` | Lee `exp` y `sub` del JWT (sin verificar firma; eso lo hace el backend). |
|
|
| `context/auth-context.jsx` | Vigila el vencimiento: temporizador al instante exacto, chequeo cada 30 s y al volver a la pestaña/ventana (`visibilitychange`, `focus`, `pageshow`). El navegador congela temporizadores en segundo plano, por eso el chequeo al volver es el que manda. |
|
|
| `services/api.js` | Nunca envía una petición con token vencido: corta la sesión antes. Un `401` con token también corta. |
|
|
| `utils/session.js` | Al vencer guarda `{ userId, ruta completa }` (`plc_return_ctx`, 24 h). Tras el login solo se usa si entra **el mismo usuario**; otro usuario la descarta. |
|
|
| `utils/drafts.js` + `hooks/useDraftForm.js` | Borradores por formulario (ver abajo). |
|
|
| `components/NavigationGuard.jsx` | Aviso al salir con cambios (`useBlocker`), advertencia nativa en F5/cierre, `DraftMark`, `useGuardedClose`. |
|
|
| `components/DraftNotice.jsx` | Aviso dentro del formulario: cambios recuperados / conflicto con el servidor. |
|
|
| `app/App.jsx` | Router de datos (`createBrowserRouter`, mismas rutas): requisito de `useBlocker`. |
|
|
|
|
Pestañas y vistas que viven en la URL (para volver exactamente ahí): proyecto `?tab=`, actividad
|
|
abierta `?activity=&activityTab=`, Organización `?tab=`, Equipos `?tab=&device=&deviceTab=`.
|
|
|
|
## Comportamiento
|
|
|
|
- **Vencimiento:** se cierra la sesión al instante (aunque no haya peticiones) y aparece el login con
|
|
el aviso "Tu sesión venció…". Al volver a entrar, el mismo usuario regresa a la misma ruta, pestaña
|
|
y popup, con la edición reabierta y sus cambios. Salir con "Cerrar sesión" no guarda ruta de retorno.
|
|
- **Borradores:** clave `plc_draft:v1:<usuario>:<formulario>:<entidad>` en `localStorage`, vigencia 7
|
|
días. Solo se guardan los campos permitidos de cada formulario (`draftAllowedFields`); el texto
|
|
libre de notas, comentarios, descripciones y observaciones no se conserva. Sobreviven a cambiar
|
|
de pestaña/menú, F5 y vencimiento. Se borran al guardar, descartar o cerrar sesión
|
|
voluntariamente. Solo se restauran si el registro sigue en lo que el backend
|
|
devuelve para ese usuario (si se borró o perdió acceso, no se abre nada).
|
|
- **Secretos:** nunca se guardan campos cuyo nombre parezca contraseña/token/PIN, archivos ni
|
|
campos fuera de la lista permitida. Al leer borradores antiguos se eliminan los campos excluidos.
|
|
- **Marcas:** campo modificado en rojo con el texto "· modificado"; pestaña, sección plegable,
|
|
botón "Nuevo …", tarjeta (Notas) y menú lateral con punto rojo + texto para lector de pantalla.
|
|
- **Salir con cambios** (menú, pestaña, cerrar popup, plegar sección): diálogo *Seguir editando* /
|
|
*Dejar pendiente* / *Descartar cambios*. Con "Dejar pendiente", al volver se reabre la edición con
|
|
los valores recuperados. F5 o cerrar la pestaña: advertencia nativa del navegador.
|
|
- **Integridad:** los borradores no se guardan automáticamente en el backend; Guardar envía los
|
|
campos del formulario con la versión leída. Si el registro cambió, se conserva el borrador y se
|
|
pide recargar para revisar la versión actual. En Info de proyecto/actividad, Equipos, SMTP y
|
|
Empresa además se consulta el servidor justo antes de guardar.
|
|
|
|
## Formularios sin recuperación (a propósito)
|
|
|
|
| Formulario | Motivo |
|
|
|---|---|
|
|
| Contraseñas (todo el módulo, incluido PIN y grupos) | Los datos están protegidos por PIN y cifrados; guardarlos en el navegador saltaría esa protección. |
|
|
| Cambiar contraseña (menú del usuario) | Solo contiene secretos. |
|
|
| Cambio de correo (Mi cuenta) | Solo se guarda el correo nuevo; la clave actual nunca se persiste. |
|
|
| Login, registro, olvidé/restablecer clave, aceptar invitación, restablecer PIN | Pantallas públicas: no hay usuario autenticado para aislar el borrador y contienen claves/tokens. |
|
|
| Documentos (subir archivo), logo y nombre de Empresa | Archivos y texto libre no se guardan en el navegador. |
|
|
| Equipos → Agentes (token de instalación) | Token secreto; generar uno es una acción de un paso. |
|
|
| Mover actividad, agregar dependencia, compartir nota, compartir Equipos | Acciones de una sola elección, sin captura de datos: se repiten en un clic. |
|
|
| Clave y texto libre en "Nuevo usuario"; clave SMTP | Solo se recuperan rol/departamento; las claves y el texto libre se vuelven a escribir. |
|
|
| Apariencia, filtros, selector de tarjetas del Panel | Se aplican al instante; no queda nada pendiente. |
|
|
|
|
## Límites conocidos
|
|
|
|
- Los borradores son de **este navegador**: no se sincronizan entre equipos.
|
|
- En un equipo compartido, los borradores de un usuario quedan en el navegador hasta guardarlos,
|
|
descartarlos, cerrar sesión voluntariamente o que venzan (7 días). Tras vencimiento de sesión
|
|
se conservan para permitir el retorno al contexto.
|
|
- Todos los formularios de edición de entidades, empresa y SMTP envían `editVersion`; el backend
|
|
rechaza con `409` una versión obsoleta. El borrador se conserva y el aviso pide revisar la
|
|
versión actual. Miembros no edita una entidad mediante formulario: sus acciones aplican cambios
|
|
puntuales de acceso.
|
|
- Los popups son modales: con uno abierto no se puede usar el menú lateral; se sale cerrándolo (pasa
|
|
por el mismo aviso) o con atrás del navegador.
|