Saltar al contenido principal

API de Usuarios

La API de Usuarios de ClickAware permite gestionar cuentas de usuario, perfiles, configuraciones y permisos de forma programática.

Modelo de Usuario

Estructura del Usuario

interface User {
id: number;
authId: string;
email: string;
username: string;
profile: {
firstName: string;
lastName: string;
displayName: string;
avatar?: string;
phone?: string;
department: string;
position: string;
manager?: number; // User ID del supervisor
};
security: {
role: 'USER' | 'MANAGER' | 'ADMIN' | 'SUPER_ADMIN';
permissions: string[];
lastLogin: string;
loginAttempts: number;
accountLocked: boolean;
twoFactorEnabled: boolean;
passwordLastChanged: string;
};
stats: {
phishingDetectionRate: number;
trainingsCompleted: number;
securityScore: number;
riskLevel: 'LOW' | 'MEDIUM' | 'HIGH';
consecutiveDetections: number;
totalPoints: number;
};
preferences: {
language: string;
timezone: string;
notifications: NotificationSettings;
trainingFrequency: string;
};
timestamps: {
createdAt: string;
updatedAt: string;
lastActiveAt: string;
};
isActive: boolean;
}

interface NotificationSettings {
email: boolean;
push: boolean;
sms: boolean;
digest: 'daily' | 'weekly' | 'monthly';
}

Endpoints Principales

GET /users

Lista usuarios con filtros y paginación.

Parámetros de Query

ParámetroTipoDescripciónEjemplo
pagenumberNúmero de página?page=2
limitnumberUsuarios por página (máx 100)?limit=50
searchstringBúsqueda por nombre/email?search=juan
departmentstringFiltrar por departamento?department=IT
rolestringFiltrar por rol?role=ADMIN
activebooleanSolo usuarios activos?active=true
sortstringOrdenar por campo?sort=createdAt:desc

Request

GET /users?page=1&limit=25&department=IT&sort=lastLogin:desc
Authorization: Bearer {access_token}

Response (200)

{
"success": true,
"data": {
"users": [
{
"id": 12345,
"authId": "auth_abc123",
"email": "juan.perez@empresa.com",
"username": "juan.perez",
"profile": {
"firstName": "Juan",
"lastName": "Pérez",
"displayName": "Juan Pérez",
"avatar": "https://cdn.clickaware.es/avatars/12345.jpg",
"phone": "+34612345678",
"department": "IT",
"position": "Senior Developer",
"manager": 67890
},
"security": {
"role": "USER",
"permissions": ["read:profile", "write:reports"],
"lastLogin": "2024-01-15T10:30:00Z",
"loginAttempts": 0,
"accountLocked": false,
"twoFactorEnabled": true,
"passwordLastChanged": "2024-01-01T00:00:00Z"
},
"stats": {
"phishingDetectionRate": 87.5,
"trainingsCompleted": 12,
"securityScore": 892,
"riskLevel": "LOW",
"consecutiveDetections": 8,
"totalPoints": 1247
},
"preferences": {
"language": "es",
"timezone": "Europe/Madrid",
"notifications": {
"email": true,
"push": true,
"sms": false,
"digest": "weekly"
},
"trainingFrequency": "weekly"
},
"timestamps": {
"createdAt": "2023-06-15T09:00:00Z",
"updatedAt": "2024-01-15T10:30:00Z",
"lastActiveAt": "2024-01-15T10:30:00Z"
},
"isActive": true
}
],
"pagination": {
"currentPage": 1,
"perPage": 25,
"total": 150,
"totalPages": 6,
"hasNext": true,
"hasPrev": false
}
},
"message": "Users retrieved successfully",
"timestamp": "2024-01-15T11:00:00Z"
}

GET /users/{id}

Obtiene los detalles completos de un usuario específico.

Request

GET /users/12345
Authorization: Bearer {access_token}

Response (200)

