Fix tenant event form package selector so it no longer renders empty-value options, handles loading/empty

states, and pulls data from the authenticated /api/v1/tenant/packages endpoint.
    (resources/js/admin/pages/EventFormPage.tsx, resources/js/admin/api.ts)
  - Harden tenant-admin auth flow: prevent PKCE state loss, scope out StrictMode double-processing, add SPA
    routes for /event-admin/login and /event-admin/logout, and tighten token/session clearing semantics (resources/js/admin/auth/{context,tokens}.tsx, resources/js/admin/pages/{AuthCallbackPage,LogoutPage}.tsx,
    resources/js/admin/router.tsx, routes/web.php)
This commit is contained in:
Codex Agent
2025-10-19 23:00:47 +02:00
parent a949c8d3af
commit 6290a3a448
95 changed files with 3708 additions and 394 deletions

View File

@@ -7,6 +7,7 @@ use App\Models\EventJoinToken;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Str;
class EventJoinTokenService
@@ -15,10 +16,13 @@ class EventJoinTokenService
{
return DB::transaction(function () use ($event, $attributes) {
$tokenValue = $this->generateUniqueToken();
$tokenHash = $this->hashToken($tokenValue);
$payload = [
'event_id' => $event->id,
'token' => $tokenValue,
'token_hash' => $tokenHash,
'token_encrypted' => Crypt::encryptString($tokenValue),
'token_preview' => $this->previewToken($tokenValue),
'label' => Arr::get($attributes, 'label'),
'usage_limit' => Arr::get($attributes, 'usage_limit'),
'metadata' => Arr::get($attributes, 'metadata', []),
@@ -34,7 +38,9 @@ class EventJoinTokenService
$payload['created_by'] = $createdBy;
}
return EventJoinToken::create($payload);
return tap(EventJoinToken::create($payload), function (EventJoinToken $model) use ($tokenValue) {
$model->setAttribute('plain_token', $tokenValue);
});
});
}
@@ -60,8 +66,16 @@ class EventJoinTokenService
public function findToken(string $token, bool $includeInactive = false): ?EventJoinToken
{
$hash = $this->hashToken($token);
return EventJoinToken::query()
->where('token', $token)
->where(function ($query) use ($hash, $token) {
$query->where('token_hash', $hash)
->orWhere(function ($inner) use ($token) {
$inner->whereNull('token_hash')
->where('token', $token);
});
})
->when(! $includeInactive, function ($query) {
$query->whereNull('revoked_at')
->where(function ($query) {
@@ -85,8 +99,25 @@ class EventJoinTokenService
{
do {
$token = Str::random($length);
} while (EventJoinToken::where('token', $token)->exists());
$hash = $this->hashToken($token);
} while (EventJoinToken::where('token_hash', $hash)->exists());
return $token;
}
protected function hashToken(string $token): string
{
return hash('sha256', $token);
}
protected function previewToken(string $token): string
{
$length = strlen($token);
if ($length <= 10) {
return $token;
}
return substr($token, 0, 6).'…'.substr($token, -4);
}
}