diff --git a/.env.example b/.env.example index 813a25f8..9d35fc56 100644 --- a/.env.example +++ b/.env.example @@ -6,6 +6,7 @@ DB_USERNAME="node_user" DB_PASSWORD="node_password" DB_DATABASE="gains" DB_URL= +SENTRY_URL= # node PORT=8087 diff --git a/package-lock.json b/package-lock.json index a269b2f6..4933f9a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/vue-fontawesome": "^3.0.3", "@popperjs/core": "^2.11.8", + "@sentry/node": "^7.75.1", "@vitejs/plugin-vue": "^4.4.0", "adm-zip": "^0.5.10", "animate.css": "^4.1.1", @@ -1674,6 +1675,65 @@ "npm": ">=7.0.0" } }, + "node_modules/@sentry-internal/tracing": { + "version": "7.75.1", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.75.1.tgz", + "integrity": "sha512-nynV+7iVcF8k3CqhvI2K7iA8h4ovJhgYHKnXR8RDDevQOqNG2AEX9+hjCj9fZM4MhKHYFqf1od2oO9lTr38kwg==", + "dependencies": { + "@sentry/core": "7.75.1", + "@sentry/types": "7.75.1", + "@sentry/utils": "7.75.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/core": { + "version": "7.75.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.75.1.tgz", + "integrity": "sha512-Kw4KyKBxbxbh8OKO0S11Tm0gWP+6AaXXYrsq3hp8H338l/wOmIzyckmCbUrc/XJeoRqaFLJbdcCrcUEDZUvsVQ==", + "dependencies": { + "@sentry/types": "7.75.1", + "@sentry/utils": "7.75.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/node": { + "version": "7.75.1", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.75.1.tgz", + "integrity": "sha512-E174NbP3j7OIqQQYPtpMGz1FfL/KE5PeGnhoACyMIk0D5MGB7Ia7Y9+nYfHB7+EOJPV2Ob6BYlhemX/MxPrYWg==", + "dependencies": { + "@sentry-internal/tracing": "7.75.1", + "@sentry/core": "7.75.1", + "@sentry/types": "7.75.1", + "@sentry/utils": "7.75.1", + "https-proxy-agent": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/types": { + "version": "7.75.1", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.75.1.tgz", + "integrity": "sha512-km+ygqgMDaFfTrbQwdhrptFqx0Oq15jZABqIoIpbaOCkCAMm+tyCqrFS8dTfaq5wpCktqWOy2qU/DOpppO99Cg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/@sentry/utils": { + "version": "7.75.1", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.75.1.tgz", + "integrity": "sha512-QzW2eRjY20epD//9/tQ0FTNwdAL6XZi+LyJNUQIeK3NMnc5NgHrgpxId87gmFq8cNx47utH1Blub8RuMbKqiwQ==", + "dependencies": { + "@sentry/types": "7.75.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -2279,6 +2339,38 @@ "node": ">=6.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/agent-base/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/ajv": { "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", @@ -6335,6 +6427,39 @@ "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==" }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/https-proxy-agent/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", diff --git a/package.json b/package.json index a9e0076c..06ffdc2b 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/vue-fontawesome": "^3.0.3", "@popperjs/core": "^2.11.8", + "@sentry/node": "^7.75.1", "@vitejs/plugin-vue": "^4.4.0", "adm-zip": "^0.5.10", "animate.css": "^4.1.1", diff --git a/src/app/app.js b/src/app/app.js index a12502be..2660a485 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -11,11 +11,12 @@ import expressJSDocSwagger from 'express-jsdoc-swagger'; import expressJsdocOptions from '../config/express-jsdoc-options.js'; import * as AppRoutes from './app.routes.js'; import { regularLimiter, apiLimiter } from '../config/rate-limiter.config.js'; -import { jwt_secret } from '../config/env.js'; +import { jwt_secret, SENTRY_URL } from '../config/env.js'; import * as Middlewares from './api/api.middlewares.js'; import CustomError from './api/api.errors.js'; import logger from '../utils/logger.js'; import redis from '../utils/redis.js'; +import Sentry from '@sentry/node'; const app = express(); const server = http.createServer(app); @@ -25,6 +26,9 @@ const io = new Server(server, { }, }); +Sentry.init({ dsn: SENTRY_URL }); +app.use(Sentry.Handlers.requestHandler()); + app.use( helmet({ contentSecurityPolicy: { @@ -56,6 +60,10 @@ app.use( }), ); +// app.get('/debug-sentry', (req, res) => { +// throw new Error('My first Sentry error!'); +// }); + app.use('/docs/*', (req, res, next) => Middlewares.authenticateUser(req, res, next, true)); expressJSDocSwagger(app)(expressJsdocOptions); @@ -140,6 +148,7 @@ app.use((req, res, next) => { */ app.use('*', regularLimiter, AppRoutes.vueHandler); +app.use(Sentry.Handlers.errorHandler()); app.use(AppRoutes.notFoundHandler); app.use(AppRoutes.errorHandler); diff --git a/src/config/env.js b/src/config/env.js index 94256431..235f6279 100644 --- a/src/config/env.js +++ b/src/config/env.js @@ -74,3 +74,5 @@ export const GITHUB = { }; export const MY_IP = process.env.MY_IP; + +export const SENTRY_URL = process.env.SENTRY_URL;