security(auth): anti-enumeration, returnTo-валидация, лимит попыток логина
Шаг 2.1 плана production-готовности: - единый 401 при любом отказе логина + constant-time bcrypt - forgot-password: идентичный ответ независимо от существования email - sanitizeReturnTo (open redirect fix в /api/documents/generate-link) - 10 неудачных попыток → блок 15 мин (in-memory, аудит) - DATABASE_SSL_REJECT_UNAUTHORIZED env (дефолт true) - доделка 0.7: статичные тексты в llm-providers/rag/finance-di2 - 8 новых тестов (104/104)
This commit is contained in:
14
server/db.ts
14
server/db.ts
@@ -27,16 +27,20 @@ function getPool(): pg.Pool {
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
// SSL включается для sslmode=require и Neon. rejectUnauthorized управляется
|
||||
// env DATABASE_SSL_REJECT_UNAUTHORIZED (дефолт true — проверка сертификата);
|
||||
// 'false' допустимо только с самоподписанными сертификатами (dev-стенды).
|
||||
const sslRequired =
|
||||
process.env.DATABASE_URL.includes("sslmode=require") ||
|
||||
process.env.DATABASE_URL.includes("neon.tech");
|
||||
const sslRejectUnauthorized = process.env.DATABASE_SSL_REJECT_UNAUTHORIZED !== "false";
|
||||
|
||||
_pool = new pg.Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
max: 50,
|
||||
idleTimeoutMillis: 30_000,
|
||||
connectionTimeoutMillis: 5_000,
|
||||
ssl:
|
||||
process.env.DATABASE_URL.includes("sslmode=require") ||
|
||||
process.env.DATABASE_URL.includes("neon.tech")
|
||||
? { rejectUnauthorized: false }
|
||||
: undefined,
|
||||
ssl: sslRequired ? { rejectUnauthorized: sslRejectUnauthorized } : undefined,
|
||||
});
|
||||
|
||||
_pool.on("error", (err) => {
|
||||
|
||||
Reference in New Issue
Block a user