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
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A API registra cada transação de conversão com todas as informações relacio

A aplicação foi desenvolvida no modelo de camadas MSC (Model-Service-Conntroller) em Node.js, utilizando Typescript, Express.js, banco de dados SQLite, ORM Sequelize e Swagger para a documentação. Tem autenticação de usuário dom Json Web Token (JWT). Além disso, é possível radar a aplicação pelo Docker.</br>
Para os testes unitários e de integração, foi utilizado Mocha, Chai e Sinon.</br>
Para deploy da aplicação, foi utilizado o [Railway](https://exchange-api.up.railway.app/).
Para deploy da aplicação, foi utilizado o [Render](https://exchange-api.onrender.com).

## Inicialização da Aplicação

Expand Down Expand Up @@ -45,8 +45,7 @@ Com a aplicação rodando acesse a [documentação da API](http://localhost:3001

## Melhorias Futuras

- Corrigir o erro de deploy no Railway (está retornando um erro de token inválido ao tentar acessar a aplicação).
- Adicionar um fluxo de entrega contínua (CI/CD).
- Corrigir o erro de deploy no Render (está retornando um erro de token inválido ao tentar acessar a aplicação).
- Melhorar os testes unitários e de integração da aplicação.

## Itens desejáveis
Expand All @@ -61,7 +60,7 @@ Com a aplicação rodando acesse a [documentação da API](http://localhost:3001
- [x] Testes de integração
- [x] Documentação dos endpoints
- [x] Estar rodando e disponível (Ex: Heroku, ou similar)
- [ ] CI/CD
- [x] CI/CD

---

Expand Down
Binary file modified database.sqlite
Binary file not shown.
31 changes: 31 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
},
"homepage": "https://bitbucket.org/recrutamento_jya_nodejs/recrutamento-conversor-nodejs-thais_kotovicz_hotmail.com#readme",
"dependencies": {
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
Expand All @@ -39,6 +40,7 @@
"@types/chai": "^4.3.4",
"@types/chai-as-promised": "^7.1.5",
"@types/chai-http": "^4.2.0",
"@types/cookie-parser": "^1.4.3",
"@types/cors": "^2.8.13",
"@types/express": "^4.17.17",
"@types/joi": "^17.2.3",
Expand Down
3 changes: 3 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'express-async-errors';
import express from 'express';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import swaggerJSDoc from 'swagger-jsdoc';
import swaggerUi from 'swagger-ui-express';
import swaggerConfig from './docs/swagger.config';
Expand All @@ -13,6 +14,8 @@ const app = express();
app.use(express.json());
app.use(cors());

app.use(cookieParser());

const swaggerDoc = swaggerJSDoc(swaggerConfig);
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc));

Expand Down
39 changes: 24 additions & 15 deletions src/middlewares/authMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import 'dotenv/config';
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { ErrorTypes } from '../errors/catalog';
import JwtService from '../services/jwtService';

export default function authMiddleware(req: Request, res: Response, next: NextFunction) {
const authorization = req.headers.authorization;
interface AuthRequest extends Request {
userId: string;
}

if (!authorization) {
throw new Error(ErrorTypes.InvalidToken);
}
interface DecodedToken {
id: string;
// outras propriedades do payload do token, se houver
}

const secret = process.env.JWT_SECRET as string;

// o token de autorização é enviado no formato 'Bearer <token>'
// o split separa a string em dois e o primeiro elemento `Bearer` não será utilizado
// A desestruturação permite que o segundo elemento `token` seja atribuído diretamente à variável token
const [token] = authorization.split(' ');
export default function authMiddleware(req: AuthRequest, res: Response, next: NextFunction) {
const token = req.cookies?.token ?? null;

try {
JwtService.validateToken(token);
return next();
} catch (error) {
if (!token) {
throw new Error(ErrorTypes.InvalidToken);
}
}

jwt.verify(token, secret, (err: jwt.JsonWebTokenError, decoded: DecodedToken) => {
if (err) throw new Error(ErrorTypes.InvalidToken);

req.userId = decoded.id;
next();
});
}

// https://github.com/expressjs/cookie-parser
2 changes: 2 additions & 0 deletions src/routes/Exchange.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Router } from 'express';
import authMiddleware from '../middlewares/authMiddleware';
import { exchangeController } from './main';
import authCookieMiddleware from '../middlewares/authCookieMiddleware';

const exchangeRouter = Router();

exchangeRouter.use(authCookieMiddleware);
exchangeRouter.use(authMiddleware);

exchangeRouter.post('/exchange', exchangeController.createTransaction);
Expand Down
2 changes: 1 addition & 1 deletion src/services/jwtService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dotenv/config';
import * as jwt from 'jsonwebtoken';
import { ErrorTypes } from '../errors/catalog';

interface IUserJwt {
export interface IUserJwt {
id: number
username: string
}
Expand Down