Незакоммиченная работа сессии 2026-09-05 (уже на проде): - lib/owner.js — реестр владельцев файлов-результатов, owner-check во всех download-роутах (IDOR) - lib/limits.js — createLimiter(): skip для админа, ipKeyGenerator (фикс ERR_ERL_KEY_GEN_IPV6) - video: обработчики 'error' у ffmpeg/ffprobe (spawn ENOENT больше не роняет сервер), таймауты - pdf: runGhostscript/gsUnavailable, водяной знак с кириллицей (fontkit + TTF) - снятие лимитов размера/количества для админа в pdf/video - журнал сессии docs/sessions/2026-09-05-0231.md
37 lines
1.5 KiB
JavaScript
37 lines
1.5 KiB
JavaScript
/**
|
||
* Общая фабрика rate-limit'ов.
|
||
*
|
||
* Зачем: у каждого роута был свой keyGenerator по req.ip, из-за чего
|
||
* express-rate-limit при старте сыпал ERR_ERL_KEY_GEN_IPV6 (IPv6-клиент мог обойти лимит),
|
||
* а лимиты применялись в том числе к администратору.
|
||
*/
|
||
|
||
const { rateLimit, ipKeyGenerator } = require('express-rate-limit');
|
||
|
||
function isAdmin(req) {
|
||
return !!(req.session && req.session.user && req.session.user.role === 'admin');
|
||
}
|
||
|
||
// Ключ: залогиненный — по пользователю, гость — по IP (через хелпер, он корректно
|
||
// сворачивает IPv6 в /64-подсеть).
|
||
function keyGenerator(req) {
|
||
const id = req.session && req.session.user && req.session.user.id;
|
||
return id ? 'user_' + id : ipKeyGenerator(req.ip);
|
||
}
|
||
|
||
// Админ не ограничивается ничем: skipAdmin: false — только там, где лимит защищает
|
||
// не сервис, а самого пользователя (например, брутфорс логина).
|
||
function createLimiter({ windowMs = 60000, max = 30, message = { error: 'Слишком много запросов' }, skipAdmin = true } = {}) {
|
||
return rateLimit({
|
||
windowMs,
|
||
max,
|
||
message,
|
||
standardHeaders: true,
|
||
legacyHeaders: false,
|
||
keyGenerator,
|
||
skip: skipAdmin ? isAdmin : () => false,
|
||
});
|
||
}
|
||
|
||
module.exports = { createLimiter, isAdmin, keyGenerator };
|