Usuarios finales: cuentas, sesiones y KV

Los endpoints de la API REST para los usuarios de tu propia aplicación: alta y activación de cuentas, contraseñas, inicio de sesión con contraseña o con código y almacén clave-valor.

Estos endpoints dan cuenta y sesión a los usuarios de tu propia aplicación (una web, una app móvil, un portal de clientes). Cada cuenta es una entidad de tu empresa, identificada por su correo, y las llamadas actúan como ese usuario, no como el empleado por defecto de la clave.

Dinaup no envía correos: devuelve el código de activación, de recuperación o de acceso en la respuesta y tu backend se lo hace llegar al usuario. Por eso estos endpoints se llaman desde tu servidor, nunca desde el navegador.

Usan el mismo token, la misma URL y los mismos límites que el resto de la API REST.

Campos comunes

Todos los cuerpos admiten dos campos opcionales. Con ellos el servidor comprueba que quien canjea un código de recuperación o de acceso es el mismo navegador que lo pidió.

CampoQué es
UserIpLa IP del usuario final, la que ve tu backend. Si lo omites, el servidor usa la IP de tu servidor.
UserAgentEl User-Agent del usuario final. Si lo omites, el de la petición de tu servidor.

Los nombres de los campos del cuerpo no distinguen mayúsculas. Todo cuerpo va con Content-Type: application/json; sin esa cabecera, la respuesta es 415.

Una respuesta correcta es JSON en camelCase, con ok a true y error a null. Un rechazo llega con su código: en Login, LoginWithCode y Session, como JSON con ok a false y el motivo en error; en los demás, como texto con el motivo. Un token de clave inválido responde 401 con {"error": "..."}, y un ritmo agotado, 429 con Retry-After.

Cuentas

POST /api/Register

Crea una cuenta pendiente y devuelve el código para activarla. Hasta que se activa no existe nada en tu Dinaup; la cuenta pendiente caduca a los 2 días. Tu backend envía activationCode al correo del usuario.

{ "Name": "Ana López", "Email": "[email protected]", "Password": "...", "UserIp": "203.0.113.7", "UserAgent": "Mozilla/5.0" }
{ "ok": true, "error": null, "pendingAccountId": "...", "activationCode": "..." }
CódigoCuándo
400Falta Email o Password, o el correo no es válido.
409Ese correo ya tiene cuenta.

POST /api/ActivateAccount

Activa la cuenta pendiente con su código y crea el usuario, que ya puede entrar con Login. Un código equivocado no anula la cuenta pendiente: se puede reintentar hasta que caduque.

{ "PendingAccountId": "...", "ActivationCode": "..." }
{ "ok": true, "error": null, "userId": "...", "loginIdentifier": "[email protected]" }
CódigoCuándo
400Cuenta pendiente desconocida, caducada o ya usada, o código incorrecto.
409Alguien registró ese correo entre el alta y la activación.

POST /api/RecoverPassword

Pide un código de recuperación para un correo. Responde 200 exista o no la cuenta; si el correo no coincide con ninguna, recoveryCode llega a null.

Si varias cuentas comparten el correo, el código es para la primera que puede iniciar sesión. Va antes la de empleado que la de cliente y, entre iguales, la más antigua.

{ "Email": "[email protected]" }
{ "ok": true, "error": null, "recoveryCode": "...", "recoveryId": "..." }
CódigoCuándo
400Falta el correo o está mal formado.
403Ninguna de las cuentas de ese correo tiene el inicio de sesión activado.

POST /api/ChangePassword

Cambia la contraseña con un código de recuperación, que vale 20 minutos y una sola vez. Envía en UserIp y UserAgent los mismos valores que en RecoverPassword, o ninguno en las dos llamadas.

{ "RecoveryCode": "...", "NewPassword": "...", "UserIp": "203.0.113.7", "UserAgent": "Mozilla/5.0" }
{ "ok": true, "error": null }
CódigoCuándo
400Código desconocido o caducado, o contraseña no válida.
403Código ya usado, eliminado, o pedido desde otra IP u otro navegador.

Sesiones

