mirror of
https://github.com/marcogll/ap_pos.git
synced 2026-01-13 13:15:16 +00:00
feat(users): improve user editing and ticket details
- Add user's full name to the database and UI.\n- Allow admins to edit user details (name, username, role).\n- Allow users to edit their own name and password.\n- Automatically set the 'staff' field on new tickets to the current user's name.\n- Bold the 'Te atendió:' label in the printed ticket.
This commit is contained in:
@@ -234,9 +234,11 @@ function renderUsersTable() {
|
|||||||
users.forEach(u => {
|
users.forEach(u => {
|
||||||
const tr = document.createElement('tr');
|
const tr = document.createElement('tr');
|
||||||
tr.innerHTML = `
|
tr.innerHTML = `
|
||||||
|
<td>${u.name}</td>
|
||||||
<td>${u.username}</td>
|
<td>${u.username}</td>
|
||||||
<td>${u.role === 'admin' ? 'Administrador' : 'Usuario'}</td>
|
<td>${u.role === 'admin' ? 'Administrador' : 'Usuario'}</td>
|
||||||
<td>
|
<td>
|
||||||
|
<button class="action-btn" data-id="${u.id}" data-action="edit-user">Editar</button>
|
||||||
${u.id !== currentUser.id ? `<button class="action-btn" data-id="${u.id}" data-action="delete-user">Eliminar</button>` : ''}
|
${u.id !== currentUser.id ? `<button class="action-btn" data-id="${u.id}" data-action="delete-user">Eliminar</button>` : ''}
|
||||||
</td>
|
</td>
|
||||||
`;
|
`;
|
||||||
@@ -276,10 +278,11 @@ async function handleSaveSettings(e) {
|
|||||||
|
|
||||||
async function handleSaveCredentials(e) {
|
async function handleSaveCredentials(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
const name = document.getElementById('s-name').value;
|
||||||
const username = document.getElementById('s-username').value;
|
const username = document.getElementById('s-username').value;
|
||||||
const password = document.getElementById('s-password').value;
|
const password = document.getElementById('s-password').value;
|
||||||
|
|
||||||
const body = { username };
|
const body = { username, name };
|
||||||
if (password) {
|
if (password) {
|
||||||
body.password = password;
|
body.password = password;
|
||||||
}
|
}
|
||||||
@@ -293,6 +296,8 @@ async function handleSaveCredentials(e) {
|
|||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
alert('Credenciales actualizadas.');
|
alert('Credenciales actualizadas.');
|
||||||
|
currentUser.name = name; // Actualizar el nombre en el estado local
|
||||||
|
currentUser.username = username;
|
||||||
document.getElementById('s-password').value = '';
|
document.getElementById('s-password').value = '';
|
||||||
} else {
|
} else {
|
||||||
const error = await response.json();
|
const error = await response.json();
|
||||||
@@ -303,31 +308,54 @@ async function handleSaveCredentials(e) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleAddUser(e) {
|
async function handleAddOrUpdateUser(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
const id = document.getElementById('u-id').value;
|
||||||
|
const name = document.getElementById('u-name').value;
|
||||||
const username = document.getElementById('u-username').value;
|
const username = document.getElementById('u-username').value;
|
||||||
const password = document.getElementById('u-password').value;
|
const password = document.getElementById('u-password').value;
|
||||||
const role = document.getElementById('u-role').value;
|
const role = document.getElementById('u-role').value;
|
||||||
|
|
||||||
|
const isUpdate = !!id;
|
||||||
|
const url = isUpdate ? `/api/users/${id}` : '/api/users';
|
||||||
|
const method = isUpdate ? 'PUT' : 'POST';
|
||||||
|
|
||||||
|
const body = { name, username, role };
|
||||||
|
if (password || !isUpdate) {
|
||||||
|
if (!password && !isUpdate) {
|
||||||
|
alert('La contraseña es obligatoria para nuevos usuarios.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
body.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('/api/users', {
|
const response = await fetch(url, {
|
||||||
method: 'POST',
|
method: method,
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ username, password, role })
|
body: JSON.stringify(body)
|
||||||
});
|
});
|
||||||
|
|
||||||
const newUser = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
alert('Usuario creado exitosamente.');
|
alert(`Usuario ${isUpdate ? 'actualizado' : 'creado'} exitosamente.`);
|
||||||
users.push(newUser);
|
if (isUpdate) {
|
||||||
|
const index = users.findIndex(u => u.id === parseInt(id));
|
||||||
|
if (index > -1) {
|
||||||
|
users[index] = { ...users[index], name, username, role };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
users.push(result);
|
||||||
|
}
|
||||||
renderUsersTable();
|
renderUsersTable();
|
||||||
formAddUser.reset();
|
formAddUser.reset();
|
||||||
|
document.getElementById('u-id').value = '';
|
||||||
} else {
|
} else {
|
||||||
alert(`Error: ${newUser.error}`);
|
alert(`Error: ${result.error}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert('Error de conexión al crear usuario.');
|
alert('Error de conexión al guardar el usuario.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +409,7 @@ async function handleNewMovement(e) {
|
|||||||
monto: Number(monto.toFixed(2)),
|
monto: Number(monto.toFixed(2)),
|
||||||
metodo: document.getElementById('m-metodo').value,
|
metodo: document.getElementById('m-metodo').value,
|
||||||
concepto: document.getElementById('m-concepto').value,
|
concepto: document.getElementById('m-concepto').value,
|
||||||
staff: document.getElementById('m-staff').value,
|
staff: currentUser.name, // Usar el nombre del usuario actual
|
||||||
notas: document.getElementById('m-notas').value,
|
notas: document.getElementById('m-notas').value,
|
||||||
fechaCita: document.getElementById('m-fecha-cita').value,
|
fechaCita: document.getElementById('m-fecha-cita').value,
|
||||||
horaCita: document.getElementById('m-hora-cita').value,
|
horaCita: document.getElementById('m-hora-cita').value,
|
||||||
@@ -424,6 +452,16 @@ function handleTableClick(e) {
|
|||||||
deleteClient(id);
|
deleteClient(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (action === 'edit-user') {
|
||||||
|
const user = users.find(u => u.id === parseInt(id));
|
||||||
|
if (user) {
|
||||||
|
document.getElementById('u-id').value = user.id;
|
||||||
|
document.getElementById('u-name').value = user.name;
|
||||||
|
document.getElementById('u-username').value = user.username;
|
||||||
|
document.getElementById('u-role').value = user.role;
|
||||||
|
document.getElementById('u-password').value = ''; // Limpiar campo de contraseña
|
||||||
|
document.getElementById('u-password').placeholder = 'Dejar en blanco para no cambiar';
|
||||||
|
}
|
||||||
} else if (action === 'delete-user') {
|
} else if (action === 'delete-user') {
|
||||||
deleteUser(parseInt(id, 10));
|
deleteUser(parseInt(id, 10));
|
||||||
}
|
}
|
||||||
@@ -508,6 +546,7 @@ function setupUIForRole(role) {
|
|||||||
const dashboardTab = document.querySelector('[data-tab="tab-dashboard"]');
|
const dashboardTab = document.querySelector('[data-tab="tab-dashboard"]');
|
||||||
const settingsTab = document.querySelector('[data-tab="tab-settings"]');
|
const settingsTab = document.querySelector('[data-tab="tab-settings"]');
|
||||||
const userManagementSection = document.getElementById('user-management-section');
|
const userManagementSection = document.getElementById('user-management-section');
|
||||||
|
const staffInput = document.getElementById('m-staff');
|
||||||
|
|
||||||
if (role === 'admin') {
|
if (role === 'admin') {
|
||||||
// El admin puede ver todo
|
// El admin puede ver todo
|
||||||
@@ -526,6 +565,11 @@ function setupUIForRole(role) {
|
|||||||
settingsTab.style.display = 'none';
|
settingsTab.style.display = 'none';
|
||||||
userManagementSection.style.display = 'none';
|
userManagementSection.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deshabilitar el campo "Atendió" para todos, ya que se autocompleta
|
||||||
|
if (staffInput) {
|
||||||
|
staffInput.disabled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -563,6 +607,7 @@ async function initializeApp() {
|
|||||||
// 3. Añadir manejadores de eventos.
|
// 3. Añadir manejadores de eventos.
|
||||||
const tabs = document.querySelector('.tabs');
|
const tabs = document.querySelector('.tabs');
|
||||||
const btnLogout = document.getElementById('btnLogout');
|
const btnLogout = document.getElementById('btnLogout');
|
||||||
|
const btnCancelEditUser = document.getElementById('btnCancelEditUser');
|
||||||
|
|
||||||
formSettings?.addEventListener('submit', handleSaveSettings);
|
formSettings?.addEventListener('submit', handleSaveSettings);
|
||||||
formCredentials?.addEventListener('submit', handleSaveCredentials);
|
formCredentials?.addEventListener('submit', handleSaveCredentials);
|
||||||
@@ -575,7 +620,7 @@ async function initializeApp() {
|
|||||||
tabs?.addEventListener('click', handleTabChange);
|
tabs?.addEventListener('click', handleTabChange);
|
||||||
|
|
||||||
if (currentUser.role === 'admin') {
|
if (currentUser.role === 'admin') {
|
||||||
formAddUser?.addEventListener('submit', handleAddUser);
|
formAddUser?.addEventListener('submit', handleAddOrUpdateUser);
|
||||||
tblUsersBody?.addEventListener('click', handleTableClick);
|
tblUsersBody?.addEventListener('click', handleTableClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -589,6 +634,13 @@ async function initializeApp() {
|
|||||||
document.getElementById('c-id').value = '';
|
document.getElementById('c-id').value = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
btnCancelEditUser?.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
formAddUser.reset();
|
||||||
|
document.getElementById('u-id').value = '';
|
||||||
|
document.getElementById('u-password').placeholder = 'Contraseña';
|
||||||
|
});
|
||||||
|
|
||||||
// 4. Cargar el resto de los datos de la aplicación.
|
// 4. Cargar el resto de los datos de la aplicación.
|
||||||
Promise.all([
|
Promise.all([
|
||||||
load(KEY_SETTINGS, DEFAULT_SETTINGS),
|
load(KEY_SETTINGS, DEFAULT_SETTINGS),
|
||||||
@@ -603,7 +655,9 @@ async function initializeApp() {
|
|||||||
updateClientDatalist();
|
updateClientDatalist();
|
||||||
|
|
||||||
if (currentUser) {
|
if (currentUser) {
|
||||||
|
document.getElementById('s-name').value = currentUser.name || '';
|
||||||
document.getElementById('s-username').value = currentUser.username;
|
document.getElementById('s-username').value = currentUser.username;
|
||||||
|
document.getElementById('m-staff').value = currentUser.name || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Configurar la UI y activar la pestaña inicial correcta.
|
// 5. Configurar la UI y activar la pestaña inicial correcta.
|
||||||
|
|||||||
@@ -183,6 +183,8 @@
|
|||||||
<h2>Mis Credenciales</h2>
|
<h2>Mis Credenciales</h2>
|
||||||
<form id="formCredentials">
|
<form id="formCredentials">
|
||||||
<div class="form-grid">
|
<div class="form-grid">
|
||||||
|
<label>Mi Nombre:</label>
|
||||||
|
<input type="text" id="s-name" required />
|
||||||
<label>Mi Usuario:</label>
|
<label>Mi Usuario:</label>
|
||||||
<input type="text" id="s-username" required />
|
<input type="text" id="s-username" required />
|
||||||
<label>Nueva Contraseña:</label>
|
<label>Nueva Contraseña:</label>
|
||||||
@@ -197,13 +199,16 @@
|
|||||||
<div class="section" id="user-management-section" style="display: none;">
|
<div class="section" id="user-management-section" style="display: none;">
|
||||||
<h2>Gestión de Usuarios</h2>
|
<h2>Gestión de Usuarios</h2>
|
||||||
<div class="sub-section">
|
<div class="sub-section">
|
||||||
<h3>Añadir Nuevo Usuario</h3>
|
<h3>Añadir/Editar Usuario</h3>
|
||||||
<form id="formAddUser">
|
<form id="formAddUser">
|
||||||
|
<input type="hidden" id="u-id" />
|
||||||
<div class="form-grid">
|
<div class="form-grid">
|
||||||
<label>Nuevo Usuario:</label>
|
<label>Nombre:</label>
|
||||||
|
<input type="text" id="u-name" required />
|
||||||
|
<label>Usuario:</label>
|
||||||
<input type="text" id="u-username" required />
|
<input type="text" id="u-username" required />
|
||||||
<label>Contraseña:</label>
|
<label>Contraseña:</label>
|
||||||
<input type="password" id="u-password" required />
|
<input type="password" id="u-password" placeholder="Dejar en blanco para no cambiar" />
|
||||||
<label>Rol:</label>
|
<label>Rol:</label>
|
||||||
<select id="u-role">
|
<select id="u-role">
|
||||||
<option value="user">Usuario (Ventas)</option>
|
<option value="user">Usuario (Ventas)</option>
|
||||||
@@ -211,7 +216,8 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<button type="submit">Crear Usuario</button>
|
<button type="submit">Guardar Usuario</button>
|
||||||
|
<button type="reset" id="btnCancelEditUser" class="btn-danger">Cancelar Edición</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@@ -221,6 +227,7 @@
|
|||||||
<table id="tblUsers">
|
<table id="tblUsers">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>Nombre</th>
|
||||||
<th>Usuario</th>
|
<th>Usuario</th>
|
||||||
<th>Rol</th>
|
<th>Rol</th>
|
||||||
<th>Acciones</th>
|
<th>Acciones</th>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ function templateTicket(mov, settings) {
|
|||||||
lines.push(`<div><span class="t-bold">${esc(mov.tipo)}</span></div>`);
|
lines.push(`<div><span class="t-bold">${esc(mov.tipo)}</span></div>`);
|
||||||
if (mov.cliente) lines.push(`<div class="t-small">Cliente: ${esc(mov.cliente)}</div>`);
|
if (mov.cliente) lines.push(`<div class="t-small">Cliente: ${esc(mov.cliente)}</div>`);
|
||||||
if (mov.concepto) lines.push(`<div class="t-small">Concepto: ${esc(mov.concepto)}</div>`);
|
if (mov.concepto) lines.push(`<div class="t-small">Concepto: ${esc(mov.concepto)}</div>`);
|
||||||
if (mov.staff) lines.push(`<div class="t-small">Atendió: ${esc(mov.staff)}</div>`);
|
if (mov.staff) lines.push(`<div class="t-small"><b>Te atendió:</b> ${esc(mov.staff)}</div>`);
|
||||||
if (mov.metodo) lines.push(`<div class="t-small">Método: ${esc(mov.metodo)}</div>`);
|
if (mov.metodo) lines.push(`<div class="t-small">Método: ${esc(mov.metodo)}</div>`);
|
||||||
if (mov.notas) lines.push(`<div class="t-small">Notas: ${esc(mov.notas)}</div>`);
|
if (mov.notas) lines.push(`<div class="t-small">Notas: ${esc(mov.notas)}</div>`);
|
||||||
|
|
||||||
|
|||||||
@@ -42,26 +42,34 @@ db.serialize(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
db.run("ALTER TABLE users ADD COLUMN name TEXT", (err) => {
|
||||||
|
if (err && !err.message.includes('duplicate column name')) {
|
||||||
|
console.error("Error adding name column to users table:", err.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
db.run(`CREATE TABLE IF NOT EXISTS users (
|
db.run(`CREATE TABLE IF NOT EXISTS users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
username TEXT UNIQUE,
|
username TEXT UNIQUE,
|
||||||
password TEXT,
|
password TEXT,
|
||||||
role TEXT DEFAULT 'user'
|
role TEXT DEFAULT 'user',
|
||||||
|
name TEXT
|
||||||
)`, (err) => {
|
)`, (err) => {
|
||||||
if (err) return;
|
if (err) return;
|
||||||
// Solo intentar insertar si la tabla fue creada o ya existía
|
// Solo intentar insertar si la tabla fue creada o ya existía
|
||||||
const adminUsername = 'admin';
|
const adminUsername = 'admin';
|
||||||
const defaultPassword = 'password';
|
const defaultPassword = 'password';
|
||||||
|
const defaultName = 'Admin'; // Nombre por defecto para el admin
|
||||||
|
|
||||||
db.get('SELECT * FROM users WHERE username = ?', [adminUsername], (err, row) => {
|
db.get('SELECT * FROM users WHERE username = ?', [adminUsername], (err, row) => {
|
||||||
if (err) return;
|
if (err) return;
|
||||||
if (!row) {
|
if (!row) {
|
||||||
bcrypt.hash(defaultPassword, SALT_ROUNDS, (err, hash) => {
|
bcrypt.hash(defaultPassword, SALT_ROUNDS, (err, hash) => {
|
||||||
if (err) return;
|
if (err) return;
|
||||||
// Insertar admin con su rol
|
// Insertar admin con su rol y nombre
|
||||||
db.run('INSERT INTO users (username, password, role) VALUES (?, ?, ?)', [adminUsername, hash, 'admin'], (err) => {
|
db.run('INSERT INTO users (username, password, role, name) VALUES (?, ?, ?, ?)', [adminUsername, hash, 'admin', defaultName], (err) => {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
console.log(`Default user '${adminUsername}' created with password '${defaultPassword}' and role 'admin'. Please change it.`);
|
console.log(`Default user '${adminUsername}' created with name '${defaultName}', password '${defaultPassword}' and role 'admin'. Please change it.`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -129,7 +137,8 @@ app.post('/api/login', (req, res) => {
|
|||||||
}
|
}
|
||||||
req.session.userId = user.id;
|
req.session.userId = user.id;
|
||||||
req.session.role = user.role; // Guardar rol en la sesión
|
req.session.role = user.role; // Guardar rol en la sesión
|
||||||
res.json({ message: 'Login successful', role: user.role });
|
req.session.name = user.name; // Guardar nombre en la sesión
|
||||||
|
res.json({ message: 'Login successful', role: user.role, name: user.name });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -147,7 +156,7 @@ app.post('/api/logout', (req, res) => {
|
|||||||
// Endpoint para verificar el estado de la autenticación en el frontend
|
// Endpoint para verificar el estado de la autenticación en el frontend
|
||||||
app.get('/api/check-auth', (req, res) => {
|
app.get('/api/check-auth', (req, res) => {
|
||||||
if (req.session.userId) {
|
if (req.session.userId) {
|
||||||
res.json({ isAuthenticated: true, role: req.session.role });
|
res.json({ isAuthenticated: true, role: req.session.role, name: req.session.name });
|
||||||
} else {
|
} else {
|
||||||
res.json({ isAuthenticated: false });
|
res.json({ isAuthenticated: false });
|
||||||
}
|
}
|
||||||
@@ -267,7 +276,7 @@ app.use('/api', apiRouter);
|
|||||||
// --- User Management (Admin) ---
|
// --- User Management (Admin) ---
|
||||||
// Proteger estas rutas para que solo los admins puedan usarlas
|
// Proteger estas rutas para que solo los admins puedan usarlas
|
||||||
apiRouter.get('/users', isAdmin, (req, res) => {
|
apiRouter.get('/users', isAdmin, (req, res) => {
|
||||||
db.all("SELECT id, username, role FROM users", [], (err, rows) => {
|
db.all("SELECT id, username, role, name FROM users", [], (err, rows) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
res.status(500).json({ error: err.message });
|
res.status(500).json({ error: err.message });
|
||||||
return;
|
return;
|
||||||
@@ -277,9 +286,9 @@ apiRouter.get('/users', isAdmin, (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
apiRouter.post('/users', isAdmin, (req, res) => {
|
apiRouter.post('/users', isAdmin, (req, res) => {
|
||||||
const { username, password, role } = req.body;
|
const { username, password, role, name } = req.body;
|
||||||
if (!username || !password || !role) {
|
if (!username || !password || !role || !name) {
|
||||||
return res.status(400).json({ error: 'Username, password, and role are required' });
|
return res.status(400).json({ error: 'Username, password, name, and role are required' });
|
||||||
}
|
}
|
||||||
if (role !== 'admin' && role !== 'user') {
|
if (role !== 'admin' && role !== 'user') {
|
||||||
return res.status(400).json({ error: 'Invalid role' });
|
return res.status(400).json({ error: 'Invalid role' });
|
||||||
@@ -289,18 +298,41 @@ apiRouter.post('/users', isAdmin, (req, res) => {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return res.status(500).json({ error: 'Error hashing password' });
|
return res.status(500).json({ error: 'Error hashing password' });
|
||||||
}
|
}
|
||||||
db.run('INSERT INTO users (username, password, role) VALUES (?, ?, ?)', [username, hash, role], function(err) {
|
db.run('INSERT INTO users (username, password, role, name) VALUES (?, ?, ?, ?)', [username, hash, role, name], function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.message.includes('UNIQUE constraint failed')) {
|
if (err.message.includes('UNIQUE constraint failed')) {
|
||||||
return res.status(409).json({ error: 'Username already exists' });
|
return res.status(409).json({ error: 'Username already exists' });
|
||||||
}
|
}
|
||||||
return res.status(500).json({ error: err.message });
|
return res.status(500).json({ error: err.message });
|
||||||
}
|
}
|
||||||
res.status(201).json({ id: this.lastID, username, role });
|
res.status(201).json({ id: this.lastID, username, role, name });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Nueva ruta para actualizar un usuario (solo admin)
|
||||||
|
apiRouter.put('/users/:id', isAdmin, (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
const { username, role, name } = req.body;
|
||||||
|
|
||||||
|
if (!username || !role || !name) {
|
||||||
|
return res.status(400).json({ error: 'Username, role, and name are required' });
|
||||||
|
}
|
||||||
|
|
||||||
|
db.run('UPDATE users SET username = ?, role = ?, name = ? WHERE id = ?', [username, role, name, id], function(err) {
|
||||||
|
if (err) {
|
||||||
|
if (err.message.includes('UNIQUE constraint failed')) {
|
||||||
|
return res.status(409).json({ error: 'Username already exists' });
|
||||||
|
}
|
||||||
|
return res.status(500).json({ error: err.message });
|
||||||
|
}
|
||||||
|
if (this.changes === 0) {
|
||||||
|
return res.status(404).json({ error: 'User not found' });
|
||||||
|
}
|
||||||
|
res.json({ message: 'User updated successfully' });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
apiRouter.delete('/users/:id', isAdmin, (req, res) => {
|
apiRouter.delete('/users/:id', isAdmin, (req, res) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
// Prevenir que el admin se elimine a sí mismo
|
// Prevenir que el admin se elimine a sí mismo
|
||||||
@@ -321,7 +353,7 @@ apiRouter.delete('/users/:id', isAdmin, (req, res) => {
|
|||||||
|
|
||||||
// --- Current User Settings ---
|
// --- Current User Settings ---
|
||||||
apiRouter.get('/user', (req, res) => {
|
apiRouter.get('/user', (req, res) => {
|
||||||
db.get("SELECT id, username, role FROM users WHERE id = ?", [req.session.userId], (err, row) => {
|
db.get("SELECT id, username, role, name FROM users WHERE id = ?", [req.session.userId], (err, row) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
res.status(500).json({ error: err.message });
|
res.status(500).json({ error: err.message });
|
||||||
return;
|
return;
|
||||||
@@ -331,9 +363,9 @@ apiRouter.get('/user', (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
apiRouter.post('/user', (req, res) => {
|
apiRouter.post('/user', (req, res) => {
|
||||||
const { username, password } = req.body;
|
const { username, password, name } = req.body;
|
||||||
if (!username) {
|
if (!username || !name) {
|
||||||
return res.status(400).json({ error: 'Username is required' });
|
return res.status(400).json({ error: 'Username and name are required' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (password) {
|
if (password) {
|
||||||
@@ -342,7 +374,7 @@ apiRouter.post('/user', (req, res) => {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return res.status(500).json({ error: 'Error hashing password' });
|
return res.status(500).json({ error: 'Error hashing password' });
|
||||||
}
|
}
|
||||||
db.run('UPDATE users SET username = ?, password = ? WHERE id = ?', [username, hash, req.session.userId], function(err) {
|
db.run('UPDATE users SET username = ?, password = ?, name = ? WHERE id = ?', [username, hash, name, req.session.userId], function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(500).json({ error: err.message });
|
return res.status(500).json({ error: err.message });
|
||||||
}
|
}
|
||||||
@@ -350,12 +382,12 @@ apiRouter.post('/user', (req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Si no se proporciona contraseña, solo actualizar el nombre de usuario
|
// Si no se proporciona contraseña, solo actualizar el nombre de usuario y el nombre
|
||||||
db.run('UPDATE users SET username = ? WHERE id = ?', [username, req.session.userId], function(err) {
|
db.run('UPDATE users SET username = ?, name = ? WHERE id = ?', [username, name, req.session.userId], function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(500).json({ error: err.message });
|
return res.status(500).json({ error: err.message });
|
||||||
}
|
}
|
||||||
res.json({ message: 'Username updated successfully' });
|
res.json({ message: 'Username and name updated successfully' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user