github nilsteampassnet/TeamPass 3.2.3.3

6 hours ago

What's Changed

This is a maintenance release on the 3.2.3 line. It fixes an attachment authorization flaw (GHSA-r6r4-5mr3-rppm), several upgrade paths that stopped or silently skipped migrations (2.x → 3.x wizard, the 3.1.5 unique index, Docker images coming from 3.2.2.6 or earlier), and an unusable TP account key that silently left users without access when their keys were generated. It also ships two contributions from @guerricv: disaster recovery onto a fresh server, and experimental QR pairing for external devices (off by default). Upgrading is recommended for all installations.

This release changes the database schema. UPGRADE_MIN_DATE is raised, so every installation goes through the upgrade wizard once. Docker containers apply the upgrade on their own at start-up.

🔒 Security fixes

  • Attachments now require the edit right, and a new item only receives the files its own session uploaded (GHSA-r6r4-5mr3-rppm, reported by @NotAFlightRisk) — deleting an attachment only checked that the folder was visible to the user, which read-only folders grant: a read-only member could permanently delete any attachment in the folder, including those of items restricted to others. Triage found a more severe flaw in item creation: new_item attached every file stored under the staging identifier sent by the browser, so a user could move another item's attachments onto an item of their own and read them. Uploads are now recorded in the user's session, and creating an item or confirming attachments only takes the files that session uploaded. The upload refuses a staging identifier that designates an existing item, and checks the edit right whenever it targets an existing item. Every 3.x release before 3.2.3.3 is affected.

