3 Commits

Author SHA1 Message Date
Andrey Antukh
1c7a73ec16
✨ Add account lockout after failed login attempts (#11402)
* ✨ Add account lockout after failed login attempts

Implement per-account brute-force protection using a Redis-backed
failed-login counter. After 5 failed attempts within 15 minutes, the
account is temporarily locked out and all login attempts (including
with the correct password) are rejected with a 429 response.

Closes #11397

AI-assisted-by: longcat-2.0

* 🐛 Bind LDAP session to directory-verified profile

The account-lockout change added a shortcut that preferred the
profile matching the typed email over the one returned by the LDAP
directory. These can differ with aliases, UPNs, or multi-valued mail
attributes, letting a user with valid LDAP credentials bind a session
to another Penpot account.

Keep the typed-email profile only for lockout checks. After LDAP
succeeds, resolve the session profile from the directory identity as
before and clear failed attempts on that profile.

AI-assisted-by: deepseek-v4.1-flash
2026-09-23 12:31:50 +02:00
Andrey Antukh
81c3b3cd56
📎 Update copyright name on file header (#11346) 2026-08-25 11:55:10 +02:00
Andrey Antukh
7c85837290
🐛 Fix session invalidation on logout to prevent token replay (#11317)
Logout only cleared the auth-token cookie but never deleted the
server-side row because delete-fn read ::id which wrap-authz no longer
sets since 363b4e3778. Make delete-fn delete via ::session/:id attached
by wrap-authz so replayed tokens are rejected (CWE-613, GHSA-mj9f-5cwq-7p3q).

Add regression tests covering invalidation, idempotency and isolation
of other sessions. Fix verified with Red→Green TDD and full backend
suite (677 tests).

Closes #11316

AI-assisted-by: muse-spark-1.2-contributor
2026-08-21 12:55:24 +02:00