backend overhaul
This commit is contained in:
44
models/ExampleModel.js
Normal file
44
models/ExampleModel.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const db = require('../db/Pool');
|
||||
|
||||
|
||||
module.exports = class ExampleModel {
|
||||
async create() {
|
||||
|
||||
}
|
||||
|
||||
async update() {
|
||||
|
||||
}
|
||||
|
||||
async findOneByEmail(email) {
|
||||
try {
|
||||
const statement = `SELECT * FROM example WHERE email = $1`;
|
||||
const values = [email];
|
||||
const result = await db.query(statement, values);
|
||||
|
||||
if (result.rows?.length) {
|
||||
return result.rows[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async findAll() {
|
||||
try {
|
||||
const statement = "SELECT * FROM example";
|
||||
const result = await db.query(statement);
|
||||
|
||||
if (result.rows?.length) return result.rows;
|
||||
return null;
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteOne() {
|
||||
|
||||
}
|
||||
}
|
||||
65
models/UserModel.js
Normal file
65
models/UserModel.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const db = require('../db/Pool');
|
||||
const pgp = require('pg-promise')({ capSQL: true });
|
||||
|
||||
module.exports = class UserModel {
|
||||
async create(data) {
|
||||
try {
|
||||
const statement = pgp.helpers.insert(data, null, 'users') + 'RETURNING *';
|
||||
const result = await db.query(statement);
|
||||
|
||||
if (result.rows.length) {
|
||||
return result.rows[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async update(data) {
|
||||
try {
|
||||
const { id, ...params } = data;
|
||||
|
||||
const condition = pgp.as.format('WHERE id = ${id} RETURNING *', { id });
|
||||
const statement = pgp.helpers.update(params, null, 'users') + condition;
|
||||
const result = await db.query(statement);
|
||||
if (result.rows.length) return result.rows[0];
|
||||
return null;
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async findOneById(id) {
|
||||
try {
|
||||
const statement = `SELECT * FROM users WHERE id = $1`;
|
||||
const values = [id];
|
||||
const result = await db.query(statement, values);
|
||||
|
||||
if (result.rows?.length) {
|
||||
return result.rows[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async findOneByEmail(email) {
|
||||
try {
|
||||
const statement = 'SELECT * FROM users WHERE email = $1';
|
||||
const values = [email];
|
||||
const result = await db.query(statement, values);
|
||||
|
||||
if (result.rows.length) {
|
||||
return result.rows[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
96
package-lock.json
generated
96
package-lock.json
generated
@@ -17,10 +17,12 @@
|
||||
"express": "^4.17.3",
|
||||
"express-session": "^1.17.3",
|
||||
"helmet": "^5.1.0",
|
||||
"http-errors": "^2.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"passport": "^0.6.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"pg": "^8.7.3",
|
||||
"pg-promise": "^10.12.0",
|
||||
"swagger-ui-express": "^4.4.0",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
@@ -169,6 +171,14 @@
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"node_modules/assert-options": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.7.0.tgz",
|
||||
"integrity": "sha512-7q9uNH/Dh8gFgpIIb9ja8PJEWA5AQy3xnBC8jtKs8K/gNVCr1K6kIvlm59HUyYgvM7oEDoLzGgPcGd9FqhtXEQ==",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -1308,14 +1318,14 @@
|
||||
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
|
||||
},
|
||||
"node_modules/pg": {
|
||||
"version": "8.7.3",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz",
|
||||
"integrity": "sha512-HPmH4GH4H3AOprDJOazoIcpI49XFsHCe8xlrjHkWiapdbHK+HLtbm/GQzXYAZwmPju/kzKhjaSfMACG+8cgJcw==",
|
||||
"version": "8.8.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz",
|
||||
"integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==",
|
||||
"dependencies": {
|
||||
"buffer-writer": "2.0.0",
|
||||
"packet-reader": "1.0.0",
|
||||
"pg-connection-string": "^2.5.0",
|
||||
"pg-pool": "^3.5.1",
|
||||
"pg-pool": "^3.5.2",
|
||||
"pg-protocol": "^1.5.0",
|
||||
"pg-types": "^2.1.0",
|
||||
"pgpass": "1.x"
|
||||
@@ -1324,7 +1334,7 @@
|
||||
"node": ">= 8.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"pg-native": ">=2.0.0"
|
||||
"pg-native": ">=3.0.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"pg-native": {
|
||||
@@ -1345,14 +1355,36 @@
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-minify": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.2.tgz",
|
||||
"integrity": "sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg==",
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-pool": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz",
|
||||
"integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==",
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz",
|
||||
"integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==",
|
||||
"peerDependencies": {
|
||||
"pg": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-promise": {
|
||||
"version": "10.12.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.12.0.tgz",
|
||||
"integrity": "sha512-7uN64iEHrhtRcOaU/AT3925S20JzQJG2nWVK2IUz5SlhB1eNdkXjAYoQtei+5kLJo81mOWcFq7x9J9VRldp0ig==",
|
||||
"dependencies": {
|
||||
"assert-options": "0.7.0",
|
||||
"pg": "8.8.0",
|
||||
"pg-minify": "1.6.2",
|
||||
"spex": "3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pg-protocol": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
|
||||
@@ -1697,6 +1729,14 @@
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/spex": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/spex/-/spex-3.2.0.tgz",
|
||||
"integrity": "sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg==",
|
||||
"engines": {
|
||||
"node": ">=4.5"
|
||||
}
|
||||
},
|
||||
"node_modules/split2": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz",
|
||||
@@ -2065,6 +2105,11 @@
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"assert-options": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.7.0.tgz",
|
||||
"integrity": "sha512-7q9uNH/Dh8gFgpIIb9ja8PJEWA5AQy3xnBC8jtKs8K/gNVCr1K6kIvlm59HUyYgvM7oEDoLzGgPcGd9FqhtXEQ=="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -2907,14 +2952,14 @@
|
||||
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
|
||||
},
|
||||
"pg": {
|
||||
"version": "8.7.3",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz",
|
||||
"integrity": "sha512-HPmH4GH4H3AOprDJOazoIcpI49XFsHCe8xlrjHkWiapdbHK+HLtbm/GQzXYAZwmPju/kzKhjaSfMACG+8cgJcw==",
|
||||
"version": "8.8.0",
|
||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz",
|
||||
"integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==",
|
||||
"requires": {
|
||||
"buffer-writer": "2.0.0",
|
||||
"packet-reader": "1.0.0",
|
||||
"pg-connection-string": "^2.5.0",
|
||||
"pg-pool": "^3.5.1",
|
||||
"pg-pool": "^3.5.2",
|
||||
"pg-protocol": "^1.5.0",
|
||||
"pg-types": "^2.1.0",
|
||||
"pgpass": "1.x"
|
||||
@@ -2930,12 +2975,28 @@
|
||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
|
||||
},
|
||||
"pg-minify": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.2.tgz",
|
||||
"integrity": "sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg=="
|
||||
},
|
||||
"pg-pool": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz",
|
||||
"integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==",
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz",
|
||||
"integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==",
|
||||
"requires": {}
|
||||
},
|
||||
"pg-promise": {
|
||||
"version": "10.12.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.12.0.tgz",
|
||||
"integrity": "sha512-7uN64iEHrhtRcOaU/AT3925S20JzQJG2nWVK2IUz5SlhB1eNdkXjAYoQtei+5kLJo81mOWcFq7x9J9VRldp0ig==",
|
||||
"requires": {
|
||||
"assert-options": "0.7.0",
|
||||
"pg": "8.8.0",
|
||||
"pg-minify": "1.6.2",
|
||||
"spex": "3.2.0"
|
||||
}
|
||||
},
|
||||
"pg-protocol": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
|
||||
@@ -3189,6 +3250,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"spex": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/spex/-/spex-3.2.0.tgz",
|
||||
"integrity": "sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg=="
|
||||
},
|
||||
"split2": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz",
|
||||
|
||||
@@ -23,10 +23,12 @@
|
||||
"express": "^4.17.3",
|
||||
"express-session": "^1.17.3",
|
||||
"helmet": "^5.1.0",
|
||||
"http-errors": "^2.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"passport": "^0.6.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"pg": "^8.7.3",
|
||||
"pg-promise": "^10.12.0",
|
||||
"swagger-ui-express": "^4.4.0",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@ const productsRouter = require('./products');
|
||||
const registerRouter = require('./register');
|
||||
const loginRouter = require('./login');
|
||||
|
||||
module.exports = (app, passport) => {
|
||||
module.exports = async (app, passport) => {
|
||||
loginRouter(app, passport);
|
||||
productsRouter(app);
|
||||
registerRouter(app);
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* IMPORTANT:
|
||||
* THIS VERSION OF THE AUTH SERVICE IS DEPRECATED
|
||||
* THESE SERVICES WILL BE MIGRATED TO AuthService.js
|
||||
* WITHIN THE SAME DIRECTORY
|
||||
**/
|
||||
|
||||
const { connect } = require('../db/Pool');
|
||||
const bcrypt = require('bcrypt');
|
||||
|
||||
|
||||
45
services/AuthService.js
Normal file
45
services/AuthService.js
Normal file
@@ -0,0 +1,45 @@
|
||||
const bcrypt = require('bcrypt');
|
||||
const createError = require('http-errors');
|
||||
const UserModel = require('../models/UserModel');
|
||||
const UserInstance = new UserModel();
|
||||
|
||||
module.exports = class AuthService {
|
||||
async register(data) {
|
||||
const { email } = data;
|
||||
|
||||
try {
|
||||
const user = await UserInstance.findOneById(email);
|
||||
if (user) {
|
||||
throw createError(409, 'Email already in use');
|
||||
}
|
||||
|
||||
return await UserInstance.create(data);
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
// yet to be implemented
|
||||
async login(data) {
|
||||
const { email, password } = data;
|
||||
|
||||
try {
|
||||
const user = await UserInstance.findOneByEmail(email);
|
||||
if (!user) throw createError(401, 'Incorrect email or password');
|
||||
|
||||
const match = await bcrypt.compare(user.password, password);
|
||||
if (!match) throw createError(401, 'Incorrect email or password');
|
||||
|
||||
return user;
|
||||
} catch(e) {
|
||||
throw createError(500, e);
|
||||
}
|
||||
}
|
||||
|
||||
// yet to be implemented
|
||||
async deleteOne(data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
// TO IMPLEMENT: google, facebook passport strategies
|
||||
}
|
||||
5
services/ExampleService.js
Normal file
5
services/ExampleService.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const pgp = require('pg-promise')({ capSQL: true });
|
||||
|
||||
module.exports = class ExampleService {
|
||||
|
||||
}
|
||||
26
services/UserService.js
Normal file
26
services/UserService.js
Normal file
@@ -0,0 +1,26 @@
|
||||
const createError = require('http-errors');
|
||||
const UserModel = require('../models/UserModel');
|
||||
const UserInstance = new UserModel();
|
||||
|
||||
module.exports = class UserService {
|
||||
async get(data) {
|
||||
const { id } = data;
|
||||
|
||||
try {
|
||||
const user = await UserInstance.findOneById(id);
|
||||
if (!user) throw createError(404, 'User not found');
|
||||
return user;
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async update(data) {
|
||||
try {
|
||||
const user = await UserInstance.update(data);
|
||||
return user;
|
||||
} catch(e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user