{
"success": true,
"data": {
"user": {
// ... datos completos del usuario
"activityHistory": [
{
"id": 1001,
"type": "PHISHING_DETECTED",
"description": "Detectó correctamente phishing de Netflix",
"points": 15,
"timestamp": "2024-01-15T09:45:00Z"
},
{
"id": 1002,
"type": "TRAINING_COMPLETED",
"description": "Completó módulo de Gestión de Contraseñas",
"points": 50,
"timestamp": "2024-01-14T16:20:00Z"
}
],
"teamMembers": [
{
"id": 12346,
"name": "María García",
"position": "Frontend Developer"
}
]
}
},
"message": "User details retrieved successfully",
"timestamp": "2024-01-15T11:00:00Z"
}

POST /users

Crea un nuevo usuario en el sistema.

Permisos Requeridos

Se requiere rol ADMIN o permiso create:users

Request

POST /users
Authorization: Bearer {access_token}
Content-Type: application/json

{
"email": "nuevo.usuario@empresa.com",
"username": "nuevo.usuario",
"profile": {
"firstName": "Nuevo",
"lastName": "Usuario",
"department": "Marketing",
"position": "Marketing Specialist",
"manager": 67890
},
"security": {
"role": "USER",
"tempPassword": "Password123!",
"forcePasswordChange": true
},
"preferences": {
"language": "es",
"timezone": "Europe/Madrid",
"trainingFrequency": "weekly"
},
"sendWelcomeEmail": true
}

Response (201)

{
"success": true,
"data": {
"user": {
"id": 12347,
"authId": "auth_def456",
"email": "nuevo.usuario@empresa.com",
"username": "nuevo.usuario",
// ... resto de campos con valores por defecto
},
"temporaryPassword": "Password123!",
"welcomeEmailSent": true,
"activationToken": "act_789xyz123"
},
"message": "User created successfully",
"timestamp": "2024-01-15T11:05:00Z"
}

PUT /users/{id}

Actualiza un usuario existente.

Request

PUT /users/12345
Authorization: Bearer {access_token}
Content-Type: application/json

{
"profile": {
"phone": "+34612345679",
"position": "Lead Developer"
},
"preferences": {
"notifications": {
"email": false,
"push": true,
"sms": true,
"digest": "daily"
}
}
}

Response (200)

{
"success": true,
"data": {
"user": {
// ... usuario actualizado
},
"changes": [
{
"field": "profile.phone",
"oldValue": "+34612345678",
"newValue": "+34612345679"
},
{
"field": "profile.position",
"oldValue": "Senior Developer",
"newValue": "Lead Developer"
}
]
},
"message": "User updated successfully",
"timestamp": "2024-01-15T11:10:00Z"
}

DELETE /users/{id}

Desactiva un usuario (soft delete).

Importante

Los usuarios no se eliminan físicamente, solo se desactivan para mantener la integridad de los datos históricos.

Request

DELETE /users/12345
Authorization: Bearer {access_token}
Content-Type: application/json

{
"reason": "Employee left company",
"transferDataTo": 67890,
"notifyUser": false
}

Response (200)

{
"success": true,
"data": {
"userId": 12345,
"deactivatedAt": "2024-01-15T11:15:00Z",
"dataTransferredTo": 67890,
"backupCreated": "backup_user_12345_20240115.json"
},
"message": "User deactivated successfully",
"timestamp": "2024-01-15T11:15:00Z"
}

Gestión de Perfiles

GET /users/{id}/profile

Obtiene el perfil público de un usuario.

Response (200)

{
"success": true,
"data": {
"profile": {
"id": 12345,
"displayName": "Juan Pérez",
"avatar": "https://cdn.clickaware.es/avatars/12345.jpg",
"department": "IT",
"position": "Senior Developer",
"stats": {
"securityScore": 892,
"rank": 23,
"badges": [
{
"id": "phishing_hunter",
"name": "Phishing Hunter",
"description": "Detectó 50+ intentos de phishing",
"earnedAt": "2024-01-10T00:00:00Z",
"icon": "️"
}
]
},
"achievements": [
{
"type": "CONSECUTIVE_DETECTIONS",
"count": 8,
"description": "8 detecciones consecutivas"
}
]
}
}
}

PUT /users/{id}/avatar

Actualiza la foto de perfil del usuario.

Request

PUT /users/12345/avatar
Authorization: Bearer {access_token}
Content-Type: multipart/form-data

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="avatar"; filename="avatar.jpg"
Content-Type: image/jpeg

