Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
## 4.4.4

### Bug Fix: `/jwt/login` still 500s on apps with custom `user_model` (continuation of 4.4.3)

v4.4.3 fixed the `Undefined constant "User"` fatal by calling `Api::loadAppModels($app)` in `resolveAuthContext`. That uncovered a second gap: the app-scoped model definition has `appId` set, which causes `ModelObject->retrieve()` to auto-switch to the app DB via `Api::dbswitch(true)`. But the app-DB credentials (host/user/password) were never configured because `Api::dbappconnect()` is called only by the normal MVC pipeline (Api.php:690) β€” which JWT bypasses.

Result: mysqli received null host/user/password and tried a Unix-socket connection β†’ `No such file or directory` β†’ HTTP 500.

Fix: `resolveAuthContext` now also calls `Api::dbappconnect($app->db_name, $app->db_username, $app->db_password)` immediately after `loadAppModels`. The HMAC pipeline does both calls back-to-back at Api.php:688-690; JWT now matches.

Apps without a custom `user_model` (default `KyteUser` path) are unaffected β€” they were never in the app-DB branch.

No schema changes. Composer upgrade is sufficient.

## 4.4.3

### Bug Fix: `/jwt/login` fatals on apps with custom `user_model`
Expand Down
25 changes: 20 additions & 5 deletions src/Core/Auth/JwtEndpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,12 +335,27 @@ private static function resolveAuthContext(?string $appIdentifier): array
}

if ($app->user_model !== null && $app->username_colname !== null && $app->password_colname !== null) {
// App-specific DataModel constants ("User", "Customer", etc.) are
// registered lazily by Api::loadAppModels when an app context is
// detected in the normal MVC pipeline. JwtEndpoint dispatches
// BEFORE that pipeline runs, so the constant we want may not
// exist yet. Load explicitly to make the constant available.
// Mirror the subset of per-app setup that Api::route() does for
// HMAC. JWT dispatches BEFORE the normal MVC pipeline runs, so
// without this block the app-specific user model can't be
// resolved or queried:
//
// 1. loadAppModels β€” registers app DataModel constants
// like "User" so constant($app->user_model) resolves.
// Without this, PHP 8 fatals "Undefined constant".
// 2. dbappconnect β€” sets the app's DB credentials.
// Without this, ModelObject->retrieve on an app-scoped
// model auto-switches to the app DB (because the loaded
// model_definition has 'appId' set) and mysqli connects
// with null host/user/password β†’ "No such file or
// directory" socket error β†’ HTTP 500.
//
// We skip defineAppEnvironmentConstants / defineAppDataStore
// (private instance methods) because login is just user
// lookup + password_verify; those constants matter for
// controller execution, not auth.
\Kyte\Core\Api::loadAppModels($app);
\Kyte\Core\Api::dbappconnect($app->db_name, $app->db_username, $app->db_password);

if (!defined($app->user_model)) {
// loadAppModels couldn't define it (no matching DataModel
Expand Down
Loading