Commit Graph
97 Commits
Author SHA1 Message Date
Daniel Hiller 8236cde954 fix: Keep the seed from refusing to start an instance that already ran
The validation added with the admin user checks reached further than intended.
The seed runs on every container start, not only on the first, and it threw on
three conditions that are normal on a second start.

The worst was the check for an existing user: after the first start the
default admin exists by definition, so every restart after that ended in a
container that would not come up. The insert is wrapped in a try and falls
back to an update precisely because it is meant to run again, and that path
was never reached.

The other two were narrower but the same shape. `validator.isEmail` rejects
`admin@localhost`, which is a common value in self-hosted setups, so an
instance that had been running for a year would stop coming up after the
upgrade.

None of it throws now. Bad input is reported on stderr and skipped, the way
an invalid username already was, and a username that belongs to someone else
is left alone rather than taken. `db:create-admin-user` keeps the strict
validation, which is where a person is there to read it and type again.
2026-09-17 00:48:08 +02:00
Daniel Hiller caa3f720e9 Merge pull request #1723 from AymanAlSuleihi/fix/create-admin-user-seed-validation
fix: Create admin user seed validation
2026-09-17 00:44:37 +02:00
Daniel Hiller de4d768831 fix: close the gaps a security review found in the default install
Reported against 2.2.1 by someone reading the source. Every finding held.

**Sign-in had no ceiling.** Failures were logged with the caller's address
and nothing more. Two counters now — one per address, one per account —
because the two attacks look different: one source working through many
accounts is caught by the first, many sources working on one account by the
second, and behind a proxy only the second still means anything.

The count is kept in the process that serves the request. PLANKA needs no
Redis and the stock deployment is one container; run several and each keeps
its own count, which multiplies the ceiling by their number. That trade is
written where the limits are configured.

**The second factor could be guessed at leisure.** Six digits, and a
pending token that stayed valid for its full ten minutes however many codes
were wrong. Wrong codes are now counted on the session row — in the
database, so the count survives a restart and holds across every process —
and when the budget is spent the session is destroyed. After that even the
right code is refused and the login starts over from the password.

**Avatars, background images and favicons** checked the token's signature
and nothing else, so a revoked session, a deactivated account or a changed
password all kept working there for as long as the signature lasted, which
is a year by default. The five checks the API makes now live in one helper
that both use, rather than the shortened copy that had drifted from it.

**A link attachment's favicon** was fetched from wherever the URL pointed.
Storing a link is harmless — it is a string the user typed — but fetching
its icon is a request the server makes to an address the user chose, and
whether an icon came back reported on what is reachable from inside the
network. Server-side fetches now refuse private, loopback and link-local
addresses, `169.254.169.254` among them. The attachment is still created:
linking to an internal wiki is a legitimate thing to do, and it was the
server's own request that had to stop.

**The signing key.** Our own compose file ships `notsecretkey`, and it is
printed in the documentation — so on any instance that copied it, anyone can
sign a token for any account. PLANKA now says so on every start, and keeps
saying it, along with a key that is missing or shorter than 32 characters.
The placeholder carries the warning inline, where it is copied from.

**The backup script** wrote password hashes, live sessions, TOTP secrets and
SMTP credentials to an unencrypted archive. `BACKUP_PASSPHRASE` now encrypts
it, and without one the script says what it just put on disk. It also says
what it is — an example for the stock compose stack, not a backup concept —
and names the window between the database dump and the file copy, which no
ordering closes.
2026-08-28 20:55:54 +02:00
Daniel Hiller d7da44efe4 feat: Add script to clean orphaned reference records
Instances that accumulated project managers, favorites, board memberships
or board subscriptions pointing at a project or board that no longer exists
had no way to find or clear them.

