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 modulo4/arquitetura-camadas/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.env
.DS_STORE
node_modules
build
3,114 changes: 3,114 additions & 0 deletions modulo4/arquitetura-camadas/package-lock.json

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions modulo4/arquitetura-camadas/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "projeto-cookenu-backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node ./build/index.js",
"build": "tsc",
"dev": "ts-node-dev ./src/index.ts",
"migrations": "tsc && node ./build/database/migrations/Migrations.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/cors": "^2.8.12",
"@types/express": "^4.17.13",
"@types/jsonwebtoken": "^8.5.8",
"@types/knex": "^0.16.1",
"@types/node": "^18.0.6",
"@types/uuid": "^8.3.4",
"@types/bcryptjs": "^2.4.2",
"ts-node-dev": "^2.0.0",
"typescript": "^4.7.4"
},
"dependencies": {
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"jsonwebtoken": "^8.5.1",
"knex": "^2.2.0",
"mysql": "^2.18.1",
"uuid": "^8.3.2"
}
}
29 changes: 29 additions & 0 deletions modulo4/arquitetura-camadas/requests.rest
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
### Endpoint de teste
GET http://localhost:3003/ping

### 1) Signup
POST http://localhost:3003/users/signup
Content-Type: application/json

{
"name": "Beltrano",
"email": "beltrano@gmail.com",
"password": "abc123"
}

### 2) Login
POST http://localhost:3003/users/login
Content-Type: application/json

{
"email": "beltrano@gmail.com",
"password": "abc123"
}

### 3) Get users
GET http://localhost:3003/users
Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImI0ZjkzZGQ1LWU2NTgtNGIwZS05ZWZmLWIyNjYwMjBkZTZiOCIsInJvbGUiOiJOT1JNQUwiLCJpYXQiOjE2NTk1MzQ5NzQsImV4cCI6MTY1OTYyMTM3NH0.E3nB9HTT3Pl3sMsc8U49ISPxx2uKGFv6oQ6R7f88iws

### 3) Delete user
GET http://localhost:3003/users/f03017bb-2c08-4cdc-bb63-7fbd7cebe01f
Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImI0ZjkzZGQ1LWU2NTgtNGIwZS05ZWZmLWIyNjYwMjBkZTZiOCIsInJvbGUiOiJOT1JNQUwiLCJpYXQiOjE2NTk1MzQ5NzQsImV4cCI6MTY1OTYyMTM3NH0.E3nB9HTT3Pl3sMsc8U49ISPxx2uKGFv6oQ6R7f88iws
9 changes: 9 additions & 0 deletions modulo4/arquitetura-camadas/src/business/PingBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class PingBusiness {
public ping = async () => {
const response = {
message: "Pong!"
}

return response
}
}
44 changes: 44 additions & 0 deletions modulo4/arquitetura-camadas/src/business/UserBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { UserDatabase } from "../database/UserDatabase";
import { User } from "../models/User";
import { Authenticator } from "../services/Authenticator";
import { HashManager } from "../services/HashManager";
import { IdGenerator } from "../services/IdGenerator";

export class UserBusiness {
async signup(user: User): Promise<string> {
const { name, email, password, role } = User;

if (!name || !email || !password || !role) {
throw new Error("Todos os dados são obrigatórios");
}

if (name.length < 3) {
throw new Error("O no me precisa ter mais de 3 caracteres");
}
if (password.length < 6) {
throw new Error("A senha deve possuir mais de 6 caracteres");
}

const userDatabase = new UserDatabase();

const userEmail = await userDatabase.userEmail(email);

if (userEmail) {
throw new Error("Email ja cadastrado");
}

// -------------------------------- //

const id = new IdGenerator().generate();

const hashPassword = await new HashManager().hash(password);

const user1 = new User(id, name, email, hashPassword, role);

const response = await userDatabase.userEmail(email);

const token = new Authenticator().generateToken({ id, role });

return token;
}
}
16 changes: 16 additions & 0 deletions modulo4/arquitetura-camadas/src/controller/PingController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Request, Response } from "express"
import { PingBusiness } from "../business/PingBusiness"

export class PingController {
public ping = async (req: Request, res: Response) => {
let errorCode = 400
try {
const pingBusiness = new PingBusiness()
const response = await pingBusiness.ping()

res.status(200).send(response)
} catch (error) {
res.status(errorCode).send({ message: error.message })
}
}
}
10 changes: 10 additions & 0 deletions modulo4/arquitetura-camadas/src/controller/UserController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Request, Response } from "express";
import { UserBusiness } from "../business/UserBusiness";

export class UserController {
async signup(req: Request, res: Response) {
const { name, email, password, role } = req.body;

const userBusiness = new UserBusiness();
}
}
24 changes: 24 additions & 0 deletions modulo4/arquitetura-camadas/src/database/BaseDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import knex, { Knex } from "knex";
import dotenv from "dotenv";
dotenv.config();

// classe molde , onde a funcao getConnection vai ser chamada pelas filhas
export abstract class BaseDataBase {
private static connection: Knex | null = null;

protected getConnetion(): Knex {
if (!BaseDataBase.connection) {
BaseDataBase.connection = knex({
client: "mysql",
connection: {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
},
});
}

return BaseDataBase.connection;
}
}
24 changes: 24 additions & 0 deletions modulo4/arquitetura-camadas/src/database/UserDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { User } from "../models/User";
import { BaseDataBase } from "./BaseDatabase";

