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
2 changes: 2 additions & 0 deletions semana19/projeto-lama/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.node_modules
.env
Empty file.
8 changes: 8 additions & 0 deletions semana19/projeto-lama/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
roots: ["<rootDir>/tests"],
transform: {
"^.+\\.tsx?$": "ts-jest",
},
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
};
6,431 changes: 6,431 additions & 0 deletions semana19/projeto-lama/package-lock.json

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions semana19/projeto-lama/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "lama-template",
"version": "1.0.0",
"description": "Template para o projeto LAMA",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "ts-node ./src/index.ts"
},
"keywords": [
"api",
"labook"
],
"author": "João Alves",
"license": "ISC",
"dependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/express": "^4.17.7",
"@types/jest": "^25.2.3",
"@types/jsonwebtoken": "^8.5.0",
"@types/knex": "^0.16.1",
"@types/uuid": "^8.0.0",
"bcryptjs": "^2.4.3",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"jest": "^26.0.1",
"knex": "^0.21.2",
"moment": "^2.27.0",
"mysql": "^2.18.1",
"ts-jest": "^26.1.0",
"ts-node": "^8.10.2",
"typescript": "^3.9.6",
"uuid": "^8.2.0"
}
}
51 changes: 51 additions & 0 deletions semana19/projeto-lama/src/business/BandBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { IdGenerator } from './../services/IdGenerator';
import { InvalidParameterError } from './../error/InvalidParameterError';
import { BandDatabase } from './../data/BandDatabase';
import { BandInputDTO, Band } from './../model/Band';
import { GenericError } from '../error/GenericError';
import { Authenticator } from '../services/Authenticator';

export class BandBusiness {
async createBand(input: BandInputDTO, token: string): Promise<string | undefined> {

const authenticator = new Authenticator()
const authenticationData = authenticator.getData(token)

if (!token) {
throw new InvalidParameterError("Invalid token")
}

if (!input.name || !input.musicGenre || !input.responsible) {
throw new GenericError("Fill all the blanks")
}

if (authenticationData.role !== "ADMIN") {
throw new GenericError("Requires admin account ")
}

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

const bandDatabase = new BandDatabase()
await bandDatabase.createBand(input, id)

return id;
}

async getBandDetails(idValue: string, nameValue: string, token: string): Promise<Band | undefined> {
const bandDatabase = new BandDatabase()
let result: any = ''
if (!token) {
throw new InvalidParameterError("Invalid token")
}

if (!idValue || (idValue && nameValue)) {
result = bandDatabase.getBandDetails("NAME", nameValue)
} else if (!nameValue) {
result = bandDatabase.getBandDetails("ID", idValue)
} else {
result = undefined
}
return result
}
}
49 changes: 49 additions & 0 deletions semana19/projeto-lama/src/business/UserBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { NotFoundError } from './../error/NotFoundError';
import { InvalidParameterError } from './../error/InvalidParameterError';
import { Authenticator } from './../services/Authenticator';
import { User } from './../model/User';
import { HashManager } from './../services/HashManager';
import { UserInputDTO, LoginInputDTO } from "../model/User";
import { UserDatabase } from "../data/UserDatabase";
import { IdGenerator } from "../services/IdGenerator";


export class UserBusiness {
async createUser(user: UserInputDTO) {

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

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

const userDatabase = new UserDatabase();
await userDatabase.createUser(id, user.email, user.name, hashPassword, user.role);

const authenticator = new Authenticator();
const accessToken = authenticator.generateToken({ id, role: user.role });

return accessToken;
}

async getUserByEmail(input: LoginInputDTO) {
const userDatabase = new UserDatabase();
const userFromDb: User = await userDatabase.getUserByEmail(input.email);

const hashManager = new HashManager();
const passwordIsCorrect = await hashManager.compare(input.password, userFromDb.getPassword())

if (!passwordIsCorrect) {
throw new InvalidParameterError("Invalid Password")
}

const authenticator = new Authenticator();
const token: string = authenticator.generateToken({ id: userFromDb.getId(), role: userFromDb.getRole() })

if (!token) {
throw new NotFoundError("User not fond")
}

return token;
}
}
49 changes: 49 additions & 0 deletions semana19/projeto-lama/src/controller/BandController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { BandBusiness } from './../business/BandBusiness';
import { BandInputDTO } from './../model/Band';
import { Request, Response } from 'express';
import { InvalidParameterError } from '../error/InvalidParameterError';

