Files
drivetimeplaner/backup/fahrschultermin_20260518_223313/www/fahrschultermin.de/app/Services/SunTimesService.php
Hermes Agent 5d87e4975c Add HttpOnly cookie auth for cross-domain SPA login
Problem: Frontend JS bundle used credentials:'same-origin' which
dropped cookies on cross-domain requests. Login worked (200) but
the subsequent /auth/me check returned 401, leaving the user stuck
on the login screen.

Fix:
- AuthController now sets a dtp_jwt HttpOnly cookie on login/refresh
- Cookie uses Domain=.fahrschultermin.de (shared between frontend
  and api subdomain), Secure, SameSite=Lax, Max-Age=8h
- JwtMiddleware reads JWT from Authorization header OR cookie
- Added AuthController::me() endpoint (was missing, caused 500)
- Logout endpoint clears the cookie
- Frontend index.php patches fetch() to use credentials:'include'
  for all /api/v1/* calls
2026-06-04 20:33:31 +02:00

56 lines
1.8 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace App\Services;
use DateInterval;
use DateTimeImmutable;
use DateTimeZone;
final class SunTimesService
{
public function forRange(array $tenant, string $from, string $to): array
{
$latitude = isset($tenant['latitude']) ? (float) $tenant['latitude'] : null;
$longitude = isset($tenant['longitude']) ? (float) $tenant['longitude'] : null;
$timezoneName = (string) ($tenant['timezone'] ?? 'Europe/Berlin');
if ($latitude === null || $longitude === null || $latitude === 0.0 && $longitude === 0.0) {
return [];
}
$timezone = new DateTimeZone($timezoneName);
$start = new DateTimeImmutable($from, new DateTimeZone('UTC'));
$end = new DateTimeImmutable($to, new DateTimeZone('UTC'));
$day = $start->setTimezone($timezone)->setTime(0, 0);
$lastDay = $end->setTimezone($timezone)->setTime(0, 0);
$result = [];
while ($day < $lastDay) {
$solar = date_sun_info($day->setTime(12, 0)->getTimestamp(), $latitude, $longitude);
$key = $day->format('Y-m-d');
$result[$key] = [
'sunrise' => $this->formatSolarTimestamp($solar['sunrise'] ?? false, $timezone),
'sunset' => $this->formatSolarTimestamp($solar['sunset'] ?? false, $timezone),
];
$day = $day->add(new DateInterval('P1D'));
}
return $result;
}
private function formatSolarTimestamp(int|float|bool $timestamp, DateTimeZone $timezone): ?string
{
if (!is_int($timestamp) && !is_float($timestamp)) {
return null;
}
return (new DateTimeImmutable('@' . (string) (int) $timestamp))
->setTimezone($timezone)
->format('H:i');
}
}