added user model and users handler

Vic
Vic 2 years ago
parent 6359baee5b
commit d30014b432

@ -19,7 +19,7 @@ exports.setup = function(options, seedLink) {
};
exports.up = function(db) {
var filePath = path.join(__dirname, 'sqls', '20220519015830-shelf-up.sql');
var filePath = path.join(__dirname, 'sqls', '20220520025053-shelf-up.sql');
return new Promise( function( resolve, reject ) {
fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
if (err) return reject(err);
@ -34,7 +34,7 @@ exports.up = function(db) {
};
exports.down = function(db) {
var filePath = path.join(__dirname, 'sqls', '20220519015830-shelf-down.sql');
var filePath = path.join(__dirname, 'sqls', '20220520025053-shelf-down.sql');
return new Promise( function( resolve, reject ) {
fs.readFile(filePath, {encoding: 'utf-8'}, function(err,data){
if (err) return reject(err);

@ -1,2 +0,0 @@
drop TABLE products;
DROP TABLE users;

@ -0,0 +1,2 @@
DROP TABLE products;
DROP TABLE users;

@ -23,6 +23,7 @@
"cross-env": "^7.0.3",
"dotenv": "^16.0.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.21",
"nodemon": "^2.0.15",
"pg": "^8.5.1",
@ -32,6 +33,7 @@
"@types/bcrypt": "^5.0.0",
"@types/express": "^4.17.9",
"@types/jasmine": "^3.6.3",
"@types/jsonwebtoken": "^8.5.8",
"@types/pg": "^7.14.7",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.10.1",

@ -1,4 +1,4 @@
import express, {Request, Response} from 'express'
import express, { Request, Response } from 'express'
import { Product, ProductStore } from '../models/product'
const productRoutes = (app: express.Application) => {
@ -13,7 +13,7 @@ const store = new ProductStore()
const index = async (req: Request, res: Response) => {
try {
const products = await store.index();
const products = await store.index()
res.json(products);
console.log('working products index')
} catch (err) {
@ -43,7 +43,7 @@ const create = async (req: Request, res: Response) => {
price: req.body.price,
}
const newProduct = await store.create(productInfo);
const newProduct = await store.create(productInfo)
res.json(newProduct)
} catch (err) {
res.status(400)
@ -54,7 +54,7 @@ const create = async (req: Request, res: Response) => {
const update = async (req: Request, res: Response) => {
try {
const product = await store.update(req.body);
const product = await store.update(req.body)
res.json({
name: req.body.name,
price: req.body.price,

@ -0,0 +1,129 @@
import express, { Request, Response, NextFunction } from 'express'
import { User, UserStore } from '../models/user'
import jwt, {Secret} from 'jsonwebtoken'
const SECRET = process.env.TOKEN_SECRET as Secret
const userRoutes = (app: express.Application) => {
app.get('/users', index)
app.get('/users/:id', read)
app.post('/users/create', verifyAuthToken, create)
app.put('/users/:id', verifyAuthToken, update)
app.delete('/users/:id', verifyAuthToken, destroy)
app.post("/users/auth", authenticate)
}
const store = new UserStore()
const verifyAuthToken = (req: Request, res: Response, next: NextFunction) => {
if (!req.headers.authorization) {
res.status(401)
res.json("Access denied, invalid token")
return false
}
try {
//const authorizationHeader = req.headers.authorization
const token = req.headers.authorization.split(" ")[1]
const decoded = jwt.verify(token, SECRET)
next()
} catch (err) {
res.status(401)
res.json("Access denied, invalid token")
}
}
let verifyUserToken = (user: User | null) => {
return jwt.sign({ user }, SECRET)
}
const index = async (req: Request, res: Response) => {
try {
const users = await store.index()
res.json(users);
} catch (err) {
res.status(400)
res.json(err)
}
}
const read = async (req: Request, res: Response) => {
try {
const user = await store.read(parseInt(req.params.id))
res.json(user)
} catch (err) {
res.status(400)
res.json(err)
}
}
const create = async (req: Request, res: Response) => {
const userInfo: User = {
firstName: req.body.fristName,
lastName: req.body.lastName,
username: req.body.username,
password: req.body.password
}
try {
const newUser = await store.create(userInfo)
res.json(verifyUserToken(newUser))
} catch(err) {
res.status(400)
res.json(err)
}
}
const update = async (req: Request, res: Response) => {
try {
const user = await store.update(req.body)
res.json({
firstName: req.body.fristName,
lastName: req.body.lastName,
username: req.body.username,
password: req.body.password
})
} catch (err) {
res.status(400)
res.json(err)
}
}
const destroy = async (req: Request, res: Response) => {
try {
const deleted = await store.delete(req.body.id)
res.json(deleted)
} catch (err) {
res.status(400)
res.json(err)
}
}
const authenticate = async (req: Request, res: Response) => {
const userInfo: User = {
username: req.body.username,
password: req.body.password
}
if (userInfo.username === undefined || userInfo.password === undefined) {
res.status(400)
}
try {
const auth: User | null = await store.authenticate(userInfo.username, userInfo.password)
res.json(verifyUserToken(auth))
} catch(err) {
res.status(401)
res.json(err)
}
}
export default userRoutes

@ -7,8 +7,8 @@ const saltRounds = SALT_ROUNDS
export type User = {
id?: number;
firstName: string;
lastName: string;
firstName?: string;
lastName?: string;
username: string;
password: string;
}

@ -2,6 +2,7 @@ import express, { Request, Response } from 'express'
import bodyParser from 'body-parser'
import productRoutes from './handlers/products'
import userRoutes from './handlers/users'
const app: express.Application = express()
const address: string = "0.0.0.0:3000"
@ -14,7 +15,7 @@ app.get('/', function (req: Request, res: Response) {
})
productRoutes(app)
userRoutes(app)
// Start express server
app.listen(port, function () {

@ -161,6 +161,13 @@
"resolved" "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz"
"version" "7.0.11"
"@types/jsonwebtoken@^8.5.8":
"integrity" "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A=="
"resolved" "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz"
"version" "8.5.8"
dependencies:
"@types/node" "*"
"@types/mime@^1":
"integrity" "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
"resolved" "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz"
@ -537,6 +544,11 @@
dependencies:
"fill-range" "^7.0.1"
"buffer-equal-constant-time@1.0.1":
"integrity" "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
"resolved" "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz"
"version" "1.0.1"
"buffer-from@^1.0.0":
"integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
"resolved" "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
@ -999,6 +1011,13 @@
"resolved" "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz"
"version" "0.1.4"
"ecdsa-sig-formatter@1.0.11":
"integrity" "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="
"resolved" "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
"version" "1.0.11"
dependencies:
"safe-buffer" "^5.0.1"
"ee-first@1.1.1":
"integrity" "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
"resolved" "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
@ -1821,6 +1840,39 @@
"resolved" "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
"version" "1.0.1"
"jsonwebtoken@^8.5.1":
"integrity" "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w=="
"resolved" "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz"
"version" "8.5.1"
dependencies:
"jws" "^3.2.2"
"lodash.includes" "^4.3.0"
"lodash.isboolean" "^3.0.3"
"lodash.isinteger" "^4.0.4"
"lodash.isnumber" "^3.0.3"
"lodash.isplainobject" "^4.0.6"
"lodash.isstring" "^4.0.1"
"lodash.once" "^4.0.0"
"ms" "^2.1.1"
"semver" "^5.6.0"
"jwa@^1.4.1":
"integrity" "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA=="
"resolved" "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz"
"version" "1.4.1"
dependencies:
"buffer-equal-constant-time" "1.0.1"
"ecdsa-sig-formatter" "1.0.11"
"safe-buffer" "^5.0.1"
"jws@^3.2.2":
"integrity" "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA=="
"resolved" "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz"
"version" "3.2.2"
dependencies:
"jwa" "^1.4.1"
"safe-buffer" "^5.0.1"
"keyv@^3.0.0":
"integrity" "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA=="
"resolved" "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz"
@ -1855,11 +1907,46 @@
"resolved" "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz"
"version" "4.2.0"
"lodash.includes@^4.3.0":
"integrity" "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
"resolved" "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz"
"version" "4.3.0"
"lodash.isboolean@^3.0.3":
"integrity" "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
"resolved" "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz"
"version" "3.0.3"
"lodash.isinteger@^4.0.4":
"integrity" "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
"resolved" "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz"
"version" "4.0.4"
"lodash.isnumber@^3.0.3":
"integrity" "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
"resolved" "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz"
"version" "3.0.3"
"lodash.isplainobject@^4.0.6":
"integrity" "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
"resolved" "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz"
"version" "4.0.6"
"lodash.isstring@^4.0.1":
"integrity" "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
"resolved" "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz"
"version" "4.0.1"
"lodash.merge@^4.6.2":
"integrity" "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
"resolved" "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz"
"version" "4.6.2"
"lodash.once@^4.0.0":
"integrity" "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
"resolved" "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz"
"version" "4.1.1"
"lodash.truncate@^4.4.2":
"integrity" "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM="
"resolved" "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz"
@ -2563,7 +2650,7 @@
dependencies:
"queue-microtask" "^1.2.2"
"safe-buffer@~5.2.0", "safe-buffer@5.2.1":
"safe-buffer@^5.0.1", "safe-buffer@~5.2.0", "safe-buffer@5.2.1":
"integrity" "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
"resolved" "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz"
"version" "5.2.1"
@ -2590,6 +2677,11 @@
"resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
"version" "5.7.1"
"semver@^5.6.0":
"integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
"resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
"version" "5.7.1"
"semver@^5.7.1":
"integrity" "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
"resolved" "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"

Loading…
Cancel
Save