Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions semana19/projeto-cookenu/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
build
.env
1,536 changes: 1,536 additions & 0 deletions semana19/projeto-cookenu/package-lock.json

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions semana19/projeto-cookenu/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "projeto-cookenu",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "ts-node-dev ./src/index.ts",
"start": "tsc && node ./build/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.0.1",
"cors": "^2.8.5",
"dotenv": "^10.0.0",
"express": "^4.17.2",
"jsonwebtoken": "^8.5.1",
"knex": "^0.95.14",
"mysql": "^2.18.1",
"uuid": "^8.3.2"
},
"devDependencies": {
"@types/bcrypt": "^5.0.0",
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/jsonwebtoken": "^8.5.6",
"@types/knex": "^0.16.1",
"@types/node": "^17.0.0",
"@types/uuid": "^8.3.3",
"ts-node-dev": "^1.1.8",
"typescript": "^4.5.4"
}
}
17 changes: 17 additions & 0 deletions semana19/projeto-cookenu/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import express from "express"
import cors from "cors"
import { AddressInfo } from "net"

export const app = express()

app.use(express.json())
app.use(cors())

const server = app.listen(process.env.PORT || 3003, () => {
if (server) {
const address = server.address() as AddressInfo
console.log(`Server is running in http://localhost:${address.port}`)
} else {
console.error(`Failure upon starting server.`)
}
})
17 changes: 17 additions & 0 deletions semana19/projeto-cookenu/src/data/BaseDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import knex, { Knex } from "knex"
import dotenv from "dotenv"

dotenv.config()

export class BaseDatabase {
protected static connection: Knex = knex({
client: "mysql",
connection: {
host: process.env.DB_HOST,
port: 3306,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_SCHEMA
}
})
}
32 changes: 32 additions & 0 deletions semana19/projeto-cookenu/src/data/RecipeDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Recipe } from "../entities/Recipe"
import { BaseDatabase } from "./BaseDatabase"

export class RecipeDatabase extends BaseDatabase {
async createRecipe(recipe: Recipe): Promise<void> {
try {
await RecipeDatabase.connection("Cookenu_Recipe").insert({
id: recipe.getId(),
title: recipe.getTitle(),
description: recipe.getDescription(),
date: recipe.getCreateDate(),
userId: recipe.getUserId()
})

} catch (error: any) {
throw new Error(error.sqlMessage || error.message)
}
}

async getRecipe(id: string): Promise<Recipe> {
try {
const recipe = await RecipeDatabase.connection("Cookenu_Recipe")
.select("*")
.where("id", id)

return recipe[0]

} catch (error:any) {
throw new Error(error.sqlMessage || error.message)
}
}
}
44 changes: 44 additions & 0 deletions semana19/projeto-cookenu/src/data/UserDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { User } from "../entities/User"
import { BaseDatabase } from "./BaseDatabase"

export class UserDatabase extends BaseDatabase {
async createUser(user: User): Promise<void> {
try {
await UserDatabase.connection("Cookenu_User").insert({
id: user.getId(),
name: user.getName(),
email: user.getEmail(),
password: user.getPassword()
})

} catch (error: any) {
throw new Error(error.sqlMessage || error.message)
}
}

async findUserByEmail(email: string): Promise<User> {
try {
const user = await UserDatabase.connection("Cookenu_User")
.select("*")
.where({ email })

return user[0] && User.toUserModel(user[0])

} catch (error: any) {
throw new Error(error.sqlMessage || error.message)
}
}

async getProfile(id: string): Promise<User[]> {
try {
const user = await UserDatabase.connection("Cookenu_User")
.select("*")
.where("id", id)

return user[0]

} catch (error:any) {
throw new Error(error.sqlMessage || error.message)
}
}
}
53 changes: 53 additions & 0 deletions semana19/projeto-cookenu/src/endpoints/createRecipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Request, Response } from "express"
import { Recipe } from "../entities/Recipe"
import { RecipeDatabase } from "../data/RecipeDatabase"
import { Authenticator } from "../services/Authenticator"
import { IdGenerator } from "../services/IdGenerator"