The script reports by default and only deletes with `--apply`, which first
asks whether a backup exists and refuses outright without a terminal to ask
on. It removes nothing but reference rows: structural orphans such as a
board without a project carry user content, and a membership whose
denormalized project is stale still grants real access to an existing
board, so both are reported and left alone.
2026-08-26 09:31:18 +02:00
Daniel Hiller 3ef87a8603 feat: Add configurable auto logout on inactivity
Users can pick an inactivity timeout in their preferences. A warning
appears 30 seconds before, and activity or a logout is synchronised
across open tabs.
2026-08-08 00:24:16 +02:00
Daniel Hiller 2e4904f77d feat: Add two-factor authentication via TOTP
Adds TOTP setup with QR code, login challenge, recovery codes and
trusted devices that let a browser skip the second factor for 30
days. Admins can reset another user's second factor by confirming
with their own password.
2026-08-07 20:11:55 +02:00
Daniel Hiller 36aa732fec feat: Remove OIDC and SSO support
Existing SSO accounts have no local password, so the migration
deactivates them before dropping is_sso_user and the
identity_provider_user table.
2026-08-07 19:15:43 +02:00
Ayman c587a1441d fix: Add password validation for admin user seeding process 2026-07-08 08:05:00 +01:00
Ayman aeb3456091 refactor: Replace while true with flag based validation 2026-07-08 07:42:04 +01:00
Ayman 2f5252faad fix: Add email uniqueness check to admin user seeding process 2026-07-08 07:17:39 +01:00
Ayman 7fbc2ea737 fix: Add username uniqueness check to admin user seeding 2026-07-08 07:17:32 +01:00
Ayman 0a2641db84 fix: Add email validation to admin user seeding process 2026-07-08 07:17:26 +01:00
Ayman 062cc3c347 fix: Add name length validation to admin user seeding process 2026-07-08 07:17:14 +01:00
Ayman 1d523cdab5 fix: Add username validation to admin user seeding process 2026-07-08 07:17:05 +01:00
Maksim Eltyshev c342d2edd7 feat: Add ability to display card ages 2026-03-18 09:42:20 +01:00
Maksim Eltyshev b2e3aac314 chore: Upgrade data structure only if S3 is enabled 2026-02-10 18:52:25 +01:00
Maksim Eltyshev 8c4859fed5 chore: Sync upgrade script with latest changes 2026-02-10 18:34:26 +01:00
Maksim Eltyshev 450bd875c1 chore: Update server dependencies 2026-02-04 12:53:15 +01:00
Maksim Eltyshev 052edc9fb1 feat: Migrate file storage to unified data directory 2026-01-31 20:27:15 +01:00
Maksim Eltyshev ffdb7254b3 fix: Enable favorites by default 2026-01-25 18:37:56 +01:00
Maksim Eltyshev b2c4c530c6 fix: Fix variable name in seeder 2026-01-23 11:42:40 +01:00
Maksim Eltyshev 1264fd5715 feat: Add internal runtime configuration 2026-01-22 18:02:42 +01:00
Maksim Eltyshev a60f8e3c3e chore: Rename for consistency 2026-01-13 17:52:31 +01:00
Maksim Eltyshev 4f5f5ddad4 feat: Display last updates in About modal 2025-12-17 15:49:33 +01:00
Maksim Eltyshev c058df8fc4 fix: Rename GIN indexes 2025-11-27 19:31:11 +01:00
Samuel b4cbd32bf2 feat: Add API key authentication (#1254)
Closes #945
2025-11-06 20:56:48 +01:00
Maksim Eltyshev c6f4dcdb70 feat: Add ability to configure and test SMTP via UI 2025-09-22 20:35:13 +02:00
Maksim Eltyshev 984b789e2e feat: Add board setting to expand task lists by default
Closes #683, closes #1333
2025-09-05 23:21:08 +02:00
Steven Correia 37bd4d1349 feat: Restore toggleable due dates (#1332) 2025-09-05 13:55:20 +02:00
Maksim Eltyshev 4d77a1f596 feat: Track storage usage 2025-08-23 00:03:20 +02:00
Maksim Eltyshev 2f4bcb0583 feat: Add legal requirements (#1306) 2025-08-21 15:10:02 +02:00
Maksim Eltyshev 48e261ffc4 fix: Improve upgrade script, log statuses
Closes #1280
2025-08-04 20:51:40 +02:00
Symon Baikov d8fbf2f909 feat: Add ability to hide completed tasks (#1210) 2025-07-21 18:33:02 +02:00
Maksim Eltyshev 230f50e3d9 feat: Add ability to link tasks to cards 2025-07-11 01:04:02 +02:00
Maksim Eltyshev 709a0d1758 feat: Persist closed state per card 2025-07-09 17:45:47 +02:00
Maksim Eltyshev b22dba0d11 feat: Move webhooks configuration from environment variable to UI 2025-07-04 22:04:11 +02:00
Maksim Eltyshev 46f4d5c1f8 fix: Canonicalize locale codes 2025-06-03 12:46:06 +02:00
Hannes 4049b4c396 feat: Display comments total on front of cards (#1146)
Closes #1136
2025-05-23 17:31:28 +02:00
Maksim Eltyshev 86cfd155f2 feat: Add board activity log 2025-05-22 23:14:46 +02:00
Maksim Eltyshev 777ff467f3 fix: Prevent upgrade script from running other migrations 2025-05-22 16:40:46 +02:00
Maksim Eltyshev 652c5e9475 fix: Use batch inserts to avoid query size limits 2025-05-19 17:27:18 +02:00
Maksim Eltyshev 2ee1166747 feat: Version 2
Closes #627, closes #1047
2025-05-10 02:09:06 +02:00
Lukas Corona 4821d407a7 feat: Ability to set list color indicator (#1033)
Closes #840
2025-02-25 15:58:59 +01:00
Maksim Eltyshev 97f4c0ab0d fix: Secure S3 attachments, bump SDK, refactoring
Closes #673
2024-11-12 15:58:22 +01:00
Nguyễn Hải Quang f20a3d50f5 feat: Add S3 support for uploads (#938) 2024-11-11 14:59:18 +01:00
Maksim Eltyshev 50519f1bcd feat: Additional httpOnly token for enhanced security in browsers 2024-09-01 09:31:04 +02:00
Maksim Eltyshev 545b3d711d fix: Fix styles, refactoring 2024-08-12 23:17:17 +02:00
Arkadiusz Dzięgiel c4c6d738a5 feat: Colorize due date and make it toggleable (#845) 2024-08-12 18:29:50 +02:00
Maksim Eltyshev 07e1903bb5 feat: Languages with country codes 2024-07-21 19:33:57 +02:00
Maksim Eltyshev 9e9827d456 fix: Fix case sensitivity of default admin environment variables 2024-03-12 20:40:46 +01:00