Fix 500 on mobile sign-in: acting account + connection errors.
Deploy Ladill Mini / deploy (push) Successful in 1m31s

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 <noreply@anthropic.com>
This commit is contained in:
isaacclad
2026-06-11 09:51:41 +00:00
co-authored by Claude Opus 4.8
parent a286f3d977
commit 90d7aab547
+21 -3
View File
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\QrTeamMember; use App\Models\QrTeamMember;
use App\Models\User; use App\Models\User;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\Response as HttpResponse; use Illuminate\Http\Client\Response as HttpResponse;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
@@ -31,7 +32,7 @@ class AuthController extends Controller
'device_name' => ['nullable', 'string', 'max:120'], 'device_name' => ['nullable', 'string', 'max:120'],
]); ]);
$response = $this->identity()->post('/api/identity/auth/login', [ $response = $this->identityPost('/api/identity/auth/login', [
'email' => $credentials['email'], 'email' => $credentials['email'],
'password' => $credentials['password'], 'password' => $credentials['password'],
]); ]);
@@ -69,7 +70,7 @@ class AuthController extends Controller
'device_name' => ['nullable', 'string', 'max:120'], '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([ $request->only([
'name', 'email', 'password', 'password_confirmation', 'company', 'name', 'email', 'password', 'password_confirmation', 'company',
'address', 'city', 'state', 'country', 'zipcode', 'address', 'city', 'state', 'country', 'zipcode',
@@ -106,10 +107,24 @@ class AuthController extends Controller
{ {
return Http::baseUrl(rtrim((string) config('services.ladill_identity.url'), '/')) return Http::baseUrl(rtrim((string) config('services.ladill_identity.url'), '/'))
->withToken((string) config('services.ladill_identity.key')) ->withToken((string) config('services.ladill_identity.key'))
->connectTimeout(10)
->timeout(20)
->acceptJson() ->acceptJson()
->asJson(); ->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. */ /** Upsert the local mirror from the identity API's OIDC claims. */
private function provisionFromResponse(HttpResponse $response): User private function provisionFromResponse(HttpResponse $response): User
{ {
@@ -157,7 +172,10 @@ class AuthController extends Controller
/** @return array<string, mixed> */ /** @return array<string, mixed> */
private function presentUser(User $user): 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 [ return [
'id' => $user->id, 'id' => $user->id,