From 90d7aab5475d32e27322cad0643230a61b7754eb Mon Sep 17 00:00:00 2001 From: isaacclad Date: Thu, 11 Jun 2026 09:51:41 +0000 Subject: [PATCH] Fix 500 on mobile sign-in: acting account + connection errors. presentUser() ran on the public login/register routes where SetActingAccount never runs, so ladill_account() was null and dereferencing it 500'd. Default the acting account to the user at sign-in, and route identity-API calls through a helper with timeouts that turns ConnectionException into a clean message instead of an unhandled 500. Co-Authored-By: Claude Opus 4.8 --- app/Http/Controllers/Api/AuthController.php | 24 ++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/AuthController.php b/app/Http/Controllers/Api/AuthController.php index 41be386..d3806fd 100644 --- a/app/Http/Controllers/Api/AuthController.php +++ b/app/Http/Controllers/Api/AuthController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Models\QrTeamMember; use App\Models\User; +use Illuminate\Http\Client\ConnectionException; use Illuminate\Http\Client\Response as HttpResponse; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -31,7 +32,7 @@ class AuthController extends Controller 'device_name' => ['nullable', 'string', 'max:120'], ]); - $response = $this->identity()->post('/api/identity/auth/login', [ + $response = $this->identityPost('/api/identity/auth/login', [ 'email' => $credentials['email'], 'password' => $credentials['password'], ]); @@ -69,7 +70,7 @@ class AuthController extends Controller 'device_name' => ['nullable', 'string', 'max:120'], ]); - $response = $this->identity()->post('/api/identity/auth/register', array_merge( + $response = $this->identityPost('/api/identity/auth/register', array_merge( $request->only([ 'name', 'email', 'password', 'password_confirmation', 'company', 'address', 'city', 'state', 'country', 'zipcode', @@ -106,10 +107,24 @@ class AuthController extends Controller { return Http::baseUrl(rtrim((string) config('services.ladill_identity.url'), '/')) ->withToken((string) config('services.ladill_identity.key')) + ->connectTimeout(10) + ->timeout(20) ->acceptJson() ->asJson(); } + /** POST to the identity API, turning connection failures into a clean message. */ + private function identityPost(string $path, array $payload): HttpResponse + { + try { + return $this->identity()->post($path, $payload); + } catch (ConnectionException $e) { + throw ValidationException::withMessages([ + 'email' => ['Could not reach Ladill sign-in. Please try again in a moment.'], + ]); + } + } + /** Upsert the local mirror from the identity API's OIDC claims. */ private function provisionFromResponse(HttpResponse $response): User { @@ -157,7 +172,10 @@ class AuthController extends Controller /** @return array */ private function presentUser(User $user): array { - $account = ladill_account(); + // On the public login/register routes SetActingAccount hasn't run and + // there's no authenticated guard yet, so ladill_account() is null — + // the acting account at sign-in is simply the user themselves. + $account = ladill_account() ?? $user; return [ 'id' => $user->id,