linter + prettier

master
Vic 2 years ago
parent 877aa4a227
commit 582171d1f9

@ -1,7 +1,7 @@
import dotenv from 'dotenv' import dotenv from "dotenv";
import { Pool } from 'pg' import { Pool } from "pg";
dotenv.config() dotenv.config();
const { const {
ENV, ENV,
@ -9,28 +9,28 @@ const {
POSTGRES_DB, POSTGRES_DB,
POSTGRES_TEST_DB, POSTGRES_TEST_DB,
POSTGRES_USER, POSTGRES_USER,
POSTGRES_PASSWORD POSTGRES_PASSWORD,
} = process.env } = process.env;
let client = new Pool(); let client = new Pool();
console.log(ENV) console.log(ENV);
if(ENV === 'dev') { if (ENV === "dev") {
client = new Pool({ client = new Pool({
host: POSTGRES_HOST, host: POSTGRES_HOST,
database: POSTGRES_DB, database: POSTGRES_DB,
user: POSTGRES_USER, user: POSTGRES_USER,
password: POSTGRES_PASSWORD, password: POSTGRES_PASSWORD,
}) });
} }
if(ENV === 'test') { if (ENV === "test") {
client = new Pool({ client = new Pool({
host: POSTGRES_HOST, host: POSTGRES_HOST,
database: POSTGRES_TEST_DB, database: POSTGRES_TEST_DB,
user: POSTGRES_USER, user: POSTGRES_USER,
password: POSTGRES_PASSWORD, password: POSTGRES_PASSWORD,
}) });
} }
export default client; export default client;

@ -1,78 +1,75 @@
import express, { Request, Response } from 'express' import express, { Request, Response } from "express";
import { Order, OrderProduct, OrderStore } from '../models/order' import { Order, OrderProduct, OrderStore } from "../models/order";
import { verifyAuthToken } from './utils' import { verifyAuthToken } from "./utils";
const orderRoutes = (app: express.Application) => { const orderRoutes = (app: express.Application) => {
app.get('/orders', index) app.get("/orders", index);
app.get('/orders/:id', read) app.get("/orders/:id", read);
app.post('/orders', verifyAuthToken, create) app.post("/orders", verifyAuthToken, create);
app.post('/orders/:id/products', verifyAuthToken, addProduct) app.post("/orders/:id/products", verifyAuthToken, addProduct);
app.delete('/orders/:id/products', verifyAuthToken, deleteProduct) app.delete("/orders/:id/products", verifyAuthToken, deleteProduct);
} };
const store = new OrderStore() const store = new OrderStore();
const index = async (req: Request, res: Response) => { const index = async (req: Request, res: Response) => {
try { try {
const orders = await store.index() const orders = await store.index();
res.json(orders) res.json(orders);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
} };
const read = async (req: Request, res: Response) => { const read = async (req: Request, res: Response) => {
try { try {
const order = await store.read(parseInt(req.params.id)) const order = await store.read(parseInt(req.params.id));
res.json(order) res.json(order);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
};
}
const create = async (req: Request, res: Response) => { const create = async (req: Request, res: Response) => {
try { try {
const orderInfo: Order = { const orderInfo: Order = {
status: req.body.status, status: req.body.status,
user_id: parseInt(req.body.user_id) user_id: parseInt(req.body.user_id),
} };
const newOrder = await store.create(orderInfo);
const newOrder = await store.create(orderInfo) res.json(newOrder);
res.json(newOrder) } catch (err) {
} catch (err) { res.status(400);
res.status(400) res.json(err);
res.json(err) }
} };
}
const addProduct = async (req: Request, res: Response) => { const addProduct = async (req: Request, res: Response) => {
try { try {
const orderProductInfo: OrderProduct = { const orderProductInfo: OrderProduct = {
order_id: parseInt(req.params.id), order_id: parseInt(req.params.id),
quantity: parseInt(req.body.quantity), quantity: parseInt(req.body.quantity),
product_id: parseInt(req.body.product_id) product_id: parseInt(req.body.product_id),
} };
const addedProduct = await store.addProduct(orderProductInfo) const addedProduct = await store.addProduct(orderProductInfo);
res.json(addedProduct) res.json(addedProduct);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
} };
const deleteProduct = async (req: Request, res: Response) => { const deleteProduct = async (req: Request, res: Response) => {
try { try {
const deletedProduct = await store.deleteProduct(parseInt(req.params.id)) const deletedProduct = await store.deleteProduct(parseInt(req.params.id));
res.json(deletedProduct) res.json(deletedProduct);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
} };
export default orderRoutes;
export default orderRoutes

@ -1,80 +1,74 @@
import express, { Request, Response } from 'express' import express, { Request, Response } from "express";
import { Product, ProductStore } from '../models/product' import { Product, ProductStore } from "../models/product";
import { verifyAuthToken } from './utils' import { verifyAuthToken } from "./utils";
const productRoutes = (app: express.Application) => { const productRoutes = (app: express.Application) => {
app.get('/products', index) app.get("/products", index);
app.get('/products/:id', read) app.get("/products/:id", read);
app.post('/products', verifyAuthToken, create) app.post("/products", verifyAuthToken, create);
app.put('/products/:id', verifyAuthToken, update) app.put("/products/:id", verifyAuthToken, update);
app.delete('/products/:id', verifyAuthToken, destroy) app.delete("/products/:id", verifyAuthToken, destroy);
} };
const store = new ProductStore() const store = new ProductStore();
const index = async (req: Request, res: Response) => { const index = async (req: Request, res: Response) => {
try { try {
const products = await store.index() const products = await store.index();
res.json(products) res.json(products);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
};
}
const read = async (req: Request, res: Response) => { const read = async (req: Request, res: Response) => {
try { try {
const product = await store.read(parseInt(req.params.id)) const product = await store.read(parseInt(req.params.id));
res.json(product) res.json(product);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
};
}
const create = async (req: Request, res: Response) => { const create = async (req: Request, res: Response) => {
try {
try { const productInfo: Product = {
const productInfo: Product = { name: req.body.name,
name: req.body.name, price: req.body.price,
price: req.body.price, };
} const newProduct = await store.create(productInfo);
const newProduct = await store.create(productInfo) res.json(newProduct);
res.json(newProduct) } catch (err) {
} catch (err) { res.status(400);
res.status(400) res.json(err);
res.json(err) }
} };
}
const update = async (req: Request, res: Response) => { const update = async (req: Request, res: Response) => {
try { try {
const productInfo: Product = { const productInfo: Product = {
id: parseInt(req.params.id), id: parseInt(req.params.id),
name: req.body.name, name: req.body.name,
price: req.body.price, price: req.body.price,
} };
const updatedProduct = await store.update(productInfo) const updatedProduct = await store.update(productInfo);
res.json(updatedProduct) res.json(updatedProduct);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
} };
const destroy = async (req: Request, res: Response) => { const destroy = async (req: Request, res: Response) => {
try { try {
const deleted = await store.delete(parseInt(req.params.id)) const deleted = await store.delete(parseInt(req.params.id));
res.json(deleted) res.json(deleted);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
};
}
export default productRoutes export default productRoutes;

@ -1,113 +1,108 @@
import express, { Request, Response } from 'express' import express, { Request, Response } from "express";
import { User, UserStore } from '../models/user' import { User, UserStore } from "../models/user";
import { verifyAuthToken, verifyUserToken} from './utils' import { verifyAuthToken, verifyUserToken } from "./utils";
const userRoutes = (app: express.Application) => { const userRoutes = (app: express.Application) => {
app.get('/users', verifyAuthToken, index) app.get("/users", verifyAuthToken, index);
app.get('/users/:id', verifyAuthToken, read) app.get("/users/:id", verifyAuthToken, read);
app.post('/users', create) app.post("/users", create);
app.put('/users/:id', verifyAuthToken, update) app.put("/users/:id", verifyAuthToken, update);
app.delete('/users/:id', verifyAuthToken, destroy) app.delete("/users/:id", verifyAuthToken, destroy);
app.post("/users/auth", authenticate) app.post("/users/auth", authenticate);
} };
const store = new UserStore()
const store = new UserStore();
const index = async (req: Request, res: Response) => { const index = async (req: Request, res: Response) => {
try { try {
const users = await store.index() const users = await store.index();
res.json(users); res.json(users);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
} };
const read = async (req: Request, res: Response) => { const read = async (req: Request, res: Response) => {
try { try {
const user = await store.read(parseInt(req.params.id)) const user = await store.read(parseInt(req.params.id));
res.json(user) res.json(user);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
} };
const create = async (req: Request, res: Response) => {
const userInfo: User = {
const create = async (req: Request, res: Response) => { firstname: req.body.firstname,
lastname: req.body.lastname,
const userInfo: User = { username: req.body.username,
firstname: req.body.firstname, password: req.body.password,
lastname: req.body.lastname, };
username: req.body.username,
password: req.body.password try {
} const newUser = await store.create(userInfo);
res.json(verifyUserToken(newUser));
try { } catch (err) {
const newUser = await store.create(userInfo) res.status(400);
res.json(verifyUserToken(newUser)) res.json(err);
} catch(err) { }
res.status(400) };
res.json(err)
}
}
const update = async (req: Request, res: Response) => { const update = async (req: Request, res: Response) => {
try { try {
const userInfo: User = { const userInfo: User = {
id: parseInt(req.params.id), id: parseInt(req.params.id),
firstname: req.body.firstname, firstname: req.body.firstname,
lastname: req.body.lastname, lastname: req.body.lastname,
username: req.body.username, username: req.body.username,
password: req.body.password password: req.body.password,
} };
const updatedUser = await store.update(userInfo) const updatedUser = await store.update(userInfo);
res.json(updatedUser) res.json(updatedUser);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
} };
const destroy = async (req: Request, res: Response) => { const destroy = async (req: Request, res: Response) => {
try { try {
const deleted = await store.delete(parseInt(req.params.id)) const deleted = await store.delete(parseInt(req.params.id));
res.json(deleted) res.json(deleted);
} catch (err) { } catch (err) {
res.status(400) res.status(400);
res.json(err) res.json(err);
} }
} };
const authenticate = async (req: Request, res: Response) => { const authenticate = async (req: Request, res: Response) => {
try { try {
const userInfo: User = { const userInfo: User = {
username: req.body.username, username: req.body.username,
password: req.body.password password: req.body.password,
} };
if (userInfo.username === undefined || userInfo.password === undefined) {
res.status(400)
res.send("Missing credentials username or password")
}
const authUser: User | null = await store.authenticate(userInfo.username, userInfo.password)
if (authUser === null) { if (userInfo.username === undefined || userInfo.password === undefined) {
res.status(401) res.status(400);
res.send("Password is incorrect") res.send("Missing credentials username or password");
}
res.json(verifyUserToken(authUser))
} catch(err) {
res.status(401)
res.json(err)
} }
}
const authUser: User | null = await store.authenticate(
userInfo.username,
userInfo.password
);
export default userRoutes if (authUser === null) {
res.status(401);
res.send("Password is incorrect");
}
res.json(verifyUserToken(authUser));
} catch (err) {
res.status(401);
res.json(err);
}
};
export default userRoutes;

@ -1,27 +1,31 @@
import jwt, { Secret } from "jsonwebtoken" import jwt, { Secret } from "jsonwebtoken";
import { User } from "../models/user" import { User } from "../models/user";
import { NextFunction, Request, Response } from "express" import { NextFunction, Request, Response } from "express";
const SECRET = process.env.TOKEN_SECRET as Secret const SECRET = process.env.TOKEN_SECRET as Secret;
export const verifyAuthToken = (req: Request, res: Response, next: NextFunction) => { export const verifyAuthToken = (
if (!req.headers.authorization) { req: Request,
res.status(401) res: Response,
res.json("Missing authorization header") next: NextFunction
) => {
if (!req.headers.authorization) {
res.status(401);
res.json("Missing authorization header");
return false return false;
} }
try { try {
const token = req.headers.authorization.split(' ')[1] const token = req.headers.authorization.split(" ")[1];
jwt.verify(token, SECRET) jwt.verify(token, SECRET);
next() next();
} catch (err) { } catch (err) {
res.status(401) res.status(401);
res.json("Access denied, invalid token") res.json("Access denied, invalid token");
} }
} };
export const verifyUserToken = (user: User | null) => { export const verifyUserToken = (user: User | null) => {
return jwt.sign({ user }, SECRET) return jwt.sign({ user }, SECRET);
} };

@ -1,135 +1,129 @@
import client from '../database' import client from "../database";
export type Order = { export type Order = {
id?: number id?: number;
status: string status: string;
user_id: number user_id: number;
} };
export type OrderProduct = { export type OrderProduct = {
id?: number id?: number;
quantity: number quantity: number;
order_id: number order_id: number;
product_id: number product_id: number;
} };
export class OrderStore { export class OrderStore {
async index(): Promise<Order[]> { async index(): Promise<Order[]> {
try { try {
const conn = await client.connect();
const conn = await client.connect() const sql = "SELECT * FROM orders";
const sql = 'SELECT * FROM orders'
const result = await conn.query(sql) const result = await conn.query(sql);
const orders = result.rows const orders = result.rows;
conn.release()
return orders conn.release();
} catch (err) { return orders;
throw new Error(`Cannot get any order ${err}`) } catch (err) {
} throw new Error(`Cannot get any order ${err}`);
} }
}
async read(user_id: number): Promise<Order> { async read(user_id: number): Promise<Order> {
try { try {
const conn = await client.connect();
const sql = "SELECT * FROM orders WHERE user_id=($1)";
const conn = await client.connect() const result = await conn.query(sql, [user_id]);
const sql = 'SELECT * FROM orders WHERE user_id=($1)' const order = result.rows[0];
const result = await conn.query(sql, [user_id]) conn.release();
const order = result.rows[0]
conn.release()
return order return order;
} catch (err) {
} catch (err) { throw new Error(`Could not find order ${user_id}. Error: ${err}`);
throw new Error(`Could not find order ${user_id}. Error: ${err}`)
}
} }
}
async create(o: Order): Promise<Order> { async create(o: Order): Promise<Order> {
try { try {
const conn = await client.connect();
const conn = await client.connect() const sql =
const sql = 'INSERT INTO orders (status, user_id) VALUES ($1, $2) RETURNING *' "INSERT INTO orders (status, user_id) VALUES ($1, $2) RETURNING *";
const result = await conn.query(sql, [o.status, o.user_id]) const result = await conn.query(sql, [o.status, o.user_id]);
const order = result.rows[0] const order = result.rows[0];
conn.release() conn.release();
return order return order;
} catch (err) {
throw new Error(`Could not add a new order ${o.user_id}. Error: ${err}`);
}
}
async addProduct(o: OrderProduct): Promise<OrderProduct> {
try {
const ordersql = "SELECT * FROM orders WHERE id=($1)";
const conn = await client.connect();
const result = await conn.query(ordersql, [o.order_id]);
const order = result.rows[0];
if (order.status !== "active") {
throw new Error(
`Could not add product ${o.product_id} to order ${o.order_id} because order status is ${order.status}`
);
}
conn.release();
} catch (err) {
throw new Error(`${err}`);
}
} catch (err) { try {
throw new Error(`Could not add a new order ${o.user_id}. Error: ${err}`) const sql =
} "INSERT INTO order_products (quantity, order_id, product_id) VALUES ($1, $2, $3) RETURNING *";
const conn = await client.connect();
const result = await conn.query(sql, [
o.quantity,
o.order_id,
o.product_id,
]);
const order = result.rows[0];
conn.release();
return order;
} catch (err) {
throw new Error(
`Could not add product ${o.product_id} to order ${o.order_id}: Error: ${err}`
);
} }
}
async addProduct(o: OrderProduct): Promise<OrderProduct> {
try { async deleteProduct(id: number): Promise<Order> {
try {
const ordersql = 'SELECT * FROM orders WHERE id=($1)' const sql = "DELETE FROM order_products WHERE order_id=($1)";
const conn = await client.connect() const conn = await client.connect();
const result = await conn.query(ordersql, [o.order_id]) const result = await conn.query(sql, [id]);
const order = result.rows[0]
conn.release();
if(order.status !== "active") { } catch (err) {
throw new Error(`Could not add product ${o.product_id} to order ${o.order_id} because order status is ${order.status}`) throw new Error(`Could not delete order ${id}: Error: ${err}`);
}
conn.release()
} catch (err) {
throw new Error(`${err}`)
}
try {
const sql = 'INSERT INTO order_products (quantity, order_id, product_id) VALUES ($1, $2, $3) RETURNING *'
const conn = await client.connect()
const result = await conn.query(sql, [o.quantity, o.order_id, o.product_id])
const order = result.rows[0]
conn.release()
return order
} catch (err) {
throw new Error(`Could not add product ${o.product_id} to order ${o.order_id}: Error: ${err}`)
}
} }
async deleteProduct(id: number): Promise<Order> { try {
try { const ordersql = "DELETE FROM orders WHERE id=($1)";
const conn = await client.connect();
const sql = 'DELETE FROM order_products WHERE order_id=($1)' const ordersResult = await conn.query(ordersql, [id]);
const conn = await client.connect() const order = ordersResult.rows[0];
const result = await conn.query(sql, [id])
conn.release();
conn.release()
return order;
} catch (err) {
} catch (err) { throw new Error(`${err}`);
throw new Error(`Could not delete order ${id}: Error: ${err}`)
}
try {
const ordersql = 'DELETE FROM orders WHERE id=($1)'
const conn = await client.connect()
const ordersResult = await conn.query(ordersql, [id])
const order = ordersResult.rows[0]
conn.release()
return order
} catch (err) {
throw new Error(`${err}`)
}
} }
} }
}

@ -1,101 +1,91 @@
import client from '../database'; import client from "../database";
export type Product = { export type Product = {
id?: number; id?: number;
name: string; name: string;
price: number; price: number;
} };
export class ProductStore { export class ProductStore {
async index(): Promise<Product[]> { async index(): Promise<Product[]> {
try { try {
const conn = await client.connect();
const conn = await client.connect() const sql = "SELECT * FROM products";
const sql = 'SELECT * FROM products'
const result = await conn.query(sql)
const products = result.rows
conn.release() const result = await conn.query(sql);
const products = result.rows;
return products conn.release();
} catch (err) { return products;
throw new Error(`Cannot get any products ${err}`) } catch (err) {
} throw new Error(`Cannot get any products ${err}`);
} }
}
async read(id: number): Promise<Product> { async read(id: number): Promise<Product> {
try { try {
const conn = await client.connect();
const sql = "SELECT * FROM products WHERE id=($1)";
const conn = await client.connect() const result = await conn.query(sql, [id]);
const sql = 'SELECT * FROM products WHERE id=($1)' const product = result.rows[0];
const result = await conn.query(sql, [id])
const product = result.rows[0]
conn.release() conn.release();
return product
} catch (err) {
throw new Error(`Could not find product ${id}. Error: ${err}`)
}
return product;
} catch (err) {
throw new Error(`Could not find product ${id}. Error: ${err}`);
} }
}
async create(p: Product): Promise<Product> {
try {
const conn = await client.connect()
const sql = 'INSERT INTO products (name, price) VALUES ($1, $2) RETURNING *'
const result = await conn.query(sql, [p.name, p.price]) async create(p: Product): Promise<Product> {
const product = result.rows[0] try {
const conn = await client.connect();
const sql =
"INSERT INTO products (name, price) VALUES ($1, $2) RETURNING *";
conn.release() const result = await conn.query(sql, [p.name, p.price]);
const product = result.rows[0];
return product conn.release();
} catch (err) {
throw new Error(`Could not add a new product ${p.name}. Error: ${err}`)
}
return product;
} catch (err) {
throw new Error(`Could not add a new product ${p.name}. Error: ${err}`);
} }
}
async update(p: Product): Promise<Product> { async update(p: Product): Promise<Product> {
try { try {
const conn = await client.connect();
const conn = await client.connect(); const sql =
const sql = 'UPDATE products SET name=$1, price=$2 WHERE id=$3 RETURNING *' "UPDATE products SET name=$1, price=$2 WHERE id=$3 RETURNING *";
const result = await conn.query(sql, [p.name, p.price, p.id])
const product = result.rows[0]
conn.release() const result = await conn.query(sql, [p.name, p.price, p.id]);
const product = result.rows[0];
return product conn.release();
} catch (err) { return product;
throw new Error(`Could not update product ${p.id}. Error: ${err}`) } catch (err) {
} throw new Error(`Could not update product ${p.id}. Error: ${err}`);
} }
}
async delete(id: number): Promise<Product> { async delete(id: number): Promise<Product> {
try { try {
const conn = await client.connect();
const conn = await client.connect() const sql = "DELETE FROM products WHERE id=($1)";
const sql = 'DELETE FROM products WHERE id=($1)'
const result = await conn.query(sql, [id])
const product = result.rows[0]
conn.release() const result = await conn.query(sql, [id]);
const product = result.rows[0];
return product conn.release();
} catch (err) { return product;
throw new Error(`Could not delete product ${id}. Error: ${err}`) } catch (err) {
} throw new Error(`Could not delete product ${id}. Error: ${err}`);
} }
}
} }

@ -1,142 +1,141 @@
import client from '../database'; import client from "../database";
import bcrypt from 'bcrypt'; import bcrypt from "bcrypt";
const { BCRYPT_PASSWORD, SALT_ROUNDS} = process.env const { BCRYPT_PASSWORD, SALT_ROUNDS } = process.env;
const pepper = BCRYPT_PASSWORD const pepper = BCRYPT_PASSWORD;
const saltRounds = SALT_ROUNDS const saltRounds = SALT_ROUNDS;
export type User = { export type User = {
id?: number; id?: number;
firstname?: string; firstname?: string;
lastname?: string; lastname?: string;
username: string; username: string;
password: string; password: string;
} };
export class UserStore { export class UserStore {
async index(): Promise<User[]> { async index(): Promise<User[]> {
try { try {
const conn = await client.connect();
const conn = await client.connect() const sql = "SELECT * FROM users";
const sql = 'SELECT * FROM users'
const result = await conn.query(sql) const result = await conn.query(sql);
const users = result.rows const users = result.rows;
conn.release() conn.release();
return users return users;
} catch (err) {
} catch (err) { throw new Error(`Cannot get any users ${err}`);
throw new Error(`Cannot get any users ${err}`)
}
} }
}
async read(id: number): Promise<User> { async read(id: number): Promise<User> {
try { try {
const conn = await client.connect() const conn = await client.connect();
const sql = 'SELECT * FROM users WHERE id=($1)' const sql = "SELECT * FROM users WHERE id=($1)";
const result = await conn.query(sql, [id]) const result = await conn.query(sql, [id]);
const user = result.rows[0] const user = result.rows[0];
conn.release() conn.release();
return user return user;
} catch (err) {
} catch (err) { throw new Error(`Could not find user ${id}. Error: ${err}`);
throw new Error(`Could not find user ${id}. Error: ${err}`)
}
} }
}
async create(u: User): Promise<User> {
try { async create(u: User): Promise<User> {
try {
const conn = await client.connect() const conn = await client.connect();
const sql = 'INSERT INTO users (firstname, lastname, username, password) VALUES ($1, $2, $3, $4) RETURNING *' const sql =
const hash = bcrypt.hashSync( "INSERT INTO users (firstname, lastname, username, password) VALUES ($1, $2, $3, $4) RETURNING *";
u.password + pepper, const hash = bcrypt.hashSync(
parseInt(saltRounds as string, 10) u.password + pepper,
) parseInt(saltRounds as string, 10)
);
const result = await conn.query(sql, [u.firstname, u.lastname, u.username, hash])
const user = result.rows[0] const result = await conn.query(sql, [
u.firstname,
conn.release() u.lastname,
u.username,
return user hash,
]);
} catch(err) { const user = result.rows[0];
throw new Error(`Could not add a new user ${u.firstname}. Error: ${err}`)
} conn.release();
return user;
} catch (err) {
throw new Error(`Could not add a new user ${u.firstname}. Error: ${err}`);
} }
}
async update(u: User): Promise<User> {
try { async update(u: User): Promise<User> {
try {
const conn = await client.connect() const conn = await client.connect();
const sql = 'UPDATE users SET firstname=$1, lastName=$2, username=$3, password=$4 WHERE id=$5 RETURNING *' const sql =
const hash = bcrypt.hashSync( "UPDATE users SET firstname=$1, lastName=$2, username=$3, password=$4 WHERE id=$5 RETURNING *";
u.password + pepper, const hash = bcrypt.hashSync(
parseInt(saltRounds as string, 10) u.password + pepper,
) parseInt(saltRounds as string, 10)
);
const result = await conn.query(sql, [u.firstname, u.lastname, u.username, hash, u.id])
const user = result.rows[0] const result = await conn.query(sql, [
u.firstname,
conn.release() u.lastname,
u.username,
return user hash,
u.id,
} catch (err) { ]);
throw new Error(`Could not update user ${u.firstname}. Error: ${err}`) const user = result.rows[0];
}
conn.release();
return user;
} catch (err) {
throw new Error(`Could not update user ${u.firstname}. Error: ${err}`);
} }
}
async delete(id: Number): Promise<User> { async delete(id: Number): Promise<User> {
try { try {
const conn = await client.connect();
const conn = await client.connect() const sql = "DELETE FROM users WHERE id=($1)";
const sql = 'DELETE FROM users WHERE id=($1)'
const result = await conn.query(sql, [id])
const user = result.rows[0]
conn.release() const result = await conn.query(sql, [id]);
const user = result.rows[0];
return user conn.release();
} catch (err) {
throw new Error(`Could not delete user ${id}. Error: ${err}`)
}
return user;
} catch (err) {
throw new Error(`Could not delete user ${id}. Error: ${err}`);
} }
}
async authenticate(username: string, password: string): Promise<User | null> { async authenticate(username: string, password: string): Promise<User | null> {
try { try {
const conn = await client.connect();
const conn = await client.connect() //const sql = 'SELECT password FROM users WHERE username=($1)'
//const sql = 'SELECT password FROM users WHERE username=($1)' const sql = "SELECT * FROM users WHERE username=($1)";
const sql = 'SELECT * FROM users WHERE username=($1)'
const result = await conn.query(sql, [username])
if(result.rows.length) { const result = await conn.query(sql, [username]);
const user = result.rows[0]
if (bcrypt.compareSync(password + pepper, user.password)) { if (result.rows.length) {
return user const user = result.rows[0];
}
}
conn.release() if (bcrypt.compareSync(password + pepper, user.password)) {
return user;
}
}
return null conn.release();
} catch (err) { return null;
throw new Error(`Could not find user ${username}. Error: ${err}`) } catch (err) {
} throw new Error(`Could not find user ${username}. Error: ${err}`);
} }
}
} }

@ -1,29 +1,27 @@
import express, { Request, Response } from 'express' import express, { Request, Response } from "express";
import bodyParser from 'body-parser' import bodyParser from "body-parser";
import productRoutes from './handlers/products' import productRoutes from "./handlers/products";
import userRoutes from './handlers/users' import userRoutes from "./handlers/users";
import orderRoutes from './handlers/orders' import orderRoutes from "./handlers/orders";
const app: express.Application = express() const app: express.Application = express();
const address: string = "0.0.0.0:3000" const address: string = "0.0.0.0:3000";
const port = 3000; const port = 3000;
app.use(bodyParser.json()) app.use(bodyParser.json());
app.get('/', function (req: Request, res: Response) { app.get("/", function (req: Request, res: Response) {
res.send('Main API') res.send("Main API");
}) });
productRoutes(app) productRoutes(app);
userRoutes(app) userRoutes(app);
orderRoutes(app) orderRoutes(app);
// Start express server // Start express server
app.listen(port, function () { app.listen(port, function () {
console.log(`starting app on: ${address}`) console.log(`starting app on: ${address}`);
}) });
export default app; export default app;

@ -1,89 +1,85 @@
import supertest from "supertest" import supertest from "supertest";
import app from "../../server" import app from "../../server";
import { Product } from '../../models/product' import { Product } from "../../models/product";
import { User } from '../../models/user' import { User } from "../../models/user";
import { Order, OrderProduct } from '../../models/order' import { Order, OrderProduct } from "../../models/order";
const token = process.env.TOKEN_SECRET_TEST as string const token = process.env.TOKEN_SECRET_TEST as string;
const request = supertest(app); const request = supertest(app);
const testProduct: Product = { const testProduct: Product = {
id: 3, id: 3,
name: "metro", name: "metro",
price: 10 price: 10,
} };
const testUser: User = { const testUser: User = {
id: 3, id: 3,
firstname: 'John', firstname: "John",
lastname: 'Doe', lastname: "Doe",
username: 'Jd', username: "Jd",
password: 'password' password: "password",
} };
const testOrder: Order = { const testOrder: Order = {
status: "active", status: "active",
user_id: 3 user_id: 3,
} };
const testOrderProduct: OrderProduct = { const testOrderProduct: OrderProduct = {
id: 2, id: 2,
quantity: 5, quantity: 5,
order_id: 2, order_id: 2,
product_id: 3 product_id: 3,
} };
describe("Order handler", () => { describe("Order handler", () => {
beforeAll(async () => {
beforeAll( async () => {
const product = await request const product = await request
.post('/products') .post("/products")
.auth(token, {type: "bearer"}) .auth(token, { type: "bearer" })
.send(testProduct) .send(testProduct);
const user = await request const user = await request
.post('/users') .post("/users")
.auth(token, {type: "bearer"}) .auth(token, { type: "bearer" })
.send(testUser) .send(testUser);
}) });
it('Should create a new order', async () => { it("Should create a new order", async () => {
const response = await request const response = await request
.post("/orders") .post("/orders")
.auth(token, {type: "bearer"}) .auth(token, { type: "bearer" })
.send(testOrder) .send(testOrder);
expect(response.status).toBe(200) expect(response.status).toBe(200);
}) });
it('Should index orders', async () => { it("Should index orders", async () => {
const response = await request const response = await request.get("/orders");
.get("/orders")
expect(response.status).toBe(200) expect(response.status).toBe(200);
}) });
it('Should get order by id', async () => { it("Should get order by id", async () => {
const response = await request const response = await request.get("/orders/2");
.get("/orders/2")
expect(response.status).toBe(200) expect(response.status).toBe(200);
}) });
it('Should add a new product to order', async () => { it("Should add a new product to order", async () => {
const response = await request const response = await request
.post('/orders/2/products') .post("/orders/2/products")
.auth(token, {type: 'bearer'}) .auth(token, { type: "bearer" })
.send(testOrderProduct) .send(testOrderProduct);
expect(response.status).toBe(200) expect(response.status).toBe(200);
}) });
it('Should delete order', async () => { it("Should delete order", async () => {
const response = await request const response = await request
.delete('/orders/2/products') .delete("/orders/2/products")
.auth(token, {type: 'bearer'}) .auth(token, { type: "bearer" });
expect(response.status).toBe(200)
})
}) expect(response.status).toBe(200);
});
});

@ -1,64 +1,57 @@
import supertest from "supertest" import supertest from "supertest";
import app from "../../server" import app from "../../server";
import { Product } from '../../models/product' import { Product } from "../../models/product";
const token = process.env.TOKEN_SECRET_TEST as string;
const token = process.env.TOKEN_SECRET_TEST as string
const request = supertest(app); const request = supertest(app);
const testProduct: Product = { const testProduct: Product = {
name: "metro", name: "metro",
price: 10 price: 10,
} };
const updatedProduct: Product = { const updatedProduct: Product = {
name: "1984", name: "1984",
price: 5 price: 5,
} };
describe("Product handler", () => { describe("Product handler", () => {
console.log("PRODUCT");
console.log("PRODUCT") it("Should create a new product", async () => {
it('Should create a new product', async () => { const response = await request
const response = await request
.post("/products") .post("/products")
.auth(token, { type: "bearer" }) .auth(token, { type: "bearer" })
.send(testProduct); .send(testProduct);
expect(response.status).toBe(200); expect(response.status).toBe(200);
}) });
it('Should index products', async () => { it("Should index products", async () => {
const response = await request const response = await request.get("/products");
.get("/products")
expect(response.status).toBe(200);
expect(response.status).toBe(200); });
})
it("Should get product by id", async () => {
const response = await request.get("/products/1");
expect(response.status).toBe(200);
});
it("Should update product with id", async () => {
const response = await request
.put("/products/1")
.auth(token, { type: "bearer" })
.send(updatedProduct);
it('Should get product by id', async () => { expect(response.status).toBe(200);
const response = await request });
.get("/products/1")
expect(response.status).toBe(200);
})
it('Should update product with id', async () => { it("Should delete product with id", async () => {
const response = await request const response = await request
.put("/products/1") .delete("/products/1")
.auth(token, { type: 'bearer'}) .auth(token, { type: "bearer" });
.send(updatedProduct)
expect(response.status).toBe(200);
})
it('Should delete product with id', async () => { expect(response.status).toBe(200);
const response = await request });
.delete("/products/1") });
.auth(token, { type: 'bearer'})
expect(response.status).toBe(200);
})
})

@ -1,75 +1,74 @@
import supertest from "supertest" import supertest from "supertest";
import app from "../../server" import app from "../../server";
import { User } from '../../models/user' import { User } from "../../models/user";
const token = process.env.TOKEN_SECRET_TEST as string const token = process.env.TOKEN_SECRET_TEST as string;
const request = supertest(app); const request = supertest(app);
const testUser: User = { const testUser: User = {
id: 1, id: 1,
firstname: 'John', firstname: "John",
lastname: 'Doe', lastname: "Doe",
username: 'Jd', username: "Jd",
password: 'password' password: "password",
} };
describe("Users handler", () => { describe("Users handler", () => {
it('Should create a new user', async () => { it("Should create a new user", async () => {
const response = await request const response = await request
.post("/users") .post("/users")
.auth(token, {type: "bearer"}) .auth(token, { type: "bearer" })
.send(testUser); .send(testUser);
expect(response.status).toBe(200) expect(response.status).toBe(200);
}) });
it('Should authenticate a user', async () => { it("Should authenticate a user", async () => {
const response = await request const response = await request
.post("/users/auth") .post("/users/auth")
.auth(token, {type: "bearer"}) .auth(token, { type: "bearer" })
.send(testUser); .send(testUser);
expect(response.status).toBe(200) expect(response.status).toBe(200);
}) });
it('Should index users', async () => { it("Should index users", async () => {
const response = await request const response = await request
.get("/users") .get("/users")
.auth(token, {type: "bearer"}) .auth(token, { type: "bearer" });
expect(response.status).toBe(200)
})
it('Should get user by id', async () => { expect(response.status).toBe(200);
const response = await request });
.get("/users/1")
.auth(token, {type: "bearer"})
expect(response.status).toBe(200) it("Should get user by id", async () => {
}) const response = await request
.get("/users/1")
.auth(token, { type: "bearer" });
it('Should update a user', async () => { expect(response.status).toBe(200);
const updatedUser = { });
id: 1,
firstname: 'Sara',
lastname: 'Doe',
username: 'Sd',
password: 'password123'
}
const response = await request
.put("/users/1")
.auth(token, {type: 'bearer'})
.send(updatedUser)
expect(response.status).toBe(200) it("Should update a user", async () => {
}) const updatedUser = {
id: 1,
firstname: "Sara",
lastname: "Doe",
username: "Sd",
password: "password123",
};
const response = await request
.put("/users/1")
.auth(token, { type: "bearer" })
.send(updatedUser);
it('Should delete a user by id', async () => { expect(response.status).toBe(200);
});
const response = await request it("Should delete a user by id", async () => {
.delete("/users/1") const response = await request
.auth(token, {type: 'bearer'}) .delete("/users/1")
.auth(token, { type: "bearer" });
expect(response.status).toBe(200) expect(response.status).toBe(200);
}) });
}) });

@ -1,98 +1,90 @@
import { User, UserStore } from '../../models/user' import { User, UserStore } from "../../models/user";
import { Product, ProductStore } from '../../models/product'; import { Product, ProductStore } from "../../models/product";
import { Order, OrderProduct, OrderStore } from '../../models/order' import { Order, OrderProduct, OrderStore } from "../../models/order";
const orderStore = new OrderStore() const orderStore = new OrderStore();
const userStore = new UserStore() const userStore = new UserStore();
const productStore = new ProductStore() const productStore = new ProductStore();
const testProduct: Product = { const testProduct: Product = {
id: 2, id: 2,
name: '1984', name: "1984",
price: 5 price: 5,
} };
const testUser: User = { const testUser: User = {
id: 2, id: 2,
firstname: 'John', firstname: "John",
lastname: 'Doe', lastname: "Doe",
username: 'Jd', username: "Jd",
password: 'password' password: "password",
} };
const testOrder: Order = { const testOrder: Order = {
id: 1, id: 1,
status: "active", status: "active",
user_id: 2 user_id: 2,
} };
const testOrderProduct: OrderProduct = { const testOrderProduct: OrderProduct = {
id: 1, id: 1,
quantity: 5, quantity: 5,
order_id: 1, order_id: 1,
product_id: 2 product_id: 2,
} };
describe("Order model", () => { describe("Order model", () => {
beforeAll(async () => {
beforeAll(async () => { await productStore.create(testProduct);
await productStore.create(testProduct) await userStore.create(testUser);
await userStore.create(testUser) });
})
console.log("ORDER");
console.log('ORDER') it("Should have an index method", () => {
it('Should have an index method', () => { expect(orderStore.index).toBeDefined();
expect(orderStore.index).toBeDefined(); });
});
it("Should have a read method", () => {
it('Should have a read method', () => { expect(orderStore.read).toBeDefined;
expect(orderStore.read).toBeDefined; });
});
it("Should have a create method", () => {
it('Should have a create method', () => { expect(orderStore.create).toBeDefined;
expect(orderStore.create).toBeDefined; });
});
it("Should have a update method", () => {
it('Should have a update method', () => { expect(orderStore.addProduct).toBeDefined;
expect(orderStore.addProduct).toBeDefined; });
});
it("Create method should add a new order", async () => {
it('Create method should add a new order', async () => { const result = await orderStore.create(testOrder);
const result = await orderStore.create(testOrder) expect(result).toEqual(testOrder);
expect(result).toEqual(testOrder) });
});
it("Index method should return a list of orders", async () => {
it('Index method should return a list of orders', async () => { const result = await orderStore.index();
const result = await orderStore.index(); expect(result[0]).toEqual(testOrder);
expect(result[0]).toEqual(testOrder) });
})
it("Read method should return a order", async () => {
const result = await orderStore.read(2);
it('Read method should return a order', async () => { expect(result).toEqual(testOrder);
const result = await orderStore.read(2); });
expect(result).toEqual(testOrder)
}) it("addProduct should add a new product to order", async () => {
const result = await orderStore.addProduct(testOrderProduct);
expect(result).toEqual(testOrderProduct);
it('addProduct should add a new product to order', async () => { });
const result = await orderStore.addProduct(testOrderProduct)
expect(result).toEqual(testOrderProduct) it("deleteProduct should delete product from order", async () => {
}) const result = await orderStore.deleteProduct(1);
it('deleteProduct should delete product from order', async () => { const checkorder = await orderStore.index();
const result = await orderStore.deleteProduct(1) expect(checkorder).toEqual([]);
});
const checkorder = await orderStore.index()
expect(checkorder).toEqual([]) afterAll(async () => {
await productStore.delete(1);
}) await userStore.delete(1);
});
});
afterAll(async () => {
await productStore.delete(1)
await userStore.delete(1)
})
});

@ -1,73 +1,68 @@
import { Product, ProductStore } from '../../models/product' import { Product, ProductStore } from "../../models/product";
const store = new ProductStore() const store = new ProductStore();
const testProduct: Product = { const testProduct: Product = {
id: 1, id: 1,
name: '1984', name: "1984",
price: 5, price: 5,
} };
const updatedProduct: Product = { const updatedProduct: Product = {
id: 1, id: 1,
name: 'The Dark Tower', name: "The Dark Tower",
price: 7 price: 7,
} };
describe("Product model", () => { describe("Product model", () => {
it('Should have an index method', () => { it("Should have an index method", () => {
expect(store.index).toBeDefined(); expect(store.index).toBeDefined();
});
it("Should have a read method", () => {
expect(store.read).toBeDefined;
});
it("Should have a create method", () => {
expect(store.create).toBeDefined;
});
it("Should have a update method", () => {
expect(store.update).toBeDefined;
});
it("Should have a delete method", () => {
expect(store.delete).toBeDefined;
});
it("Create method should add a product", async () => {
const result = await store.create(testProduct);
expect(result).toEqual(testProduct);
});
it("Index method should return a list of products", async () => {
const result = await store.index();
expect(result).toEqual([testProduct]);
});
it("Read method should return a product", async () => {
const result = await store.read(1);
expect(result).toEqual(testProduct);
});
it("Update method should update a product", async () => {
const result = await store.update(updatedProduct);
expect(result).toEqual({
id: 1,
name: "The Dark Tower",
price: 7,
}); });
});
it('Should have a read method', () => { it("Delete method should remove the product", async () => {
expect(store.read).toBeDefined; store.delete(1);
}); const result = await store.index();
it('Should have a create method', () => {
expect(store.create).toBeDefined;
});
it('Should have a update method', () => {
expect(store.update).toBeDefined;
});
it('Should have a delete method', () => {
expect(store.delete).toBeDefined;
});
it('Create method should add a product', async () => {
const result = await store.create(testProduct);
expect(result).toEqual(testProduct);
});
it('Index method should return a list of products', async () => { expect(result).toEqual([]);
const result = await store.index(); });
expect(result).toEqual([testProduct]);
});
it('Read method should return a product', async () => {
const result = await store.read(1);
expect(result).toEqual(testProduct);
});
it('Update method should update a product', async () => {
const result = await store.update(updatedProduct);
expect(result).toEqual({
id: 1,
name: 'The Dark Tower',
price: 7,
});
});
it('Delete method should remove the product', async () => {
store.delete(1);
const result = await store.index()
expect(result).toEqual([]);
});
}); });

@ -1,110 +1,111 @@
import { User, UserStore } from '../../models/user' import { User, UserStore } from "../../models/user";
import bcrypt from 'bcrypt' import bcrypt from "bcrypt";
const { BCRYPT_PASSWORD } = process.env;
const pepper = BCRYPT_PASSWORD;
const { BCRYPT_PASSWORD } = process.env const store = new UserStore();
const pepper = BCRYPT_PASSWORD
const store = new UserStore()
const testUser: User = { const testUser: User = {
id: 1, id: 1,
firstname: 'John', firstname: "John",
lastname: 'Doe', lastname: "Doe",
username: 'Jd', username: "Jd",
password: 'password' password: "password",
} };
const updatedUser: User = { const updatedUser: User = {
id: 1, id: 1,
firstname: 'Sara', firstname: "Sara",
lastname: 'Doe', lastname: "Doe",
username: 'Sd', username: "Sd",
password: 'password123' password: "password123",
} };
describe("User model", () => { describe("User model", () => {
console.log("USER") console.log("USER");
it('Should have an index method', () => { it("Should have an index method", () => {
expect(store.index).toBeDefined(); expect(store.index).toBeDefined();
}); });
it('Should have a read method', () => { it("Should have a read method", () => {
expect(store.read).toBeDefined; expect(store.read).toBeDefined;
}); });
it('Should have a create method', () => { it("Should have a create method", () => {
expect(store.create).toBeDefined; expect(store.create).toBeDefined;
}); });
it('Should have a update method', () => { it("Should have a update method", () => {
expect(store.update).toBeDefined; expect(store.update).toBeDefined;
}); });
it('Should have a delete method', () => { it("Should have a delete method", () => {
expect(store.delete).toBeDefined; expect(store.delete).toBeDefined;
}); });
it('Create method should create a new user', async () => { it("Create method should create a new user", async () => {
const result = await store.create(testUser); const result = await store.create(testUser);
expect(result.firstname).toEqual(testUser.firstname) expect(result.firstname).toEqual(testUser.firstname);
expect(result.lastname).toEqual(testUser.lastname) expect(result.lastname).toEqual(testUser.lastname);
expect(result.username).toEqual(testUser.username) expect(result.username).toEqual(testUser.username);
expect(bcrypt.compareSync(testUser.password + pepper, result.password)).toBeTrue expect(bcrypt.compareSync(testUser.password + pepper, result.password))
}) .toBeTrue;
});
it("Index method should should return a list of users", async () => {
it('Index method should should return a list of users', async () => { const result = await store.index();
expect(result[0].firstname).toEqual(testUser.firstname);
expect(result[0].lastname).toEqual(testUser.lastname);
const result = await store.index(); expect(result[0].username).toEqual(testUser.username);
expect(result[0].firstname).toEqual(testUser.firstname) expect(bcrypt.compareSync(testUser.password + pepper, result[0].password))
expect(result[0].lastname).toEqual(testUser.lastname) .toBeTrue;
expect(result[0].username).toEqual(testUser.username) });
expect(bcrypt.compareSync(testUser.password + pepper, result[0].password)).toBeTrue
}) it("Read method should return user", async () => {
const result = await store.read(1);
it('Read method should return user', async () => {
const result = await store.read(1); expect(result.firstname).toEqual(testUser.firstname);
expect(result.lastname).toEqual(testUser.lastname);
expect(result.firstname).toEqual(testUser.firstname) expect(result.username).toEqual(testUser.username);
expect(result.lastname).toEqual(testUser.lastname) expect(bcrypt.compareSync(testUser.password + pepper, result.password))
expect(result.username).toEqual(testUser.username) .toBeTrue;
expect(bcrypt.compareSync(testUser.password + pepper, result.password)).toBeTrue });
})
it("Authenticate method", async () => {
it('Authenticate method', async () => { const authUser = {
const authUser = { username: "Jd",
username: 'Jd', password: "password",
password: 'password' };
} const result = await store.authenticate(
const result = await store.authenticate(authUser.username, authUser.password); authUser.username,
authUser.password
if (result) { );
expect(result.firstname).toEqual(testUser.firstname)
expect(result.lastname).toEqual(testUser.lastname) if (result) {
expect(result.username).toEqual(testUser.username) expect(result.firstname).toEqual(testUser.firstname);
expect(bcrypt.compareSync(testUser.password + pepper, result.password)).toBeTrue expect(result.lastname).toEqual(testUser.lastname);
} expect(result.username).toEqual(testUser.username);
expect(bcrypt.compareSync(testUser.password + pepper, result.password))
}) .toBeTrue;
}
it('Update method should create a new user', async () => { });
const result = await store.update(updatedUser);
it("Update method should create a new user", async () => {
expect(result.firstname).toEqual(updatedUser.firstname) const result = await store.update(updatedUser);
expect(result.lastname).toEqual(updatedUser.lastname)
expect(result.username).toEqual(updatedUser.username) expect(result.firstname).toEqual(updatedUser.firstname);
expect(bcrypt.compareSync(updatedUser.password + pepper, result.password)).toBeTrue expect(result.lastname).toEqual(updatedUser.lastname);
}) expect(result.username).toEqual(updatedUser.username);
expect(bcrypt.compareSync(updatedUser.password + pepper, result.password))
it('Delete method should delete a user by Id', async () => { .toBeTrue;
const result = await store.delete(1); });
const checkUsers = await store.index()
it("Delete method should delete a user by Id", async () => {
expect(checkUsers).toEqual([]) const result = await store.delete(1);
}) const checkUsers = await store.index();
})
expect(checkUsers).toEqual([]);
});
});

Loading…
Cancel
Save