17a824f925
Milestone 1 (auth foundation):
- Installed laravel/sanctum; HasApiTokens on User; published config + migration.
- routes/api.php with /api/v1; Sanctum 'ability' middleware alias registered.
- AuthController: POST login (long-lived revocable device token w/ ability
mobile-sync + devices table), GET me, POST logout. New Device model/table.
Milestone 2 (vertical slice, offline-first):
- progress_updates: +uuid (client-generated) +client_updated_at.
- ProjectApiController: GET projects (accessibleBy), GET projects/{id}/bundle
(project/phases/layers/features, membership-authorized).
- SyncController: POST sync — batch ops, idempotent by uuid, per-op result
(applied/duplicate/error), server-set user_id, authz by permission+membership.
Currently handles progress_update.create.
Tests: tests/Feature/Api/MobileApiTest (9 passing) — auth, accessible projects,
bundle authz, sync apply+idempotency, permission enforcement.
Also fixed a latent schema bug: projects.reference (and external_reference_1)
existed in the live DB but had no migration — added a guarded migration so fresh
installs match production.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
88 lines
3.0 KiB
PHP
88 lines
3.0 KiB
PHP
<?php
|
|
|
|
use Illuminate\Cookie\Middleware\EncryptCookies;
|
|
use Illuminate\Foundation\Http\Middleware\ValidateCsrfToken;
|
|
use Laravel\Sanctum\Http\Middleware\AuthenticateSession;
|
|
use Laravel\Sanctum\Sanctum;
|
|
|
|
return [
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Stateful Domains
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Requests from the following domains / hosts will receive stateful API
|
|
| authentication cookies. Typically, these should include your local
|
|
| and production domains which access your API via a frontend SPA.
|
|
|
|
|
*/
|
|
|
|
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
|
|
'%s%s',
|
|
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
|
|
Sanctum::currentApplicationUrlWithPort(),
|
|
// Sanctum::currentRequestHost(),
|
|
))),
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Sanctum Guards
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| This array contains the authentication guards that will be checked when
|
|
| Sanctum is trying to authenticate a request. If none of these guards
|
|
| are able to authenticate the request, Sanctum will use the bearer
|
|
| token that's present on an incoming request for authentication.
|
|
|
|
|
*/
|
|
|
|
'guard' => ['web'],
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Expiration Minutes
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| This value controls the number of minutes until an issued token will be
|
|
| considered expired. This will override any values set in the token's
|
|
| "expires_at" attribute, but first-party sessions are not affected.
|
|
|
|
|
*/
|
|
|
|
'expiration' => null,
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Token Prefix
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Sanctum can prefix new tokens in order to take advantage of numerous
|
|
| security scanning initiatives maintained by open source platforms
|
|
| that notify developers if they commit tokens into repositories.
|
|
|
|
|
| See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
|
|
|
|
|
*/
|
|
|
|
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Sanctum Middleware
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| When authenticating your first-party SPA with Sanctum you may need to
|
|
| customize some of the middleware Sanctum uses while processing the
|
|
| request. You may change the middleware listed below as required.
|
|
|
|
|
*/
|
|
|
|
'middleware' => [
|
|
'authenticate_session' => AuthenticateSession::class,
|
|
'encrypt_cookies' => EncryptCookies::class,
|
|
'validate_csrf_token' => ValidateCsrfToken::class,
|
|
],
|
|
|
|
];
|