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
4 changes: 4 additions & 0 deletions Backend/Semana5/aula2/exercicios-routes-backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
build
.env
.vscode
2,649 changes: 2,649 additions & 0 deletions Backend/Semana5/aula2/exercicios-routes-backend/package-lock.json

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions Backend/Semana5/aula2/exercicios-routes-backend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "to-do-list",
"version": "1.0.0",
"description": "## ESTRUTURA DE DADOS",
"main": "index.js",
"scripts": {
"start": "tsc && node --inspect ./build/index.js",
"dev": "ts-node-dev ./src/index.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"knex": "^0.21.5",
"mysql": "^2.18.1",
"uuid": "^8.3.1"
},
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/cors": "^2.8.8",
"@types/express": "^4.17.8",
"@types/jsonwebtoken": "^8.5.0",
"@types/knex": "^0.16.1",
"@types/node": "^14.11.2",
"@types/uuid": "^8.3.0",
"ts-node-dev": "^1.0.0-pre.63",
"typescript": "^4.0.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type task = {
id: string,
title: string,
description: string,
deadline: string,
authorId: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { task } from "./task"

export enum USER_ROLES {
NORMAL = 'NORMAL',
ADMIN = 'ADMIN'
}

export type authenticationData = {
id: string,
role: USER_ROLES
}

export type user = {
id: string,
name: string,
nickname: string,
email: string,
password: string,
role: USER_ROLES,
task?: task[]
}

export type signupInputDTO = {
name: string,
nickname: string,
email: string,
password: string,
role: USER_ROLES
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as jwt from "jsonwebtoken"
import { authenticationData } from "../entities/user"

export const generateToken = (
payload: authenticationData
): string => {
return jwt.sign(
payload,
process.env.JWT_KEY as string,
{
expiresIn: "24min"
}
)
}

export const getTokenData = (
token: string
): authenticationData => {
return jwt.verify(
token,
process.env.JWT_KEY as string
) as authenticationData
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as bcrypt from 'bcryptjs';

export const hash = async (plainText: string): Promise<string> => {
const rounds = Number(process.env.BCRYPT_COST);
const salt = await bcrypt.genSalt(rounds);
return bcrypt.hash(plainText, salt)
}

export const compare = async (plainText: string, cypherText: string): Promise<boolean> => {
return bcrypt.compare(plainText, cypherText)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { v4 } from "uuid"

export const generateId = (): string => v4()
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { insertTask, selectTaskById } from "../data/taskDatabase"
import { generateId } from "./services/idGenerator"

export const businessCreateTask = async (
title: string,
description: string,
deadline: string,
authorId: string
) => {

if (
!title ||
!description ||
!deadline ||
!authorId
) {
throw new Error('"title", "description", "deadline" e "authorId" são obrigatórios')
}

const id: string = generateId()

await insertTask({
id,
title,
description,
deadline,
authorId,
})
}

export const businessGetTaskById = async(
id:string
)=>{

const result = await selectTaskById(id)

if (!result) {
throw new Error("Tarefa não encontrada")
}

const taskWithUserInfo = {
id: result.id,
title: result.title,
description: result.description,
deadline: result.deadline,
status: result.status,
authorId: result.author_id,
authorNickname: result.nickname
}

return taskWithUserInfo
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { compare, hash } from "./services/hashManager";
import { insertUser, selectUserByEmail, selectUserById } from "../data/userDatabase";
import { generateToken } from "./services/authenticator";
import { generateId } from "./services/idGenerator";
import { user, USER_ROLES } from "./entities/user";
import { setTask } from "../data/models/userModel";
import { selectTaskByUserId } from "../data/taskDatabase";

export const businessSignup = async (
name: string,
nickname: string,
email: string,
password: string,
role: USER_ROLES
) => {

if (
!name ||
!nickname ||
!email ||
!password ||
!role
) {
throw new Error('Preencha os campos "name","nickname", "email" e "password"')
}

const id: string = generateId()

const cypherPassword = await hash(password);

await insertUser({
id,
name,
nickname,
email,
password: cypherPassword,
role
})

const token: string = generateToken({
id,
role: role
})

return token
}

export const businessLogin = async (
email: string,
password: string
) => {
if (!email || !password) {
throw new Error("'email' e 'senha' são obrigatórios")
}

const user: user = await selectUserByEmail(email)

if (!user) {
throw new Error("Usuário não encontrado ou senha incorreta")
}

const passwordIsCorrect: boolean = await compare(password, user.password)

if (!passwordIsCorrect) {
throw new Error("Usuário não encontrado ou senha incorreta")
}

const token: string = generateToken({
id: user.id,
role: user.role
})

return token
}

export const businessGetProfile = async (id: string) => {
const user = await selectUserById(id)

const userTask = await selectTaskByUserId(id)

setTask(user, userTask)

return user
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from 'express'
import { createTask,getTaskById } from '../../controller/taskController'


export const taskRoute = express.Router()

taskRoute.put('/task', createTask)
taskRoute.get('/task/:id', getTaskById)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from 'express'
import { signup, login, getProfile } from '../../controller/userController'

export const userRoute = express.Router()

userRoute.post('/signup', signup)
userRoute.post('/login', login)
userRoute.get('/', getProfile)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Request, Response } from "express";
import { businessCreateTask, businessGetTaskById } from "../business/taskBusiness";

export const getTaskById = async (
req: Request,
res: Response
) => {
try {

const { id } = req.params

const taskWithUserInfo = await businessGetTaskById(id)

res.status(200).send(taskWithUserInfo)

} catch (error) {
res.status(400).send(error.message)
}
}

export const createTask = async (
req: Request,
res: Response
) => {
try {

const { title, description, deadline, authorId } = req.body

await businessCreateTask(
title,
description,
deadline,
authorId
)

res.status(201).end()

} catch (error) {
res.statusMessage = error.message
res.status(500).end()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Request, Response } from "express";
import { getTokenData } from "../business/services/authenticator";
import { businessGetProfile, businessLogin, businessSignup } from "../business/userBusiness";

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

const token = await businessLogin(email, password)

res.send({
message: "Usuário logado!",
token
})

} catch (error) {
res.status(400).send(error.message)
}
}
export const signup = async (
req: Request,
res: Response
) => {
try {
const { name, nickname, email, password, role } = req.body

const token = await businessSignup(
name,
nickname,
email,
password,
role
)

res
.status(201)
.send({
message: "Usuário criado!",
token
})

} catch (error) {
res.status(400).send(error.message)
}
}

export const getProfile = async (req: Request, res: Response) => {

const verifyToken = getTokenData(req.headers.authorization as string)

const id = verifyToken.id

const profile = await businessGetProfile(id)

res
.status(200)
.send({
profile: profile
})
}
Loading