Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR de correção #15

Open
wants to merge 33 commits into
base: correcao-projeto
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3b0dc6e
instalação das dependencias e modulos iniciais
OsmanRodrigues Jul 20, 2020
a68c4ce
Merge pull request #1 from future4code/work-osman-segunda
wcardosos Jul 20, 2020
5b0f011
ajustes na organização das dependencias
OsmanRodrigues Jul 21, 2020
c81b76f
Merge pull request #2 from future4code/work-osman-segunda
WellDMLT Jul 21, 2020
7dfd53a
organização das variabeis de ambiente
OsmanRodrigues Jul 21, 2020
7912a41
implementação do endpoint /post/create
OsmanRodrigues Jul 21, 2020
5ea98ca
Merge pull request #3 from future4code/work-osman-terca
wcardosos Jul 21, 2020
a48f927
arquivos iniciais
WellDMLT Jul 22, 2020
914eb2c
Merge pull request #4 from future4code/wellington
OsmanRodrigues Jul 22, 2020
6ee86c3
implementação do endpoit getpostbyid
OsmanRodrigues Jul 22, 2020
6256396
Merge pull request #5 from future4code/work-osman-quarta
OsmanRodrigues Jul 22, 2020
69c9f3d
Revert "implementação do endpoit getpostbyid"
OsmanRodrigues Jul 22, 2020
7c9f2ec
Merge pull request #6 from future4code/revert-5-work-osman-quarta
OsmanRodrigues Jul 22, 2020
62886ab
implementação do endpoit getpostbyid
OsmanRodrigues Jul 22, 2020
0f42efd
pequenos ajustes no endpoint getpostbyid
OsmanRodrigues Jul 22, 2020
a0213cd
Merge branch 'master' into work-osman-quarta
OsmanRodrigues Jul 22, 2020
597c0d6
Merge pull request #7 from future4code/work-osman-quarta
wcardosos Jul 23, 2020
559f4e0
Refatoração do código
WellDMLT Jul 23, 2020
7ec92a6
Merge pull request #8 from future4code/wellington-dia-2
OsmanRodrigues Jul 23, 2020
b115526
modificação do getpostbyid para retornar uma data padrão e não um obj…
OsmanRodrigues Jul 23, 2020
8c9137a
implementação da classe custom error e validção dos endpoints /post/c…
OsmanRodrigues Jul 23, 2020
4d1d736
Merge pull request #9 from future4code/work-osman-quinta
WellDMLT Jul 23, 2020
1942bd7
método de signup feito
WellDMLT Jul 24, 2020
ad3a93e
estrutura de login, algumas partes realizadas
WellDMLT Jul 24, 2020
edb9631
Merge pull request #10 from future4code/wellington-dia-3
OsmanRodrigues Jul 24, 2020
5e6f7d9
login finalizado
WellDMLT Jul 24, 2020
33f0fe6
Merge pull request #11 from future4code/welligton-dia-4
OsmanRodrigues Jul 24, 2020
0bbad38
Feed implementado
wcardosos Jul 24, 2020
1f2ca66
Merge pull request #12 from future4code/feed
OsmanRodrigues Jul 24, 2020
4bb83d8
implementação dos endpoints create e delete friendship
OsmanRodrigues Jul 24, 2020
89e8bd9
Merge pull request #13 from future4code/work-osman-sexta
WellDMLT Jul 24, 2020
9bf9fbd
commit pré-entrega final
OsmanRodrigues Jul 24, 2020
368cad5
Merge pull request #14 from future4code/work-final
OsmanRodrigues Aug 5, 2020
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 .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
.env
2,053 changes: 2,053 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "julian-labook2",
"version": "1.0.0",
"description": "backend de rede social desenvolvido como projeto da semana 18",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "clear && ts-node ./src/index.ts"
},
"repository": {
"type": "git",
"url": "git+https://github.com/future4code/julian-labook2.git"
},
"author": "Osman Rodrigues, Wellington Cardoso e Wagner Cardoso",
"license": "ISC",
"bugs": {
"url": "https://github.com/future4code/julian-labook2/issues"
},
"homepage": "https://github.com/future4code/julian-labook2#readme",
"dependencies": {
"@types/bcrypt": "^3.0.0",
"@types/bcryptjs": "^2.4.2",
"@types/express": "^4.17.0",
"@types/jsonwebtoken": "^8.5.0",
"@types/knex": "^0.16.1",
"@types/moment": "^2.13.0",
"@types/node": "^14.0.23",
"@types/uuid": "^8.0.0",
"bcryptjs": "^2.4.3",
"dotenv": "^8.2.0",
"express": "^4.17.0",
"jsonwebtoken": "^8.5.1",
"knex": "^0.21.2",
"moment": "^2.27.0",
"mysql": "^2.18.1",
"ts-node": "^8.10.2",
"typescript": "^3.9.7",
"uuid": "^8.2.0"
}
}
50 changes: 50 additions & 0 deletions src/business/PostsBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {PostsDatabase} from '../data/PostsDatabase';
import {IdGenerator} from '../services/utils/IdGenerator';
import {CustomError} from '../error/CustomError';

