Initial Version

This commit is contained in:
root
2025-12-21 10:09:54 -05:00
commit 4ae6befc7b
422 changed files with 47225 additions and 0 deletions

View File

@@ -0,0 +1,144 @@
<?php
namespace KTXC\Controllers;
use DI\Attribute\Inject;
use KTXC\Http\Response\Response;
use KTXC\Http\Response\FileResponse;
use KTXC\Http\Response\JsonResponse;
use KTXC\Http\Response\RedirectResponse;
use KTXF\Controller\ControllerAbstract;
use KTXF\Routing\Attributes\AnonymousRoute;
use KTXC\Service\SecurityService;
use KTXC\SessionIdentity;
use KTXC\Http\Request\Request;
class DefaultController extends ControllerAbstract
{
public function __construct(
private readonly SecurityService $securityService,
private readonly SessionIdentity $identity,
#[Inject('rootDir')] private readonly string $rootDir,
) {}
#[AnonymousRoute('/', name: 'root', methods: ['GET'])]
public function home(Request $request): Response
{
// If an authenticated identity is available, serve the private app
if ($this->identity->identifier()) {
return new FileResponse(
$this->rootDir . '/public/private.html',
Response::HTTP_OK,
['Content-Type' => 'text/html']
);
}
// User is not authenticated - serve the public app
// If there's an accessToken cookie present but invalid, clear it
$response = new FileResponse(
$this->rootDir . '/public/public.html',
Response::HTTP_OK,
['Content-Type' => 'text/html']
);
// Clear any stale auth cookies since the user is not authenticated
if ($request->cookies->has('accessToken')) {
$response->headers->clearCookie('accessToken', '/');
}
if ($request->cookies->has('refreshToken')) {
$response->headers->clearCookie('refreshToken', '/security/refresh');
}
return $response;
}
#[AnonymousRoute('/login', name: 'login', methods: ['GET'])]
public function login(): Response
{
return new FileResponse(
$this->rootDir . '/public/public.html',
Response::HTTP_OK,
['Content-Type' => 'text/html']
);
}
#[AnonymousRoute('/logout', name: 'logout_get', methods: ['GET'])]
public function logoutGet(Request $request): Response
{
// Blacklist the current access token if present
$accessToken = $request->cookies->get('accessToken');
if ($accessToken) {
$claims = $this->securityService->extractTokenClaims($accessToken);
if ($claims && isset($claims['jti'])) {
$this->securityService->logout($claims['jti'], $claims['exp'] ?? null);
}
}
$response = new RedirectResponse(
'/login',
Response::HTTP_SEE_OTHER
);
// Clear both authentication cookies
$response->headers->clearCookie('accessToken', '/');
$response->headers->clearCookie('refreshToken', '/security/refresh');
return $response;
}
#[AnonymousRoute('/logout', name: 'logout_post', methods: ['POST'])]
public function logoutPost(Request $request): Response
{
// Blacklist the current access token if present
$accessToken = $request->cookies->get('accessToken');
if ($accessToken) {
$claims = $this->securityService->extractTokenClaims($accessToken);
if ($claims && isset($claims['jti'])) {
$this->securityService->logout($claims['jti'], $claims['exp'] ?? null);
}
}
$response = new JsonResponse(['message' => 'Logged out successfully']);
// Clear both authentication cookies
$response->headers->clearCookie('accessToken', '/');
$response->headers->clearCookie('refreshToken', '/security/refresh');
return $response;
}
/**
* Catch-all route for SPA routing.
* Serves the appropriate HTML based on authentication status,
* allowing client-side routing to handle the actual path.
*/
#[AnonymousRoute('/{path}', name: 'spa_catchall', methods: ['GET'])]
public function catchAll(Request $request, string $path = ''): Response
{
// If an authenticated identity is available, serve the private app
if ($this->identity->identifier()) {
return new FileResponse(
$this->rootDir . '/public/private.html',
Response::HTTP_OK,
['Content-Type' => 'text/html']
);
}
// User is not authenticated - serve the public app
$response = new FileResponse(
$this->rootDir . '/public/public.html',
Response::HTTP_OK,
['Content-Type' => 'text/html']
);
// Clear any stale auth cookies since the user is not authenticated
if ($request->cookies->has('accessToken')) {
$response->headers->clearCookie('accessToken', '/');
}
if ($request->cookies->has('refreshToken')) {
$response->headers->clearCookie('refreshToken', '/security/refresh');
}
return $response;
}
}