[binary image data]
------WebKitFormBoundary7MA4YWxkTrZu0gW--

Response (200)

{
"success": true,
"data": {
"avatarUrl": "https://cdn.clickaware.es/avatars/12345.jpg?v=1642249800",
"thumbnails": {
"small": "https://cdn.clickaware.es/avatars/12345_small.jpg",
"medium": "https://cdn.clickaware.es/avatars/12345_medium.jpg",
"large": "https://cdn.clickaware.es/avatars/12345_large.jpg"
}
},
"message": "Avatar updated successfully"
}

Gestión de Seguridad

PUT /users/{id}/password

Cambio de contraseña para un usuario.

Request

PUT /users/12345/password
Authorization: Bearer {access_token}
Content-Type: application/json

{
"currentPassword": "contraseña_actual",
"newPassword": "nueva_contraseña_segura_123!",
"forceLogout": true
}

Response (200)

{
"success": true,
"data": {
"passwordChanged": true,
"sessionsInvalidated": 3,
"nextPasswordChange": "2024-07-15T11:20:00Z"
},
"message": "Password updated successfully"
}

POST /users/{id}/reset-password

Reinicia la contraseña de un usuario (solo administradores).

Request

POST /users/12345/reset-password
Authorization: Bearer {access_token}
Content-Type: application/json

{
"generateTemporary": true,
"sendEmail": true,
"forceChangeOnLogin": true
}

Response (200)

{
"success": true,
"data": {
"temporaryPassword": "TempPass789!",
"expiresAt": "2024-01-16T11:25:00Z",
"emailSent": true,
"resetToken": "reset_abc123def456"
},
"message": "Password reset successfully"
}

POST /users/{id}/lock

Bloquea la cuenta de un usuario.

Request

POST /users/12345/lock
Authorization: Bearer {access_token}
Content-Type: application/json

{
"reason": "Security violation - suspicious activity",
"duration": 3600, // segundos, 0 = indefinido
"notifyUser": true
}

POST /users/{id}/unlock

Desbloquea la cuenta de un usuario.

Request

POST /users/12345/unlock
Authorization: Bearer {access_token}
Content-Type: application/json

{
"resetFailedAttempts": true,
"notifyUser": true
}

Estadísticas y Actividad

GET /users/{id}/stats

Obtiene estadísticas detalladas del usuario.

Response (200)

{
"success": true,
"data": {
"stats": {
"securityMetrics": {
"phishingDetectionRate": 87.5,
"averageDetectionTime": 45, // segundos
"falsePositives": 2,
"missedThreats": 3,
"improvementRate": 12.5 // % último mes
},
"trainingProgress": {
"modulesCompleted": 12,
"totalModules": 25,
"completionRate": 48,
"averageScore": 89.5,
"timeSpent": 14400, // segundos
"certificates": 3
},
"activitySummary": {
"loginsLast30Days": 22,
"phishingEncounters": 15,
"trainingSessions": 8,
"pointsEarned": 347,
"rankImprovement": 5
},
"riskAssessment": {
"currentLevel": "LOW",
"factors": [
{
"category": "Phishing Susceptibility",
"score": 85,
"trend": "improving"
},
{
"category": "Password Hygiene",
"score": 92,
"trend": "stable"
}
],
"recommendations": [
"Complete Social Engineering module",
"Enable 2FA on all accounts"
]
}
}
}
}

GET /users/{id}/activity

Obtiene el historial de actividad del usuario.

Parámetros

  • limit: Número de actividades a retornar (default: 50)
  • offset: Desplazamiento para paginación
  • type: Filtrar por tipo de actividad
  • from: Fecha de inicio (ISO 8601)
  • to: Fecha de fin (ISO 8601)

Response (200)

