From 1c6cf171241c75f9243b9f90df40f673775135bb Mon Sep 17 00:00:00 2001 From: swoocn Date: Sat, 6 Apr 2024 09:29:22 -0400 Subject: [PATCH] Restore Backend Logging Framework w/ Winston MongoDB transport. --- backend/logger.js | 14 +- backend/logging-config.js | 35 ++- backend/mongodb.js | 16 ++ backend/package-lock.json | 208 +++++++++++++++--- backend/package.json | 6 +- backend/server.js | 13 +- backend/src/authMiddleware/isAuthenticated.js | 10 +- backend/src/controllers/productControllers.js | 12 +- backend/src/controllers/searchController.js | 10 +- backend/src/controllers/shopController.js | 34 +-- .../src/controllers/transactionController.js | 15 +- backend/src/controllers/userControllers.js | 16 +- backend/src/handlers/payments.js | 42 ++-- backend/src/handlers/users.js | 25 ++- backend/src/models/shopModel.js | 10 +- 15 files changed, 346 insertions(+), 120 deletions(-) create mode 100644 backend/mongodb.js diff --git a/backend/logger.js b/backend/logger.js index 22890bf..9b07a22 100644 --- a/backend/logger.js +++ b/backend/logger.js @@ -1,7 +1,15 @@ const winston = require('winston'); const configureLogging = require('./logging-config'); -const loggingConfig = configureLogging(); -const logger = winston.createLogger(loggingConfig); +const initializeLogger = async () => { + try { + const loggingConfig = await configureLogging(); + const logger = winston.createLogger(loggingConfig); + return logger; + } catch (error) { + console.error('Error initializing logger:', error); + return null; + } +}; -module.exports = logger; +module.exports = initializeLogger; diff --git a/backend/logging-config.js b/backend/logging-config.js index 6196b3d..d080246 100644 --- a/backend/logging-config.js +++ b/backend/logging-config.js @@ -1,34 +1,53 @@ const dotenv = require("dotenv"); const winston = require('winston'); +const connectDB = require("./mongodb"); + +require('winston-mongodb'); dotenv.config(); -const configureLogging = () => { - console.log(`VERCEL_ENV: ${process.env.VERCEL_ENV}`); +const configureLogging = async () => { + // console.log(`VERCEL_ENV: ${process.env.VERCEL_ENV}`); // check if the app is running in localhost mode or sandbox const isDevelopment = () => { return process.env.VERCEL_ENV === "localhost" || process.env.VERCEL_ENV === "sandbox"; }; - // determine the logging configuration based on the environment + // determine the logging configuration based on the server environment if (isDevelopment()) { return { level: 'debug', - format: winston.format.cli(), + format: winston.format.combine( + winston.format.errors({ stack: true }), + winston.format.cli() + ), transports: [ new winston.transports.Console() ] }; } else { + await connectDB(); + return { - level: 'error', - format: winston.format.cli(), + level: 'info', + format: winston.format.combine( + winston.format.errors({ stack: true }), + winston.format.timestamp(), // GMT + winston.format.json() + ), transports: [ - new winston.transports.Console() + new winston.transports.MongoDB({ + db: process.env.MONGODB_URL, + options: { + useNewUrlParser: true, + useUnifiedTopology: true + }, + collection: 'serverLogs' + }) ] }; } -} +}; module.exports = configureLogging; diff --git a/backend/mongodb.js b/backend/mongodb.js new file mode 100644 index 0000000..de2b9bb --- /dev/null +++ b/backend/mongodb.js @@ -0,0 +1,16 @@ +const mongoose = require("mongoose"); +const dotenv = require("dotenv"); + +dotenv.config(); + +const connectDB = async () => { + try { + const conn = await mongoose.connect(process.env.MONGODB_URL); + // console.log(`Mongo DB Connection successfully attained: ${conn.connection.host}`); + return conn; + } catch (err) { + console.error("Mongo DB Connection failed", err); + } +}; + +module.exports = connectDB; diff --git a/backend/package-lock.json b/backend/package-lock.json index 8717bc1..46afc84 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -1,15 +1,14 @@ { - "name": "@map-of-pi/map-of-pi", + "name": "map-of-pi", "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@map-of-pi/map-of-pi", + "name": "map-of-pi", "version": "2.0.0", "license": "PiOS", "dependencies": { - "@map-of-pi/map-of-pi": "file:..", "connect-mongo": "^5.1.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", @@ -17,9 +16,10 @@ "express": "^4.18.2", "express-session": "^1.17.3", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.1.0", + "mongoose": "^8.3.0", "morgan": "^1.10.0", - "winston": "^3.12.0" + "winston": "^3.12.0", + "winston-mongodb": "^5.1.1" }, "devDependencies": { "eslint": "^8.57.0", @@ -29,8 +29,9 @@ } }, "..": { - "name": "@map-of-pi/map-of-pi", + "name": "map-of-pi", "version": "2.0.0", + "extraneous": true, "dependencies": { "axios": "~1.6.7" }, @@ -1219,14 +1220,10 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@map-of-pi/map-of-pi": { - "resolved": "..", - "link": true - }, "node_modules/@mongodb-js/saslprep": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz", - "integrity": "sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.5.tgz", + "integrity": "sha512-XLNOMH66KhJzUJNwT/qlMnS4WsNDWD5ASdyaSH3EtK+F4r/CFGa3jT4GNi4mfOitGvWXtdLgQJkQjxSVrio+jA==", "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -1830,6 +1827,42 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/bl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/bl/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/bl/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", @@ -1935,9 +1968,9 @@ } }, "node_modules/bson": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", - "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.6.0.tgz", + "integrity": "sha512-BVINv2SgcMjL4oYbBuCQTpE3/VKOSxrOA8Cj/wQP7izSzlBGVomdm+TcUd0Pzy0ytLSSDweCKQ6X3f5veM5LQA==", "engines": { "node": ">=16.20.1" } @@ -2222,6 +2255,11 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -2330,6 +2368,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3624,6 +3670,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4359,9 +4410,9 @@ } }, "node_modules/kareem": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", - "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.6.0.tgz", + "integrity": "sha512-B9wwgyKKKZkxYZXQzefvb/Ykh9eHixxR+ttTP2c/Pq8NvHi1iYIAImf3nj/DXkPcnenjGEffhPWXnCFRIbNAhw==", "engines": { "node": ">=12.0.0" } @@ -4643,12 +4694,12 @@ } }, "node_modules/mongodb": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", - "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.5.0.tgz", + "integrity": "sha512-Fozq68InT+JKABGLqctgtb8P56pRrJFkbhW0ux+x1mdHeyinor8oNzJqwLjV/t5X5nJGfTlluxfyMnOXNggIUA==", "dependencies": { - "@mongodb-js/saslprep": "^1.1.0", - "bson": "^6.2.0", + "@mongodb-js/saslprep": "^1.1.5", + "bson": "^6.4.0", "mongodb-connection-string-url": "^3.0.0" }, "engines": { @@ -4697,13 +4748,13 @@ } }, "node_modules/mongoose": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.1.0.tgz", - "integrity": "sha512-kOA4Xnq2goqNpN9EmYElGNWfxA9H80fxcr7UdJKWi3UMflza0R7wpTihCpM67dE/0MNFljoa0sjQtlXVkkySAQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.3.0.tgz", + "integrity": "sha512-Y5QNnuA38CEin8hnA+q//nUVztIi4Xklu9xlmbkd1KdWHnIlemSwf5IL/evcI+e2zplL4g5Y6PMkO+nPSAnIdA==", "dependencies": { - "bson": "^6.2.0", - "kareem": "2.5.1", - "mongodb": "6.3.0", + "bson": "^6.5.0", + "kareem": "2.6.0", + "mongodb": "6.5.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -4899,6 +4950,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/optional-require": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", + "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", + "dependencies": { + "require-at": "^1.0.6" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -5126,6 +5188,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -5270,6 +5337,14 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/require-at": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", + "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", + "engines": { + "node": ">=4" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -5406,6 +5481,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -6058,6 +6145,67 @@ "node": ">= 12.0.0" } }, + "node_modules/winston-mongodb": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/winston-mongodb/-/winston-mongodb-5.1.1.tgz", + "integrity": "sha512-tlDksYDCsSka6vLzB/cg19B+kRbVH/y9JQdXVXc5r4TSLEgX1Ivj/vHyedYlYzNMAZkSSfexwI/dSDn3f9/Qkg==", + "dependencies": { + "mongodb": "^3.6.2", + "winston-transport": "^4.4.0" + }, + "engines": { + "node": ">=6.8.1" + }, + "peerDependencies": { + "winston": "^3.0.0" + } + }, + "node_modules/winston-mongodb/node_modules/bson": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", + "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/winston-mongodb/node_modules/mongodb": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.4.tgz", + "integrity": "sha512-K5q8aBqEXMwWdVNh94UQTwZ6BejVbFhh1uB6c5FKtPE9eUMZPUO3sRZdgIEcHSrAWmxzpG/FeODDKL388sqRmw==", + "dependencies": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "optional-require": "^1.1.8", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4" + }, + "optionalDependencies": { + "saslprep": "^1.0.0" + }, + "peerDependenciesMeta": { + "aws4": { + "optional": true + }, + "bson-ext": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "mongodb-extjson": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, "node_modules/winston-transport": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz", diff --git a/backend/package.json b/backend/package.json index 6fc3af0..63e38f4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -16,7 +16,6 @@ "release": "changeset publish" }, "dependencies": { - "@map-of-pi/map-of-pi": "file:..", "connect-mongo": "^5.1.0", "cookie-parser": "^1.4.6", "cors": "^2.8.5", @@ -24,9 +23,10 @@ "express": "^4.18.2", "express-session": "^1.17.3", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.1.0", + "mongoose": "^8.3.0", "morgan": "^1.10.0", - "winston": "^3.12.0" + "winston": "^3.12.0", + "winston-mongodb": "^5.1.1" }, "devDependencies": { "eslint": "^8.57.0", diff --git a/backend/server.js b/backend/server.js index 1c9fd41..e8e86c1 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,14 +1,12 @@ const fs = require("fs"); const path = require("path"); const express = require("express"); -const mongoose = require("mongoose"); const session = require("express-session"); const morganLogger = require("morgan"); const cors = require("cors"); -const MongoStore = require("connect-mongo"); const cookieParser = require("cookie-parser"); const dotenv = require("dotenv"); -const logger = require("./logger"); +const connectDB = require("./mongodb"); dotenv.config(); @@ -23,7 +21,6 @@ const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use((req, res, next) => { - logger.info(`Received request: ${req.method} ${req.url}`); next(); }); @@ -48,13 +45,13 @@ app.use("/payments", paymentRoutes); app.use("/transactions", transactionRoutes); app.use("/shops",shopRoutes) -mongoose - .connect(`${process.env.MONGODB_URL}`) +// call the connectDB function to initialize MongoDB connection +connectDB() .then(() => { app.listen(process.env.PORT, () => { - logger.info(`Successful connection to DB ${process.env.MONGODB_URL} and app server running on port ${process.env.PORT}`); + console.log("Server started on port", process.env.PORT); }); }) .catch((err) => { - logger.error("Error while connectiong to DB", err); + console.error("Error starting server", err); }); diff --git a/backend/src/authMiddleware/isAuthenticated.js b/backend/src/authMiddleware/isAuthenticated.js index c2e01c6..465ff71 100644 --- a/backend/src/authMiddleware/isAuthenticated.js +++ b/backend/src/authMiddleware/isAuthenticated.js @@ -1,6 +1,12 @@ const jwt = require("jsonwebtoken"); const User = require("../models/userModel"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); const isAuthenticated = async (req, res, next) => { logger.debug("isAuthenticated middleware started"); @@ -26,7 +32,7 @@ const isAuthenticated = async (req, res, next) => { next(); } catch (error) { - logger.error("Error verifying token:", error); + logger.error(`Error verifying token: ${error.stack}`); return res .status(401) .json({ error: "User unauthorized; token is invalid", details: error.message }); diff --git a/backend/src/controllers/productControllers.js b/backend/src/controllers/productControllers.js index 4e1732d..0e2abfe 100644 --- a/backend/src/controllers/productControllers.js +++ b/backend/src/controllers/productControllers.js @@ -1,6 +1,12 @@ const Product = require("../models/productModel"); const Shop = require("../models/shopModel"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); const addProductToShop = async (req, res) => { const { shopId } = req.params; @@ -18,11 +24,11 @@ const addProductToShop = async (req, res) => { shop.products.push(newProduct); await shop.save(); - logger.info("Product added successfully"); + logger.info("Product added successfully", newProduct); return res.status(200).json({ message: "Product added successfully", newProduct }); } catch (error) { - logger.error("Internal server error while adding product:", error.message); + logger.error(`Internal server error while adding product: ${error.stack}`); return res.status(500).json({ error: "Internal server error" }); } }; diff --git a/backend/src/controllers/searchController.js b/backend/src/controllers/searchController.js index e36e87c..86bff83 100644 --- a/backend/src/controllers/searchController.js +++ b/backend/src/controllers/searchController.js @@ -1,6 +1,12 @@ const Shop = require("../models/shopModel"); const Product = require("../models/productModel"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); const search = async (req, res) => { try { @@ -43,7 +49,7 @@ const search = async (req, res) => { res.status(200).json({ shops }); } catch (error) { - logger.error("Internal server error while searching:", error.message); + logger.error(`Internal server error while searching: ${error.stack}`); return res.status(500).json({ error: "Internal server error" }); } }; diff --git a/backend/src/controllers/shopController.js b/backend/src/controllers/shopController.js index fb5543c..e9ff17b 100644 --- a/backend/src/controllers/shopController.js +++ b/backend/src/controllers/shopController.js @@ -1,19 +1,25 @@ const Product = require("../models/productModel"); const Shop = require("../models/shopModel"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); const getAllShops = async (req, res) => { try { const shops = await Shop.find().populate("products"); if (shops.length > 0) { - logger.info("Successfully fetched all shops"); + logger.debug("Successfully fetched all shops"); return res.status(200).json({ shops }); } else { - logger.info("No shops found"); + logger.debug("No shops found"); return res.status(404).json({ message: "No shops found" }); } } catch (error) { - logger.error("Error while searching all shops:", error.message); + logger.error(`Error while searching all shops: ${error.stack}`); return res.status(500).json({ error: "Internal server error" }); } }; @@ -26,7 +32,7 @@ const registerShop = async (req, res) => { logger.info("Successfully registered new shop:", newShop); return res.status(200).json({ newShop }); } catch (error) { - logger.error("Error while registering new shop:", error.message); + logger.error(`Error while registering new shop: ${error.stack}`); return res.status(500).json({ error: "Internal server error" }); } }; @@ -36,14 +42,14 @@ const getSingleShop = async (req, res) => { try { const shop = await Shop.findById(shopId); if (shop) { - logger.info("Successfully fetched single shop:", shop); + logger.debug("Successfully fetched single shop:", shop); return res.status(200).json({ shop }); } else { - logger.info("No shop found"); + logger.debug("No shop found"); return res.status(404).json({ message: "No shop found" }); } } catch (error) { - logger.error("Error while searching single shop:", error.message); + logger.error(`Error while searching single shop: ${error.stack}`); return res.status(500).json({ error: "Internal server error" }); } }; @@ -55,14 +61,14 @@ const deleteShop = async (req, res) => { const shopToDelete = await Shop.findById(shopId); if (shopToDelete && shopToDelete.owner === currentUser.uid) { await Shop.findByIdAndDelete(shopId); - logger.info("Successfully deleted shop:", shopToDelete); + logger.debug("Successfully deleted shop:", shopToDelete); return res.status(200).json({ message: "Shop deleted successfully" }); } else { logger.warn("Shop removal denied due to lack of permission"); return res.status(401).json({ message: "Shop removal denied due to lack of permission" }); } } catch (error) { - logger.error("Error while deleting shop:", error.message); + logger.error(`Error while deleting shop: ${error.stack}`); return res.status(500).json({ error: "Internal server error while deleting shop" }); } }; @@ -81,7 +87,7 @@ const updateShop = async (req, res) => { return res.status(401).json({ message: "Unauthorized to update this shop" }); } } catch (error) { - logger.error("Error while updating shop:", error.message); + logger.error(`Error while updating shop: ${error.stack}`); return res.status(500).json({ error: "Internal server error while updating shop" }); } }; @@ -92,14 +98,14 @@ const getShopProducts = async (req, res) => { try { const products = await Product.find({ shop: shopId }); if (products.length > 0) { - logger.info("Successfully fetched products for shop"); + logger.debug("Successfully fetched products for shop"); return res.status(200).json({ products }); } else { - logger.info("Shop has no products"); + logger.debug("Shop has no products"); return res.status(200).json({ message: "Shop has no products" }); } } catch (error) { - logger.error("Error while searching products for a shop:", error.message); + logger.error(`Error while searching products for a shop: ${error.stack}`); return res.status(500).json({ error: "Internal server error" }); } }; diff --git a/backend/src/controllers/transactionController.js b/backend/src/controllers/transactionController.js index de01c74..c337656 100644 --- a/backend/src/controllers/transactionController.js +++ b/backend/src/controllers/transactionController.js @@ -1,16 +1,21 @@ const Order = require("../models/orderModel"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); const getUserTransactions = async (req, res) => { - const currentUser = req.currentUser; + const currentUser = req.currentUser; try { - const transactions = await Order.find({ user: currentUser.uid }).sort({ createdAt: 1 }) - logger.info("Successfully fetched user transactions"); + logger.debug("Successfully fetched user transactions"); return res.status(200).json({ transactions }); } catch (error) { - logger.error("Error getting user transactions:", error.message); + logger.error(`Error getting user transactions: ${error.stack}`); return res.status(500).json({ error: "Internal server error", details: error.message }); } }; diff --git a/backend/src/controllers/userControllers.js b/backend/src/controllers/userControllers.js index 7d85deb..089a116 100644 --- a/backend/src/controllers/userControllers.js +++ b/backend/src/controllers/userControllers.js @@ -2,7 +2,13 @@ const Shop = require("../models/shopModel"); const User = require("../models/userModel"); const platformAPIClient = require("../services/platformAPIClient"); const jwt = require("jsonwebtoken"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); const signInUser = async (req, res) => { const authResult = req.body.authResult; @@ -13,7 +19,7 @@ const signInUser = async (req, res) => { }); logger.debug("User details from /me endpoint:", me.data); } catch (error) { - logger.error("Invalid access token:", error.message); + logger.error(`Invalid access token: ${error.stack}`); return res.status(401).json({ error: "Invalid access token" }); } @@ -44,7 +50,7 @@ const signInUser = async (req, res) => { ); res.status(200).json({ currentUser, token }); } catch (error) { - logger.error("Internal server error:", error.message); + logger.error(`Internal server error: ${error.stack}`); res.status(500).json({ error: "Internal server error" }); } }; @@ -63,7 +69,7 @@ const signOutUser = async (req, res) => { todo: "Remember to remove user token from localstorage", }); } catch (error) { - logger.error("Internal server error:", error.message); + logger.error(`Internal server error: ${error.stack}`); res.status(500).json({ error: "Internal server error" }); } }; @@ -75,7 +81,7 @@ const verifyUserToken = async (req, res) => { const currentUser = await User.findOne({ uid: decoded.userId }); res.status(200).json({ currentUser, token }); } catch (error) { - logger.error("Internal server error while verifying user token:", error.message); + logger.error(`Internal server error while verifying user token: ${error.stack}`); res.status(500).json({ error: "Internal server error" }); } }; diff --git a/backend/src/handlers/payments.js b/backend/src/handlers/payments.js index 3b36979..ceaf40a 100644 --- a/backend/src/handlers/payments.js +++ b/backend/src/handlers/payments.js @@ -4,7 +4,13 @@ const platformAPIClient = require("../services/platformAPIClient"); const Order = require("../models/orderModel"); const User = require("../models/userModel"); const isAuthenticated = require("../authMiddleware/isAuthenticated"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); const router = express.Router(); @@ -41,22 +47,19 @@ router.post("/incomplete",isAuthenticated, async (req, res) => { { $set: { txid, paid: true } } ); - // increment user balance - const currentUser = req.currentUser; + const currentUser = req.currentUser; if (currentUser) { await User.updateOne({ uid: currentUser.uid }, { $inc: { balance: order.amount } }); } - - // let Pi Servers know that the payment is completed await platformAPIClient.post(`/v2/payments/${paymentId}/complete`, { txid }); - logger.info(`Handled the incomplete payment ${paymentId}`); + logger.info(`Handled the incomplete payment: ${paymentId}`); return res.status(200).json({ message: `Handled the incomplete payment ${paymentId}` }); } catch (error) { - logger.error("Error in /incomplete route:", error); + logger.error(`Error in /incomplete route: ${error.stack}`); return res.status(500).json({ message: "Internal Server Error" }); } }); @@ -64,8 +67,8 @@ router.post("/incomplete",isAuthenticated, async (req, res) => { // approve the current payment router.post("/approve", isAuthenticated, async (req, res) => { try { - logger.info("Approve route triggered for the user"); - logger.info(`Current user: ${req.currentUser}; JWT ID: ${req.currentUser.uid}`); + logger.debug("Approve route triggered for the user"); + logger.debug(`Current user: ${req.currentUser}; JWT ID: ${req.currentUser.uid}`); if (!req.currentUser) { logger.warn("Sign in required for current user"); @@ -95,7 +98,7 @@ router.post("/approve", isAuthenticated, async (req, res) => { logger.info(`Approved the payment ${paymentId}`); return res.status(200).json({ message: `Approved the payment ${paymentId}` }); } catch (error) { - logger.error("Error in /approve route:", error); + logger.error(`Error in /approve route: ${error.stack}`); return res.status(500).json({ message: "Internal Server Error" }); } }); @@ -118,22 +121,11 @@ router.post("/complete", isAuthenticated, async (req, res) => { { $set: { txid: txid, paid: true } } ); - // console.log("***********form complete***************"); - // console.log(req.currentUser); - // console.log("***********form complete***************"); - const currentUser = req.currentUser; const amountToAdd = parseInt(currentPayment.data.amount, 10) || 0; - logger.info("Completed the payment:", paymentId); + logger.debug("Completed the payment:", paymentId); logger.info("User deposit amount:", currentPayment.data.amount); - // console.log("this is type of amount : ", typeof currentPayment.data.amount); - // console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - // console.log("this is actual amount from gpt : ", amountToAdd); - // console.log("this is type of amount : ", typeof amountToAdd); - // console.log( - // "***********amount user is deposting to app***************" - // ); // notifying pi server that transaction is completed await platformAPIClient.post(`/v2/payments/${paymentId}/complete`, { txid }); @@ -144,7 +136,7 @@ router.post("/complete", isAuthenticated, async (req, res) => { return res.status(200).json({ message: `Completed the payment ${paymentId}` }); } catch (error) { - logger.error("Error in /complete route:", error); + logger.error(`Error in /complete route: ${error.stack}`); return res.status(500).json({ message: "Internal Server Error" }); } }); @@ -160,10 +152,10 @@ router.post("/cancelled_payment", async (req, res) => { { $set: { cancelled: true } } ); - logger.info("Cancelled the payment:", paymentId); + logger.debug("Cancelled the payment:", paymentId); return res.status(200).json({ message: `Cancelled the payment ${paymentId}` }); } catch (error) { - logger.error("Error in /cancelled_payment route:", error); + logger.error(`Error in /cancelled_payment route: ${error.stack}`); return res.status(500).json({ message: "Internal Server Error" }); } }); diff --git a/backend/src/handlers/users.js b/backend/src/handlers/users.js index f29c2d0..30d852e 100644 --- a/backend/src/handlers/users.js +++ b/backend/src/handlers/users.js @@ -3,7 +3,13 @@ const router = express.Router(); const platformAPIClient = require("../services/platformAPIClient"); const User = require("../models/userModel"); const jwt = require("jsonwebtoken"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); // handle the user auth accordingly @@ -15,9 +21,9 @@ router.post("/signin", async (req, res) => { headers: { Authorization: `Bearer ${auth.accessToken}` }, }); - logger.info("User details from /me endpoint:", me.data); + logger.debug("User details from /me endpoint:", me.data); } catch (err) { - logger.error("Invalid access token:", err.message); + logger.error(`Invalid access token: ${error.stack}`); return res.status(401).json({ error: "Invalid access token" }); } @@ -45,11 +51,11 @@ router.post("/signin", async (req, res) => { } // Issuing token for succesful login const token = jwt.sign({userId:currentUser.uid},process.env.JWT_SECRET,{expiresIn:"20m"}) - logger.info("User signed in successfully:", currentUser.uid); + logger.debug("User signed in successfully:", currentUser.uid); // Sending current user with hsi token in my fronted return res.status(200).json({currentUser,token}); } catch (error) { - logger.error("User sign in failed", error); + logger.error(`User sign in failed: ${error.stack}`); return res.status(500).json({ error: "Internal Server Error" }); } }); @@ -57,29 +63,28 @@ router.post("/signin", async (req, res) => { router.get("/signout", async (req, res) => { // Clear currentUser from the session upon signout - logger.info("User signed out"); + logger.debug("User signed out"); return res.status(200).json({ message: "User signed out" }); }); // token verifying fujction that will auto login user when his token is still valid -//this is called in my fronted when app did mount(for initial loading) +// this is called in my fronted when app did mount(for initial loading) router.post("/verify-token", async (req, res) => { try { const token = req.body.token; const decoded = jwt.verify(token, process.env.JWT_SECRET); - const currentUser = await User.findOne({ uid: decoded.userId }); if (currentUser) { - logger.info("User token verified successfully:", currentUser.uid); + logger.debug("User token verified successfully:", currentUser.uid); return res.status(200).json({ currentUser }); } else { logger.warn("Invalid access token"); return res.status(401).json({ error: "Invalid access token" }); } } catch (error) { - logger.error("User access token expired; User needs to login"); + logger.error(`User access token expired; User needs to login: ${error.stack}`); return res.status(500).json({ error: "Internal Server Error" }); } }); diff --git a/backend/src/models/shopModel.js b/backend/src/models/shopModel.js index 5dc5678..ce635fd 100644 --- a/backend/src/models/shopModel.js +++ b/backend/src/models/shopModel.js @@ -1,7 +1,13 @@ const mongoose = require("mongoose"); const Product = require("./productModel"); const User = require("./userModel"); -const logger = require("../../logger"); +const initializeLogger = require("../../logger"); + +let logger; + +initializeLogger().then((initializedLogger) => { + logger = initializedLogger; +}); const shopSchema = new mongoose.Schema({ name: String, @@ -42,7 +48,7 @@ shopSchema.pre("remove", async function (next) { await Product.deleteMany({ shop: this._id }); next(); } catch (error) { - logger.error("Product failed to be deleted with shop", error); + logger.error(`Product failed to be deleted with shop: ${error.stack}`); next(error); } });