diff --git a/backend/package-lock.json b/backend/package-lock.json index a113507..0622811 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -18,7 +18,7 @@ }, "devDependencies": { "@eslint/js": "^9.2.0", - "eslint": "^9.2.0", + "eslint": "^9.3.0", "globals": "^15.1.0" } }, @@ -58,11 +58,52 @@ "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.15.1.tgz", + "integrity": "sha512-K4gzNq+yymn/EVsXYmf+SBcBro8MTf+aXJZUphM96CdzUEr+ClGDvAbpmaEK+cGVigVXIgs9gNmvHAlrzzY5JQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/config-array/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==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/eslintrc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.0.2.tgz", - "integrity": "sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -82,10 +123,11 @@ } }, "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -103,6 +145,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -114,54 +157,29 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@eslint/js": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.2.0.tgz", - "integrity": "sha512-ESiIudvhoYni+MdsI8oD7skpprZ89qKocwRM2KEvhhBJ9nl5MRh7BXU5GTod7Mdygq+AUl+QzId6iWJKR/wABA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.4.0.tgz", + "integrity": "sha512-fdI7VJjP3Rvc70lC4xkFXHB0fiPeojiL1PxVG6t1ZvXQrarj893PweuBTujxDUFk0Fxj4R7PIIAZ/aiiyZPZcg==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/@eslint/object-schema": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.3.tgz", + "integrity": "sha512-HAbhAYKfsAC2EkTqve00ibWIZlaU74Z1EHwAjYr4PXF0YU2VEA1zSIKSSpKszRLRWwHzzRZXvK632u+uXzvsvw==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array/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==", - "dev": true - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -175,17 +193,12 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true - }, "node_modules/@humanwhocodes/retry": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.2.4.tgz", - "integrity": "sha512-Ttl/jHpxfS3st5sxwICYfk4pOH0WrLI1SpW283GgQL7sCWU7EHIOhX4b4fkIxr3tkfzwg8+FNojtzsIEE7Ecgg==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -246,6 +259,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -258,6 +272,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -267,6 +282,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -306,7 +322,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/array-flatten": { "version": "1.1.1", @@ -317,7 +334,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/body-parser": { "version": "1.20.2", @@ -347,6 +365,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -383,6 +402,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -425,7 +445,8 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.4", @@ -581,18 +602,19 @@ } }, "node_modules/eslint": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.2.0.tgz", - "integrity": "sha512-0n/I88vZpCOzO+PQpt0lbsqmn9AsnsJAQseIqhZFI8ibQT0U1AkEKRxA3EVMos0BoHSXDQvCXY25TUjB5tr8Og==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.4.0.tgz", + "integrity": "sha512-sjc7Y8cUD1IlwYcTS9qPSvGjAC8Ne9LctpxKKu3x/1IC9bnOg98Zy6GxEJUfr1NojMgVPlyANXYns8oE2c1TAA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^3.0.2", - "@eslint/js": "9.2.0", - "@humanwhocodes/config-array": "^0.13.0", + "@eslint/config-array": "^0.15.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.4.0", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.2.3", + "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", "chalk": "^4.0.0", @@ -652,6 +674,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -687,6 +710,7 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz", "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.11.3", "acorn-jsx": "^5.3.2", @@ -816,13 +840,15 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -1064,6 +1090,7 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -1073,6 +1100,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -1150,13 +1178,15 @@ "node_modules/js-sha256": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz", - "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==" + "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==", + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -1174,7 +1204,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -1286,6 +1317,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1383,6 +1415,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -1459,6 +1492,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1524,6 +1558,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -1711,6 +1746,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -1781,6 +1817,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } diff --git a/backend/package.json b/backend/package.json index 62bf180..136dc91 100644 --- a/backend/package.json +++ b/backend/package.json @@ -7,7 +7,8 @@ "create-db": "node src/create_db.mjs", "test": "node src/index.js", "lint": "eslint . --report-unused-disable-directives --max-warnings 0", - "db-test": "docker run --rm -P -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD='1234' --name pg postgres:alpine" + "db-test": "docker run --rm -P -p 127.0.0.1:5432:5432 -e POSTGRES_PASSWORD='1234' --name pg postgres:alpine", + "prepare": "husky install" }, "author": "", "license": "ISC", @@ -21,7 +22,7 @@ }, "devDependencies": { "@eslint/js": "^9.2.0", - "eslint": "^9.2.0", + "eslint": "^9.3.0", "globals": "^15.1.0" } -} \ No newline at end of file +} diff --git a/backend/src/create_db.mjs b/backend/src/create_db.mjs index 95232f7..2f1ec5d 100644 --- a/backend/src/create_db.mjs +++ b/backend/src/create_db.mjs @@ -1,12 +1,11 @@ -import postgres from "postgres" - -let sql = postgres('postgresql://postgres:1234@localhost:5432') // will use psql environment variables +const postgres = require("postgres"); +let sql = postgres("postgresql://postgres:1234@localhost:5432"); // will use psql environment variables //await sql`drop database test;` -await sql`create database test;` +await sql`create database test;`; -sql = postgres('postgresql://postgres:1234@localhost:5432/test') +sql = postgres("postgresql://postgres:1234@localhost:5432/test"); await sql`CREATE TABLE newsletter ( newsletter_id SERIAL PRIMARY KEY, @@ -17,13 +16,13 @@ await sql`CREATE TABLE newsletter ( length INT, reading_time INT, created_time TIMESTAMP WITH TIME ZONE DEFAULT CAST(TIMEOFDAY() AS TIMESTAMP WITH TIME ZONE) - );` + );`; -await sql`INSERT INTO newsletter (newsletter_title, newsletter_body, tags, author, length, reading_time) VALUES ('Tech Trends', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultricies felis in purus tempus, vitae vestibulum ex tincidunt. Duis rhoncus arcu et urna tempor, at fringilla justo pretium. Integer convallis, eros vitae ultrices pulvinar, urna dui varius dui, id sagittis felis ligula sed justo. Nam tempus turpis et quam sodales vestibulum.', 'technology, trends, coding', 'John Doe', 300, 1);` +await sql`INSERT INTO newsletter (newsletter_title, newsletter_body, tags, author, length, reading_time) VALUES ('Tech Trends', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ultricies felis in purus tempus, vitae vestibulum ex tincidunt. Duis rhoncus arcu et urna tempor, at fringilla justo pretium. Integer convallis, eros vitae ultrices pulvinar, urna dui varius dui, id sagittis felis ligula sed justo. Nam tempus turpis et quam sodales vestibulum.', 'technology, trends, coding', 'John Doe', 300, 1);`; await sql`CREATE TABLE subscriber ( subscriber_id SERIAL PRIMARY KEY, email TEXT, created_time TIMESTAMP WITH TIME ZONE DEFAULT CAST(TIMEOFDAY() AS TIMESTAMP WITH TIME ZONE), is_verified BOOLEAN DEFAULT false -)` +)`; diff --git a/backend/src/db.js b/backend/src/db.js index bbc8dc1..246a969 100644 --- a/backend/src/db.js +++ b/backend/src/db.js @@ -1,19 +1,26 @@ +// // db.js +// const postgres = require("postgres"); +// require("dotenv").config({path : 'DatabaseCreds.env'}); -// db.js -import postgres from 'postgres' +// /* +// SETTING UP DB CONNECTION +// */ -require('dotenv').config() +// const USERNAME = process.env.Db_Username; +// const PASSWORD = process.env.Db_Password; +// const HOST_NAME = process.env.Db_Host; +// const PORT = process.env.Db_Host; +// const DB_NAME = process.env.Db_Database; -/* - SETTING UP DB CONNECTION -*/ +// const sql = postgres( +// `postgres://${USERNAME}:${PASSWORD}@${HOST_NAME}:${PORT}/${DB_NAME}` +// ); -const USERNAME = process.env.USERNAME -const PASSWORD = process.env.PASSWORD -const HOST_NAME = process.env.HOST_NAME -const PORT = process.env.PORT -const DB_NAME = process.env.DB_NAME +// console.log("USERNAME:", USERNAME); +// console.log("PASSWORD:", PASSWORD); +// console.log("HOST_NAME:", HOST_NAME); +// console.log("PORT:", PORT); +// console.log("DB_NAME:", DB_NAME); +// console.log(sql); -const sql = postgres(`postgres://${USERNAME}:${PASSWORD}@${HOST_NAME}:${PORT}/${DB_NAME}`) - -export default sql +// module.exports = sql; diff --git a/backend/src/dbScript.js b/backend/src/dbScript.js index fefec70..4cc3bdf 100644 --- a/backend/src/dbScript.js +++ b/backend/src/dbScript.js @@ -1,30 +1,29 @@ -import sql from './db.js' +const sql = require("./db.js"); -/** - * @createDB function to create db +/* @createDB function to create db * @createEventsTable function to create Events table * @getEvents function to retreive all events * @createEvent function to insert an event record * @params : id,ename,ebody,edesc,etags,time_conducted,room_number,status - * + * * @getEventByName function to get event by its name * @params : name of the event */ async function createDB(name) { - const users = await sql` - CREATE DATABASE ${ name } - ` + await sql` + CREATE DATABASE ${name} + `; } async function createEventsTable() { - //CREATE ENUM TYPE FOR STATUS - await sql` + //CREATE ENUM TYPE FOR STATUS + await sql` CREATE TYPE status_state AS ENUM ('ended','upcoming'); - ` - // CREATE EVENTS TABLE - await sql` + `; + // CREATE EVENTS TABLE + await sql` CREATE TABLE Events( eid INT PRIMARY KEY, ename VARCHAR(255), @@ -38,33 +37,41 @@ async function createEventsTable() { default current_timestamp, updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); - ` - } + `; +} - async function getEvents(){ - const events = await sql` +async function getEvents() { + const events = await sql` select * from events - ` - } + `; + return events; +} - async function getEventById(id){ - const events = await sql` +async function getEventById(id) { + const events = await sql` select * from events where eid = ${id} - ` - } + `; + return events; +} - async function createEvent(event){ - // INSERT ROW INTO EVENTS +async function createEvent(event) { + // INSERT ROW INTO EVENTS - // Destructuring the events object - const {id,ename,ebody,edesc,etags,time_conducted,room_number,status} = event; + // Destructuring the events object + const { + id, + ename, + ebody, + edesc, + etags, + time_conducted, + room_number, + status, + } = event; - await sql ` + await sql` insert into Events values(${id},${ename},${ebody},${edesc},${etags},${time_conducted},${room_number},${status}) - ` - } - - module.exports = {getEvents,getEventById,createEvent} - - + `; +} +module.exports = {createDB , createEventsTable, getEvents, getEventById, createEvent }; diff --git a/backend/src/events/endpoints/data.js b/backend/src/events/endpoints/data.js index 4aefdc0..3c2e562 100644 --- a/backend/src/events/endpoints/data.js +++ b/backend/src/events/endpoints/data.js @@ -11,28 +11,26 @@ var jsonParser = bodyParser.json() router.get('/', auth, async (req, res) => { let result = await getEvents(); - res.send('message':'events fetched', 'data': result }); + res.send({'message' : 'events fetched', 'data': result}); }) router.get('/:eventId', auth, async (req, res) => { let id = req.params.eventId; - const result = await getEventById(); + const result = await getEventById(id); res.send({ 'message': 'event fetched', 'data': result }) }) router.post('/', jsonParser, auth, async (req, res) => { let event = req.body; - let result = await createEvent(event); - res.send({ 'message': 'event inserted', 'data': result }) }) router.put('/:eventId', auth, jsonParser, async (req, res) => { let id = req.params.eventId; - let event = req.body; + //let event = req.body; - let result = await sql`update newsletter set ${sql(newsletter, 'newsletter_title', 'newsletter_body', 'tags', 'author', 'length', 'reading_time') + let result = await sql`update newsletter set ${sql('newsletter', 'newsletter_title', 'newsletter_body', 'tags', 'author', 'length', 'reading_time') } where newsletter_id = ${id} returning *` diff --git a/backend/src/index.js b/backend/src/index.js index fd1c040..3421625 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -3,14 +3,19 @@ require('dotenv').config() const express = require('express') -const newsletter = require('./newsletter/endpoints/data.js') -const subscription = require('./newsletter/endpoints/subscription.js') +// const newsletter = require("./newsletter/endpoints/data.js"); +// const subscription = require("./newsletter/endpoints/subscription.js"); -const app = express() -const port = 3000 +//verifying endpoints for projects +const projects = require("./projects/endpoints/data.js"); -app.use('/newsletters', newsletter) -app.use('/subscriptions', subscription) +const app = express(); +const port = 3000; + +app.use("/projects", projects); + +// app.use("/newsletters", newsletter); +// app.use("/subscriptions", subscription); app.get('/', (req, res) => { res.send('Hello World!'); diff --git a/backend/src/middleware/api_keys.env b/backend/src/middleware/api_keys.env new file mode 100644 index 0000000..863ac9e --- /dev/null +++ b/backend/src/middleware/api_keys.env @@ -0,0 +1 @@ +API_KEY = abcdefg12345679 \ No newline at end of file diff --git a/backend/src/middleware/auth.js b/backend/src/middleware/auth.js index 1f2ca15..27115d7 100644 --- a/backend/src/middleware/auth.js +++ b/backend/src/middleware/auth.js @@ -1,10 +1,23 @@ -var sha256 = require('js-sha256'); +const sha256 = require("js-sha256"); +const dotenv = require("dotenv"); +const path = require('path') + +// Load environment variables from the new .env file +dotenv.config({ path: path.join(__dirname, "api_keys.env") }); module.exports = function (req, res, next) { - if (sha256(process.env.api_key) === req.headers.authorization) { - next() - } else { - let error = new Error("Unauthorized.") - next(error) - } -} \ No newline at end of file + const apiKey = process.env.API_KEY; + + console.log("API Key from Environment:", apiKey); + console.log("Authorization Header:", req.headers.authorization); + if (!apiKey) { + return next(new Error("NO Api Key set")); + } + + if (sha256(apiKey) === req.headers.authorization) { + next(); + } else { + let error = new Error("Unauthorized."); + next(error); + } +}; diff --git a/backend/src/projects.js b/backend/src/projects.js new file mode 100644 index 0000000..4b1a992 --- /dev/null +++ b/backend/src/projects.js @@ -0,0 +1,126 @@ +const postgres = require("postgres"); +let sql = postgres("postgresql://postgres:rudy123@localhost:5432/test"); + +/* +The following file contains the code to +assemble the projects table, display functions and functions to +perform CRUD Operations + */ + +async function addProjectsTable() { + try { + // Drop the Projects table if it exists and other dependencies + await sql` + DROP TABLE IF EXISTS Projects CASCADE; + `; + + // Drop the ENUM type if it exists + await sql` + DROP TYPE IF EXISTS project_status; + `; + + // Create ENUM for project status + await sql` + CREATE TYPE project_status AS ENUM('Hiring', 'Completed', 'Ongoing'); + `; + + // Create the Projects table + await sql` + CREATE TABLE Projects ( + id SERIAL PRIMARY KEY, + name VARCHAR(50), + body VARCHAR(200), + description VARCHAR(200), + tags VARCHAR(200), + status project_status, + created_date DATE, + last_modified TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP + ); + `; + + await sql` + CREATE OR REPLACE FUNCTION update_last_modified() + RETURNS trigger + LANGUAGE 'plpgsql' + AS $$ + BEGIN + NEW.last_modified = CURRENT_TIMESTAMP; + RETURN NEW; + END; + $$; + `; + await sql` + CREATE OR REPLACE TRIGGER trigger_update_last_modified + BEFORE UPDATE + ON Projects + FOR EACH ROW + EXECUTE FUNCTION update_last_modified(); + `; + console.log("Table Created"); + + //Inserting dummy data to ensure working + await sql` + INSERT INTO Projects (id, name, body, description, tags, status, created_date, last_modified) + VALUES ( + ${1001}, + ${"Tech Club Website"}, + ${"Official Website of UOWD Tech Club"}, + ${"-"}, + ${"Web Development"}, + ${"Ongoing"}, + ${"2024-04-19"}, + NOW() + ); + `; + } catch (err) { + console.error("Error creating table:", err); + } +} + +addProjectsTable(); + +async function createProject(projects) { + const { + id, + name, + body, + description, + tags, + status, + created_date, + last_modified, + } = projects; + + try { + await sql` + INSERT INTO Projects (id, name, body, description, tags, status, created_date, last_modified) + VALUES (${id}, ${name}, ${body}, ${description}, ${tags}, ${status}, ${created_date}, ${last_modified}); + `; + } catch (err) { + console.error("Error creating project:", err); + } +} + +async function fetchProjects() { + try { + const projects = await sql` + SELECT * FROM Projects; + `; + return projects; + } catch (err) { + console.error("Error fetching projects:", err); + } +} + +async function fetchProjectsByID(id) { + try { + const project = await sql` + SELECT * FROM Projects WHERE id = ${id}; + `; + return project[0]; + } catch (err) { + console.error("Error fetching project by ID:", err); + } +} + +module.exports = { createProject, fetchProjects, fetchProjectsByID }; diff --git a/backend/src/projects/endpoints/data.js b/backend/src/projects/endpoints/data.js new file mode 100644 index 0000000..83ed632 --- /dev/null +++ b/backend/src/projects/endpoints/data.js @@ -0,0 +1,33 @@ +const { + createProject, + fetchProjects, + fetchProjectsByID, +} = require("../../projects.js"); + +//const auth = require("../../middleware/auth.js"); + +var bodyParser = require("body-parser"); +var jsonParser = bodyParser.json(); + +const router = require("express-promise-router")(); + +router.get("/", async (req, res) => { + let result = await fetchProjects(); + console.log("Authorization Header:", req.headers.authorization); + res.status(200); + res.send({ message: "Projects fetched", data: result }); +}); + +router.get("/:projectId", async (req, res) => { + let id = req.params.projectId; + const result = await fetchProjectsByID(id); + res.send({ message: "Project fetched", data: result }); +}); + +router.post("/", jsonParser, async (req, res) => { + let project = req.body; + let result = await createProject(project); + res.send({ message: "Project added", data: result }); +}); + +module.exports = router;