Saltearse al contenido

Invitaciones

ARGUS tiene dos flujos de invitación distintos. Ambos usan tokens firmados de un solo uso y ambos aterrizan en la misma ruta /invite, pero difieren en alcance y duración.

Los dos tipos de invitación

Invitaciones de organización — cuentas completas

Una invitación de organización añade un usuario con un OrgRole real (admin, manager, operator, observer). Las invitaciones aceptadas crean una membresía permanente en orgs/{orgId}/members/{uid}.

  • Quién envía: cualquiera con admin.users (roles superadmin, admin, manager).
  • Duración: 7 días por defecto, configurable por invitación.
  • Desde: Admin → Usuarios (/admin/users).

Invitaciones de invitado a misión

Un enlace de corta duración que da acceso a una sola operación — sin membresía en organización, sin otras misiones, sin superficies de administración. Útil para compartir una operación con una agencia externa durante unas horas.

  • Quién envía: propietario de la misión o admin de la organización.
  • Duración: 1 h / 12 h / 24 h / 7 d.
  • Desde: Detalle de misión → Compartir (/operations/:id).
  • Acceso: solo lectura por defecto; conmutadores opcionales “puede anotar” / “puede transmitir por PTT”.

Los invitados inician sesión o se registran para esa única operación; cuando el enlace expira o es revocado, pierden acceso inmediatamente.

Enviar una invitación de organización

  1. Ve a /admin/users, haz clic en Invitar usuario.
  2. Rellena Correo, Rol (integrado o personalizado si tu plan lo soporta), expira en opcional (por defecto 7 días), mensaje opcional.
  3. Haz clic en Enviar. El servidor crea un OrgInvitation + InviteTokenDoc con el token opaco, y luego envía el correo.

La invitación pendiente aparece en la lista de usuarios con una insignia gris “Pendiente” — desde ahí puedes Copiar enlace, Reenviar o Revocar.

Enviar una invitación de invitado a misión

  1. Abre la misión en /operations/:id.
  2. Haz clic en Compartir.
  3. Elige Como invitado (frente a añadir un usuario existente como participante).
  4. Introduce el correo, establece la expiración, elige un preset de permisos y haz clic en Enviar.

El documento de la misión recibe una nueva entrada en su subcolección guestInvites y el correo sale con la misma forma de URL /invite?token=... — el token lleva si es una invitación de organización o una invitación de invitado a misión.

Canjear una invitación

El correo de invitación contiene un enlace como https://app.argus.tactical/invite?token=<opaque>. Abrirlo enruta a InviteComponent en /invite, que:

  1. Verifica el token. Estados: loadingready / invalid / expired / revoked / accepted.
  2. Muestra la oferta — quien invita, nombre de la organización, rol y fecha de expiración.
  3. Se ramifica según la autenticación:
    • Ya has iniciado sesión — muestra Aceptar invitación. InvitationService.acceptInvite() ejecuta la transacción en el servidor, crea la membresía y te lleva al dashboard.
    • No has iniciado sesión — mini formulario de autenticación pre-rellenado con el correo de la invitación. Alterna entre Iniciar sesión y Crear cuenta; al enviarlo, te autentica y acepta en un solo paso (loginAndAccept() / registerAndAccept()).
  4. El estado “Bienvenido a {org}” se renderiza con un botón Entrar al Dashboard.

Qué puede salir mal

  • Inválida — el token no existe / está malformado.
  • Expirada — pasó expiresOn.
  • Revocada — el remitente la revocó antes de que la aceptaras.
  • Ya aceptada — ya la has usado antes.
  • Error — fallo del lado del servidor durante acceptInvite; el componente ofrece Reintentar.

El correo de la invitación es autoritativo — aceptar mientras has iniciado sesión con un usuario distinto se rechaza.

Revocar una invitación

Desde /admin/usersInvitaciones pendientes → acciones de fila → Revocar. Revocar escribe status: 'revoked' en el OrgInvitation. El token deja de funcionar inmediatamente incluso si el correo sigue en la bandeja de entrada del destinatario. Las invitaciones de invitado a misión se revocan de la misma manera desde la página de detalle de misión.

Notas de seguridad

  • Los tokens de invitación son opacos, criptográficamente aleatorios y de un solo uso.
  • El InviteTokenDoc vive en una colección de Firestore separada del OrgInvitation en sí — los clientes pueden buscar un token sin poder enumerar las invitaciones existentes de una organización.
  • Aceptar una invitación es una escritura transaccional — la membresía se crea y la invitación se marca como accepted de forma atómica.

Relacionado