export class BandController {
async createBand(req: Request, res: Response) {
try {
const input: BandInputDTO = {
name: req.body.name,
musicGenre: req.body.music_genre,
responsible: req.body.responsible
}

const token = req.headers.authorization as string

const bandBusiness = new BandBusiness()
const bandId = await bandBusiness.createBand(input, token)


res.status(200).send({ message: "Register a new band!", bandId })
} catch (error) {
res.status(error.errorCode || 400).send({ message: error.message })
}
}

async getBandDetail(req: Request, res: Response) {
try {
const id = req.body.id
const name = req.body.name

const token = req.headers.authorization as string

const bandBusiness = new BandBusiness()

if (!id && !name) {
throw new InvalidParameterError("Requires id or name")
}

const response = await bandBusiness.getBandDetails(id, name, token)

res.status(200).send({ response })

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

49 changes: 49 additions & 0 deletions semana19/projeto-lama/src/controller/UserController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { UserDatabase } from './../data/UserDatabase';
import { Request, Response } from "express";
import { UserInputDTO, LoginInputDTO } from "../model/User";
import { UserBusiness } from "../business/UserBusiness";
import { BaseDatabase } from "../data/BaseDatabase";

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

const userBusiness = new UserBusiness();
const token = await userBusiness.createUser(input);

res.status(200).send({ token });

} catch (error) {
res.status(error.errorCode || 400).send({ message: error.message });
}

await BaseDatabase.destroyConnection();
}

async login(req: Request, res: Response) {
try {
const input: LoginInputDTO = {
email: req.body.email,
password: req.body.password
}

const userBusiness = new UserBusiness()
const token = await userBusiness.getUserByEmail(input)

if (!token) {
throw new Error("Invalid login")
}

res.status(200).send({ token })
} catch (error) {
res.status(error.errorCode || 400).send({ message: error.message });
}
}

}
59 changes: 59 additions & 0 deletions semana19/projeto-lama/src/data/BandDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { BandInputDTO, Band } from './../model/Band';
import { BaseDatabase } from "./BaseDatabase";


export class BandDatabase extends BaseDatabase {
private static TABLE_NAME = "lama_band"

public async createBand(
input: BandInputDTO,
id: string
): Promise<void> {
try {
const name: string = input.name
const music_genre: string = input.musicGenre
const responsible: string = input.responsible
await this.getConnection()
.insert({
id,
name,
music_genre,
responsible
})
.into(BandDatabase.TABLE_NAME);
} catch (error) {
throw new Error(error.sqlMessage || error.message);
}
}

public async getBandDetails(
typeOfValue: string,
value: string
): Promise<any> {
try {
if (typeOfValue === 'ID') {
const id = value
const result = await this.getConnection()
.select("*")
.from(BandDatabase.TABLE_NAME)
.where({ id });
return result

} else if (typeOfValue === 'NAME') {
const result = await this.getConnection()
.select("*")
.from(BandDatabase.TABLE_NAME)
.where({ "name": value })
return result
} else {
console.log("Invalid value of parameter")
return undefined
}

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


32 changes: 32 additions & 0 deletions semana19/projeto-lama/src/data/BaseDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import knex from "knex";
import Knex from "knex";


export abstract class BaseDatabase {

private static connection: Knex | null = null;

protected getConnection(): Knex {
if (!BaseDatabase.connection) {
BaseDatabase.connection = 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_NAME,
},
});
}

return BaseDatabase.connection;
}

public static async destroyConnection(): Promise<void> {
if (BaseDatabase.connection) {
await BaseDatabase.connection.destroy();
BaseDatabase.connection = null;
}
}
}
39 changes: 39 additions & 0 deletions semana19/projeto-lama/src/data/UserDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { BaseDatabase } from "./BaseDatabase";
import { User } from "../model/User";

export class UserDatabase extends BaseDatabase {

private static TABLE_NAME = "lama_user";

public async createUser(
id: string,
email: string,
name: string,
password: string,
role: string
): Promise<void> {
try {
await this.getConnection()
.insert({
id,
email,
name,
password,
role
})
.into(UserDatabase.TABLE_NAME);
} catch (error) {
throw new Error(error.sqlMessage || error.message);
}
}

public async getUserByEmail(email: string): Promise<User> {
const result = await this.getConnection()
.select("*")
.from(UserDatabase.TABLE_NAME)
.where({ email });

return User.toUserModel(result[0]);
}

}
6 changes: 6 additions & 0 deletions semana19/projeto-lama/src/error/BaseError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export abstract class BaseError extends Error {
constructor(message: string, public code: number) {
super(message);
}
}

Loading