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 Semana17/Aula3/Warmup.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1. Atualmente o processo de autenticação é feito pegando a senha encriptada do usuário e o login e comparando, caso sejam iguais o usuário recebe um token e é liberado para acessar a página

2. o "refresh token" é um token com tempo de expiração, assim como utilizavamos na aula de segunda, mas sem o token, usando um tempo máximo de expiração
7 changes: 7 additions & 0 deletions Semana17/Aula3/template-webservices/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
build

.env

.vscode
requests.rest
2,661 changes: 2,661 additions & 0 deletions Semana17/Aula3/template-webservices/package-lock.json

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions Semana17/Aula3/template-webservices/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "to-do-list",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "tsc && node --inspect ./build/index.js",
"dev-start": "ts-node-dev ./src/index.ts"
},
"author": "Labenu",
"license": "ISC",
"dependencies": {
"@types/bcryptjs": "^2.4.2",
"axios": "^0.21.1",
"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.2"
},
"devDependencies": {
"@types/cors": "^2.8.8",
"@types/express": "^4.17.8",
"@types/jsonwebtoken": "^8.5.1",
"@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"
}
}
13 changes: 13 additions & 0 deletions Semana17/Aula3/template-webservices/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import express from 'express'
import cors from 'cors'

const app = express()

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

app.listen(3003, ()=>{
console.log('Servidor rodando na porta 3003')
})

export default app
18 changes: 18 additions & 0 deletions Semana17/Aula3/template-webservices/src/connection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import knex from 'knex'
import dotenv from 'dotenv'

dotenv.config()

const connection = knex({
client: 'mysql',
connection: {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_SCHEMA,
port: 3306,
multipleStatements: true
}
})

export default connection
64 changes: 64 additions & 0 deletions Semana17/Aula3/template-webservices/src/endpoints/createUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Request, Response } from "express";
import connection from "../connection";
import { generateToken } from "../services/authenticator";
import generateId from "../services/idGenerator";
import { user, userRole, address } from "../types";
import { hash } from "../services/hashManager";
import getAddressInfo from '../services/getAddressInfo'

export default async function createUser(
req: Request,
res: Response
): Promise<void> {
try {

const { name, nickname, email, password, role } = req.body
const {CEP, numero, complemento} = req.body.address

if (!name || !nickname || !email || !password || !role || !CEP) {
res.statusCode = 422
throw new Error("Preencha os campos 'name','nickname', 'password', 'email' e 'role'")
}

if(role.toUpperCase() !== userRole.ADMIN && role.toUpperCase() !== userRole.NORMAL){
res.statusCode = 422
throw new Error("Os valores possíveis para 'role' são NORMAL e ADMIN")
}

const [user] = await connection('to_do_list_users')
.where({ email })

if (user) {
res.statusCode = 409
throw new Error('Email já cadastrado')
}

const id: string = generateId();

const cypherText = await hash(password);





const newAddress: Promise<address | null> = getAddressInfo(CEP, numero, complemento)

const newUser: user = { id, name, nickname, email, password: cypherText, role, address: newAddress}


await connection('to_do_list_users')
.insert(newUser)

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

res.status(201).send({ token })

} catch (error) {

if (res.statusCode === 200) {
res.status(500).send({ message: "Internal server error" })
} else {
res.send({ message: error.message })
}
}
}
48 changes: 48 additions & 0 deletions Semana17/Aula3/template-webservices/src/endpoints/editUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Request, Response } from "express";
import connection from "../connection";
import { getTokenData } from "../services/authenticator";
import { authenticationData, userPersonalInfo, userRole } from "../types";

