Files
drivetimeplaner/backup/old_api_20260520/app/Repositories/StudentTenantRepository.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

77 lines
2.5 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace App\Repositories;
final class StudentTenantRepository extends BaseRepository
{
public function findByUserAndTenant(int $userId, int $tenantId): ?array
{
$stmt = $this->db->prepare(
'SELECT * FROM student_tenants WHERE student_user_id = :user_id AND tenant_id = :tenant_id'
);
$stmt->execute(['user_id' => $userId, 'tenant_id' => $tenantId]);
$result = $stmt->fetch();
return $result ?: null;
}
public function create(int $userId, int $tenantId, string $status = 'pending'): array
{
$stmt = $this->db->prepare(
'INSERT INTO student_tenants (student_user_id, tenant_id, status)
VALUES (:user_id, :tenant_id, :status) RETURNING *'
);
$stmt->execute([
'user_id' => $userId,
'tenant_id' => $tenantId,
'status' => $status,
]);
return $stmt->fetch();
}
public function confirm(int $id, int $confirmedBy): bool
{
$stmt = $this->db->prepare(
'UPDATE student_tenants
SET status = \'active\', confirmed_at = NOW(), confirmed_by = :confirmed_by
WHERE id = :id RETURNING id'
);
$stmt->execute(['id' => $id, 'confirmed_by' => $confirmedBy]);
return (bool) $stmt->fetch();
}
public function suspend(int $id): bool
{
$stmt = $this->db->prepare(
'UPDATE student_tenants SET status = \'suspended\' WHERE id = :id RETURNING id'
);
$stmt->execute(['id' => $id]);
return (bool) $stmt->fetch();
}
public function getPendingForTenant(int $tenantId): array
{
$stmt = $this->db->prepare(
'SELECT st.*, u.email, u.first_name, u.last_name
FROM student_tenants st
JOIN users u ON u.id = st.student_user_id
WHERE st.tenant_id = :tenant_id AND st.status = \'pending\'
ORDER BY st.registered_at DESC'
);
$stmt->execute(['tenant_id' => $tenantId]);
return $stmt->fetchAll();
}
public function getActiveForUser(int $userId): array
{
$stmt = $this->db->prepare(
'SELECT st.*, t.name AS tenant_name
FROM student_tenants st
JOIN tenants t ON t.id = st.tenant_id
WHERE st.student_user_id = :user_id AND st.status = \'active\''
);
$stmt->execute(['user_id' => $userId]);
return $stmt->fetchAll();
}
}