require('dotenv').config(); const fs = require('fs'); const bodyParser = require('body-parser'); const jsonServer = require('json-server'); const jwt = require('jsonwebtoken'); const bcrypt = require('bcrypt'); const path = require('path'); const scanPhoto = require('./scanphoto.js'); const SECRET_KEY = process.env.JWT_SECRET || '123456789'; const EXPIRES_IN = process.env.JWT_EXPIRES || '1h'; const PORT = process.env.SERVER_PORT || 4000; const server = jsonServer.create(); // ----------------------------------------------------- // STATIC FILES // ----------------------------------------------------- server.use(jsonServer.defaults({ static: path.join(__dirname, '../public') })); // ----------------------------------------------------- // CONFIG ENDPOINT (PUBBLICO) // ----------------------------------------------------- server.get('/config', (req, res) => { res.json({ baseUrl: process.env.BASE_URL }); }); // ----------------------------------------------------- // ROUTER DB // ----------------------------------------------------- let router; if (fs.existsSync('./api_v1/db.json')) { router = jsonServer.router('./api_v1/db.json'); } else { const initialData = fs.readFileSync('api_v1/initialDB.json', 'utf8'); fs.writeFileSync('api_v1/db.json', initialData); router = jsonServer.router('./api_v1/db.json'); } // ----------------------------------------------------- // USERS DB // ----------------------------------------------------- const userdb = JSON.parse(fs.readFileSync('./api_v1/users.json', 'UTF-8')); server.use(bodyParser.urlencoded({ extended: true })); server.use(bodyParser.json()); // ----------------------------------------------------- // JWT HELPERS // ----------------------------------------------------- function createToken(payload) { return jwt.sign(payload, SECRET_KEY, { expiresIn: EXPIRES_IN }); } function verifyToken(token) { return jwt.verify(token, SECRET_KEY, (err, decode) => decode || err); } function isAuthenticated({ email, password }) { return userdb.users.findIndex( user => user.email === email && bcrypt.compareSync(password, user.password) ) !== -1; } // ----------------------------------------------------- // RESET DB // ----------------------------------------------------- function resetDB() { const initialData = fs.readFileSync('api_v1/initialDB.json', 'utf8'); fs.writeFileSync('api_v1/db.json', initialData); router.db.setState(JSON.parse(initialData)); console.log('DB resettato'); } // ----------------------------------------------------- // HOME // ----------------------------------------------------- server.get('/', (req, res) => { res.sendFile(path.resolve("public/index.html")); }); // ----------------------------------------------------- // SCAN FOTO // ----------------------------------------------------- server.get('/scan', async (req, res) => { resetDB(); await scanPhoto('./public/photos/original'); console.log("Ricaricato"); res.send({ status: 'Ricaricato' }); }); // ----------------------------------------------------- // FILE STATICI // ----------------------------------------------------- server.get('/files', (req, res) => { res.sendFile(path.resolve("public/" + req.query.file)); }); // ----------------------------------------------------- // RESET DB MANUALE // ----------------------------------------------------- server.get('/initDB', (req, res) => { resetDB(); res.send({ status: 'DB resettato' }); }); // ----------------------------------------------------- // LOGIN (PUBBLICO) // ----------------------------------------------------- server.post('/auth/login', (req, res) => { const { email, password } = req.body; if (!isAuthenticated({ email, password })) { return res.status(401).json({ status: 401, message: 'Incorrect email or password' }); } const token = createToken({ email }); res.status(200).json({ token }); }); // ----------------------------------------------------- // JWT MIDDLEWARE (TUTTO IL RESTO È PROTETTO) // ----------------------------------------------------- server.use(/^(?!\/auth).*$/, (req, res, next) => { if (!req.headers.authorization || req.headers.authorization.split(' ')[0] !== 'Bearer') { return res.status(401).json({ status: 401, message: 'Bad authorization header' }); } try { verifyToken(req.headers.authorization.split(' ')[1]); next(); } catch (err) { res.status(401).json({ status: 401, message: 'Error: access_token is not valid' }); } }); // ----------------------------------------------------- // ROUTER JSON-SERVER // ----------------------------------------------------- server.use(router); // ----------------------------------------------------- // START SERVER // ----------------------------------------------------- server.listen(PORT, () => { console.log(`Auth API server running on port ${PORT} ...`); });