Skip to content

Commit

Permalink
refatora tipos de usuário e aplica rate limiting nas rotas de autenti…
Browse files Browse the repository at this point in the history
…cação e snippets
  • Loading branch information
Jonhvmp committed Dec 7, 2024
1 parent 540eedb commit 2abb41b
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 141 deletions.
186 changes: 99 additions & 87 deletions backend/package-lock.json

Large diffs are not rendered by default.

4 changes: 0 additions & 4 deletions backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { connectDB } from './config/database'
import cors from 'cors';
import helmet from 'helmet';
import morgan from 'morgan';
import { authenticatedLimiter, limiter } from './utils/rateLimiting';

const app = express();

Expand All @@ -30,9 +29,6 @@ app.use('/api/auth', authRoutes);

app.use('/api/snippets', snippetRoutes);

app.use(limiter); // Aplicando o rate limiter
app.use('/api', authenticatedLimiter) // Aplicando o rate limiter apenas para rotas autenticadas

// Passando uma mensagem dinâmica para o middleware de erro
app.use((req: Request, res: Response, next: NextFunction): void => {
res.status(404).json({ message: 'Rota não encontrada' });
Expand Down
2 changes: 1 addition & 1 deletion backend/src/controllers/authController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const loginUser = async (req: Request, res: Response, next: NextFunction)

// Verifica se o usuário está bloqueado
if (user.isLocked()) {
return handleValidationError(res, 'Conta bloqueada devido a várias tentativas de login. Tente novamente mais tarde.');
return handleValidationError(res, 'Conta bloqueada devido a várias tentativas de login. Tente novamente mais tarde.');
}

const isMatch = await user.comparePassword(password);
Expand Down
9 changes: 5 additions & 4 deletions backend/src/routes/authRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { registerUser, loginUser, forgotPassword, resetPassword } from '../contr
import { body } from 'express-validator';
import { ValidationChain, Result, validationResult } from 'express-validator';
import { validateResetToken } from '../middlewares/validateResetToken';
import { limiter } from '../utils/rateLimiting';

// Criando um method switch para validação de campos
interface ValidationMethod {
Expand Down Expand Up @@ -68,14 +69,14 @@ const asyncHandler = (fn: Function) => (req: any, res: any, next: any) => {
const router = Router();

// Rotas para usuários
router.post('/register', validate('register'), validateRequest, asyncHandler(registerUser)); // Registro de um novo usuário
router.post('/register', validate('register'), limiter, validateRequest, asyncHandler(registerUser)); // Registro de um novo usuário

router.post('/login', validate('login'), validateRequest, asyncHandler(loginUser)); // Login de usuário
router.post('/login', validate('login'), limiter, validateRequest, asyncHandler(loginUser)); // Login de usuário

// Rotas de forgot e reset password
router.post('/forgot-password', validate('forgot-password'), validateRequest, asyncHandler(forgotPassword)); // Solicitação de redefinição de senha
router.post('/forgot-password', limiter, validate('forgot-password'), validateRequest, asyncHandler(forgotPassword)); // Solicitação de redefinição de senha

router.post('/reset-password/:token', validateResetToken, validate('reset-password'), validateRequest, asyncHandler(resetPassword));
router.post('/reset-password/:token', limiter, validateResetToken, validate('reset-password'), validateRequest, asyncHandler(resetPassword));


router.use((err: any, req: Request, res: Response, next: NextFunction): void => {
Expand Down
25 changes: 13 additions & 12 deletions backend/src/routes/snippetRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,53 +13,54 @@ import {
fetchSharedSnippet,
shareSnippet,
} from '../controllers/snippetController';
import { authenticatedLimiter, limiter } from '../utils/rateLimiting';

const router = Router();

// Rotas para snippets
router.get('/public-snippets', validateToken, (req, res, next) => {
router.get('/public-snippets', authenticatedLimiter, validateToken, (req, res, next) => {
fetchPublicSnippets(req, res, next).catch(next); // Propaga erros ao middleware
}); // Busca snippets públicos

router.post('/create-snippets', validateToken, (req, res, next) => {
router.post('/create-snippets', authenticatedLimiter, validateToken, (req, res, next) => {
createSnippet(req, res, next).catch(next);
}); // Criação de um novo snippet

router.get('/my-snippets', validateToken, (req, res, next) => {
router.get('/my-snippets', authenticatedLimiter, validateToken, (req, res, next) => {
fetchMySnippets(req, res, next).catch(next);
}); // Busca snippets do usuário

router.get('/my-favorites', validateToken, (req, res, next) => {
router.get('/my-favorites', authenticatedLimiter, validateToken, (req, res, next) => {
fetchMySnippetsFavorite(req, res, next).catch(next);
}); // Busca snippets favoritos do usuário

router.get('/search', validateToken, (req, res, next) => {
router.get('/search', authenticatedLimiter, validateToken, (req, res, next) => {
fetchPublicSnippets(req, res, next).catch(next);
}); // Busca snippets por termo

router.get('/tags', validateToken, (req, res, next) => {
router.get('/tags', authenticatedLimiter, validateToken, (req, res, next) => {
fetchPublicSnippets(req, res, next).catch(next);
}); // Busca snippets por tag

router.get('/shared/:link', fetchSharedSnippet); // Busca snippets compartilhados com o usuário
router.get('/shared/:link', limiter, fetchSharedSnippet); // Busca snippets compartilhados com o usuário

router.post('/:id/share', validateToken, (req, res, next) => {
router.post('/:id/share', authenticatedLimiter, validateToken, (req, res, next) => {
shareSnippet(req, res, next).catch(next);
}); // Compartilha um snippet

router.put('/:id', validateToken, (req, res, next) => {
router.put('/:id', authenticatedLimiter, validateToken, (req, res, next) => {
updateSnippet(req, res, next).catch(next);
}); // Atualização de um snippet existente

router.delete('/:id', validateToken, (req, res, next) => {
router.delete('/:id', authenticatedLimiter, validateToken, (req, res, next) => {
deleteSnippet(req, res, next).catch(next);
}); // Exclusão de um snippet

router.get('/:id', validateToken, (req, res, next) => {
router.get('/:id', authenticatedLimiter, validateToken, (req, res, next) => {
getSnippet(req, res, next).catch(next);
}); // Busca um snippet específico

router.patch('/:id/favorite', validateToken, (req, res, next) => {
router.patch('/:id/favorite', authenticatedLimiter, validateToken, (req, res, next) => {
markFavorite(req, res, next).catch(next);
}); // Marca ou desmarca como favorito

Expand Down
1 change: 1 addition & 0 deletions backend/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import app from './app';
import env from './config/env';
import './types/';

const PORT = env.PORT || '';

Expand Down
11 changes: 11 additions & 0 deletions backend/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Request } from 'express';

declare module 'express-serve-static-core' {
interface Request {
user?: {
id: string;
name?: string;
email?: string;
};
}
}
7 changes: 0 additions & 7 deletions backend/src/types/types/index.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion backend/src/utils/rateLimiting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export const limiter = rateLimit({
// Limite de requisições por usuário autenticado
export const authenticatedLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutos
max: 500, // 500 requisições
max: 500,
message: 'Você atingiu o limite de requisições. Por favor, tente novamente em 15 minutos.',
});
39 changes: 14 additions & 25 deletions backend/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,18 @@
{
"compilerOptions": {
/* Language and Environment */
"target": "ES2020", // Define a versão ECMAScript para o código gerado.
"module": "commonjs", // Sistema de módulos padrão para Node.js.
"lib": ["ES2020"], // Inclui declarações para ES2020.
"esModuleInterop": true, // Permite importação de módulos ES6 como CommonJS.
"forceConsistentCasingInFileNames": true, // Garante consistência de capitalização em nomes de arquivos.

/* Modules */
"moduleResolution": "node", // Resolve módulos como o Node.js.
"resolveJsonModule": true, // Permite a importação de módulos JSON.

/* Typo Roots */
"typeRoots": ["./node_modules/@types", "./src/types"], // Caminho para as definições de tipo.

/* Emit */
"outDir": "./dist", // Define o diretório de saída para arquivos compilados.
"rootDir": "./src", // Define o diretório raiz para os arquivos TypeScript.
"types": ["jest"], // Inclui tipos de teste do Jest.
"sourceMap": true, // Gera arquivos de mapa de origem para depuração.

/* Type Checking */
"strict": true, // Habilita todas as verificações de tipo estritas.
"skipLibCheck": true // Ignora a verificação de tipo em arquivos de declaração (.d.ts).
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"strict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"typeRoots": ["./node_modules/@types", "./src/types"], // Certifique-se disso!
"resolveJsonModule": true,
"outDir": "./dist",
"rootDir": "./src",
"skipLibCheck": true
},
"include": ["src/**/*"], // Inclui apenas a pasta 'src' para compilação.
"exclude": ["node_modules", "dist"] // Exclui 'node_modules' e 'dist' da compilação.
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

0 comments on commit 2abb41b

Please sign in to comment.