✨ New features

  • Disaster recovery on a fresh server (PR #5439, @guerricv) — a new installer assistant (/install/recovery.php) and its CLI (app/scripts/disaster-recovery.php) restore a complete encrypted .tpbackup and its original .tprecovery Recovery Package without running a normal installation first. The assistant imports into an empty dedicated database and verifies the original key chain and document references. It then replays the shipped 3.2.2/3.2.3 migrations in isolated processes and checks item decryption. Only after that does it publish a newly generated configuration, in maintenance mode. The operator is then guided through file permissions, installer removal and scheduler restoration. Restored sessions, tokens, device credentials and Secure Send links are invalidated, and backup schedules and LAPR stay disabled until an administrator reviews them. Supported sources: 3.2.2.x and 3.2.3.x, complete backups taken with Include documents, no downgrade. Read the Disaster recovery guide, and rehearse a restore before you need one.
  • Experimental QR pairing for external devices (PR #5437, @guerricv) — off by default, enabled in Settings → API → Mobile application. Once it is on, a user pairs a compatible client from the External devices tab of their profile. The QR code only carries the instance URL and a short-lived invitation; the user compares a six-digit code on both screens and approves the exact device, and a dedicated Personal Access Token is then delivered encrypted to the device's ephemeral key. Device credentials expire (90 days by default) and each one can be revoked by its owner. Administrators can inspect and revoke them from the same settings tab, and revoking a credential ends its API sessions. Pairing requires HTTPS. No client is published yet: the feature targets client developers, with the protocol in docs/api/device-pairing.md and an Android integration guide.

🛠️ Improvements

  • Backups are taken from one consistent database snapshot (PR #5439, @guerricv) — every backup, manual or scheduled, now reads the whole database inside a single read-only InnoDB snapshot. A second backup cannot start while one is running, and maintenance mode stays on until the package is written, then goes back to its previous state. A database holding a non-InnoDB table is refused. See the upgrade notes: this changes what users see during a backup.
  • The database records the complete release that upgraded it — teampass_version only holds the line (3.2.3), so a database upgraded by 3.2.2.3 and one upgraded by 3.2.2.8 looked identical, which hid a skipped migration. A new teampass_version_full setting (for example 3.2.3.3) is written next to it by the installer, the upgrade wizard and the Docker entrypoint. The wizard now shows the version it upgrades from, and the container log names complete releases (Upgrading database from 3.2.2.3 to 3.2.3.3).
  • Browser extension documentation — the popup features added since 1.8.2 are documented (keyboard shortcuts, folder browsing, recent items, TOTP fill and live code, theme, site access, licence troubleshooting, the passkey "last request" card), and the PIN length is corrected: exactly 6 digits.

🐛 Bug fixes

  • Docker upgrades skipped migrations, and non-admin sign-ins then failed with an HTTP 500 (discussion #5436) — teampass_version stores only the line, while patch releases keep appending to upgrade_run_<line>.php. The container's upgrade chain skipped the step equal to the recorded version. A database installed by 3.2.2.3 and moved to a 3.2.3.x image therefore received the 3.2.3 migration alone: nested_tree.deletion_protected and the other 3.2.2.4–3.2.2.8 changes were never applied. The entrypoint now replays the recorded version's step (the migrations are idempotent). An instance already upgraded this way is not repaired automatically: the Docker guide has a section, Incomplete schema after a jump from 3.2.2.6 or earlier to 3.2.3.x, with the check query and the repair (record 3.2.1, then recreate the container).
  • No sign-in is accepted while a database upgrade is pending — the upgrade gate only disabled the login button in the browser. The OAuth2 callback and the passkey sign-in reach the server directly, so on a stale schema a non-admin sign-in ended in an HTTP 500. The server now refuses every sign-in while an upgrade is required. The login page also disables the OAuth2 and passkey buttons and skips the OAuth2 auto-login redirect.
  • An unusable TP account key silently left users without access (discussion #5424) — the internal TP account key can stop opening, typically after a database was imported into a new installation. Nothing noticed: items keep reaching existing users through public keys, while every key generation for a user wrote empty sharekeys and reported success. Key generation now refuses to run instead, and refuses to replace the key pair of a user who still holds sharekeys. The dashboard encryption status turns red. Tools → Restore missing sharekeys names the cause (missing account, unreadable password, missing or unreadable private key) and can rebuild the TP key pair, after which the repair recreates its reference keys. The "re-save the object" advice was removed from the tool and the documentation: saving an item only re-encrypts a value that changed.
  • 2.x → 3.x upgrades stopped with an HTTP 500 on the user keys step (PR #5438, @MarMarAba) — step 3 of the v3 user migration wrote every log sharekey with object_id = 0. Since 3.1.5 creates a unique index before that step, the second sharekey for the same user failed and the wizard stopped. Steps 3 to 6 also decided when to stop from the first row's id instead of a row count, which could leave rows beyond the first batch without sharekeys.
  • The upgrade wizard stopped at 3.1.5 on databases migrated from 2.x — such databases carry duplicate (object_id, user_id) sharekeys, so the 3.1.5 unique index could not be created, and the error was returned as invalid JSON ("unexpected answer"). Duplicates are now removed before the index is created (the most recent row is kept), and the 3.1.5 and 3.1.6 steps always answer valid JSON.
  • LAPR endpoints and rotated passwords — a rotated password kept the strength rating of the password it replaced, so a generated 20-character password still showed as weak. Deleting an endpoint paused its managed accounts instead of releasing them: they were hidden, could not be removed, and kept their items locked. They are now released, and background maintenance releases those left behind by earlier releases. An endpoint whose SSH credential item is gone (deleted, inactive or moved to a personal folder) no longer holds its host: enrolling the host again replaces it, and the dead endpoint stays listed and flagged so that operators who can read the credential folder can delete it.

⬆️ Upgrade notes

  • Schema. The upgrade creates the device_pairings table, adds purpose, pairing_id and revoked_at to api_tokens and source_token_id to api_sessions, and seeds the device_pairing_enabled (0), device_pairing_token_lifetime_days (90) and device_pairing_schema settings. Existing API tokens keep working unchanged. teampass_version_full is written when the upgrade completes.
  • Backups sign non-administrators out while they run. Because a backup now keeps maintenance mode on for its whole duration, a non-admin user who makes a request during that window is signed out, exactly as with manual maintenance mode. On a large instance with documents this can take minutes: schedule backups outside working hours, and expect it when an administrator starts one during the day. A backup also stops with an error when the database holds a table that is not InnoDB, a storage engine the upgrade wizard already requires for every table.
  • Offline clients of GET /api/v1/item/changes. Responses now carry a generation value. After a disaster recovery, a client that does not send back the generation it adopted on its last full sync receives full_sync_required on every request. Nothing changes for an instance that has never been recovered.
  • Docker instances already upgraded from 3.2.2.6 or earlier to 3.2.3.0–3.2.3.2 may still lack the 3.2.2 columns. Run the check query from the Docker guide (see the bug fix above) before upgrading.
  • Back up your database before upgrading, as always.

Full Changelog: 3.2.3.2...3.2.3.3

Important

  • Requires at least PHP 8.2

Languages

Please join Teampass v3 translation project on Poeditor and translate it for your language.

Installation

Follow instructions from Documentation.

Upgrade

Follow instructions from Documentation.

Ideas and comments

Are welcome ... please use Discussions.

Download TeamPass

Don't miss a new TeamPass release

NewReleases is sending notifications on new releases.