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:
112
app/Services/Analytics/JoinTokenAnalyticsRecorder.php
Normal file
112
app/Services/Analytics/JoinTokenAnalyticsRecorder.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Analytics;
|
||||
|
||||
use App\Models\EventJoinToken;
|
||||
use App\Models\EventJoinTokenEvent;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class JoinTokenAnalyticsRecorder
|
||||
{
|
||||
public function record(
|
||||
?EventJoinToken $joinToken,
|
||||
string $eventType,
|
||||
Request $request,
|
||||
array $context = [],
|
||||
?string $providedToken = null,
|
||||
?int $httpStatus = null
|
||||
): void {
|
||||
try {
|
||||
EventJoinTokenEvent::create($this->buildPayload(
|
||||
$joinToken,
|
||||
$eventType,
|
||||
$request,
|
||||
$context,
|
||||
$providedToken,
|
||||
$httpStatus
|
||||
));
|
||||
} catch (\Throwable $exception) {
|
||||
// Never block the main request if analytics fails
|
||||
report($exception);
|
||||
}
|
||||
}
|
||||
|
||||
private function buildPayload(
|
||||
?EventJoinToken $joinToken,
|
||||
string $eventType,
|
||||
Request $request,
|
||||
array $context,
|
||||
?string $providedToken,
|
||||
?int $httpStatus
|
||||
): array {
|
||||
$route = $request->route();
|
||||
$routeName = $route ? $route->getName() : null;
|
||||
$deviceId = (string) $request->header('X-Device-Id', $request->input('device_id', ''));
|
||||
$deviceId = $deviceId !== '' ? substr(preg_replace('/[^a-zA-Z0-9_-]/', '', $deviceId), 0, 64) : null;
|
||||
|
||||
$tokenHash = null;
|
||||
$tokenPreview = null;
|
||||
|
||||
if ($joinToken) {
|
||||
$tokenHash = $joinToken->token_hash ?? null;
|
||||
$tokenPreview = $joinToken->token_preview ?? null;
|
||||
} elseif ($providedToken) {
|
||||
$tokenHash = hash('sha256', $providedToken);
|
||||
$tokenPreview = $this->buildPreview($providedToken);
|
||||
}
|
||||
|
||||
$eventId = $joinToken?->event_id;
|
||||
$tenantId = null;
|
||||
|
||||
if ($joinToken && $joinToken->relationLoaded('event')) {
|
||||
$tenantId = $joinToken->event?->tenant_id;
|
||||
} elseif ($joinToken) {
|
||||
$tenantId = $joinToken->event()->value('tenant_id');
|
||||
}
|
||||
|
||||
return [
|
||||
'event_join_token_id' => $joinToken?->getKey(),
|
||||
'event_id' => $eventId,
|
||||
'tenant_id' => $tenantId,
|
||||
'token_hash' => $tokenHash,
|
||||
'token_preview' => $tokenPreview,
|
||||
'event_type' => $eventType,
|
||||
'route' => $routeName,
|
||||
'http_method' => $request->getMethod(),
|
||||
'http_status' => $httpStatus,
|
||||
'device_id' => $deviceId,
|
||||
'ip_address' => $request->ip(),
|
||||
'user_agent' => $this->shortenUserAgent($request->userAgent()),
|
||||
'context' => $context ?: null,
|
||||
'occurred_at' => now(),
|
||||
];
|
||||
}
|
||||
|
||||
private function shortenUserAgent(?string $userAgent): ?string
|
||||
{
|
||||
if ($userAgent === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Str::length($userAgent) > 1024) {
|
||||
return Str::substr($userAgent, 0, 1024);
|
||||
}
|
||||
|
||||
return $userAgent;
|
||||
}
|
||||
|
||||
private function buildPreview(string $token): string
|
||||
{
|
||||
$token = trim($token);
|
||||
$length = Str::length($token);
|
||||
|
||||
if ($length <= 10) {
|
||||
return $token;
|
||||
}
|
||||
|
||||
return Str::substr($token, 0, 6).'…'.Str::substr($token, -4);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user