{
"success": true,
"data": {
"activities": [
{
"id": 1001,
"type": "PHISHING_DETECTED",
"category": "SECURITY",
"description": "Detectó correctamente email de phishing (Netflix)",
"details": {
"campaignId": "camp_123",
"templateName": "Netflix Account Suspended",
"detectionTime": 32,
"confidence": 0.95
},
"points": 15,
"timestamp": "2024-01-15T09:45:00Z",
"ipAddress": "192.168.1.100",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."
},
{
"id": 1002,
"type": "TRAINING_COMPLETED",
"category": "LEARNING",
"description": "Completó módulo: Gestión Avanzada de Contraseñas",
"details": {
"moduleId": "mod_456",
"score": 95,
"timeSpent": 1800,
"attempts": 1
},
"points": 50,
"timestamp": "2024-01-14T16:20:00Z"
}
],
"summary": {
"totalActivities": 247,
"categories": {
"SECURITY": 156,
"LEARNING": 78,
"PROFILE": 13
},
"pointsEarned": 2840
}
}
}

Gestión de Equipos

GET /users/{id}/team

Obtiene los miembros del equipo del usuario.

Response (200)

{
"success": true,
"data": {
"team": {
"id": "team_it_001",
"name": "IT Department",
"manager": {
"id": 67890,
"name": "Ana García",
"position": "IT Director"
},
"members": [
{
"id": 12345,
"name": "Juan Pérez",
"position": "Senior Developer",
"securityScore": 892,
"rank": 2
},
{
"id": 12346,
"name": "María López",
"position": "Frontend Developer",
"securityScore": 756,
"rank": 5
}
],
"stats": {
"averageSecurityScore": 824,
"teamRank": 3,
"totalMembers": 12,
"activeMembers": 11
}
}
}
}

PUT /users/{id}/manager

Asigna o cambia el supervisor de un usuario.

Request

PUT /users/12345/manager
Authorization: Bearer {access_token}
Content-Type: application/json

{
"managerId": 67890,
"effectiveDate": "2024-02-01T00:00:00Z",
"notifyBoth": true
}

Búsqueda Avanzada

POST /users/search

Búsqueda avanzada de usuarios con múltiples criterios.

Request

POST /users/search
Authorization: Bearer {access_token}
Content-Type: application/json

{
"criteria": {
"text": "juan developer",
"departments": ["IT", "Engineering"],
"roles": ["USER", "MANAGER"],
"securityScore": {
"min": 500,
"max": 1000
},
"riskLevel": ["LOW", "MEDIUM"],
"lastActive": {
"from": "2024-01-01T00:00:00Z",
"to": "2024-01-15T23:59:59Z"
},
"trainingCompletion": {
"min": 50 // % mínimo de completitud
}
},
"sort": [
{ "field": "securityScore", "direction": "desc" },
{ "field": "lastLogin", "direction": "desc" }
],
"pagination": {
"page": 1,
"limit": 25
}
}

Response (200)

{
"success": true,
"data": {
"users": [
// ... usuarios que coinciden con criterios
],
"facets": {
"departments": {
"IT": 45,
"Engineering": 23,
"Marketing": 8
},
"riskLevels": {
"LOW": 67,
"MEDIUM": 8,
"HIGH": 1
}
},
"pagination": {
"currentPage": 1,
"totalResults": 76,
"totalPages": 4
}
}
}

Importación y Exportación

POST /users/import

Importa usuarios desde un archivo CSV o Excel.

Request

POST /users/import
Authorization: Bearer {access_token}
Content-Type: multipart/form-data

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="users.csv"
Content-Type: text/csv

email,firstName,lastName,department,position,manager
juan.perez@empresa.com,Juan,Pérez,IT,Developer,ana.garcia@empresa.com
maria.lopez@empresa.com,María,López,IT,Designer,ana.garcia@empresa.com
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="options"

{
"sendWelcomeEmails": true,
"forcePasswordChange": true,
"defaultRole": "USER",
"skipDuplicates": false
}
------WebKitFormBoundary7MA4YWxkTrZu0gW--

Response (202)

{
"success": true,
"data": {
"jobId": "import_job_abc123",
"status": "PROCESSING",
"estimatedCompletion": "2024-01-15T11:35:00Z",
"previewResults": {
"totalRows": 150,
"validRows": 147,
"errors": [
{
"row": 23,
"error": "Invalid email format: invalid-email"
},
{
"row": 67,
"error": "Manager not found: nonexistent@empresa.com"
}
]
}
},
"message": "Import job started successfully"
}

GET /users/export

Exporta usuarios a formato CSV/Excel.

Request

GET /users/export?format=csv&fields=email,name,department,lastLogin&filter=active:true
Authorization: Bearer {access_token}

Response (200)

email,name,department,lastLogin
juan.perez@empresa.com,Juan Pérez,IT,2024-01-15T10:30:00Z
maria.lopez@empresa.com,María López,IT,2024-01-15T09:15:00Z

️ Herramientas de Administración

POST /users/bulk-update

Actualización masiva de usuarios.

Request

POST /users/bulk-update
Authorization: Bearer {access_token}
Content-Type: application/json

{
"criteria": {
"department": "Marketing"
},
"updates": {
"preferences.trainingFrequency": "monthly",
"preferences.notifications.digest": "weekly"
},
"dryRun": false
}

Response (200)

{
"success": true,
"data": {
"affectedUsers": 23,
"changes": [
{
"field": "preferences.trainingFrequency",
"usersAffected": 23
},
{
"field": "preferences.notifications.digest",
"usersAffected": 23
}
],
"executionTime": 1.2
}
}

GET /users/audit-log

Registro de auditoría de cambios en usuarios.

Response (200)

{
"success": true,
"data": {
"auditEntries": [
{
"id": "audit_001",
"action": "USER_UPDATED",
"userId": 12345,
"changedBy": 67890,
"changes": [
{
"field": "profile.position",
"oldValue": "Developer",
"newValue": "Senior Developer"
}
],
"timestamp": "2024-01-15T11:20:00Z",
"ipAddress": "192.168.1.150",
"reason": "Promotion"
}
]
}
}

Integración con Clientes

React Hook Example

import { useState, useEffect } from 'react';
import { useClickAwareAPI } from './hooks/useClickAwareAPI';

function UserProfile({ userId }) {
const { api } = useClickAwareAPI();
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
async function fetchUser() {
try {
setLoading(true);
const response = await api.get(`/users/${userId}`);
setUser(response.data.user);
} catch (error) {
console.error('Error fetching user:', error);
} finally {
setLoading(false);
}
}

fetchUser();
}, [userId, api]);

const updateProfile = async (updates) => {
try {
const response = await api.put(`/users/${userId}`, { profile: updates });
setUser(response.data.user);
return { success: true };
} catch (error) {
return { success: false, error: error.message };
}
};

if (loading) return <div>Cargando perfil...</div>;

return (
<div className="user-profile">
<img src={user.profile.avatar} alt={user.profile.displayName} />
<h2>{user.profile.displayName}</h2>
<p>{user.profile.position} - {user.profile.department}</p>

<div className="security-score">
<strong>Puntuación de Seguridad: {user.stats.securityScore}</strong>
<div className="risk-level risk-{user.stats.riskLevel.toLowerCase()}">
Nivel de Riesgo: {user.stats.riskLevel}
</div>
</div>

<button onClick={() => updateProfile({ phone: '+34612345679' })}>
Actualizar Teléfono
</button>
</div>
);
}

Vue.js Composable

import { ref, computed } from 'vue';
import { useClickAwareAPI } from '@/composables/useClickAwareAPI';

export function useUser(userId) {
const { api } = useClickAwareAPI();
const user = ref(null);
const loading = ref(false);
const error = ref(null);

const securityScoreColor = computed(() => {
if (!user.value) return 'gray';
const score = user.value.stats.securityScore;
if (score >= 800) return 'green';
if (score >= 600) return 'yellow';
return 'red';
});

const fetchUser = async () => {
loading.value = true;
error.value = null;

try {
const response = await api.get(`/users/${userId}`);
user.value = response.data.user;
} catch (err) {
error.value = err.message;
} finally {
loading.value = false;
}
};

const updateUser = async (updates) => {
try {
const response = await api.put(`/users/${userId}`, updates);
user.value = response.data.user;
return { success: true };
} catch (err) {
return { success: false, error: err.message };
}
};

return {
user: readonly(user),
loading: readonly(loading),
error: readonly(error),
securityScoreColor,
fetchUser,
updateUser
};
}

Próximos Pasos

¿Ya dominas la gestión de usuarios? Explora otros recursos: