core.login_attempts наповнювалась на кожній спробі входу й читалась рівно в одному місці — для стримування підбору. Ні ендпойнта, ні сторінки. На питання «хто заходив у мій моніторинг» продукт мав відповідь у базі й не мав способу її показати. ГОЛОВНЕ БУЛА НЕ ВЕРСТКА. У таблиці немає tenant_id — саме тому ці події й не в аудиті. Показати «як є» означало б віддати одному кабінету спроби входу чужих людей. Прив'язка непряма: спроба -> користувач -> членство, трьома шляхами одночасно (user_id, username, email) в одному JOIN LATERAL з tenant_id усередині. Саме JOIN, а не LEFT JOIN: без збігу рядок ПРИБИРАЄТЬСЯ, а не лишається без імені. На бойових даних це не теорія: у власника немає пошти, тож за email не прив'язується ЖОДНА з 94 спроб. Шлях через username дає 93. Невдала спроба з неіснуючим логіном не належить нікому: рядком не показується, але рахується числом — сигнал «логіни перебирають» лишається, чужа людина в чужий кабінет не потрапляє. Ізоляцію перевірено проти справжньої бази (TestLoginAttemptsTenantIsolation). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| alerting | ||
| auth | ||
| cronx | ||
| crypto | ||
| difftext | ||
| gitstore | ||
| grpcapi | ||
| httpapi | ||
| logbuf | ||
| store | ||