Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions backend/src/middleware/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,9 @@ export async function requireAdmin(req: AuthRequest, res: Response, next: NextFu
return res.status(401).json({ error: 'Usuário não autenticado' });
}

// Lista de emails de admin (gustavo.caetano@gmail.com + variável de ambiente)
const defaultAdminEmails = ['gustavo.caetano@gmail.com'];
// Lista de emails de admin (configurado via variável de ambiente)
// 🛡️ SECURITY: No hardcoded admin emails allowed. Use ADMIN_EMAILS env var.
const defaultAdminEmails: string[] = [];
const envAdminEmails = (process.env.ADMIN_EMAILS || '').split(',').map(e => e.trim().toLowerCase()).filter(e => e);
const adminEmails = [...defaultAdminEmails, ...envAdminEmails].map(e => e.toLowerCase());

Expand Down
57 changes: 57 additions & 0 deletions backend/src/tests/auth-admin-config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

import { requireAdmin } from '../middleware/auth.js';
import { jest } from '@jest/globals';

describe('requireAdmin Middleware Configuration Check', () => {
let req: any;
let res: any;
let next: any;
let originalEnv: string | undefined;

beforeAll(() => {
originalEnv = process.env.ADMIN_EMAILS;
});

afterAll(() => {
process.env.ADMIN_EMAILS = originalEnv;
});

beforeEach(() => {
req = {
user: {
email: 'gustavo.caetano@gmail.com'
}
};
res = {
status: jest.fn().mockReturnThis(),
json: jest.fn()
};
next = jest.fn();
process.env.ADMIN_EMAILS = ''; // Ensure env var is empty
});

it('DENIES access when admin email is NOT in env var', async () => {
// 🛡️ Verify Fix: Hardcoded email should no longer work
await requireAdmin(req, res, next);
expect(next).not.toHaveBeenCalled();
expect(res.status).toHaveBeenCalledWith(403);
expect(res.json).toHaveBeenCalledWith(expect.objectContaining({
code: 'ADMIN_REQUIRED'
}));
});

it('ALLOWS access when admin email IS in env var', async () => {
process.env.ADMIN_EMAILS = 'other@admin.com, gustavo.caetano@gmail.com';
await requireAdmin(req, res, next);
expect(next).toHaveBeenCalled();
expect(res.status).not.toHaveBeenCalled();
});

it('denies access to non-admin email even if env var is set', async () => {
process.env.ADMIN_EMAILS = 'admin@example.com';
req.user.email = 'attacker@example.com';
await requireAdmin(req, res, next);
expect(next).not.toHaveBeenCalled();
expect(res.status).toHaveBeenCalledWith(403);
});
});
Loading