export class PostsBusiness{

async createPost(
img_url: string,
type?:string,
create_at?: string,
description?:string
){
//TODO: validar criação de post mediante access token
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lembrem de remover os comentários depois!

if(! img_url || img_url.trim() === ''){
throw new CustomError(416,'Missing post image url.');
}else if(! img_url.includes('http')){
throw new CustomError(406,'Invalid post image url.');
};
Comment on lines +14 to +18
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gostei da validação aqui!


const usePostsDb = new PostsDatabase();
const idGen = new IdGenerator();

await usePostsDb.createPost({
id: idGen.generate(),
img_url,
type,
create_at,
description
});
};

Comment on lines +22 to +31
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O endpoint realmente acabou por criar o post sem gravar o autor do post

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Macacos me mordam! Eu lembrei de ter arrumado o campo na tabela pra receber essa info, mas esqueci de mudar na query! haha

async getPostById(id:string): Promise<any>{
//TODO: validar consulta de post mediante access token
if(id.length != 36){
throw new CustomError(416,'Invalid post id.');
};
try{
const usePostsDb = new PostsDatabase();
const dbResponse = await usePostsDb.getPostById(id);

if(! dbResponse){
throw new CustomError(416,'Post not found.');
};

return dbResponse;
}catch(e){
throw new CustomError(400, e.message);
};
};
};
91 changes: 91 additions & 0 deletions src/business/UserBusiness.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { UserDatabase } from "../data/UserDatabase";
import { IdGenerator } from "../services/utils/IdGenerator";
import {HashManager} from '../services/utils/HashManager';
import {Authenticator} from '../services/utils/Authenticator';
import {CustomError} from '../error/CustomError';