La sesión vive en el servidor de tu empresa: tu backend guarda userId y sessionId y valida cada petición con Session.

POST /api/Login

{ "User": "[email protected]", "Password": "...", "UserIp": "203.0.113.7", "UserAgent": "Mozilla/5.0" }
{
  "ok": true,
  "error": null,
  "sessionId": "...",
  "userId": "...",
  "userName": "Ana López",
  "loginIdentifier": "[email protected]",
  "pending2FA": false,
  "mustChangePassword": false
}
CampoQué dice
pending2FAEl usuario tiene que completar un segundo factor TOTP antes de operar.
mustChangePasswordEl usuario tiene que cambiar la contraseña.

Con credenciales incorrectas o un usuario sin acceso, la respuesta es 401 o 403 con { "ok": false, "error": "..." }. Sin User o sin Password, 400.

POST /api/Session

Valida una sesión y devuelve sus datos, con la misma forma que Login.

{ "UserId": "...", "SessionId": "..." }

Una sesión cerrada, caducada o inexistente responde 401 con { "ok": false, "error": "..." }. Si UserId o SessionId no son GUID, 400.

POST /api/Logout

Cierra la sesión en el servidor. Es idempotente: cerrar una sesión ya cerrada responde igual.

{ "UserId": "...", "SessionId": "..." }
{ "ok": true }

Inicio de sesión con código

El usuario entra con un código de 6 dígitos que tu backend le envía, sin contraseña. El código vale 10 minutos y una sola vez.

POST /api/RequestLoginCode

Pide un código de acceso para un correo. Responde 200 exista o no la cuenta; si el correo no coincide con ninguna, loginCode llega a null. Si varias cuentas comparten el correo, el código es para la primera que puede iniciar sesión.

{ "Email": "[email protected]", "UserIp": "203.0.113.7", "UserAgent": "Mozilla/5.0" }
{ "ok": true, "error": null, "loginCode": "123456", "loginCodeId": "..." }
CódigoCuándo
400Falta el correo o está mal formado.
403Ninguna de las cuentas de ese correo tiene el inicio de sesión activado.

POST /api/LoginWithCode

Canjea el código por una sesión, con la misma respuesta que Login. Envía en UserIp y UserAgent los mismos valores que en RequestLoginCode, o ninguno en las dos llamadas.

{ "Email": "[email protected]", "LoginCode": "123456", "UserIp": "203.0.113.7", "UserAgent": "Mozilla/5.0" }

El código se gasta al canjearlo, aunque la sesión no llegue a abrirse. Los intentos fallidos cuentan sobre todos los códigos que ese correo pidió en los últimos 10 minutos: pedir uno nuevo no pone la cuenta a cero.

CódigoCuándo
400Falta el correo o el código, o ese correo no pidió ningún código en los últimos 10 minutos.
401El servidor no pudo abrir la sesión.
403Código incorrecto, caducado o ya usado, pedido desde otra IP u otro navegador, o 5 intentos fallidos.

Almacén clave-valor

Un par se identifica por Space y Key, textos libres de hasta 200 caracteres: el reparto por usuario o por app lo decides tú. Los pares se guardan en la sección Dinaup KV de tu empresa.

POST /api/GetKV

{ "Key": "preferencias", "Space": "usuario-1234" }
{ "ok": true, "error": null, "key": "preferencias", "value": "{\"tema\":\"oscuro\"}" }

Si el par no existe, value llega vacío ("").

POST /api/SetKV

Guarda o sustituye el valor del par.

{ "Key": "preferencias", "Space": "usuario-1234", "Value": "{\"tema\":\"oscuro\"}" }
{ "ok": true, "error": null, "key": "preferencias", "value": "" }

Value admite hasta 100.000 caracteres. En GetKV y SetKV, sin Key la respuesta es 400; un Space o una Key de más de 200 caracteres, o un Value de más de 100.000, responden 400 con ok a false y el motivo en error, como El valor no puede superar los 100000 caracteres.

Cómo gestiona una app .NET la sesión de cada empresa: Apps multi-tenant.

En esta página