From d1be2269a4353045771d71ddf004cd1d42d86042 Mon Sep 17 00:00:00 2001 From: urieljareth Date: Thu, 13 Aug 2026 17:11:59 -0600 Subject: [PATCH] =?UTF-8?q?security:=20eliminar=20exposici=C3=B3n=20de=20c?= =?UTF-8?q?ontrase=C3=B1as=20en=20frontend=20y=20proteger=20endpoints?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/index.ts | 4 ++-- src/components/AdminPanel.tsx | 16 ++++++++-------- src/components/VotingStep.tsx | 6 +++--- src/services/api.ts | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/server/index.ts b/server/index.ts index b2f12df..29dc3c5 100644 --- a/server/index.ts +++ b/server/index.ts @@ -191,7 +191,7 @@ app.delete('/api/vote/:voter', async (req: Request, res: Response): Promise => { const providedKey = req.headers['x-admin-key'] || req.body?.password || req.query?.key; if (!isValidAdminKey(providedKey)) { - res.status(401).json({ success: false, error: 'Contraseña de administración incorrecta. Use REMOVERVOTOE3.' }); + res.status(401).json({ success: false, error: 'Contraseña de autorización incorrecta.' }); return; } diff --git a/src/components/AdminPanel.tsx b/src/components/AdminPanel.tsx index 00f7f43..3ee1d80 100644 --- a/src/components/AdminPanel.tsx +++ b/src/components/AdminPanel.tsx @@ -41,8 +41,8 @@ export const AdminPanel: React.FC = ({ } const trimmedPass = password.trim(); - if (trimmedPass !== 'REMOVERVOTOE3' && trimmedPass !== 'RESETEOE3') { - setAdminMsg({ text: 'Contraseña incorrecta. Se requiere "REMOVERVOTOE3".', type: 'error' }); + if (!trimmedPass) { + setAdminMsg({ text: 'Ingresa la contraseña de autorización.', type: 'error' }); return; } @@ -60,7 +60,7 @@ export const AdminPanel: React.FC = ({ setPassword(''); } catch (err) { setAdminMsg({ - text: `Error al remover voto: ${err instanceof Error ? err.message : 'Error desconocido'}`, + text: err instanceof Error ? err.message : 'Error al remover voto', type: 'error', }); } finally { @@ -70,8 +70,8 @@ export const AdminPanel: React.FC = ({ const handleResetAllVotes = async () => { const trimmedPass = password.trim(); - if (trimmedPass !== 'REMOVERVOTOE3' && trimmedPass !== 'RESETEOE3') { - setAdminMsg({ text: 'Ingresa la contraseña "REMOVERVOTOE3" para vaciar todos los votos.', type: 'error' }); + if (!trimmedPass) { + setAdminMsg({ text: 'Ingresa la contraseña de autorización para vaciar todos los votos.', type: 'error' }); return; } @@ -93,7 +93,7 @@ export const AdminPanel: React.FC = ({ setPassword(''); } catch (err) { setAdminMsg({ - text: `Error al vaciar votos: ${err instanceof Error ? err.message : 'Error desconocido'}`, + text: err instanceof Error ? err.message : 'Error al vaciar votos', type: 'error', }); } finally { @@ -378,7 +378,7 @@ const VOTOS_EMBEBIDOS = ${JSON.stringify(rawVotes, null, 2)};`; Remover Voto Individual o de Pruebas (DELETE) - Clave requerida: REMOVERVOTOE3 + Requiere clave de autorización @@ -403,7 +403,7 @@ const VOTOS_EMBEBIDOS = ${JSON.stringify(rawVotes, null, 2)};`; type="password" value={password} onChange={(e) => setPassword(e.target.value)} - placeholder="Clave: REMOVERVOTOE3" + placeholder="Contraseña de autorización" className="w-full px-3 py-2.5 bg-white/[0.04] border border-white/10 rounded-xl text-white text-xs focus:border-[#00B7D4] focus:outline-none" /> diff --git a/src/components/VotingStep.tsx b/src/components/VotingStep.tsx index 14cb216..44ec480 100644 --- a/src/components/VotingStep.tsx +++ b/src/components/VotingStep.tsx @@ -31,8 +31,8 @@ export const VotingStep: React.FC = ({ const handleRemoveExistingVote = async () => { if (!normalizedVoter) return; const trimmedPass = removePassword.trim(); - if (trimmedPass !== 'REMOVERVOTOE3' && trimmedPass !== 'RESETEOE3') { - setRemoveError('Contraseña incorrecta. Se requiere "REMOVERVOTOE3".'); + if (!trimmedPass) { + setRemoveError('Ingresa la contraseña de autorización.'); return; } @@ -208,7 +208,7 @@ export const VotingStep: React.FC = ({ type="password" value={removePassword} onChange={(e) => setRemovePassword(e.target.value)} - placeholder="Clave: REMOVERVOTOE3" + placeholder="Contraseña de autorización" className="flex-1 px-3 py-2 bg-black/60 border border-red-500/30 rounded-lg text-white text-xs placeholder:text-gray-500 focus:outline-none focus:border-red-400" />