Actualizar perfil de usuario
PUT/profile/:id
Actualiza el usuario {id}. Un usuario solo puede modificarse a sí mismo (otro {id} responde 403). Un usuario con la cuenta inactiva (active = 0) no puede modificar nada: responde 403 (La cuenta está inactiva.). El cuerpo lleva un único campo records: un string con un objeto JSON serializado (no un objeto JSON anidado). La fila actualizada es siempre la de {id}; records.id se ignora. Nunca se escriben password, remember_token, email_verified_at (enviado por el cliente), current_password ni las fechas de auditoría (la contraseña se cambia con POST /forgot-password y POST /reset-password). type_id y active no se pueden cambiar desde aquí: si se envían, se ignoran sin error. Avatar: enviar imgdata (data URL base64, p. ej. data:image/png;base64,...) y, opcionalmente, imgname; se guarda en users/{id}/profile/{imgname} (solo se usa el nombre del archivo, sin rutas; si imgname falta o es null se usa avatar.png) y se asigna a avatar. El contenido no se valida (ni formato, ni tamaño, ni tipo de imagen): se guarda tal cual tras decodificarlo. imgdata debe incluir el prefijo data:...;base64,: sin coma se descarta su primer carácter y el archivo queda corrupto, sin error. Si no hay nada después de la coma, el avatar no cambia y no se avisa. Si no se puede escribir el archivo, la respuesta es igualmente 200 y avatar queda apuntando a un archivo inexistente. El archivo se escribe antes de guardar los demás campos: si después el guardado falla (500), el archivo queda escrito pero avatar no cambia. avatar también se puede enviar directamente en records (texto, máx. 255) y se guarda tal cual, sin validar; si viene imgdata con contenido, la ruta calculada lo reemplaza. Longitudes: no se validan; un first_name o last_name de más de 120 caracteres (y un avatar de más de 255) se recorta sin error; un email nuevo de 255 caracteres o más no se recorta: responde 422 con el mensaje de correo que no puede recibir mensajes; y un first_name null se guarda como texto vacío. Correo: para no modificarlo, omita email en records. Si records.email es un texto distinto del guardado (se comparan sin espacios al inicio ni al final), debe poder recibir mensajes (sin tildes, eñes ni espacios intermedios antes de la @ y con dominio válido); si no, responde 422 y no se guarda nada. Si records.email no es texto ni null (número, booleano, arreglo u objeto) también responde 422 con el mismo mensaje, aunque no se esté cambiando el correo. Un email igual al actual no se valida, así que un usuario con un correo antiguo inválido puede seguir editando el resto de campos. Un email vacío, solo con espacios o null responde 422 (El correo electrónico es obligatorio: no se puede dejar vacío.) si el usuario ya tiene un correo: el correo de inicio de sesión no se puede borrar. Si el correo nuevo es otro (sin distinguir mayúsculas) y ya lo usa otro usuario, incluso uno eliminado, responde 422 (Ya existe una cuenta con ese correo electrónico.) y no se guarda nada. El correo se guarda sin espacios al inicio ni al final. Cambio de correo: cuando el correo cambia (sin distinguir mayúsculas; un cambio solo de mayúsculas no cuenta) se aplican, en este orden: (a) tope de 3 cambios guardados por hora por usuario (el de {id}, lo haga él o un administrador); el cuarto responde 429 (Demasiados cambios de correo. Intenta de nuevo más tarde.) con cabecera Retry-After; los intentos rechazados no cuentan. (b) Si el usuario cambia su propio correo (también un administrador), debe enviar su contraseña actual en records.current_password; si falta o no coincide responde 422 con errors.current_password (La contraseña actual no es correcta.). Tras 5 contraseñas erróneas en 15 minutos responde 429 (Demasiados intentos con la contraseña actual. Intenta de nuevo más tarde.) aunque la siguiente sea correcta. Un administrador que cambia el correo de otro usuario no la envía. current_password nunca se guarda y se ignora si el correo no cambia. (c) El correo nuevo no debe usarlo otro usuario (422). Después, el correo nuevo se guarda sin verificar (email_verified_at = null en la misma escritura), se envía el enlace de verificación al correo nuevo y un aviso de seguridad al correo anterior (con el correo nuevo enmascarado, p. ej. nu*****@empresa.com, y la indicación de contactar a soporte si no fue el titular). El aviso al correo anterior no se envía si el usuario no tenía correo guardado o si el correo anterior no puede recibir mensajes (por ejemplo, un correo antiguo con tildes o eñes); el enlace de verificación al correo nuevo se envía igual y la respuesta sigue siendo 200. Si alguno de los dos envíos falla solo se registra en el log y la respuesta sigue siendo 200 (el enlace se puede pedir de nuevo con POST /email/verification-notification). Un enlace de verificación enviado a un correo anterior ya no sirve. La sesión actual sigue activa, pero el siguiente POST /auth/login responde 400 (El correo electrónico no ha sido verificado...) hasta que se verifique el correo nuevo. La respuesta lo indica con email_verification_required = true. Aplica también cuando un administrador cambia el correo de otro usuario.
Request
Responses
- 200
- 401
- 403
- 404
- 422
- 429
- 500
Usuario actualizado. user contiene los valores ya guardados. email_verification_required es true solo si el correo cambió: el correo nuevo quedó sin verificar, se envió el enlace de verificación y el próximo inicio de sesión lo exige.
No autenticado: token Bearer ausente, inválido, expirado o revocado.
El usuario (1) intenta modificar a otro usuario: message = No tiene permiso para modificar este usuario. (se comprueba primero), o (2) tiene la cuenta inactiva y se modifica a sí mismo: message = La cuenta está inactiva.
No existe un usuario con el {id} indicado.
En ningún caso se guarda nada. (1) records ausente, vacío, número o booleano, o un texto que no decodifica a un objeto JSON: message = El campo records debe ser un objeto JSON serializado., sin errors. Si records se envía como objeto o arreglo JSON anidado (en lugar de string) responde el 500 genérico del servidor (ver 500). (2) records.email cambia a un correo que no puede recibir mensajes, o no es texto ni null (número, booleano, arreglo u objeto): message y errors.email con el texto del ejemplo. (3) records.email vacío, solo espacios o null y el usuario ya tiene correo: El correo electrónico es obligatorio: no se puede dejar vacío. (4) El correo nuevo ya lo usa otro usuario (sin distinguir mayúsculas, incluidos los eliminados): Ya existe una cuenta con ese correo electrónico. En (2), (3) y (4) errors.email trae el mismo texto que message. (5) El usuario cambia su propio correo y records.current_password falta o no es su contraseña: message = La contraseña actual no es correcta. y errors.current_password con el mismo texto (sin errors.email); se comprueba antes que (4).
Cambio de correo bloqueado temporalmente; no se guarda nada. (1) Ya se guardaron 3 cambios de correo de este usuario en la última hora: Demasiados cambios de correo. Intenta de nuevo más tarde. (2) 5 contraseñas actuales erróneas en 15 minutos al cambiar el propio correo: Demasiados intentos con la contraseña actual. Intenta de nuevo más tarde. La cabecera Retry-After trae los segundos que faltan. También puede responder 429 el límite general de la API (60 peticiones por minuto); en ese caso el cuerpo es ThrottleErrorResponse ({"message":"Too Many Attempts."}, sin success, fuera de los textos de este esquema) e incluye las cabeceras Retry-After, X-RateLimit-Limit y X-RateLimit-Remaining.
Response Headers
Segundos hasta poder intentarlo de nuevo.
Error de base de datos al guardar (p. ej. un type_id que no existe, o un correo que otro usuario guardó entre la validación y el guardado); no se guarda ningún campo. message es un objeto cuyo error trae un texto seguro según el tipo de error (Ya existe un registro con ese valor (dato duplicado)., Falta un dato obligatorio., No se puede completar: un dato relacionado no existe., Los datos no cumplen las reglas de integridad (dato duplicado o en uso). o No se pudo completar la operación en la base de datos.); nunca incluye el SQL ni los valores enviados. Si el archivo del avatar ya se había escrito, queda en disco. Otros 500 responden el error genérico del servidor, sin success y sin este formato ({"message":"Server Error"} si se envía Accept: application/json): records enviado como objeto o arreglo JSON anidado en lugar de string; un campo admitido de records (distinto de email) con un objeto JSON como valor (p. ej. {"first_name":{}}); imgdata enviado como arreglo u objeto, o imgname enviado como arreglo u objeto junto con un imgdata con contenido (sin imgdata, imgname se ignora); o no se pudo crear la carpeta del avatar. Si solo falla la escritura del archivo del avatar no hay error: responde 200 y avatar apunta a un archivo inexistente.