export async function createRecipe(req: Request, res: Response): Promise<void> {
try {
const token = req.headers.authorization
const { title, description } = req.body

if (!token) {
res.statusCode = 422
throw new Error("É necessária uma autorização a ser passada nos headers.")
}

if (!title || !description) {
res.statusCode = 422
throw new Error("Os campos 'title' e 'description' são obrigatórios.")
}

const id: string = new IdGenerator().id()
const createDate = new Date(Date.now())


const tokenData = new Authenticator().getTokenData(token)

if (!tokenData) {
res.statusCode = 401
throw new Error("token inválido.")
}

const newRecipe = new Recipe(
id,
title,
description,
createDate,
tokenData.id
)

await new RecipeDatabase().createRecipe(newRecipe)


res.status(201).send({ message: 'Receita criada com sucesso.' })

} catch (error: any) {
if (res.statusCode === 200) {
res.status(500).send({ message: "Internal server error" })
} else {
res.send({ message: error.sqlMessage || error.message })
}
}
}
32 changes: 32 additions & 0 deletions semana19/projeto-cookenu/src/endpoints/getProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Request, Response } from "express"
import { UserDatabase } from "../data/UserDatabase"
import { Authenticator } from "../services/Authenticator"

export async function getProfile(req: Request, res: Response): Promise<void> {
try {
const token = req.headers.authorization

if (!token) {
res.statusCode = 422
throw new Error("É necessária uma autorização a ser passada nos headers.")
}

const tokenData = new Authenticator().getTokenData(token)

if (!tokenData) {
res.statusCode = 401
throw new Error("token inválido.")
}

const userDataBase = await new UserDatabase().getProfile(tokenData.id)

res.status(200).send(userDataBase)

} catch (error:any) {
if (res.statusCode === 200) {
res.status(500).send({ message: "Internal server error" })
} else {
res.send({ message: error.sqlMessage || error.message })
}
}
}
38 changes: 38 additions & 0 deletions semana19/projeto-cookenu/src/endpoints/getProfileById.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Request, Response } from "express"
import { UserDatabase } from "../data/UserDatabase"
import { Authenticator } from "../services/Authenticator"

export async function getProfileById(req: Request, res: Response): Promise<void> {
try {
const token = req.headers.authorization
const id = req.params.id

if (!token || !id) {
res.statusCode = 422
throw new Error("É necessário um id e uma autorização a ser passada nos headers.")
}

const tokenData = new Authenticator().getTokenData(token)

if (!tokenData) {
res.statusCode = 401
throw new Error("token inválido.")
}

const userDataBase = await new UserDatabase().getProfile(id)

if (!userDataBase) {
res.statusCode = 404
throw new Error("Id de usuário não econtrado.")
}

res.status(200).send(userDataBase)

} catch (error:any) {
if (res.statusCode === 200) {
res.status(500).send({ message: "Internal server error" })
} else {
res.send({ message: error.sqlMessage || error.message })
}
}
}
38 changes: 38 additions & 0 deletions semana19/projeto-cookenu/src/endpoints/getRecipeById.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Request, Response } from "express"
import { RecipeDatabase } from "../data/RecipeDatabase"
import { Authenticator } from "../services/Authenticator"

export async function getRecipeById(req: Request, res: Response): Promise<void> {
try {
const token = req.headers.authorization
const id = req.params.id

if (!token || !id) {
res.statusCode = 422
throw new Error("É necessário um id e uma autorização a ser passada nos headers.")
}

const tokenData = new Authenticator().getTokenData(token)

if (!tokenData) {
res.statusCode = 401
throw new Error("token inválido.")
}

const recipeDataBase = await new RecipeDatabase().getRecipe(id)

if (!recipeDataBase) {
res.statusCode = 404
throw new Error("Id de receita não econtrado.")
}

res.status(200).send(recipeDataBase)

} catch (error:any) {
if (res.statusCode === 200) {
res.status(500).send({ message: "Internal server error" })
} else {
res.send({ message: error.sqlMessage || error.message })
}
}
}
41 changes: 41 additions & 0 deletions semana19/projeto-cookenu/src/endpoints/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Request, Response } from "express"
import { UserDatabase } from "../data/UserDatabase"
import { Authenticator } from "../services/Authenticator"
import { HashManager } from "../services/HashManager"

export async function login(req: Request, res: Response): Promise<void> {
try {
const { email, password } = req.body

if (!email || !password) {
res.statusCode = 422
throw new Error("Os campos 'email' e 'password' são obrigatórios.")
}

const userDataBase = new UserDatabase()
const user = await userDataBase.findUserByEmail(email)

if (!user) {
res.statusCode = 409
throw new Error("Esse email não está cadastrado.")
}

const passwordIsCorrect: boolean = new HashManager().compareHash(password, user.getPassword())

if (!passwordIsCorrect) {
res.statusCode = 401
throw new Error("Email ou senha incorretos.")
}

const token: string = new Authenticator().generateToken({ id: user.getId() })

res.status(201).send({ message: 'Usuário logado com sucesso!', token })

} catch (error: any) {
if (res.statusCode === 200) {
res.status(500).send({ message: "Internal server error" })
} else {
res.send({ message: error.sqlMessage || error.message })
}
}
}
Loading