export class UserDatabase extends BaseDataBase {
public static TABLE_USERS = "Arq_Users";

async userEmail(email: string): Promise<User | undefined> {
const result = await this.getConnetion()
.select("*")
.from(UserDatabase.TABLE_USERS)
.where({ email });
if (!result.length) {
return undefined;
}

return new User(
result[0].id,
result[0].nome,
result[0].email,
result[0].senha,
result[0].role
);
}
}
49 changes: 49 additions & 0 deletions modulo4/arquitetura-camadas/src/database/migrations/Migrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { BaseDatabase } from "../BaseDatabase"
import { UserDatabase } from "../UserDatabase"
import { users } from "./data"

class Migrations extends BaseDatabase {
execute = async () => {
try {
console.log("Creating tables...")
await this.createTables()
console.log("Tables created successfully.")

console.log("Populating tables...")
await this.insertData()
console.log("Tables populated successfully.")

console.log("Migrations completed.")
} catch (error) {
console.log("Error in migrations...")
console.log(error.message)
} finally {
console.log("Ending connection...")
BaseDatabase.connection.destroy()
console.log("Connection closed graciously.")
}
}

createTables = async () => {
await BaseDatabase.connection.raw(`
DROP TABLE IF EXISTS ${UserDatabase.TABLE_USERS};

CREATE TABLE IF NOT EXISTS ${UserDatabase.TABLE_USERS}(
id VARCHAR(255) PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
role ENUM("NORMAL", "ADMIN") DEFAULT "NORMAL" NOT NULL
);
`)
}

insertData = async () => {
await BaseDatabase
.connection(UserDatabase.TABLE_USERS)
.insert(users)
}
}

const migrations = new Migrations()
migrations.execute()
25 changes: 25 additions & 0 deletions modulo4/arquitetura-camadas/src/database/migrations/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { IUserDB, USER_ROLES } from "../../models/User"

export const users: IUserDB[] = [
{
id: "bb9b7ee8-ae4b-4bd1-9bd6-e7e21594399b",
name: "Astrodev",
email: "astrodev@gmail.com",
password: "$2a$12$RBAWOHpUvGTE.MEeIohAzec9tlVqtNA/x2PMPt/Hrt0vI437cQdJC", // bananinha
role: USER_ROLES.ADMIN
},
{
id: "f03017bb-2c08-4cdc-bb63-7fbd7cebe01f",
name: "Fulano",
email: "fulano@gmail.com",
password: "$2a$12$PULtVNlAll87D6E8pR/0HO9vbzVDPaUMA89rc5cNmYoAAepbwmkcO", // qwerty00
role: USER_ROLES.NORMAL
},
{
id: "7079b8e4-95cd-48aa-82a9-77454e94b789",
name: "Ciclana",
email: "ciclana@gmail.com",
password: "$2a$12$LkWMqS3oPhP2iVMcZOVvWer9ahUPulxjB0EA4TWPxWaRuEEfYGu/i", // asdfg123
role: USER_ROLES.NORMAL
}
]
18 changes: 18 additions & 0 deletions modulo4/arquitetura-camadas/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import express from 'express'
import cors from 'cors'
import dotenv from "dotenv"
import { pingRouter } from './router/pingRouter'
import { userRouter } from './router/userRouter'

dotenv.config()

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

app.listen(process.env.PORT || 3003, () => {
console.log(`Servidor rodando na porta ${process.env.PORT || 3003}`)
})

app.use("/ping", pingRouter)
app.use("/users", userRouter)
62 changes: 62 additions & 0 deletions modulo4/arquitetura-camadas/src/models/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
export enum USER_ROLES {
NORMAL = "NORMAL",
ADMIN = "ADMIN"
}

export interface IUserDB {
id: string,
name: string,
email: string,
password: string,
role: USER_ROLES
}

export class User {
constructor(
private id: string,
private name: string,
private email: string,
private password: string,
private role: USER_ROLES
) {}

public getId = () => {
return this.id
}

public getName = () => {
return this.name
}

public getEmail = () => {
return this.email
}

public getPassword = () => {
return this.password
}

public getRole = () => {
return this.role
}

public setId = (newId: string) => {
this.id = newId
}

public setName = (newName: string) => {
this.name = newName
}

public setEmail = (newEmail: string) => {
this.email = newEmail
}

public setPassword = (newPassword: string) => {
this.password = newPassword
}

public setRole = (newRole: USER_ROLES) => {
this.role = newRole
}
}
8 changes: 8 additions & 0 deletions modulo4/arquitetura-camadas/src/router/pingRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Router } from 'express'
import { PingController } from '../controller/PingController'

export const pingRouter = Router()

const pingController = new PingController()

pingRouter.get("/", pingController.ping)
6 changes: 6 additions & 0 deletions modulo4/arquitetura-camadas/src/router/userRouter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Router } from 'express'
import { UserController } from '../controller/UserController'

export const userRouter = Router()

const userController = new UserController()
Loading