backend overhaul

This commit is contained in:
Mikayla Dobson
2022-09-22 13:14:43 -05:00
parent 905b3266a3
commit 75ebb5e43d
9 changed files with 276 additions and 16 deletions

44
models/ExampleModel.js Normal file
View 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
View 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
View File

@@ -17,10 +17,12 @@
"express": "^4.17.3", "express": "^4.17.3",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"helmet": "^5.1.0", "helmet": "^5.1.0",
"http-errors": "^2.0.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"pg": "^8.7.3", "pg": "^8.7.3",
"pg-promise": "^10.12.0",
"swagger-ui-express": "^4.4.0", "swagger-ui-express": "^4.4.0",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },
@@ -169,6 +171,14 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" "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": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1308,14 +1318,14 @@
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
}, },
"node_modules/pg": { "node_modules/pg": {
"version": "8.7.3", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz", "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz",
"integrity": "sha512-HPmH4GH4H3AOprDJOazoIcpI49XFsHCe8xlrjHkWiapdbHK+HLtbm/GQzXYAZwmPju/kzKhjaSfMACG+8cgJcw==", "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==",
"dependencies": { "dependencies": {
"buffer-writer": "2.0.0", "buffer-writer": "2.0.0",
"packet-reader": "1.0.0", "packet-reader": "1.0.0",
"pg-connection-string": "^2.5.0", "pg-connection-string": "^2.5.0",
"pg-pool": "^3.5.1", "pg-pool": "^3.5.2",
"pg-protocol": "^1.5.0", "pg-protocol": "^1.5.0",
"pg-types": "^2.1.0", "pg-types": "^2.1.0",
"pgpass": "1.x" "pgpass": "1.x"
@@ -1324,7 +1334,7 @@
"node": ">= 8.0.0" "node": ">= 8.0.0"
}, },
"peerDependencies": { "peerDependencies": {
"pg-native": ">=2.0.0" "pg-native": ">=3.0.1"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"pg-native": { "pg-native": {
@@ -1345,14 +1355,36 @@
"node": ">=4.0.0" "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": { "node_modules/pg-pool": {
"version": "3.5.1", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz",
"integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==", "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==",
"peerDependencies": { "peerDependencies": {
"pg": ">=8.0" "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": { "node_modules/pg-protocol": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
@@ -1697,6 +1729,14 @@
"semver": "bin/semver.js" "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": { "node_modules/split2": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", "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", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" "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": { "balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -2907,14 +2952,14 @@
"integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
}, },
"pg": { "pg": {
"version": "8.7.3", "version": "8.8.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.7.3.tgz", "resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz",
"integrity": "sha512-HPmH4GH4H3AOprDJOazoIcpI49XFsHCe8xlrjHkWiapdbHK+HLtbm/GQzXYAZwmPju/kzKhjaSfMACG+8cgJcw==", "integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==",
"requires": { "requires": {
"buffer-writer": "2.0.0", "buffer-writer": "2.0.0",
"packet-reader": "1.0.0", "packet-reader": "1.0.0",
"pg-connection-string": "^2.5.0", "pg-connection-string": "^2.5.0",
"pg-pool": "^3.5.1", "pg-pool": "^3.5.2",
"pg-protocol": "^1.5.0", "pg-protocol": "^1.5.0",
"pg-types": "^2.1.0", "pg-types": "^2.1.0",
"pgpass": "1.x" "pgpass": "1.x"
@@ -2930,12 +2975,28 @@
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" "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": { "pg-pool": {
"version": "3.5.1", "version": "3.5.2",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.1.tgz", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz",
"integrity": "sha512-6iCR0wVrro6OOHFsyavV+i6KYL4lVNyYAB9RD18w66xSzN+d8b66HiwuP30Gp1SH5O9T82fckkzsRjlrhD0ioQ==", "integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==",
"requires": {} "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": { "pg-protocol": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz", "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": { "split2": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz",

View File

@@ -23,10 +23,12 @@
"express": "^4.17.3", "express": "^4.17.3",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"helmet": "^5.1.0", "helmet": "^5.1.0",
"http-errors": "^2.0.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"passport": "^0.6.0", "passport": "^0.6.0",
"passport-local": "^1.0.0", "passport-local": "^1.0.0",
"pg": "^8.7.3", "pg": "^8.7.3",
"pg-promise": "^10.12.0",
"swagger-ui-express": "^4.4.0", "swagger-ui-express": "^4.4.0",
"uuid": "^8.3.2" "uuid": "^8.3.2"
}, },

View File

@@ -3,7 +3,7 @@ const productsRouter = require('./products');
const registerRouter = require('./register'); const registerRouter = require('./register');
const loginRouter = require('./login'); const loginRouter = require('./login');
module.exports = (app, passport) => { module.exports = async (app, passport) => {
loginRouter(app, passport); loginRouter(app, passport);
productsRouter(app); productsRouter(app);
registerRouter(app); registerRouter(app);

View File

@@ -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 { connect } = require('../db/Pool');
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');

45
services/AuthService.js Normal file
View 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
}

View File

@@ -0,0 +1,5 @@
const pgp = require('pg-promise')({ capSQL: true });
module.exports = class ExampleService {
}

26
services/UserService.js Normal file
View 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);
}
}
}