Seguridad
Sesiones y seguridad para un producto de IA. Dispositivos activos con cierre de sesión que anima la salida de las filas, cambio de contraseña con un medidor de fortaleza en vivo, configuración de dos factores con un código QR real, una verificación de 6 dígitos y códigos de recuperación descargables, passkeys mediante WebAuthn y eliminación de la cuenta tras una confirmación escrita.
Todo producto de IA acaba teniendo la misma página de seguridad: dónde has iniciado sesión, cómo inicias sesión y cómo salir. Security es esa página, construida sobre los grupos y filas del bloque Settings, con cada flujo conectado a callbacks asíncronos que tú controlas.
Active sessions enumera cada dispositivo con su navegador, sistema, ubicación y cuándo estuvo activo por última vez, en tiempo relativo claro. Este dispositivo está marcado y no se puede cerrar su sesión desde aquí. Cerrar la sesión de un dispositivo muestra el progreso en su botón, luego la fila se pliega y el foco pasa a la siguiente fila. Cerrar la sesión en todos los demás pregunta primero y nombra los dispositivos cuya sesión cerrará.
Change password comprueba mientras escribes: un medidor de fortaleza de cuatro pasos y una lista de lo que aún falta, sin bloquear nada de lo que escribes. Si tu servidor dice que la contraseña actual es incorrecta, el mensaje aparece bajo ese campo y el foco vuelve a él, conservando todo lo que escribiste. Puedes cerrar otras sesiones en el mismo paso.
La configuración de dos factores dibuja un código QR real y escaneable para el enlace otpauth que devuelve tu servidor, muestra la clave de configuración con un botón de copiar para cuando no se puede escanear y, en un móvil, ofrece abrir el enlace en una app de autenticación. El código de 6 dígitos se comprueba solo en cuanto está completo, sacude y se borra si es incorrecto, y luego muestra códigos de recuperación para copiar o descargar como archivo de texto. Desactivarlo pregunta primero.
Passkeys llama a tu flujo de WebAuthn y gestiona las respuestas del navegador: cerrar el aviso no añade nada y no muestra error, y un dispositivo que ya tiene una passkey lo indica. Eliminar la cuenta requiere la frase exacta, enumera lo que se va con ella y mantiene el diálogo abierto con tu mensaje si el servidor dice que no.
Añade el registro Pro a components.json
components.json Añade tu token
Crea un token en tu página de cuenta y colócalo en
.env.localcomoHEXTAUI_PRO_TOKEN.Añade el bloque
pnpm dlx shadcn@latest add @hextaui-pro/security
Conéctalo a tu API
Pasa lo que tiene la cuenta ahora y un callback asíncrono para cada acción. Resuelve cuando el servidor termine y actualiza los datos, y cada parte muestra su propio progreso. Lanza un error para mostrar tu mensaje en su sitio, y lo que escribió la persona se conserva.
Usa las partes por separado
SecuritySessions, SecurityPasswordRow, SecurityTwoFactorRow, SecurityPasskeys y SecurityDeleteAccount funcionan cada uno por separado, así que puedes colocarlos en cualquier sección. Devuelve errores de campo desde onChangePassword para mostrarlos bajo el campo.
Anatomía
Las partes que compones, de fuera hacia dentro.
| Parte | Descripción |
|---|---|
SecuritySettings | Todo lo de abajo en una sola llamada. Cada parte aparece cuando pasas los datos y callbacks que necesita. |
SecuritySessions | Un grupo que enumera los dispositivos con sesión iniciada, con cierre de sesión por dispositivo y para todas las demás sesiones. |
SecurityPasswordRow | Una fila que abre el diálogo de cambio de contraseña. |
SecurityTwoFactorRow | Una fila con el estado de dos factores, el diálogo de configuración y la confirmación de desactivación. |
SecurityPasskeys | Un grupo que enumera las passkeys, con añadir y quitar. |
SecurityDeleteAccount | Un grupo con la fila de eliminar cuenta y su confirmación escrita. |
measurePassword | La comprobación de fortaleza que usa el diálogo de contraseña, para tus propios formularios. |
| Prop | Tipo | Predeterminado |
|---|---|---|
emailEl correo de la cuenta. Se usa en la frase de eliminación, la pista del gestor de contraseñas y el archivo de códigos de recuperación. | string | – |
sessions{ id, browser, os, device?, location?, lastActive, current? }. device es "desktop", "laptop", "phone" o "tablet". | SecuritySession[] | – |
onSignOutSessionCierra una sesión. Quítala de sessions cuando se resuelva y la fila se pliega. | (id: string) => Promise<void> | – |
onSignOutOtherSessionsCierra todas las sesiones excepto la actual. Se ejecuta después de que la persona confirme. | () => Promise<void> | – |
passwordChangedAtSe muestra como Last changed bajo Password. | Date | string | number | null | – |
onChangePasswordDevuelve { currentPassword } o { newPassword } para mostrar un mensaje bajo ese campo, o lanza un error para mostrarlo sobre los botones. | ({ currentPassword, newPassword, signOutOthers }) => Promise<void | errors> | – |
twoFactorEnabledSi los dos factores están activados. | boolean | false |
onStartTwoFactorCrea un secreto pendiente cuando se abre el diálogo de configuración. uri es el enlace otpauth dibujado como código QR; secret es por defecto el que está en uri. | () => Promise<{ uri, secret?, recoveryCodes? }> | – |
onVerifyTwoFactorComprueba el código de 6 dígitos y activa los dos factores. Devuelve códigos de recuperación para mostrarlos, o lanza un error si el código es incorrecto. | (code: string) => Promise<void | string[]> | – |
onDisableTwoFactorDesactiva los dos factores. Se ejecuta después de que la persona confirme. | () => Promise<void> | – |
passkeys{ id, name, createdAt, lastUsed? }. | SecurityPasskey[] | – |
onAddPasskeyEjecuta tu registro de WebAuthn. Un NotAllowedError o AbortError cuenta como cancelado y no muestra nada. | () => Promise<void> | – |
onRemovePasskeyQuita una passkey. Se ejecuta después de que la persona confirme. | (id: string) => Promise<void> | – |
passkeysSupportedSustituye la comprobación de compatibilidad con WebAuthn. | boolean | detected |
onDeleteAccountElimina la cuenta. Se ejecuta después de que la persona escriba la frase. Lanza un error para mantener el diálogo abierto con tu mensaje. | () => Promise<void> | – |
deleteConsequencesLo que se elimina, enumerado en la confirmación. | ReactNode[] | – |
SecuritySessions
También acepta todas las props de SettingsGroup.
| Prop | Tipo | Predeterminado |
|---|---|---|
sessionsLos dispositivos con sesión iniciada. | SecuritySession[] | – |
onSignOutCierra una sesión. | (id: string) => Promise<void> | – |
onSignOutOthersCierra todas las demás sesiones. | () => Promise<void> | – |
titleEl encabezado del grupo. | ReactNode | "Active sessions" |
| Prop | Tipo | Predeterminado |
|---|---|---|
emailSe rellena en un campo de nombre de usuario oculto para que los gestores de contraseñas actualicen el inicio de sesión correcto. | string | – |
changedAtCuándo cambió la contraseña por última vez. | Date | string | number | null | – |
onChangePasswordIgual que en SecuritySettings. | (change) => Promise<void | errors> | – |
| Prop | Tipo | Predeterminado |
|---|---|---|
emailSe nombra en la confirmación y en el archivo de códigos de recuperación. | string | – |
enabledSi los dos factores están activados. | boolean | – |
onStartIgual que onStartTwoFactor. | () => Promise<{ uri, secret?, recoveryCodes? }> | – |
onVerifyIgual que onVerifyTwoFactor. | (code: string) => Promise<void | string[]> | – |
onDisableIgual que onDisableTwoFactor. | () => Promise<void> | – |
SecurityPasskeys
También acepta todas las props de SettingsGroup.
| Prop | Tipo | Predeterminado |
|---|---|---|
passkeysLas passkeys guardadas. | SecurityPasskey[] | – |
onAddEjecuta tu registro de WebAuthn. | () => Promise<void> | – |
onRemoveQuita una passkey. | (id: string) => Promise<void> | – |
supportedSi este navegador puede crear passkeys. | boolean | detected |
SecurityDeleteAccount
También acepta todas las props de SettingsGroup.
| Prop | Tipo | Predeterminado |
|---|---|---|
emailLa frase de confirmación es delete seguido de esto. | string | – |
onDeleteElimina la cuenta. | () => Promise<void> | – |
consequencesLo que se elimina con ella. | ReactNode[] | – |
titleEl encabezado del grupo. | ReactNode | "Danger zone" |
| Key | Acción |
|---|---|
| Tab | Recorre las filas y sus botones, y luego cada diálogo. |
| Enter | Envía el formulario de contraseña desde cualquier campo, y elimina la cuenta desde el campo de la frase cuando coincide. |
| Escape | Cierra un diálogo, salvo mientras algo se está guardando. |
| 0–9 | Rellena el código de verificación. Se comprueba solo cuando están los seis dígitos, y pegar un código también funciona. |
- Las acciones destructivas nunca reciben el foco primero. Las confirmaciones nombran lo que afectan, como los dispositivos cuya sesión se cierra o el correo que se elimina, y el campo de la frase de eliminación recibe el foco en lugar del botón.
- Cuando una fila se pliega, el foco pasa al botón de la fila siguiente, o a la anterior, para que nunca caiga a la página. Cerrar un diálogo devuelve el foco al botón que lo abrió, o a su sustituto cuando ese botón ya no existe.
- Los cierres de sesión, las passkeys añadidas y quitadas y la fortaleza de la contraseña se anuncian de forma polite. Los errores de tus callbacks se anuncian como alertas y permanecen junto al campo o botón al que pertenecen.
- Cada requisito de contraseña indica si se cumple, el código QR tiene una etiqueta de texto, y la clave de configuración y los códigos de recuperación son texto legible que puedes seleccionar.
- Con movimiento reducido, las filas se desvanecen en lugar de plegarse y los cambios de paso no se deslizan. En modo de alto contraste, el código QR y el medidor de fortaleza conservan sus formas.
Construido con
Los componentes gratuitos de HextaUI con los que está hecho Security. Cada uno se instala por separado.
Código
12 archivos, añadidos a components/blocks/security.