From daf64c1e347bed12eae7c1d0df245c96fc6777b0 Mon Sep 17 00:00:00 2001 From: Miguel Puerta Date: Sat, 9 Dec 2023 22:59:30 +0100 Subject: [PATCH] feat: adds logging with morgan --- package-lock.json | 104 +++++++++++++++++++++++++++++++++++++ package.json | 4 ++ src/app.js | 67 +++++++++--------------- src/database/connection.js | 4 -- src/middlewares/morgan.js | 24 +++++++++ src/models/Static.js | 14 ----- 6 files changed, 157 insertions(+), 60 deletions(-) delete mode 100644 src/database/connection.js create mode 100644 src/middlewares/morgan.js delete mode 100644 src/models/Static.js diff --git a/package-lock.json b/package-lock.json index fc98bac..41e9f3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,14 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "cookie-parser": "^1.4.6", "dotenv": "^16.3.1", "express": "^4.18.2", + "helmet": "^7.1.0", "mongoose": "^8.0.0", + "morgan": "^1.10.0", "pjson": "^1.0.9", + "uuidv4": "^6.2.13", "yargs": "^17.7.2" } }, @@ -32,6 +36,11 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/uuid": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" + }, "node_modules/@types/webidl-conversions": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.2.tgz", @@ -85,6 +94,22 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -193,6 +218,26 @@ "node": ">= 0.6" } }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-parser/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -445,6 +490,14 @@ "node": ">= 0.4" } }, + "node_modules/helmet": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", + "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -636,6 +689,32 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/mpath": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", @@ -708,6 +787,14 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -985,6 +1072,23 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/uuidv4": { + "version": "6.2.13", + "resolved": "https://registry.npmjs.org/uuidv4/-/uuidv4-6.2.13.tgz", + "integrity": "sha512-AXyzMjazYB3ovL3q051VLH06Ixj//Knx7QnUSi1T//Ie3io6CpsPu9nVMOx5MoLWh6xV0B9J0hIaxungxXUbPQ==", + "dependencies": { + "@types/uuid": "8.3.4", + "uuid": "8.3.2" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index c5e2e81..0a5b49c 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,14 @@ "author": "", "license": "ISC", "dependencies": { + "cookie-parser": "^1.4.6", "dotenv": "^16.3.1", "express": "^4.18.2", + "helmet": "^7.1.0", "mongoose": "^8.0.0", + "morgan": "^1.10.0", "pjson": "^1.0.9", + "uuidv4": "^6.2.13", "yargs": "^17.7.2" } } diff --git a/src/app.js b/src/app.js index 49e4128..99ee2fa 100644 --- a/src/app.js +++ b/src/app.js @@ -2,16 +2,36 @@ require('dotenv').config(); const express = require('express'); const path = require('path'); const pjson = require('pjson'); +const cookieParser = require("cookie-parser"); +const morgan = require('morgan'); +const helmet = require('helmet'); const app = express(); -const db = require('./database/connection.js'); +const { assignId, skipStatics, skipStatusServer } = require('./middlewares/morgan'); const BootService = require('./services/boot.service'); const execMode = BootService.getExecutionMode(); const PORT = process.env.PORT || 3000; -const Static = require("./models/Static"); -let globalViews = 0; -db.then(() => console.log(`Connected to mongodb server`)).catch((err) => - console.log(`mongodb connection failed: ${err}`), +app.use(express.json()) +app.use(cookieParser()); +app.use(helmet({ + contentSecurityPolicy: false +})); +morgan.token('user-ip', function(req) { + return execMode == "pro" ? req.headers['X-Real-IP'] : req.ip; +}); +morgan.token('accepted-cookies', function(req) { + return Boolean(req.cookies['cookie-accepted']); +}); +morgan.token('id', function getId(req) { + return req.id; +}); +app.use(assignId); +app.use( + morgan('New request from [:user-ip] \n{ \n Request ID: :id \n Method: :method \n Route: :url \n Status code: :status \n Response time: :response-time \n Accepted Cookies: :accepted-cookies \n}', { + skip: function (req, res) { + return skipStatics(req, res) || skipStatusServer(req, res); + } + }) ); app.get('/status', (req, res) => { @@ -25,35 +45,6 @@ app.get('/status', (req, res) => { }); }); -app.get('/views', (req, res) => { - res.send(globalViews.toString()); -}); - -app.use(async (req, res, next) => { - const requestedPath = req.url; - - if (requestedPath.indexOf('.') === -1) { - console.log('Requested:', requestedPath); - try { - let static = await Static.findOne({ staticName: 'GLOBAL' }); - if (!static) { - static = new Static({ - staticName: 'GLOBAL', - views: 0 - }); - } - static.views++; - const savedStatic = await static.save(); - globalViews = savedStatic.views; - console.log('Current views:', globalViews); - } catch (err) { - console.log('Error:', err); - } - } - - next(); -}); - app.use(express.static(path.join(__dirname, 'public'))); app.get('*', function(req, res){ @@ -62,13 +53,5 @@ app.get('*', function(req, res){ app.listen(PORT, async() => { console.log(`Server listening in port ${PORT}`); - try { - let static = await Static.findOne({ staticName: 'GLOBAL' }); - if (static) { - globalViews = static.views; - } - } catch (err) { - console.log('Error:', err); - } }); diff --git a/src/database/connection.js b/src/database/connection.js deleted file mode 100644 index 7fe7a4d..0000000 --- a/src/database/connection.js +++ /dev/null @@ -1,4 +0,0 @@ -require('dotenv').config(); -const mongoose = require('mongoose'); - -module.exports = mongoose.connect('mongodb://127.0.0.1/blog'); \ No newline at end of file diff --git a/src/middlewares/morgan.js b/src/middlewares/morgan.js new file mode 100644 index 0000000..578ff4b --- /dev/null +++ b/src/middlewares/morgan.js @@ -0,0 +1,24 @@ +require('dotenv').config(); +const { v4: uuidv4 } = require('uuid') + +function assignId(req, res, next) { + req.id = uuidv4(); + next(); +} + +function skipStatics(req, res) { + const staticFilesPrefixes = ['/css', '/js', '/images', '/img', '/fonts']; + return staticFilesPrefixes.some(prefix => req.originalUrl.startsWith(prefix)); +} + +function skipStatusServer(req, res) { + const statusServerIP = process.env.STATUS_SERVER_IP; + return req.headers['x-real-ip'] == statusServerIP; +} + +module.exports = { + assignId, + skipStatics, + skipStatusServer +} + diff --git a/src/models/Static.js b/src/models/Static.js deleted file mode 100644 index 6d82b7a..0000000 --- a/src/models/Static.js +++ /dev/null @@ -1,14 +0,0 @@ -const mongoose = require('mongoose'); - -const StaticSchema = new mongoose.Schema({ - staticName: { - type: String, - required: true, - }, - views: { - type: Number, - required: true, - } -}); - -module.exports = mongoose.model('Static', StaticSchema); \ No newline at end of file