export default async function createUser(
req: Request,
res: Response
): Promise<void> {
try {

const { name, nickname }: userPersonalInfo = req.body

const token: string = req.headers.authorization!

const tokenData: authenticationData | null = getTokenData(token)

if(!tokenData){
res.statusCode = 401
throw new Error("Unatuthorized");
}

if(tokenData.role !== userRole.ADMIN){
res.statusCode = 401
throw new Error("Apenas usuários administradores podem acessar.");
}

if (!name && !nickname) {
res.statusCode = 422
res.statusMessage = "Informe o(s) novo(s) 'name' ou 'nickname'"
throw new Error("caí aqui")
}

await connection('to_do_list_users')
.update({ name, nickname })
.where({ id: tokenData.id })

res.send({message: "Atualizado!"});

} catch (error) {

if (res.statusCode === 200) {
res.status(500).send({message: error.message})
}

res.send({message: error.message})
}
}
42 changes: 42 additions & 0 deletions Semana17/Aula3/template-webservices/src/endpoints/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Request, Response } from "express"
import connection from "../connection"
import { generateToken } from "../services/authenticator"
import { userCredentials } from "../types"
import { compare } from "../services/hashManager"

export default async function login(
req: Request,
res: Response
): Promise<void> {
try {

const { email, password }: userCredentials = req.body

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

const [user] = await connection("to_do_list_users")
.where({ email });

const hashCompare = await compare(password, user.password);

if (!user || !hashCompare) {
res.statusCode = 401;
throw new Error("Credenciais inválidas");
}

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

res.send({ token })

} catch (error) {

if (res.statusCode == 200) {
res.status(500).send({ message: "Internal server error" })
} else {
res.send({ message: error.message })
}
}
}
13 changes: 13 additions & 0 deletions Semana17/Aula3/template-webservices/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import app from "./app";
import editUser from './endpoints/editUser';
import createUser from './endpoints/createUser';
import login from './endpoints/login';
import { hash, compare } from "./services/hashManager";
import getAddressInfo from './services/getAddressInfo';

app.post('/user/signup', createUser)
app.post('/user/login', login)
app.put('/user/edit', editUser)

let i = getAddressInfo("82590300", 15, "casa")
console.log(i)
49 changes: 49 additions & 0 deletions Semana17/Aula3/template-webservices/src/services/authenticator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as jwt from "jsonwebtoken"
import { authenticationData } from "../types"
import dotenv from "dotenv"

dotenv.config()

// const myToken = jwt.sign(
// {
// id: "123456"
// },
// "hklsdf9347583945yfgdfiguydifgdgdf",
// {
// expiresIn: "24d"
// }
// )

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

export const getTokenData = (
token: string
): authenticationData | null => {
try {

const { id, role } = jwt.verify(token, process.env.JWT_KEY!) as authenticationData

return { id, role }

} catch (error) {

console.log(error.message);
return null
}
}


// console.log(
// jwt.verify(
// myToken,
// "hklsdf9347583945yfgdfiguydifgdgdf"
// )
// )
31 changes: 31 additions & 0 deletions Semana17/Aula3/template-webservices/src/services/getAddressInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import axios from 'axios'
import { address } from '../types'

const getAddressInfo = async (CEP: string, numero: number, complemento: string): Promise<address | null> => {
try {
const response = await axios.get(`https://viacep.com.br/ws/${CEP}/json/`)

console.log("variavel response.data: ", response.data)

const retorno: address = {
CEP: response.data.cep,
numero: numero,
complemento: complemento,
logradouro: response.data.logradouro,
bairro: response.data.bairro,
cidade: response.data.localidade,
estado: response.data.uf
}

console.log("variavel Retorno: ", retorno)

return retorno

} catch (error) {
return null
}


}

export default getAddressInfo
23 changes: 23 additions & 0 deletions Semana17/Aula3/template-webservices/src/services/hashManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as bcrypt from "bcryptjs";

export const hash = async (s:string): Promise<string> => {

//definindo a complexidade/cost (o quão fundo vamos cavar)
const rounds: number = Number(process.env.BCRYPT_COST);

if(isNaN(Number(process.env.BCRYPT_COST))){
throw new Error("O cost precisa ser um número");
}

//gerar o salt (começar a cavar, tendo como parametro o quao fundo)
const salt = await bcrypt.genSalt(rounds);

//esconder o nosso tesouro (usando como parametro o nosso salt)
const result = await bcrypt.hash(s, salt);

return result;
}

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

const generateId = (): string => v4()

export default generateId
Loading