From c7b7544c35a6e67fef2b0101423019db596ec3b4 Mon Sep 17 00:00:00 2001 From: Filip Prosovsky Date: Wed, 30 Sep 2020 22:39:54 +0000 Subject: [PATCH 1/4] code rewritten to pg-promise --- db-cheatsheet | 2 +- helpers/db-connection.js | 15 --- helpers/db.js | 15 +++ models/articles.js | 88 ++++++--------- models/comments.js | 5 +- models/likes.js | 5 +- models/login.js | 20 +--- models/signup.js | 29 +---- package-lock.json | 235 ++++++--------------------------------- package.json | 5 +- routes/articles.js | 14 ++- 11 files changed, 107 insertions(+), 326 deletions(-) delete mode 100644 helpers/db-connection.js create mode 100644 helpers/db.js diff --git a/db-cheatsheet b/db-cheatsheet index f862191..13fc834 100644 --- a/db-cheatsheet +++ b/db-cheatsheet @@ -1,7 +1,7 @@ INSERT INTO users (username,password,passwordsalt,email) VALUES('usertest','testpass','testpasssalt','test@test.com'); INSERT INTO categories (name) VALUES('testCategory'); -SELECT returns undefined or object +SELECT returns results.rows all rows as objects INSERT returns array [0 = inserted data, 1 = affected rows] Delete return object UPDATE returns array [0 = inserted data, 1 = affected rows] diff --git a/helpers/db-connection.js b/helpers/db-connection.js deleted file mode 100644 index 38b02c2..0000000 --- a/helpers/db-connection.js +++ /dev/null @@ -1,15 +0,0 @@ -require('dotenv').config(); -const Sequelize = require('sequelize'); - - var host= process.env.host; - var user= process.env.user; - var password= process.env.password; - var database= process.env.database; - -// connection -const sequelize = new Sequelize(database, user, password, { - host: host, - dialect: 'postgres', -}); - -module.exports = sequelize; \ No newline at end of file diff --git a/helpers/db.js b/helpers/db.js new file mode 100644 index 0000000..a56c70d --- /dev/null +++ b/helpers/db.js @@ -0,0 +1,15 @@ +require('dotenv').config(); + +const pgp = require('pg-promise')(/* initialization options */); + +const cn = { + host: process.env.host, + port: 5432, + database: process.env.database, + user: process.env.user, + password: process.env.password +}; +const db = pgp(cn); // database instance; + + +module.exports = db; \ No newline at end of file diff --git a/models/articles.js b/models/articles.js index e3fc511..fe4e3e4 100644 --- a/models/articles.js +++ b/models/articles.js @@ -1,37 +1,31 @@ -// DB connection specification + sequelize drive, do db.query to procees with query -const db = require('../helpers/db-connection.js') -const Sequelize = require('sequelize'); +// pg DB connection from config file /helpers/db.js,, automatically converts to JSON on output with result.rows +const db = require('../helpers/db.js') // query to list all LIKED articles for specific user // SELECT * FROM articles INNER JOIN likes l on articles.id = l.article_id // INNER JOIN users u on u.id = l.user_id WHERE u.id=28; exports.getAll = async function getAll() { - let results = await db.query('SELECT *, views FROM articles, views WHERE views.id = articles.id \ - ORDER BY "modifiedDate" DESC;', { - type: Sequelize.QueryTypes.SELECT, - raw: true, - returning: true, - logging: false - }) + let sql = 'SELECT *, views FROM articles, views WHERE views.id = articles.id \ + ORDER BY "modifiedDate" DESC;' + let results = await db.query(sql) .then(results => { return results - }); + }) + .catch(e => console.error(e.stack)) return results; } exports.getById = async function getById(id) { - let result = await db.query('SELECT * FROM articles INNER JOIN views ON views.id = articles.id \ - WHERE articles.id=' + id + '; \ - UPDATE views SET views = views + 1 WHERE id =' + id + ';', { - type: Sequelize.QueryTypes.SELECT, - raw: true, - logging: false, - returning: true - }) - .then(result => { + let sql = 'SELECT * FROM articles INNER JOIN views ON views.id = articles.id \ + WHERE articles.id='+id+';'; + let result = await db.query(sql) + .then(async result => { + let sql='UPDATE views SET views = views + 1 WHERE id = '+id+';'; + await db.query(sql) return result - }); + }) + .catch(e => console.error(e.stack)) return result } @@ -39,21 +33,19 @@ exports.getById = async function getById(id) { exports.createArticle = async function createArticle(newArticle) { let keys = Object.keys(newArticle) let values = Object.values(newArticle) - keysQuoted = keys.map(q => `"${q}"`); + console.log(keys) + console.log(values) + let keysQuoted = keys.map(q => `"${q}"`); + let valuesQuoted = values.map(q => `'${q}'`); if ((keys != null) && (values != null)) { - let sql = `WITH articles AS (INSERT INTO articles (`+keysQuoted+`) VALUES(:values) RETURNING *), \ - views AS (INSERT INTO views (id) SELECT id FROM articles RETURNING *) \ - SELECT articles.*, views.views FROM articles, views WHERE views.id = articles.id;`; - let obj = await db.query(sql, { - raw: true, - replacements: { values: values }, - returning: true, - logging: false, - type: Sequelize.QueryTypes.INSERT - }) + let sql = `WITH articles AS (INSERT INTO articles(`+keysQuoted+`) VALUES(`+valuesQuoted+`) RETURNING *), \ + views AS (INSERT INTO views(id) SELECT id FROM articles RETURNING *) \ + SELECT articles.*, views.views FROM articles, views WHERE views.id = articles.id;`; + let obj = await db.query(sql) .then(obj => { return obj - }); + }) + .catch(e => console.error(e.stack)) return obj } } @@ -61,20 +53,16 @@ exports.createArticle = async function createArticle(newArticle) { exports.updateArticle = async function updateArticle(id, updatedArticle) { let keys = Object.keys(updatedArticle) let values = Object.values(updatedArticle) - keysQuoted = keys.map(q => `"${q}"`); + let keysQuoted = keys.map(q => `"${q}"`); + let valuesQuoted = values.map(q => `'${q}'`); let i = 0; for (i; i < keys.length; i++) { - let sql = `UPDATE articles SET `+keysQuoted[i]+`=:values WHERE id=`+ id +' RETURNING *;'; - var obj = await db.query(sql, { - raw: true, - replacements: { values: values[i] }, - returning: true, - logging: false, - type: Sequelize.QueryTypes.UPDATE - }) + let sql = `UPDATE articles SET `+keysQuoted[i]+`=`+valuesQuoted[i]+` WHERE id=`+ id +' RETURNING *;'; + var obj = await db.query(sql) .then(obj => { - return obj; - }); + return obj + }) + .catch(e => console.error(e.stack)) } return obj; } @@ -82,15 +70,11 @@ exports.updateArticle = async function updateArticle(id, updatedArticle) { exports.deleteArticle = async function deleteArticle(id) { let sql = 'DELETE FROM views WHERE id='+id+'; \ DELETE FROM articles WHERE id='+id+' RETURNING title;'; - let obj = await db.query(sql, { - returning: true, - raw: true, - logging: false, - type: Sequelize.QueryTypes.DELETE - }) + let obj = await db.query(sql) .then(obj => { - return obj; - }); + return obj + }) + .catch(e => console.error(e.stack)) return obj; } diff --git a/models/comments.js b/models/comments.js index ede69ab..42a8f42 100644 --- a/models/comments.js +++ b/models/comments.js @@ -1,6 +1,5 @@ -// DB connection specification + sequelize drive, do db.query to procees with query -const db = require('../helpers/db-connection.js') -const Sequelize = require('sequelize'); +// pg DB connection from config file /helpers/db.js +const db = require('../helpers/db.js') exports.getComments = async function getComments(articleId) { diff --git a/models/likes.js b/models/likes.js index acc309c..702d4fe 100644 --- a/models/likes.js +++ b/models/likes.js @@ -1,6 +1,5 @@ -// DB connection specification + sequelize drive, do db.query to procees with query -const db = require('../helpers/db-connection.js') -const Sequelize = require('sequelize'); +// pg DB connection from config file /helpers/db.js +const db = require('../helpers/db.js') exports.addLike = async function addLike(articleId, userId) { let sql = 'INSERT INTO likes (article_id, user_id) \ diff --git a/models/login.js b/models/login.js index 7025d16..e6cd70a 100644 --- a/models/login.js +++ b/models/login.js @@ -1,16 +1,10 @@ -const db = require('../helpers/db-connection.js'); -const Sequelize = require('sequelize'); +// pg DB connection from config file /helpers/db.js +const db = require('../helpers/db.js') const bcrypt = require('bcrypt'); exports.getUsername = async function getUsername(login) { - let username = await db.query('SELECT username FROM users WHERE username = :login;', { - type: Sequelize.QueryTypes.SELECT, - replacements: {login: login}, - raw: true, - returning: true, - logging: false - }) + let username = await db.query('SELECT username FROM users WHERE username =$1;', login) .then(username => { return username }); @@ -27,13 +21,7 @@ exports.compareSecret = async function compareSecret(secret, hash) { // updated exports.getLoginData = async function getLoginData(login) { - let loginData = await db.query('SELECT username,password FROM users WHERE username = :login;', { - type: Sequelize.QueryTypes.SELECT, - replacements: {login: login}, - raw: true, - returning: true, - logging: false - }) + let loginData = await db.query('SELECT username,password FROM users WHERE username =$1;', login) .then(loginData => { return { username: loginData[0].username, diff --git a/models/signup.js b/models/signup.js index e458db8..c500cff 100644 --- a/models/signup.js +++ b/models/signup.js @@ -1,16 +1,10 @@ -const db = require('../helpers/db-connection.js') -const Sequelize = require('sequelize'); +// pg DB connection from config file /helpers/db.js +const db = require('../helpers/db.js') const bcrypt = require('bcrypt'); exports.getUsername = async function getUsername(login) { - let username = await db.query('SELECT username FROM users WHERE username = :login;', { - type: Sequelize.QueryTypes.SELECT, - replacements: {login: login}, - raw: true, - returning: true, - logging: false - }) + let username = await db.query('SELECT username FROM users WHERE username = $1;', login) .then(username => { return username }); @@ -18,13 +12,7 @@ exports.getUsername = async function getUsername(login) { } exports.getEmail = async function getEmail(email) { - let eMail = await db.query('SELECT email FROM users WHERE email = :email;', { - type: Sequelize.QueryTypes.SELECT, - replacements: {email: email}, - raw: true, - returning: true, - logging: false - }) + let eMail = await db.query('SELECT email FROM users WHERE email = $1;', email) .then(eMail => { return eMail }); @@ -34,13 +22,8 @@ exports.getEmail = async function getEmail(email) { exports.signupUser = async function signupUser(userdata) { let keys = Object.keys(userdata) let values = Object.values(userdata) - await db.query('INSERT INTO users ('+keys+') VALUES(:values);', { - type: Sequelize.QueryTypes.INSERT, - replacements: {values: values}, - raw: true, - returning: false, - logging: false - }) + let valuesQuoted = values.map(q => `'${q}'`); + await db.query('INSERT INTO users ('+keys+') VALUES('+valuesQuoted+');') } exports.validateEmail = async function validateEmail(email) { diff --git a/package-lock.json b/package-lock.json index ad7dcc5..9bc23d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,11 +22,6 @@ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, - "@types/node": { - "version": "14.11.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz", - "integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==" - }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -130,6 +125,11 @@ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", "optional": true }, + "assert-options": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.6.2.tgz", + "integrity": "sha512-KP9S549XptFAPGYmLRnIjQBL4/Ry8Jx5YNLQZ/l+eejqbTidBMnw4uZSAsUrzBq/lgyqDYqxcTF7cOxZb9gyEw==" + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -1932,11 +1932,6 @@ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, - "denque": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", - "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -1973,11 +1968,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" }, - "dottie": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", - "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==" - }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -2231,14 +2221,6 @@ } } }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "requires": { - "is-property": "^1.0.2" - } - }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -2538,11 +2520,6 @@ "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.0.0.tgz", "integrity": "sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8=" }, - "inflection": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", - "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2736,11 +2713,6 @@ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "optional": true }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -2978,11 +2950,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2996,14 +2963,6 @@ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -3192,19 +3151,6 @@ "minimist": "^1.2.5" } }, - "moment": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.0.tgz", - "integrity": "sha512-z6IJ5HXYiuxvFTI6eiQ9dm77uE0gyy1yXNApVHqTcnIKfY9tIwEjlzsZ6u1LQXvVgKeTnv9Xm7NDvJ7lso3MtA==" - }, - "moment-timezone": { - "version": "0.5.31", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.31.tgz", - "integrity": "sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA==", - "requires": { - "moment": ">= 2.9.0" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -3221,60 +3167,6 @@ "sqlstring": "2.3.1" } }, - "mysql2": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-2.2.5.tgz", - "integrity": "sha512-XRqPNxcZTpmFdXbJqb+/CtYVLCx14x1RTeNMD4954L331APu75IC74GDqnZMEt1kwaXy6TySo55rF2F3YJS78g==", - "requires": { - "denque": "^1.4.1", - "generate-function": "^2.3.1", - "iconv-lite": "^0.6.2", - "long": "^4.0.0", - "lru-cache": "^6.0.0", - "named-placeholders": "^1.1.2", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", - "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "sqlstring": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz", - "integrity": "sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==" - } - } - }, - "named-placeholders": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.2.tgz", - "integrity": "sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==", - "requires": { - "lru-cache": "^4.1.3" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -3349,6 +3241,11 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.2.tgz", "integrity": "sha512-+D4s2HCnxPd5PjjI0STKwncjXTUKKqm74MDMz9OPXavjsGmjkvwgLtA5yoxJUdmpj52+2u+RrXgPipahKczMKg==" }, + "node-postgres": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/node-postgres/-/node-postgres-0.6.2.tgz", + "integrity": "sha512-wjaW+KutPOFemtBDuogyy6OMMOs2vpSOwuqbUhFUbrDEOTk66K2lmRyvOdO4t26qGtnPyZXQ4bAuF17cBhi5aQ==" + }, "node-pre-gyp": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", @@ -3705,11 +3602,27 @@ "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" }, + "pg-minify": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.1.tgz", + "integrity": "sha512-ujanxJJB9CSDUvlAOshtjdKAywOPR2vY0a7D+vvgk5rbrYcthZA7TjpN+Z+UwZsz/G/bUexYDT6huE33vYVN0g==" + }, "pg-pool": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" }, + "pg-promise": { + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.6.1.tgz", + "integrity": "sha512-Ahde0/04RmEPwryMcDV8ya4XXjfNWD44EuckgFPFQOIX/3smZS2ygeSXPEy4DmDxoSkSF6Y6vK8Bc4fN+bYMxg==", + "requires": { + "assert-options": "0.6.2", + "pg": "8.3.3", + "pg-minify": "1.6.1", + "spex": "3.0.2" + } + }, "pg-protocol": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.2.5.tgz", @@ -3790,11 +3703,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, "pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -4036,14 +3944,6 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "optional": true }, - "retry-as-promised": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", - "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", - "requires": { - "any-promise": "^1.3.0" - } - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -4096,56 +3996,6 @@ } } }, - "seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4=" - }, - "sequelize": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.3.5.tgz", - "integrity": "sha512-MiwiPkYSA8NWttRKAXdU9h0TxP6HAc1fl7qZmMO/VQqQOND83G4nZLXd0kWILtAoT9cxtZgFqeb/MPYgEeXwsw==", - "requires": { - "debug": "^4.1.1", - "dottie": "^2.0.0", - "inflection": "1.12.0", - "lodash": "^4.17.15", - "moment": "^2.26.0", - "moment-timezone": "^0.5.31", - "retry-as-promised": "^3.2.0", - "semver": "^7.3.2", - "sequelize-pool": "^6.0.0", - "toposort-class": "^1.0.1", - "uuid": "^8.1.0", - "validator": "^10.11.0", - "wkx": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" - } - } - }, - "sequelize-pool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz", - "integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==" - }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -4338,6 +4188,11 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "optional": true }, + "spex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spex/-/spex-3.0.2.tgz", + "integrity": "sha512-ZNCrOso+oNv5P01HCO4wuxV9Og5rS6ms7gGAqugfBPjx1QwfNXJI3T02ldfaap1O0dlT1sB0Rk+mhDqxt3Z27w==" + }, "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", @@ -4525,11 +4380,6 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, - "toposort-class": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", - "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" - }, "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", @@ -4714,11 +4564,6 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==" - }, "v8flags": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", @@ -4727,11 +4572,6 @@ "user-home": "^1.1.1" } }, - "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -4777,14 +4617,6 @@ "string-width": "^4.0.0" } }, - "wkx": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", - "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", - "requires": { - "@types/node": "*" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4811,11 +4643,6 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "ylru": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz", diff --git a/package.json b/package.json index 1dc03a0..fc1efb9 100644 --- a/package.json +++ b/package.json @@ -25,11 +25,10 @@ "koa-bodyparser": "^4.3.0", "koa-mysql": "^1.0.3", "koa-router": "^9.4.0", - "mysql": "^2.18.1", - "mysql2": "^2.2.5", + "node-postgres": "^0.6.2", "nodemon": "^2.0.4", "pg": "^8.3.3", "pg-hstore": "^2.3.3", - "sequelize": "^6.3.5" + "pg-promise": "^10.6.1" } } diff --git a/routes/articles.js b/routes/articles.js index 1f8982d..c1ccea0 100644 --- a/routes/articles.js +++ b/routes/articles.js @@ -19,9 +19,10 @@ router.del('/:id([0-9]{1,})', deleteArticle); // Function to get all articles async function getAll(ctx, next) { results = await service.getAll(); + console.log(results) if ((results != null) && (results.length > 0)) { ctx.status = 200; - ctx.body = JSON.parse(JSON.stringify(results)); + ctx.body = results; } else { ctx.status = 404; @@ -34,6 +35,7 @@ async function getById(ctx, next) { let id = ctx.params.id; if ((id > 0) && (id != NaN)) { let result = await service.getById(id); + console.log(result) if ((result != null) && (result.length > 0)) { ctx.status = 200; ctx.body = JSON.parse(JSON.stringify(result)); @@ -53,10 +55,10 @@ async function getById(ctx, next) { // Function to create article --- needs to be handled async function createArticle(ctx, next) { let newArticle = ctx.request.body; - try { + try { let obj = await service.createArticle(newArticle); ctx.status = 201; - ctx.body = JSON.parse(JSON.stringify(obj[0])); + ctx.body = obj; } catch(e) { ctx.status = 400; @@ -69,12 +71,12 @@ async function updateArticle(ctx, next) { let id = ctx.params.id; let updatedArticle = ctx.request.body; if (id > 0) { - try { + try { var returnedObj = await service.getById(id); if ((returnedObj != null) && (returnedObj.length > 0)) { let obj = await service.updateArticle(id, updatedArticle); ctx.status = 201; - ctx.body = JSON.parse(JSON.stringify(obj[0])); + ctx.body = obj[0]; } else { ctx.status = 404; @@ -101,7 +103,7 @@ async function deleteArticle(ctx, next) { if ((result.length > 0) && (result != null)) { let obj = await service.deleteArticle(id); //check the article - ctx.body = JSON.parse(JSON.stringify(obj)); + ctx.body = obj[0]; ctx.status = 201; } else { From c3b2720a13f3dab410ea487fc303efa441b9e340 Mon Sep 17 00:00:00 2001 From: Filip Prosovsky Date: Thu, 1 Oct 2020 16:26:06 +0000 Subject: [PATCH 2/4] fully migrated to pg-promise --- index.js | 2 ++ models/articles.js | 2 -- models/comments.js | 45 ++++++++++-------------------------------- models/likes.js | 28 ++++---------------------- package-lock.json | 49 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + routes/comments.js | 16 +++++++-------- routes/likes.js | 17 +++++++--------- 8 files changed, 81 insertions(+), 79 deletions(-) diff --git a/index.js b/index.js index c276ee0..995f814 100644 --- a/index.js +++ b/index.js @@ -11,6 +11,8 @@ const likes = require('./routes/likes.js'); + + const app = new Koa(); const router = new Router(); diff --git a/models/articles.js b/models/articles.js index fe4e3e4..a2caa08 100644 --- a/models/articles.js +++ b/models/articles.js @@ -33,8 +33,6 @@ exports.getById = async function getById(id) { exports.createArticle = async function createArticle(newArticle) { let keys = Object.keys(newArticle) let values = Object.values(newArticle) - console.log(keys) - console.log(values) let keysQuoted = keys.map(q => `"${q}"`); let valuesQuoted = values.map(q => `'${q}'`); if ((keys != null) && (values != null)) { diff --git a/models/comments.js b/models/comments.js index 42a8f42..7867f35 100644 --- a/models/comments.js +++ b/models/comments.js @@ -4,12 +4,7 @@ const db = require('../helpers/db.js') exports.getComments = async function getComments(articleId) { let result = await db.query('SELECT comments.*, articles.id FROM comments,articles \ - WHERE (comments.article_id=articles.id) AND (articles.id='+articleId+') ORDER BY comments."modifiedDate";', { - type: Sequelize.QueryTypes.SELECT, - raw: true, - logging: false, - returning: true - }) + WHERE (comments.article_id=articles.id) AND (articles.id='+articleId+') ORDER BY comments."modifiedDate";') .then(result => { return result }); @@ -20,16 +15,11 @@ exports.addComment = async function addComment(newComment, articleId, userId) { let keys = Object.keys(newComment) let values = Object.values(newComment) keysQuoted = keys.map(q => `"${q}"`); + valuesQuoted = values.map(q => `'${q}'`); if ((keys != null) && (values != null)) { let sql = `INSERT INTO comments (`+keysQuoted+`, article_id, user_id) \ - VALUES(:values, :article_id, :user_id) RETURNING *;`; - let obj = await db.query(sql, { - raw: true, - replacements: { values: values, article_id: articleId, user_id: userId }, - returning: true, - logging: console.log, - type: Sequelize.QueryTypes.INSERT - }) + VALUES(`+valuesQuoted+`, `+articleId+`, `+userId+`) RETURNING *;`; + let obj = await db.query(sql) .then(obj => { return obj }); @@ -41,19 +31,14 @@ exports.updateComment = async function updateComment(commentId, userId, updatedC let keys = Object.keys(updatedComment) let values = Object.values(updatedComment) keysQuoted = keys.map(q => `"${q}"`); + valuesQuoted = values.map(q => `'${q}'`); let i = 0; for (i; i < keys.length; i++) { - let sql = `UPDATE comments SET `+keysQuoted[i]+`=:values \ + let sql = `UPDATE comments SET `+keysQuoted[i]+`=`+valuesQuoted[i]+` \ WHERE (id=`+ commentId +') AND (user_id='+userId+') RETURNING *;'; - var obj = await db.query(sql, { - raw: true, - replacements: { values: values[i] }, - returning: true, - logging: console.log, - type: Sequelize.QueryTypes.UPDATE - }) + var obj = await db.query(sql) .then(obj => { - return obj; + return obj }); } return obj; @@ -61,12 +46,7 @@ exports.updateComment = async function updateComment(commentId, userId, updatedC exports.deleteComment = async function deleteComment(commentId,userId) { let sql = 'DELETE FROM comments WHERE (id='+commentId+') AND (user_id='+userId+');'; - let obj = await db.query(sql, { - returning: true, - raw: true, - logging: false, - type: Sequelize.QueryTypes.DELETE - }) + let obj = await db.query(sql) .then(obj => { return obj; }); @@ -76,12 +56,7 @@ exports.deleteComment = async function deleteComment(commentId,userId) { exports.checkCommentOwner = async function checkCommentOwner(commentId,userId) { let sql = 'SELECT id, user_id FROM comments \ WHERE (user_id='+userId+') AND (id='+commentId+');'; - let obj = await db.query(sql, { - type: Sequelize.QueryTypes.SELECT, - raw: true, - logging: false, - returning: true - }) + let obj = await db.query(sql) .then(obj => { return obj }); diff --git a/models/likes.js b/models/likes.js index 702d4fe..d8b57d4 100644 --- a/models/likes.js +++ b/models/likes.js @@ -6,12 +6,7 @@ exports.addLike = async function addLike(articleId, userId) { SELECT articles.id, users.id \ FROM (SELECT id FROM articles WHERE id='+articleId+') articles \ , (SELECT id FROM users WHERE id='+userId+') users;' - var obj = await db.query(sql, { - raw: true, - returning: true, - logging: console.log, - type: Sequelize.QueryTypes.INSERT - }) + var obj = await db.query(sql) .then(obj => { return obj; }); @@ -20,12 +15,7 @@ exports.addLike = async function addLike(articleId, userId) { exports.checkLike = async function checkLike(articleId,userId) { let sql = 'SELECT user_id,article_id FROM likes WHERE (article_id='+articleId+') AND user_id='+userId+';'; - var obj = await db.query(sql, { - raw: true, - returning: true, - logging: console.log, - type: Sequelize.QueryTypes.SELECT - }) + var obj = await db.query(sql) .then(obj => { return obj; }); @@ -36,12 +26,7 @@ return obj; exports.checkUser = async function checkUser(userId) { let sql = 'SELECT id FROM users WHERE id='+userId+';'; - var obj = await db.query(sql, { - raw: true, - returning: true, - logging: console.log, - type: Sequelize.QueryTypes.SELECT - }) + var obj = await db.query(sql) .then(obj => { return obj; }); @@ -50,12 +35,7 @@ return obj; exports.removeLike = async function removeLike(articleId, userId) { let sql = 'DELETE FROM likes WHERE article_id='+articleId+' AND user_id='+userId+' RETURNING true;' - var obj = await db.query(sql, { - raw: true, - returning: true, - logging: false, - type: Sequelize.QueryTypes.DELETE - }) + var obj = await db.query(sql) .then(obj => { return obj; }); diff --git a/package-lock.json b/package-lock.json index 9bc23d7..3f11c9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2460,6 +2460,11 @@ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, + "http-content-range-format": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/http-content-range-format/-/http-content-range-format-1.0.0.tgz", + "integrity": "sha1-H6KFHyTSl1da96FIjWPeAuS4Q3g=" + }, "http-errors": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.0.tgz", @@ -2910,6 +2915,32 @@ } } }, + "koa-pagination": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/koa-pagination/-/koa-pagination-4.0.0.tgz", + "integrity": "sha512-sFBC7gny11D+8S5GYZwSskmrY9Wa8QCvbgB+XvEn8mtl3P5eNbjqaUlh+3mxcJ5s3xdqc2zf2jz0XuRa8OGa8g==", + "requires": { + "debug": "^4.1.1", + "http-content-range-format": "^1.0.0", + "range-specifier-parser": "^1.0.2", + "standard-http-error": "^2.0.1" + }, + "dependencies": { + "debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "koa-router": { "version": "9.4.0", "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-9.4.0.tgz", @@ -3755,6 +3786,11 @@ } } }, + "range-specifier-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/range-specifier-parser/-/range-specifier-parser-1.0.2.tgz", + "integrity": "sha1-rYm3+vclg4ywyr/psJtoN8EAAsg=" + }, "raw-body": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", @@ -4215,6 +4251,19 @@ "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" }, + "standard-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/standard-error/-/standard-error-1.1.0.tgz", + "integrity": "sha1-I+UWj6HAggGJ5YEnAaeQWFENDTQ=" + }, + "standard-http-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/standard-http-error/-/standard-http-error-2.0.1.tgz", + "integrity": "sha1-+K6RcuPO+cs40ucIShkl9Xp8NL0=", + "requires": { + "standard-error": ">= 1.1.0 < 2" + } + }, "static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", diff --git a/package.json b/package.json index fc1efb9..ab7dc85 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "koa": "^2.13.0", "koa-bodyparser": "^4.3.0", "koa-mysql": "^1.0.3", + "koa-pagination": "^4.0.0", "koa-router": "^9.4.0", "node-postgres": "^0.6.2", "nodemon": "^2.0.4", diff --git a/routes/comments.js b/routes/comments.js index 7d1b28d..97e4537 100644 --- a/routes/comments.js +++ b/routes/comments.js @@ -36,12 +36,12 @@ async function addComment(ctx, next) { let newComment = ctx.request.body; let articleId = ctx.params.id; let userId = uId.userId // will get based on session, now specified by query - try { + try { let obj = await service.addComment(newComment, articleId, userId); ctx.status = 201; ctx.body = JSON.parse(JSON.stringify(obj[0])); - } - catch(e) { + } + catch(e) { ctx.status = 400; ctx.body = 'You submitted wrong values or you missing some, please check and try again'; } @@ -53,13 +53,12 @@ async function updateComment(ctx, next) { let updatedComment = ctx.request.body; let userId = uId.userId // will get based on session, now specified by query if (commentId > 0) { - try { + try { var check = await service.checkCommentOwner(commentId,userId); - console.log(check[0]) - if (typeof check[0] !== "undefined") { + if (typeof check !== "undefined") { let obj = await service.updateComment(commentId, userId, updatedComment); ctx.status = 201; - ctx.body = JSON.parse(JSON.stringify(obj[0])); + ctx.body = obj; } else { ctx.status = 404; @@ -84,7 +83,8 @@ async function deleteComment(ctx, next) { let userId = uId.userId // will get based on session, now specified by query if ((commentId > 0) && (commentId != NaN)) { let check = await service.checkCommentOwner(commentId,userId); - if (typeof check[0] !== "undefined") { + console.log(check) + if (typeof check !== "undefined") { await service.deleteComment(commentId,userId); ctx.body = 'Comment was deleted'; ctx.status = 201; diff --git a/routes/likes.js b/routes/likes.js index 64746e9..0e5d6d3 100644 --- a/routes/likes.js +++ b/routes/likes.js @@ -16,12 +16,11 @@ async function addLike(ctx, next) { let checkArticle = await articles.getById(articleId); // temp check as it will be checked with logon session let checkUser = await service.checkUser(userId); - if (typeof checkArticle[0] !== "undefined") { - if (typeof checkUser[0] !== "undefined") { + if (typeof checkArticle !== "undefined") { + if (typeof checkUser !== "undefined") { try { let check = await service.checkLike(articleId, userId); - console.log(check[0]) - if (typeof check[0] === "undefined") { + if (check.length === 0) { let ids = await service.addLike(articleId, userId); console.log(ids) ctx.status = 201; @@ -55,14 +54,12 @@ async function addLike(ctx, next) { let checkArticle = await articles.getById(articleId); // temp check as it will be checked with logon session let checkUser = await service.checkUser(userId); - if (typeof checkArticle[0] !== "undefined") { - if (typeof checkUser[0] !== "undefined") { + if (typeof checkArticle != null) { + if (typeof checkUser != null) { try { let check = await service.checkLike(articleId, userId); - console.log(check[0]) - if (typeof check[0] !== "undefined") { - let ids = await service.removeLike(articleId, userId); - console.log(ids) + if (check.length != 0) { + await service.removeLike(articleId, userId); ctx.status = 201; ctx.body = 'Unliked'; } From deeeb3aa38c92ca2b1bf277ef35dbc3bda1b0655 Mon Sep 17 00:00:00 2001 From: Filip Prosovsky Date: Sun, 4 Oct 2020 18:23:28 +0000 Subject: [PATCH 3/4] add basicAuth --- auth/basic.js | 6 ++++++ strategies/basicAuth.js | 33 +++++++++++++++++++++++++++++++++ strategies/verify.js | 23 +++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 auth/basic.js create mode 100644 strategies/basicAuth.js create mode 100644 strategies/verify.js diff --git a/auth/basic.js b/auth/basic.js new file mode 100644 index 0000000..1e3090a --- /dev/null +++ b/auth/basic.js @@ -0,0 +1,6 @@ +const passport = require('koa-passport'); +const basicAuth = require('../strategies/basicAuth'); + +passport.use(basicAuth); + +module.exports = passport.authenticate(['basic'], {session:false}); \ No newline at end of file diff --git a/strategies/basicAuth.js b/strategies/basicAuth.js new file mode 100644 index 0000000..a62fd49 --- /dev/null +++ b/strategies/basicAuth.js @@ -0,0 +1,33 @@ +const BasicStrategy = require('passport-http').BasicStrategy; +const service = require('./verify'); + +const checkUserAndPass = async (username, password, done) => { + // look up the user and check the password if the user exists + // call done() with either an error or the user, depending on outcome + let result; + try { + result = await service.getUsername(username); + if (result.length) { + const user = result[0]; + if (await service.verifySecret(username, password)) { + console.log(`Successfully authenticated user ${username}`); + return done(null, user); + } + else { + console.log(`Password incorrect for user ${username}`); + } + } + else { + console.log(`No user found with username ${username}`); + } + return done(null, false); // username or password were incorrect + } + catch (error) { + console.error(`Error during authentication for user ${username}`); + return done(error); + } + +} + +const strategy = new BasicStrategy(checkUserAndPass); +module.exports = strategy; \ No newline at end of file diff --git a/strategies/verify.js b/strategies/verify.js new file mode 100644 index 0000000..5b81e60 --- /dev/null +++ b/strategies/verify.js @@ -0,0 +1,23 @@ +const db = require('../helpers/db.js') +const bcrypt = require('bcrypt'); + +exports.getUsername = async function getUsername(login) { + let username = await db.query('SELECT username FROM users WHERE username =$1;', login) + .then(username => { + return username + }) + .catch(e => console.error(e.stack)); + return username; +} + +exports.verifySecret = async function verifySecret(username, password) { + let result = await db.query('SELECT password FROM users WHERE username =$1;', username) + .then(async passwordhash => { + passwordhash = passwordhash[0].password + let result = await bcrypt.compare(password,passwordhash) + return result + }) + .catch(e => console.error(e.stack)) + return result +} + From 4a0927eae066c3090fc30a3074b4dc5fa5e69ea2 Mon Sep 17 00:00:00 2001 From: Filip Prosovsky Date: Sun, 4 Oct 2020 18:24:18 +0000 Subject: [PATCH 4/4] only registered user can see article by ID(test) --- routes/articles.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/routes/articles.js b/routes/articles.js index c1ccea0..d3bfbac 100644 --- a/routes/articles.js +++ b/routes/articles.js @@ -2,14 +2,15 @@ const Router = require('koa-router'); const bodyParser = require('koa-bodyparser'); //adding prefix as articles.js will be used when manipulating with articles on /api/v1/articles/... const router = Router({prefix: '/api/v1/articles'}); -const service = require('../models/articles') +const service = require('../models/articles'); +const auth = require('../auth/basic') // Router methods used - functions router.get('/', getAll); router.post('/', bodyParser(), createArticle); // add view +1 when getById invoked -router.get('/:id([0-9]{1,})', getById); +router.get('/:id([0-9]{1,})', auth, getById); router.patch('/:id([0-9]{1,})', bodyParser(), updateArticle); router.del('/:id([0-9]{1,})', deleteArticle);