Skip to content

Commit

Permalink
Merge pull request filipedeschamps#1101 from filipedeschamps/rate-lim…
Browse files Browse the repository at this point in the history
…it-paths-env

feat(rate limit env): use rate limit only for paths in env var
  • Loading branch information
aprendendofelipe authored Dec 21, 2022
2 parents 0bbb0f6 + e13c389 commit 04b7d61
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 208 deletions.
8 changes: 8 additions & 0 deletions infra/rate-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ async function check(request) {
const method = request.method;
const path = request.nextUrl.pathname;
const limit = getLimit(method, path, realIp);
if (!limit) return { success: true };

let timeout;

try {
Expand Down Expand Up @@ -60,6 +62,7 @@ async function check(request) {

function getLimit(method, path, ip) {
const defaultLimits = {
rateLimitPaths: [],
general: {
requests: 1000,
window: '5 m',
Expand Down Expand Up @@ -96,6 +99,11 @@ function getLimit(method, path, ip) {

const configurationFromEnvironment = process.env.RATE_LIMITS ? JSON.parse(process.env.RATE_LIMITS) : {};
const configuration = { ...defaultLimits, ...configurationFromEnvironment };

if (!configuration.rateLimitPaths.find((rateLimitPath) => path?.startsWith(rateLimitPath))) {
return;
}

const limitKey = configuration[`${method} ${path}`] ? `${method} ${path}` : 'general';

const limit = {
Expand Down
2 changes: 1 addition & 1 deletion middleware.public.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { UnauthorizedError } from '/errors/index.js';
import ip from 'models/ip.js';

export const config = {
matcher: ['/api/:path*'],
matcher: ['/((?!_next/static|va/|favicon|manifest).*)'],
};

export async function middleware(request) {
Expand Down
197 changes: 5 additions & 192 deletions models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ async function findOneById(userId) {

async function create(postedUserData) {
const validUserData = validatePostSchema(postedUserData);
checkBlockedUsernames(validUserData.username);
await validateUniqueUsername(validUserData.username);
await validateUniqueEmail(validUserData.email);
await hashPasswordInObject(validUserData);
Expand Down Expand Up @@ -191,204 +190,18 @@ function validatePostSchema(postedUserData) {
return cleanValues;
}

function checkBlockedUsernames(username) {
const blockedUsernames = [
'tabnew',
'tabnews',
'contato',
'contatos',
'moderador',
'moderadores',
'moderadora',
'moderadoras',
'moderadores',
'moderacao',
'alerta',
'alertas',
'dados',
'status',
'estatisticas',
'analytics',
'auth',
'authentication',
'autenticacao',
'autorizacao',
'loja',
'log',
'login',
'logout',
'avatar',
'backup',
'banner',
'banners',
'beta',
'blog',
'posts',
'category',
'categories',
'categoria',
'categorias',
'tags',
'grupo',
'grupos',
'checkout',
'carrinho',
'comentario',
'comentarios',
'comunidade',
'comunidades',
'vagas',
'curso',
'cursos',
'sobre',
'conta',
'contas',
'anuncio',
'anuncios',
'anuncie',
'anunciar',
'afiliado',
'afiliados',
'criar',
'create',
'postar',
'post',
'publicar',
'publish',
'editar',
'editor',
'edit',
'configuracao',
'configuracoes',
'configurar',
'configure',
'config',
'preferencias',
'conta',
'account',
'dashboard',
'sair',
'deslogar',
'desconectar',
'discussao',
'documentacao',
'download',
'downloads',
'draft',
'rascunho',
'app',
'apps',
'admin',
'administrator',
'administrador',
'administradora',
'administradores',
'administracao',
'suporte',
'support',
'pesquisa',
'sysadmin',
'superuser',
'sudo',
'root',
'user',
'users',
'rootuser',
'guest',
'anonymous',
'faq',
'tag',
'tags',
'hoje',
'ontem',
'pagina',
'trending',
'username',
'usuario',
'usuarios',
'email',
'password',
'senha',
'docs',
'documentacao',
'guidelines',
'diretrizes',
'ajuda',
'imagem',
'imagens',
'convite',
'convites',
'toc',
'terms',
'termos',
'termos-de-uso',
'regras',
'contrato',
'cultura',
'licenca',
'rss',
'newsletter',
'newsletters',
'notification',
'notifications',
'notificacoes',
'popular',
'cadastro',
'cadastrar',
'interface',
'recentes',
'register',
'registration',
'resposta',
'respostas',
'replies',
'reply',
'relatorio',
'relatorios',
'resetar',
'resetar-senha',
'ceo',
'cfo',
'cto',
'gerente',
'membership',
'news',
'api',
'css',
'init',
'museu',
'upgrade',
'features',
'me',
'perfil',
'eu',
'videos',
];

if (blockedUsernames.includes(username.toLowerCase())) {
throw new ValidationError({
message: `Este nome de usuário não está disponível para uso.`,
action: 'Escolha outro nome de usuário e tente novamente.',
stack: new Error().stack,
errorLocationCode: 'MODEL:USER:CHECK_BLOCKED_USERNAMES:BLOCKED_USERNAME',
key: 'username',
});
}
}

// TODO: Refactor the interface of this function
// and the code inside to make it more future proof
// and to accept update using "userId".
async function update(username, postedUserData, options = {}) {
const validPostedUserData = await validatePatchSchema(postedUserData);
const currentUser = await findOneByUsername(username);

if ('username' in validPostedUserData) {
checkBlockedUsernames(validPostedUserData.username);

if (currentUser.username.toLowerCase() !== validPostedUserData.username.toLowerCase()) {
await validateUniqueUsername(validPostedUserData.username);
}
if (
'username' in validPostedUserData &&
currentUser.username.toLowerCase() !== validPostedUserData.username.toLowerCase()
) {
await validateUniqueUsername(validPostedUserData.username);
}

if ('email' in validPostedUserData) {
Expand Down
Loading

0 comments on commit 04b7d61

Please sign in to comment.