diff --git a/Documents/Images/logo.png b/Documents/Images/logo.png old mode 100755 new mode 100644 index 5294913e..9510ec12 Binary files a/Documents/Images/logo.png and b/Documents/Images/logo.png differ diff --git a/Sources/public/index.php b/Sources/public/index.php index ea0cfb45..3cd3a5da 100755 --- a/Sources/public/index.php +++ b/Sources/public/index.php @@ -12,7 +12,7 @@ use Manager\DataManager; use Repository\IUserRepository; use Shared\ArgumentControllerResolver; use Shared\IArgumentResolver; -use Stub\AuthService; +use Network\AuthService; use Stub\NotificationRepository; use Stub\TrainingRepository; use Stub\UserRepository; @@ -30,13 +30,13 @@ use Network\RelationshipService; use Network\INotificationService; use Stub\NotificationService; - +use App\Router\Session; use Stub\StubData; use Twig\Environment; use Twig\Loader\FilesystemLoader; use Shared\IHashPassword; use Shared\HashPassword; - +use Shared\Log; $appFactory = new AppCreator(); $appFactory->registerService(IArgumentResolver::class, ArgumentControllerResolver::class); @@ -54,7 +54,6 @@ $appFactory->registerService(IUserRepository::class, UserRepository::class); - $appFactory->registerService(\Twig\Loader\LoaderInterface::class, function() { return new FilesystemLoader(__DIR__ . '/../src/app/views/Templates'); }); @@ -69,7 +68,7 @@ $app = $appFactory->create(); if (!is_null($app)){ // Ajout des Middleware /*$app->use(new LoggingMiddleware());*/ - $app->use(new AuthMiddleware()); + $app->use(new AuthMiddleware($appFactory->getDicontainer()->get(IAuthService::class) )); $app->mapControllers(); $app->run(RequestFactory::createFromGlobals()); } diff --git a/Sources/src/app/App.php b/Sources/src/app/App.php index 623e4380..071ccb52 100644 --- a/Sources/src/app/App.php +++ b/Sources/src/app/App.php @@ -29,9 +29,6 @@ class App private FrontController $frontController; - private Session $session; - - public function __construct(string $appName, int $version, \App\Container $diContainer) { $this->appName = $appName; @@ -39,7 +36,7 @@ class App $this->container = $diContainer; $this->router = new Router(""); $this->frontController = new FrontController($this->router,$this->container); - $this->session = Session::getInstance(); + Session::getInstance(); } public function use(IHttpMiddleware $middleware) @@ -140,9 +137,9 @@ class App /** @var RouteAttribute $route */ $route = $attribute->newInstance(); - + $this->router->addControllerRoute( - implode('|', $route->getMethods()), + $route->getMethods(), $prefix . $route->getPath(), $controllerClass, $method->getName(), diff --git a/Sources/src/app/AppCreator.php b/Sources/src/app/AppCreator.php index d2ac0de6..efe670d9 100644 --- a/Sources/src/app/AppCreator.php +++ b/Sources/src/app/AppCreator.php @@ -23,6 +23,12 @@ class AppCreator $this->services[] = $serviceId; return $this; } + public function registerSingleton(string $serviceId, $service): self + { + $this->container->set($serviceId, $service, Container::SINGLETON); + $this->services[] = $serviceId; + return $this; + } /** * Create an instance or perform actions based on the current application environment. @@ -40,7 +46,6 @@ class AppCreator case 'development': // Create a new instance of the App class in the 'development' environment return new App("HeartTrack", 1, $this->container); - break; case 'html': // Load the index.test.php file in case of the 'html' environment require_once __DIR__ . '/index.test.php'; @@ -71,7 +76,8 @@ class AppCreator if ($reflectionClass->isSubclassOf(BaseController::class)) { // Register in DI container $this->container->set($fullClassName, function () use ($fullClassName) { - $controllerInstance = new $fullClassName(); + /** @var $controllerInstance **/ + $controllerInstance = $this->container->resolve($fullClassName); $controllerInstance->setContainer($this->container); return $controllerInstance; }); @@ -86,6 +92,10 @@ class AppCreator { return $this->services; } + + public function getDicontainer(){ + return $this->container; + } } diff --git a/Sources/src/app/Container.php b/Sources/src/app/Container.php index d7c86d10..e8d647e9 100644 --- a/Sources/src/app/Container.php +++ b/Sources/src/app/Container.php @@ -11,31 +11,45 @@ class Container implements ContainerInterface { private array $entries = []; + const SINGLETON = 'singleton'; + const TRANSIENT = 'transient'; + public function get(string $id) { - if ($this->has($id)) { $entry = $this->entries[$id]; - if (is_callable($entry)) { - return $entry($this); + + if ($entry['lifecycle'] === self::SINGLETON) { + if ($entry['instance'] === null) { + $entry['instance'] = $this->resolve($entry['concrete']); + } + return $entry['instance']; + } + + if (is_callable($entry['concrete'])) { + return $entry['concrete']($this); } - $id = $entry; + return $this->resolve($entry['concrete']); } return $this->resolve($id); } + public function has(string $id): bool { return isset($this->entries[$id]); } - public function set(string $id, callable|string $concrete): void + public function set(string $id, callable|string $concrete, string $lifecycle = self::TRANSIENT): void { - $this->entries[$id] = $concrete; - + $this->entries[$id] = [ + 'concrete' => $concrete, + 'lifecycle' => $lifecycle, + 'instance' => null + ]; } public function resolve(string $id) diff --git a/Sources/src/app/controller/AuthController.php b/Sources/src/app/controller/AuthController.php index 71529391..02e76312 100644 --- a/Sources/src/app/controller/AuthController.php +++ b/Sources/src/app/controller/AuthController.php @@ -4,140 +4,139 @@ namespace App\Controller; use App\Container; use App\Router\Request\IRequest; +use App\Router\Response\RedirectResponse; use App\Router\Response\Response; use App\Router\Response\IResponse; +use App\Router\Session; use Manager\UserManager; use Shared\Attributes\Route; use Shared\Validation; use Twig\Environment; use Data\Core\Preferences; use Shared\Log; +use function PHPUnit\Framework\isEmpty; class AuthController extends BaseController { + private UserManager $userMgr; + public function __construct(UserManager $manager){ + parent::__construct(); + $this->userMgr = $manager; + } #[Route('/login', name: 'login',methods: ['POST'])] - public function login(IRequest $request): IResponse { - + public function login(string $email,string $password, IRequest $request): IResponse { $error = []; + try { - $log=Validation::clean_string($request->getBody()['email']); - $mdp=Validation::clean_string($request->getBody()['password']); - } catch (\Throwable $th) { - $error = "Wrong cred"; - } - - if($this->container->get(UserManager::class)->login($log,$mdp)){ - return $this->redirectToRoute('/'); - } - else{ - $error [] = "Erreur de connexion. Essayez encore"; - } - return $this->render('./page/login.html.twig', ['error' => $error]); - - - - } + $log=$email; // should check email with verrify email + $mdp=Validation::clean_string($password); + if($this->userMgr->login($log,$mdp)){ + return new RedirectResponse('/'); + } + else{ + $error [] = "Erreur de connexion. Essayez encore"; - #[Route('/log', name: 'baseLog',methods: ['GET'])] - public function index(IRequest $request): IResponse { + return $this->render('./page/login.html.twig',[ + 'css' => $this->preference->getCookie(), + 'login_error'=> $error, + ]); + } + // should only cath a type of Exception not all + } catch (\Throwable $th) { + $error [] =$th->getMessage(); + return $this->render('./page/login.html.twig',[ + 'css' => $this->preference->getCookie(), + 'login_error'=> $error, + ]); + + } + + } + #[Route('/login', name: 'login2',methods: ['GET'])] + public function login2(IRequest $request): IResponse { + return $this->render('./page/login.html.twig',[ 'css' => $this->preference->getCookie(), - 'pp' => "test2", - 'user' => "Doe", - 'role' => "Athlète", - 'friendship' => [], - 'analyzes' => [], - 'mails' => [], - 'users' => [], - 'infoUser' => [], - 'exos' => [], - 'member' => [] + ]); + + } + #[Route('/register', name: 'register2' , methods:['GET'])] + public function register2(IRequest $request): IResponse{ + return $this->render('./page/register.html.twig',[ + 'css' => $this->preference->getCookie(), ]); } - #[Route('/register', name: 'register' , methods:['GET'])] - public function register(IRequest $request): IResponse + #[Route('/register', name: 'register' , methods:['POST'])] + public function register( + string $nom, + string $prenom, + string $username, + string $mail, + string $motDePasse, + string $sexe, + float $taille, + float $poids, + string $dateNaissance, + string $roleName, + IRequest $request): IResponse { - if ($request->getMethod() == 'POST') { - $nom = $request->getBody()['nom']; - - $prenom = $request->getBody()['prenom']; - - $username = $request->getBody()['username']; - - $email = $request->getBody()['email']; - - $motDePasse = $request->getBody()['motDePasse']; - - $sexe = $request->getBody()['sexe']; - - $taille = $request->getBody()['taille']; - - $poids = $request->getBody()['poids']; - - $dateNaissanceStr = $request->getBody()['nom']; - $dateNaissance = new \DateTime($dateNaissanceStr); - - - if (!$dateNaissance) { - throw new \Exception("Date de naissance non valide. Format attendu : YYYY-MM-DD"); - } - - $roleName = $request->getBody()['roleName']; - + $error = []; + try { $registrationData = [ 'nom' => $nom, 'prenom' => $prenom, 'username' => $username, - 'email' => $email, + 'email' => $mail, 'sexe' => $sexe, 'taille' => $taille, 'poids' => $poids, - 'dateNaissance' => $dateNaissance, + 'dateNaissance' => $dateNaissance, 'roleName' => $roleName ]; - try { - if ($this->container->get(UserManager::class)->register($email, $motDePasse, $registrationData)) { - return $this->redirectToRoute('/'); - } else { - - $error [] = 'L\'inscription a échoué. Veuillez réessayer.'; - } - } catch (\Exception $e) { - $error [] = 'Erreur lors de l\'inscription: ' . $e->getMessage(); + if ($this->userMgr->register($mail, $motDePasse, $registrationData) ) { + return new RedirectResponse('/'); + } else { + $error [] = 'L\'inscription a échoué. Veuillez réessayer.'; + + return $this->render('./page/register.html.twig',[ + 'css' => $this->preference->getCookie(), + 'register_error'=> $error, + ]); } + } catch (\Throwable $e) { + $error [] =$e->getMessage(); + + return $this->render('./page/register.html.twig', ['css' => $this->preference->getCookie(),"register_error" => $error ]); + } + - return $this->render('/register.html.twig'); } +//string $ancienMotDePasse,string $nouveauMotDePasse,string $confirmerMotDePasse, - - #[Route(path: '/mdp', name: 'mdp', methods: ['POST'])] - public function mdp(string $ancienMotDePasse,string $nouveauMotDePasse,string $confirmerMotDePasse, IRequest $req): Response + #[Route(path: '/forgetPassword', name: 'forget-password2', methods: ['GET'])] + public function forgetPassword2(IRequest $request): IResponse + { + return $this->render('./page/password.html.twig',[ + 'css' => $this->preference->getCookie(), + ]); + } + + #[Route(path: '/forgetPassword', name: 'forget-password', methods: ['POST'])] + public function forgetPassword(string $mail, IRequest $request): IResponse { - - // CONFIRMER LES DONNESS !!!!! IMPORTANT - return $this->render('./page/settings.html.twig',[ + return $this->render('./page/password.html.twig',[ 'css' => $this->preference->getCookie(), - 'pp' => "test2", - 'user' => "Doe", - 'role' => "Athlète", - 'friendship' => [], - 'analyzes' => [], - 'mails' => [], - 'users' => [], - 'infoUser' => [], - 'exos' => [], - 'member' => [] ]); } @@ -145,4 +144,4 @@ class AuthController extends BaseController -} \ No newline at end of file +} diff --git a/Sources/src/app/controller/BaseController.php b/Sources/src/app/controller/BaseController.php index da6249a1..2def46b5 100644 --- a/Sources/src/app/controller/BaseController.php +++ b/Sources/src/app/controller/BaseController.php @@ -8,13 +8,14 @@ use App\Router\Response\RedirectResponse; use App\Router\Response\Response; use Psr\Container\ContainerInterface; - +use Shared\Log; abstract class BaseController { protected Preferences $preference; public function __construct(){ + $this->preference = new Preferences(); } protected ContainerInterface $container; @@ -62,18 +63,5 @@ abstract class BaseController return new RedirectResponse($url, $status); } - protected function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponse - { - return $this->redirect($this->generateUrl($route, $parameters), $status); - } - - /* - * TODO : Should hanle ierror if the route is not existing - * */ - protected function generateUrl(string $route, array $parameters = []): string - { - return $this->container->get(\App\Router\Router::class)->generate($route, $parameters); - } - } \ No newline at end of file diff --git a/Sources/src/app/controller/Controller.php b/Sources/src/app/controller/Controller.php index efadb62e..35d7dec9 100644 --- a/Sources/src/app/controller/Controller.php +++ b/Sources/src/app/controller/Controller.php @@ -391,6 +391,50 @@ class Controller extends BaseController } + + + #[Route(path: '/pass', name: 'pass', methods: ['GET'])] + public function pass(): Response + { + + // CONFIRMER LES DONNESS !!!!! IMPORTANT + + return $this->render('./page/password.html.twig',[ + 'css' => $this->preference->getCookie(), + 'pp' => "test2", + 'user' => "Doe", + 'role' => "Athlète", + 'friendship' => [], + 'analyzes' => [], + 'mails' => [], + 'users' => [], + 'infoUser' => [], + 'exos' => [], + 'member' => [] + ]); + } + + #[Route(path: '/password', name: 'password', methods: ['POST'])] + public function password(string $email, IRequest $req): Response + { + + // CONFIRMER LES DONNESS !!!!! IMPORTANT + + return $this->render('./page/login.html.twig',[ + 'css' => $this->preference->getCookie(), + 'pp' => "test2", + 'user' => "Doe", + 'role' => "Athlète", + 'friendship' => [], + 'analyzes' => [], + 'mails' => [], + 'users' => [], + 'infoUser' => [], + 'exos' => [], + 'member' => [] + ]); + } + } diff --git a/Sources/src/app/controller/FrontController.php b/Sources/src/app/controller/FrontController.php index 7676ec67..f46d694b 100644 --- a/Sources/src/app/controller/FrontController.php +++ b/Sources/src/app/controller/FrontController.php @@ -48,6 +48,7 @@ class FrontController { $this->handleError(404, $e->getMessage()); } catch(\Throwable $e){ + Log::dd($e->getLine() . $e->getFile() . $e->getMessage() ); $this->handleError(501, $e->getMessage()); } } @@ -65,7 +66,7 @@ class FrontController { // TODO : Don't work need Antoine help private function handleError(int $statusCode, $message) : void { if (!$this->container->has(\Twig\Environment::class)) { - throw new \LogicException('You cannot use the "renderView" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".'); + throw new \LogicException('You cannot use the "renderView" method if the Twig Bundle is not available. Try running "composer require ".'); } $response = new Response($this->container->get(\Twig\Environment::class)->render('./error/error.html.twig',['title'=> $message , "code" => $statusCode, "name" => $message, "descr" => $message ]),$statusCode); diff --git a/Sources/src/app/controller/UserController.php b/Sources/src/app/controller/UserController.php index 371db47a..9a8abfb0 100644 --- a/Sources/src/app/controller/UserController.php +++ b/Sources/src/app/controller/UserController.php @@ -13,7 +13,6 @@ use Shared\Log; class UserController extends BaseController { - #[Route(path: '/', name: 'home', methods: ['GET'])] public function index(): Response { diff --git a/Sources/src/app/router/Router.php b/Sources/src/app/router/Router.php index 1461e7cf..dec1d043 100644 --- a/Sources/src/app/router/Router.php +++ b/Sources/src/app/router/Router.php @@ -1,12 +1,15 @@ path = $path; $this->routes = new \AltoRouter(); } - + /** * Adds a new Route to the collection. * @@ -46,28 +50,37 @@ class Router { * @param Route $route The route object. * @throws \InvalidArgumentException If method is not supported. */ - public function add(string $method, Route $route) { + public function add(string $method, Route $route) + { if (!in_array($method, self::$verbs)) { throw new \InvalidArgumentException("Method not supported"); } $this->routes->map($method, $route->getPath(), $route->getCallable(), $route->getName()); } - + /** * Adds a route for a controller action. - * - * @param string $method The HTTP method. + * TODO : the problème is that AltoRouter is a map so i can't have mutilple Route just by doing this:(i need to find a logic to resolve this beavior) #[Route('/login', name: 'login',methods: ['POST','GET'])] + * @param string|array $methods HTTP method. * @param string $path The path for the route. * @param mixed $controller The controller object. * @param string $action The action method in the controller. * @param string $name (Optional) The name of the route. * @throws \InvalidArgumentException If method is not supported. */ - public function addControllerRoute(string $method, string $path, $controller, string $action, string $name = '') { - if (!in_array($method, self::$verbs)) { - throw new \InvalidArgumentException("Method not supported"); + public function addControllerRoute(string|array $methods, string $path, $controller, string $action, string $name = '') + { + + if (is_string($methods)) { + $methods = [$methods]; // Convert to an array if it's a string + } + + foreach ($methods as $method) { + if (!in_array($method, self::$verbs)) { + throw new \InvalidArgumentException("Method not supported"); + } + $this->routes->map($method, $path, [$controller, $action], $name); } - $this->routes->map($method, $path, [$controller, $action], $name); } // TODO: Implement the extractParams method. @@ -80,7 +93,8 @@ class Router { * @param callable $callable The callback function. * @param string $name The name of the route. */ - public function get(string $path, callable $callable, $name) { + public function get(string $path, callable $callable, $name) + { $this->routes->map('GET', $path, $callable, $name); } @@ -92,7 +106,8 @@ class Router { * @param IRequest $request The request object. * @return array|null The matched route or null if no match. */ - public function match(IRequest $request): ?array { + public function match(IRequest $request): ?array + { return $this->routes->match($request->getRequestUri(), $request->getMethod()) ?: null; } @@ -101,16 +116,17 @@ class Router { * * @return array The array of routes. */ - public function getRoutes() { + public function getRoutes() + { return []; // TODO: Implement the actual logic to return routes. } - public function generate (string $routeName, array $params = array()): string + public function generate(string $routeName, array $params = array()): string { - return $this->routes->generate($routeName,$params); + return $this->routes->generate($routeName, $params); } } -?> +?> \ No newline at end of file diff --git a/Sources/src/app/router/Session.php b/Sources/src/app/router/Session.php index 3c97d606..ae615363 100644 --- a/Sources/src/app/router/Session.php +++ b/Sources/src/app/router/Session.php @@ -111,8 +111,7 @@ class Session if ( $this->sessionState == self::SESSION_STARTED ) { $this->sessionState = !session_destroy(); - unset( $_SESSION ); - + session_unset(); // Clear all session variables return !$this->sessionState; } diff --git a/Sources/src/app/router/middleware/AuthMiddleware.php b/Sources/src/app/router/middleware/AuthMiddleware.php index 806531bf..a2b95c29 100644 --- a/Sources/src/app/router/middleware/AuthMiddleware.php +++ b/Sources/src/app/router/middleware/AuthMiddleware.php @@ -2,26 +2,24 @@ namespace App\Router\Middleware; use App\Router\Session; +use Network\IAuthService; use Shared\Log; use App\Router\Request\IRequest; use App\Router\Response\RedirectResponse; class AuthMiddleware extends Middleware { - public function handle(IRequest $request, callable $next) { - // if (isset($_SESSION['user'])) { - // $resp =new RedirectResponse("/"); - // $resp->send(); - // exit; - // } -// La page n’est pas redirigée correctement -// Firefox a détecté que le serveur redirige la demande pour cette adresse d’une manière qui n’aboutira pas. + private IAuthService $auth; + public function __construct(IAuthService $auth) { + $this->auth = $auth; + } + public function handle(IRequest $request, callable $next) { + $excludedUrls = ['/login', '/register','/forgetPassword']; -// La cause de ce problème peut être la désactivation ou le refus des cookies. - // if (!isset($_SESSION['user'])) { - // $resp =new RedirectResponse("/log"); - // $resp->send(); - // exit; - // } + if ($this->auth->getCurrentUser() === null && !in_array($request->getRequestUri(), $excludedUrls)) { + $resp = new RedirectResponse("/login"); + $resp->send(); + exit; + } return parent::handle($request, $next); } } \ No newline at end of file diff --git a/Sources/src/app/router/response/RedirectResponse.php b/Sources/src/app/router/response/RedirectResponse.php index 7a34037e..a077568f 100644 --- a/Sources/src/app/router/response/RedirectResponse.php +++ b/Sources/src/app/router/response/RedirectResponse.php @@ -2,6 +2,9 @@ namespace App\Router\Response; +use App\Router\Session; +use Shared\Log; + class RedirectResponse implements IResponse { private $content; @@ -49,12 +52,13 @@ class RedirectResponse implements IResponse public function send(): void { + http_response_code($this->statusCode); foreach ($this->headers as $name => $value) { header("$name: $value"); } - + header("Location: " . $this->url); // Optionally echo content if any diff --git a/Sources/src/app/views/Templates/authbase.html.twig b/Sources/src/app/views/Templates/authbase.html.twig index 7abf72f5..6a8b9bea 100644 --- a/Sources/src/app/views/Templates/authbase.html.twig +++ b/Sources/src/app/views/Templates/authbase.html.twig @@ -34,15 +34,10 @@ -
+ - + diff --git a/Sources/src/app/views/Templates/error/error.html.twig b/Sources/src/app/views/Templates/error/error.html.twig index 4110a803..7f3fd3db 100644 --- a/Sources/src/app/views/Templates/error/error.html.twig +++ b/Sources/src/app/views/Templates/error/error.html.twig @@ -3,5 +3,12 @@ {% block title %}{{code}} : {{title}}{% endblock %} -{% block nb %}