export class UserBusiness{

public async signup(name: string, email: string, password: string, role:string){

try {
const idGenerator = new IdGenerator();
const id:string = idGenerator.generate();

const useHashed = new HashManager();
const passwordHashed = await useHashed.hash(password);

const userDatabase = new UserDatabase();
await userDatabase.signup(id, name, email, passwordHashed, role)

const autheticated = new Authenticator();
const token = autheticated.generateToken({ id, name, email, role },process.env.ACC_TOKEN_EXPIRES_IN);


return { accessToken: token }

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

public async login(email:string, password:string){
const userDatabase = new UserDatabase();
const userInfo = await userDatabase.getByEmail(email);

const checkedPassword = new HashManager();
const comparePassword = await checkedPassword.checkHash(userInfo.password ,password);

const autheticated = new Authenticator();
const token = autheticated.generateToken( userInfo ,process.env.ACC_TOKEN_EXPIRES_IN);

return comparePassword && token;

};

public async makeFriendship(friendId: string, token: string){
//TODO: não permitir amizades duplicadas ou com o mesmo id de usuário e amigo
if(!token){
throw new CustomError(416, 'Token de acesso ausente.')
};

const useAuthenticator = new Authenticator();
const useUserDb = new UserDatabase();

const userTokenInfos = useAuthenticator.getData(token);
const userDbInfos = await useUserDb.getById(userTokenInfos.id);

if(!userDbInfos){
throw new CustomError(404, 'Usuário não encontrado.');
};

try{
await useUserDb.createFriendship(userTokenInfos.id, friendId);
}catch(e){
throw new CustomError(400, e.message)
};
};

public async deleteFriendship(friendId: string, token: string){
if(!token){
throw new CustomError(416, 'Token de acesso ausente.')
};

const useAuthenticator = new Authenticator();
const useUserDb = new UserDatabase();

const userTokenInfos = useAuthenticator.getData(token);
const userDbInfos = await useUserDb.getById(userTokenInfos.id);

if(!userDbInfos){
throw new CustomError(404, 'Usuário não encontrado.');
};

try{
const useUserDb = new UserDatabase();
await useUserDb.deleteFriendship(userTokenInfos.id, friendId);
}catch(e){
throw new CustomError(400, e.message)
};
};
};
41 changes: 41 additions & 0 deletions src/controller/FeedController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Request, Response } from 'express';
import { Authenticator } from '../services/utils/Authenticator';
import { PostsDatabase } from '../data/PostsDatabase';

export class FeedController {
async showFeed(request: Request, response: Response) {
try {
const { authorization } = request.headers;
const { type } = request.query;
const auth = new Authenticator();
const payload = auth.getData(authorization);
const postsDb = new PostsDatabase();

const feedData = await postsDb.showFeed(payload.id);

await postsDb.destroyConnection();

return response.send({ feed: feedData });
} catch(e) {
response.status(400).send({ error: e.message})
}
}

async showFeedByType(request: Request, response: Response) {
try {
const { authorization } = request.headers;
const { type } = request.query;
const auth = new Authenticator();
auth.getData(authorization);
const postsDb = new PostsDatabase();

const feedData = await postsDb.showFeedByType(type as string);

await postsDb.destroyConnection();

return response.send({ feed: feedData });
} catch(e) {
response.status(400).send({ error: e.message });
}
}
}
35 changes: 35 additions & 0 deletions src/controller/PostsController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {Request, Response} from 'express';
import {PostsBusiness} from '../business/PostsBusiness';
import {PostsDatabase} from '../data/PostsDatabase';

import moment from 'moment';

export class PostsController {
async createPost(req: Request, res: Response){
try{
const body = req.body;
await new PostsBusiness().createPost(
body.img_url, body.type, body.create_at, body.description
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uma possibilidade aqui é deixar a criação das datas automática!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eu passei por precaução pq tinha uma validação no business e um default pra o campo de data lá no banco atribuir a curdate caso não fosse passada uma data. É melhor prevenir do que remediar! haha

);

res.send({message: `Post created successfully!`}).status(200);

await new PostsDatabase().destroyConnection();
}catch(e){
res.status(400).send({error: e.message});
}
};
async getPostById(req: Request, res: Response): Promise<void>{
try{
const postId = String(req.params.id);
const response = await new PostsBusiness().getPostById(postId);

res.send({post:{
...response, create_at: moment(response.create_at, 'YYYY/MM/DD').format('DD/MM/YYYY')
}}).status(200);
}catch(e){
res.status(400).send({error: e.message});
};
};
};

70 changes: 70 additions & 0 deletions src/controller/UserController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Request, Response } from "express";
import { UserBusiness } from "../business/UserBusiness";

export class UserController {

async signup(req: Request, res: Response) {
const userBusiness: UserBusiness = new UserBusiness();

try {
const name = req.body.name;
const email = req.body.email;
const password = req.body.password;
const role = req.body.role;

const result = await userBusiness.signup(name, email, password, role);

res.status(200).send({ message: "Usuário criado com sucesso", result });

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

/* TODO validações de senha e email */

async login(req: Request, res: Response) {
const userBusiness: UserBusiness = new UserBusiness();

try {
const body = req.body

const requestInfo = await userBusiness.login(body.email, body.password);


if(requestInfo){
res.status(200).send({accessToken: requestInfo })
}

} catch (error) {
res.status(400).send({ error: error.message });
}
Comment on lines +31 to +41
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Temos um probleminha aqui. Se a senha estiver incorreta nunca caímos no catch e o endpoint carrega para sempre

};

async makeFriendship(req: Request, res: Response){
const headersToken = req.headers.authorization;
const useUserBusiness: UserBusiness = new UserBusiness();
try {
const body = req.body
await useUserBusiness.makeFriendship(body.friendId, headersToken);

res.status(200).send({message: 'Amizade criada com sucesso!'})
} catch (error) {
res.status(400).send({ error: error.message });
}
};

async deleteFriendship(req: Request, res: Response){
const headersToken = req.headers.authorization;
const useUserBusiness: UserBusiness = new UserBusiness();

try {
const body = req.body
await useUserBusiness.deleteFriendship(body.friendId, headersToken);

res.status(200).send({message: 'Amizade desfeita com sucesso!'})
} catch (error) {
res.status(400).send({ error: error.message });
}
};
};
28 changes: 28 additions & 0 deletions src/data/BaseDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import knex from "knex"
import Knex from "knex"

export abstract class BaseDatabase{
private static connection: Knex | null = null;

public getConnection(tableName?:string): 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 async destroyConnection() {
await BaseDatabase.connection.destroy()
BaseDatabase.connection = null;
};
};
Loading