refactor: implement centralized auth middleware and standardize cross-subdomain session management
This commit is contained in:
@@ -1,122 +1,76 @@
|
||||
// api.mebboat.it/api/users
|
||||
|
||||
const router = require('express').Router();
|
||||
const { query } = require('../storage/database');
|
||||
const auth = require('../core/auth.core');
|
||||
const userAuth = require('../middlewares/user.security');
|
||||
const internalAuth = require('../middlewares/internal.security');
|
||||
|
||||
// ─── VALIDAZIONE INPUT ──────────────────────────────────────────────
|
||||
const USERNAME_REGEX = /^[a-zA-Z0-9_.\-]{3,50}$/;
|
||||
const TELEGRAM_ID_REGEX = /^[0-9]{5,15}$/;
|
||||
const TELEGRAM_REGEX = /^[0-9]{5,15}$/;
|
||||
|
||||
// ─── ROTTE INTERNAL (prima del router.use userAuth) ─────────────────
|
||||
// ─── SERVICE-TO-SERVICE (x-internal-api-key) ────────────────────────
|
||||
|
||||
router.get('/', internalAuth, async (req, res) => {
|
||||
try {
|
||||
const result = await query(
|
||||
'SELECT id, username, is_active, created_at, telegram_id FROM users'
|
||||
);
|
||||
res.json(result.rows);
|
||||
const users = await auth.getAllUsers();
|
||||
res.json(users);
|
||||
} catch (err) {
|
||||
console.error('[USERS] Errore lista utenti:', err);
|
||||
res.status(500).json({ error: 'Errore interno del server' });
|
||||
console.error('[USERS] list:', err.message);
|
||||
res.status(500).json({ error: 'internal' });
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/tonotify', internalAuth, async (req, res) => {
|
||||
try {
|
||||
const result = await query(
|
||||
'SELECT telegram_id FROM users WHERE telegram_id IS NOT NULL'
|
||||
);
|
||||
res.json(result.rows);
|
||||
const users = await auth.getUsersToNotify();
|
||||
res.json(users);
|
||||
} catch (err) {
|
||||
console.error('[USERS] Errore lista notifiche:', err);
|
||||
res.status(500).json({ error: 'Errore interno del server' });
|
||||
console.error('[USERS] tonotify:', err.message);
|
||||
res.status(500).json({ error: 'internal' });
|
||||
}
|
||||
});
|
||||
|
||||
// ─── ROTTE USER (tutte le rotte sotto usano userAuth) ───────────────
|
||||
// ─── USER AUTH (cookie/JWT) ─────────────────────────────────────────
|
||||
|
||||
router.use(userAuth);
|
||||
|
||||
router.get('/me', async (req, res) => {
|
||||
try {
|
||||
const result = await query(
|
||||
'SELECT id, username, is_active, created_at, telegram_id FROM users WHERE id = $1',
|
||||
[req.user.user_id]
|
||||
);
|
||||
|
||||
if (result.rows.length === 0) {
|
||||
return res.status(404).json({ error: 'Utente non trovato' });
|
||||
}
|
||||
|
||||
res.json(result.rows[0]);
|
||||
const user = await auth.getUserById(req.user.user_id);
|
||||
if (!user) return res.status(404).json({ error: 'user_not_found' });
|
||||
res.json(user);
|
||||
} catch (err) {
|
||||
console.error('[USERS] Errore recupero utente:', err);
|
||||
res.status(500).json({ error: 'Errore interno del server' });
|
||||
console.error('[USERS] me:', err.message);
|
||||
res.status(500).json({ error: 'internal' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/me/username', async (req, res) => {
|
||||
const newUsername = req.query.newUsername || req.body?.newUsername;
|
||||
|
||||
if (!newUsername || typeof newUsername !== 'string') {
|
||||
return res.status(400).json({ error: 'Nuovo username richiesto' });
|
||||
const newUsername = req.body?.newUsername || req.query.newUsername;
|
||||
if (!newUsername || typeof newUsername !== 'string' || !USERNAME_REGEX.test(newUsername)) {
|
||||
return res.status(400).json({ error: 'invalid_username' });
|
||||
}
|
||||
|
||||
// Validazione formato username
|
||||
if (!USERNAME_REGEX.test(newUsername)) {
|
||||
return res.status(400).json({
|
||||
error: 'Username non valido. Deve contenere 3-50 caratteri alfanumerici, underscore, punto o trattino.'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await query(
|
||||
'UPDATE users SET username = $1 WHERE id = $2 RETURNING username',
|
||||
[newUsername, req.user.user_id]
|
||||
);
|
||||
|
||||
if (result.rowCount === 0) {
|
||||
return res.status(404).json({ error: 'Utente non trovato' });
|
||||
}
|
||||
|
||||
res.json({ success: true, username: result.rows[0].username });
|
||||
const updated = await auth.updateUsername(req.user.user_id, newUsername);
|
||||
if (!updated) return res.status(404).json({ error: 'user_not_found' });
|
||||
res.json({ success: true, username: updated.username });
|
||||
} catch (err) {
|
||||
if (err.code === '23505') {
|
||||
return res.status(409).json({ error: 'Questo username è già in uso' });
|
||||
}
|
||||
console.error('[USERS] Errore aggiornamento username:', err);
|
||||
res.status(500).json({ error: 'Errore interno del server' });
|
||||
if (err.code === '23505') return res.status(409).json({ error: 'username_taken' });
|
||||
console.error('[USERS] update username:', err.message);
|
||||
res.status(500).json({ error: 'internal' });
|
||||
}
|
||||
});
|
||||
|
||||
router.put('/me/telegram', async (req, res) => {
|
||||
const telegramId = req.query.telegramId || req.body?.telegramId;
|
||||
|
||||
if (!telegramId || typeof telegramId !== 'string') {
|
||||
return res.status(400).json({ error: 'Telegram ID richiesto' });
|
||||
const telegramId = req.body?.telegramId || req.query.telegramId;
|
||||
if (!telegramId || typeof telegramId !== 'string' || !TELEGRAM_REGEX.test(telegramId)) {
|
||||
return res.status(400).json({ error: 'invalid_telegram_id' });
|
||||
}
|
||||
|
||||
// Validazione formato Telegram ID (solo numeri, 5-15 cifre)
|
||||
if (!TELEGRAM_ID_REGEX.test(telegramId)) {
|
||||
return res.status(400).json({
|
||||
error: 'Telegram ID non valido. Deve contenere solo numeri (5-15 cifre).'
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await query(
|
||||
'UPDATE users SET telegram_id = $1 WHERE id = $2',
|
||||
[telegramId, req.user.user_id]
|
||||
);
|
||||
res.json({ success: true, message: 'Telegram ID aggiornato' });
|
||||
await auth.updateTelegram(req.user.user_id, telegramId);
|
||||
res.json({ success: true });
|
||||
} catch (err) {
|
||||
if (err.code === '23505') {
|
||||
return res.status(409).json({ error: 'Questo Telegram ID è già associato a un altro account' });
|
||||
}
|
||||
console.error('[USERS] Errore aggiornamento telegram:', err);
|
||||
res.status(500).json({ error: 'Errore interno del server' });
|
||||
if (err.code === '23505') return res.status(409).json({ error: 'telegram_taken' });
|
||||
console.error('[USERS] update telegram:', err.message);
|
||||
res.status(500).json({ error: 'internal' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user