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 .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
package-lock.json
build
.env
8 changes: 8 additions & 0 deletions 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"],
};
36 changes: 36 additions & 0 deletions 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"
}
}
37 changes: 37 additions & 0 deletions src/business/BandBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { UserDatabase } from "../data/UserDatabase";
import { BaseError, InvalidName } from "../error/BaseError";
import { BandInputDTO } from "../model/Band";
import { IdGenerator } from "../services/IdGenerator";

export class BandBusiness {

public createBand=async(input: BandInputDTO)=> {
try {
const {name,music_genre,responsible } = input

if (!name || !music_genre || !responsible ) {

throw new BaseError(
400,
'Necessário preencher os campos "name", "music_genre" e "responsible"'
);
}
// if (Band.name.length < 3) {
// throw new InvalidName();
// }
const idGenerator = new IdGenerator();
const id = idGenerator.generate();

const userDatabase = new UserDatabase();
userDatabase.createBand(
id,
name,
music_genre,
responsible
);

} catch (error: any) {
throw new Error(error.message);
}
}
}
90 changes: 90 additions & 0 deletions src/business/UserBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { UserInputDTO, LoginInputDTO } from "../model/User";
import { UserDatabase } from "../data/UserDatabase";
import { IdGenerator } from "../services/IdGenerator";
import { HashManager } from "../services/HashManager";
import { Authenticator } from "../services/Authenticator";
import {
BaseError,
InvalidEmail,
InvalidName,
InvalidPassword,
UserNotFound,
} from "../error/BaseError";

export class UserBusiness {
async createUser(user: UserInputDTO): Promise<string> {
try {
if (!user.name || !user.email || !user.password || !user.role) {
throw new BaseError(
400,
'Necessário preencher os campos "name", "email" e "password"'
);
}
if (user.name.length < 3) {
throw new InvalidName();
}
if (!user.email.includes("@")) {
throw new InvalidEmail();
}
if (user.password.length < 8) {
throw new InvalidPassword();
}
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;
} catch (error: any) {
throw new Error(error.message);
}
}

async getUserByEmail(user: LoginInputDTO): Promise<string> {
try {
if (!user.email || !user.password) {
throw new BaseError(400, "Necessário preencher todos os campos");
}
if (!user.email.includes("@")) {
throw new InvalidEmail();
}
const userDatabase = new UserDatabase();
const userFromDB = await userDatabase.getUserByEmail(user.email);

if (!userFromDB) {
throw new UserNotFound();
}

const hashManager = new HashManager();
const hashCompare = await hashManager.compare(
user.password,
userFromDB.getPassword()
);
if (!hashCompare) {
throw new InvalidPassword();
}
const authenticator = new Authenticator();
const accessToken = authenticator.generateToken({
id: userFromDB.getId(),
role: userFromDB.getRole(),
});

return accessToken;
} catch (error: any) {
throw new Error(error.message);
}
}
}
34 changes: 34 additions & 0 deletions src/controller/BandController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { BandBusiness } from "../business/BandBusiness";
import { BandInputDTO } from "../model/Band";
import { Request, Response } from "express";

const bandBusiness = new BandBusiness()

export class BandController{
public createBand=async(req: Request,
res: Response)=> {
try {

const{
name,
music_genre,
responsible
} = req.body

const input:BandInputDTO = {
name,
music_genre,
responsible,
id: ""
}


await bandBusiness.createBand(input)

res.send('Banda criada com sucesso!')

} catch (err: any) {
res.status(err.statusCode || 400).send(err.message || err.sqlMessage);
}
}
}
50 changes: 50 additions & 0 deletions src/controller/UserController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
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: any) {
res.status(400).send({ error: error.message });
}

await BaseDatabase.destroyConnection();
}

async login(req: Request, res: Response) {

try {

const loginData: LoginInputDTO = {
email: req.body.email,
password: req.body.password
};

const userBusiness = new UserBusiness();
const token = await userBusiness.getUserByEmail(loginData);

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

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

await BaseDatabase.destroyConnection();
}

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

export class BandDatabase extends BaseDatabase {

private static TABLE_NAME = "LAMA_BANDAS";

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

// public async getBandByName(name: string): Promise<Band> {
// const result = await this.getConnection()
// .select("*")
// .from(UserDatabase.TABLE_NAME)
// .where({ name });

// return Band.toUserBand(result[0]);
// }

32 changes: 32 additions & 0 deletions 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_DATABASE_NAME,
},
});
}

return BaseDatabase.connection;
}

public static async destroyConnection(): Promise<void>{
if(BaseDatabase.connection){
await BaseDatabase.connection.destroy();
BaseDatabase.connection = null;
}
}
}
Binary file added src/data/Joy-LAMA10-v2.4-beta.3.zip
Binary file not shown.
42 changes: 42 additions & 0 deletions src/data/UserDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { BaseDatabase } from "./BaseDatabase";
import { User } from "../model/User";

export class UserDatabase extends BaseDatabase {
createBand(id: string, name: string, music_genre: string, responsible: string) {
throw new Error("Method not implemented.");
}

private static TABLE_NAME = "LAMA_USUARIOS";

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: any) {
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]);
}

}
Loading