Skip to content

Conversation

@guerricv
Copy link
Contributor

@guerricv guerricv commented Dec 26, 2025

Summary

This PR fixes multiple issues reproducible on TeamPass 3.1.5.17 (fresh installs and restored production backups).

  • Installer (run.step6.php): ensure the internal TP system user (TP_USER_ID = 9999997) is created successfully on fresh installs (fixes admin-side HTTP 500 / TypeError in cryption() when TP user is missing).
  • users.queries.php: fix HTTP 500 when creating a user with "Create a new folder and a role for" enabled (domain folder/role creation) and ensure newly created local users always get auth_type='local' (fixes missing Reset password action when auth_type defaults to NULL).
  • users.queries.php: preserve auth_type on soft-delete so restored users keep their original authentication method (fixes restored accounts stuck with auth_type='none', and missing actions like local password reset).
  • main.functions.php: fix HTTP 500 when creating folders, caused by a legacy role lookup still selecting users.fonction_id (no longer present in recent schemas).

Affected version

  • Observed on: TeamPass 3.1.5.17

1) Root cause & fix (installer): missing internal “TP” system user (TP_USER_ID = 9999997)

On fresh installs, some admin pages/actions can trigger an HTTP 500 (TypeError in cryption()) when the code expects the internal TP user to exist in the users table, but the lookup SELECT … WHERE id = TP_USER_ID returns no row (so $userInfo becomes null).

Why the TP user is missing

  • In 3.1.5.17, the installer step that creates the users table no longer includes legacy columns such as groupes_visibles, fonction_id, groupes_interdits, favourites, latest_items.
  • However, install/install-steps/run.step6.php still attempts to create the TP user using an INSERT referencing those removed columns.
  • MySQL/MariaDB rejects the INSERT (unknown column …), so the TP user is never created (and the installer doesn’t always surface this clearly).

Quick DB check

SELECT id, login
FROM teampass_users
WHERE id IN (9999991, 9999997, 9999999);

Expected: OTV (9999991), TP (9999997), API (9999999). In the broken case, TP is missing.

Fix

Update install/install-steps/run.step6.php and remove the legacy fields from the TP-user INSERT: groupes_visibles, fonction_id, groupes_interdits, favourites, latest_items. Optionally set email and user_ip to none.

Optional hardening note: a defensive null-check in sources/admin.queries.php could avoid a hard 500 if TP is missing, but the correct fix is to ensure the installer creates TP successfully.


2) Fix: HTTP 500 when creating a user with “Create a new folder and a role for …”

How to reproduce

  1. Go to Admin > Users → create a new user
  2. Enable "Create a new folder and a role for"
  3. Save

Observed error (example)

MeekroDBException: Field 'categories' doesn't have a default value
... sources/users.queries.php

Root cause

The domain folder insertion into nested_tree did not set categories. On strict DB configurations where nested_tree.categories has no default value, the insert fails and triggers an HTTP 500.

Fix

  • Provide a safe default for nested_tree.categories when inserting the domain folder.
  • Also align folder insert fields (icons) with other folder creation code paths.
  • Replace legacy role assignment using users.fonction_id (and an incorrect is_int() usage) with a proper role assignment via setUserRoles().

2b) Additional fix: local users created with NULL auth_type (missing reset password action)

Context

On instances where teampass_users.auth_type has DEFAULT NULL, locally-created users could end up with auth_type = NULL. In this case, the UI hides local-password actions (e.g. the Reset password button), even though the user is a regular local account.

Evidence

SHOW COLUMNS FROM teampass_users LIKE 'auth_type';
-- Default = NULL

Fix

In sources/users.queries.php, explicitly set auth_type = 'local' when creating a user from the admin UI (local user creation flow). This ensures the UI consistently exposes local password management actions.

Validation

  • ✅ The Reset password action is available again for newly created local users.
  • ✅ Editing a local user keeps auth_type = 'local'.
  • ✅ Disabling a local user keeps auth_type = 'local'.
  • ✅ LDAP user provisioning remains unaffected: newly created LDAP users keep auth_type = 'ldap' and can authenticate/access items normally.

3) Fix: HTTP 500 when creating a folder (Folders page)

How to reproduce

  1. Go to Folders → create a new folder

Observed error (example)

MeekroDBException: Unknown column 'fonction_id' in 'SELECT'
... sources/main.functions.php (getUsersWithRoles)
... triggered by folders.class.php (refreshCacheForUsersWithSimilarRoles)

Root cause

A legacy query in getUsersWithRoles() still selects fonction_id from users, but roles are stored in users_roles on recent schemas. This breaks the cache refresh during folder creation.

Fix

  • Update getUsersWithRoles() to build role lists from users_roles (LEFT JOIN + GROUP_CONCAT) instead of selecting users.fonction_id.
  • Harden role parsing in PHP (cast to integers + strict comparison) to avoid type mismatch issues.

Testing

  • ✅ Fresh install (with patched installer step): TP user (9999997) is created, and admin actions that previously triggered a 500 no longer fail.
  • ✅ User creation with “Create a new folder and a role for …” enabled works (no HTTP 500).
  • ✅ Newly created local users have auth_type='local' and the UI exposes the Reset password action.
  • ✅ Folder creation works (no HTTP 500).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant