From 98c026b9466904b68b9f3098b2a1bbd19e19b367 Mon Sep 17 00:00:00 2001 From: rodude123 Date: Sun, 9 Oct 2022 02:40:06 +0100 Subject: [PATCH 1/5] Created the JWT authentication for the editor so that it's more secure and can potentially be used to create a desktop app in the future. Used Tuupola's JWT auth middleware implementation to help with the auth part. Used Firebase's JWT method to create the token Signed-off-by: rodude123 --- .gitignore | 4 +- composer.json | 4 +- composer.lock | 388 +++++++++++++++++++++++++++++++++++++- dist/api/index.php | 42 ++--- dist/api/middleware.php | 91 +++++++++ dist/api/projectData.php | 4 + dist/api/timelineData.php | 8 + dist/api/user.php | 53 +++++- src/api/index.php | 42 ++--- src/api/middleware.php | 91 +++++++++ src/api/projectData.php | 4 + src/api/timelineData.php | 8 + src/api/user.php | 53 +++++- 13 files changed, 728 insertions(+), 64 deletions(-) create mode 100644 dist/api/middleware.php create mode 100644 src/api/middleware.php diff --git a/.gitignore b/.gitignore index 42d443b..1adac6c 100644 --- a/.gitignore +++ b/.gitignore @@ -75,5 +75,5 @@ fabric.properties .env vendor/* node_modules/* -src/api/config.php -dist/api/config.php +./src/api/config.php +./dist/api/config.php diff --git a/composer.json b/composer.json index 8b188d8..f8d24a5 100644 --- a/composer.json +++ b/composer.json @@ -11,6 +11,8 @@ "laminas/laminas-httphandlerrunner": "^2.0", "selective/samesite-cookie": "^0.3.0", "ext-json": "*", - "slim/slim": "^4.10" + "slim/slim": "^4.10", + "rbdwllr/psr-jwt": "^2.0", + "tuupola/slim-jwt-auth": "^3.6" } } diff --git a/composer.lock b/composer.lock index 74f5c23..aeeb7ea 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bbd0a827a6d61bc9032697dbd94a5045", + "content-hash": "79f27ef0ad8fb8ffff7e6726df8c1f79", "packages": [ { "name": "fig/http-message-util", @@ -62,6 +62,63 @@ }, "time": "2020-11-24T22:02:12+00:00" }, + { + "name": "firebase/php-jwt", + "version": "v5.5.1", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "83b609028194aa042ea33b5af2d41a7427de80e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/83b609028194aa042ea33b5af2d41a7427de80e6", + "reference": "83b609028194aa042ea33b5af2d41a7427de80e6", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">=4.8 <=9" + }, + "suggest": { + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v5.5.1" + }, + "time": "2021-11-08T20:18:51+00:00" + }, { "name": "guzzlehttp/psr7", "version": "2.4.0", @@ -1346,6 +1403,130 @@ }, "time": "2019-03-08T08:55:37+00:00" }, + { + "name": "rbdwllr/psr-jwt", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/RobDWaller/psr-jwt.git", + "reference": "c32c7ee4c86fe30a7f38ba4763ef8793ad60b1bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/RobDWaller/psr-jwt/zipball/c32c7ee4c86fe30a7f38ba4763ef8793ad60b1bb", + "reference": "c32c7ee4c86fe30a7f38ba4763ef8793ad60b1bb", + "shasum": "" + }, + "require": { + "nyholm/psr7": "^1.5", + "php": ">=7.4.0", + "psr/http-message": "^1.0", + "psr/http-server-middleware": "^1.0", + "rbdwllr/reallysimplejwt": "^4.0" + }, + "require-dev": { + "infection/infection": "^0.20", + "mockery/mockery": "^1.5", + "phploc/phploc": "^7.0", + "phpmd/phpmd": "^2.12", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-mockery": "^1.0", + "phpunit/phpunit": "^9.0", + "sebastian/phpcpd": "^6.0", + "squizlabs/php_codesniffer": "^3.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Tests\\": "tests/", + "PsrJwt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Waller", + "email": "rdwaller1984@googlemail.com" + } + ], + "description": "A PSR 7 compliant JSON Web Token Middleware Library.", + "keywords": [ + "Authentication", + "authorisation", + "json", + "json web tokens", + "jwt", + "php", + "psr-7", + "tokens" + ], + "support": { + "issues": "https://github.com/RobDWaller/psr-jwt/issues", + "source": "https://github.com/RobDWaller/psr-jwt/tree/2.0.1" + }, + "time": "2022-06-11T13:28:17+00:00" + }, + { + "name": "rbdwllr/reallysimplejwt", + "version": "4.0.3", + "source": { + "type": "git", + "url": "https://github.com/RobDWaller/ReallySimpleJWT.git", + "reference": "2b92aba98c71cfc4046dea895659450bfce530ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/RobDWaller/ReallySimpleJWT/zipball/2b92aba98c71cfc4046dea895659450bfce530ed", + "reference": "2b92aba98c71cfc4046dea895659450bfce530ed", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "require-dev": { + "infection/infection": "^0.20", + "phpbench/phpbench": "^1.0", + "phploc/phploc": "^7.0", + "phpmd/phpmd": "^2.9", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^9.5", + "sebastian/phpcpd": "^6.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "ReallySimpleJWT\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rob Waller", + "email": "rdwaller1984@gmail.com" + } + ], + "description": "A really simple library to generate user authentication JSON Web Tokens.", + "keywords": [ + "Authentication", + "json", + "json web tokens", + "jwt", + "php", + "tokens" + ], + "support": { + "issues": "https://github.com/RobDWaller/ReallySimpleJWT/issues", + "source": "https://github.com/RobDWaller/ReallySimpleJWT/tree/4.0.3" + }, + "time": "2021-07-12T10:12:22+00:00" + }, { "name": "selective/samesite-cookie", "version": "0.3.0", @@ -1744,6 +1925,211 @@ } ], "time": "2022-05-10T07:21:04+00:00" + }, + { + "name": "tuupola/callable-handler", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/tuupola/callable-handler.git", + "reference": "0bc7b88630ca753de9aba8f411046856f5ca6f8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tuupola/callable-handler/zipball/0bc7b88630ca753de9aba8f411046856f5ca6f8c", + "reference": "0bc7b88630ca753de9aba8f411046856f5ca6f8c", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0", + "psr/http-server-middleware": "^1.0" + }, + "require-dev": { + "overtrue/phplint": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0", + "squizlabs/php_codesniffer": "^3.2", + "tuupola/http-factory": "^0.4.0|^1.0", + "zendframework/zend-diactoros": "^1.6.0|^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Tuupola\\Middleware\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mika Tuupola", + "email": "tuupola@appelsiini.net", + "homepage": "https://appelsiini.net/", + "role": "Developer" + } + ], + "description": "Compatibility layer for PSR-7 double pass and PSR-15 middlewares.", + "homepage": "https://github.com/tuupola/callable-handler", + "keywords": [ + "middleware", + "psr-15", + "psr-7" + ], + "support": { + "issues": "https://github.com/tuupola/callable-handler/issues", + "source": "https://github.com/tuupola/callable-handler/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/tuupola", + "type": "github" + } + ], + "time": "2020-09-09T08:31:54+00:00" + }, + { + "name": "tuupola/http-factory", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/tuupola/http-factory.git", + "reference": "ae3f8fbdd31cf2f1bbe920b38963c5e4d1e9c454" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tuupola/http-factory/zipball/ae3f8fbdd31cf2f1bbe920b38963c5e4d1e9c454", + "reference": "ae3f8fbdd31cf2f1bbe920b38963c5e4d1e9c454", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0", + "psr/http-factory": "^1.0" + }, + "conflict": { + "nyholm/psr7": "<1.0" + }, + "provide": { + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9.0", + "overtrue/phplint": "^3.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0", + "squizlabs/php_codesniffer": "^3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Tuupola\\Http\\Factory\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mika Tuupola", + "email": "tuupola@appelsiini.net", + "homepage": "https://appelsiini.net/", + "role": "Developer" + } + ], + "description": "Lightweight autodiscovering PSR-17 HTTP factories", + "homepage": "https://github.com/tuupola/http-factory", + "keywords": [ + "http", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/tuupola/http-factory/issues", + "source": "https://github.com/tuupola/http-factory/tree/1.4.0" + }, + "funding": [ + { + "url": "https://github.com/tuupola", + "type": "github" + } + ], + "time": "2021-09-14T12:46:25+00:00" + }, + { + "name": "tuupola/slim-jwt-auth", + "version": "3.6.0", + "source": { + "type": "git", + "url": "https://github.com/tuupola/slim-jwt-auth.git", + "reference": "d9ed8bca77a0ef2a95ab48e65ddc26073b99c5ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tuupola/slim-jwt-auth/zipball/d9ed8bca77a0ef2a95ab48e65ddc26073b99c5ff", + "reference": "d9ed8bca77a0ef2a95ab48e65ddc26073b99c5ff", + "shasum": "" + }, + "require": { + "firebase/php-jwt": "^3.0|^4.0|^5.0", + "php": "^7.1|^8.0", + "psr/http-message": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/log": "^1.0|^2.0|^3.0", + "tuupola/callable-handler": "^0.3.0|^0.4.0|^1.0", + "tuupola/http-factory": "^0.4.0|^1.0.2" + }, + "require-dev": { + "equip/dispatch": "^2.0", + "laminas/laminas-diactoros": "^2.0", + "overtrue/phplint": "^1.0", + "phpstan/phpstan": "^0.12.43", + "phpunit/phpunit": "^7.0|^8.0|^9.0", + "squizlabs/php_codesniffer": "^3.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Tuupola\\Middleware\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mika Tuupola", + "email": "tuupola@appelsiini.net", + "homepage": "https://appelsiini.net/", + "role": "Developer" + } + ], + "description": "PSR-7 and PSR-15 JWT Authentication Middleware", + "homepage": "https://github.com/tuupola/slim-jwt-auth", + "keywords": [ + "auth", + "json", + "jwt", + "middleware", + "psr-15", + "psr-7" + ], + "support": { + "issues": "https://github.com/tuupola/slim-jwt-auth/issues", + "source": "https://github.com/tuupola/slim-jwt-auth/tree/3.6.0" + }, + "funding": [ + { + "url": "https://github.com/tuupola", + "type": "github" + } + ], + "time": "2022-01-12T11:15:02+00:00" } ], "packages-dev": [], diff --git a/dist/api/index.php b/dist/api/index.php index d7a152a..2c657ca 100644 --- a/dist/api/index.php +++ b/dist/api/index.php @@ -1,4 +1,4 @@ -addRoutingMiddleware(); - -$ssConfig = new SameSiteCookieConfiguration(["same_site" => "strict"]); - -// add in same site cookie stuff -$app->add(new SameSiteCookieMiddleware($ssConfig)); - -// for error checking -$errorMiddleware = $app->addErrorMiddleware(true, true, true); // set base path for all routes $app->setBasePath("/api"); -// return all responses as JSON -/*$app->add(function($request, $handler) { - $response = $handler->handle($request); - return $response->withHeader("Content-Type", "application/json"); -});*/ +// Add middleware +new middleware($app); $timelineData = new timelineData(); $projectData = new projectData(); @@ -277,8 +267,9 @@ $app->post("/user/login", function (Request $request, Response $response) if ($user->checkUser($data["username"], $data["password"])) { // yay, user is logged in - $_SESSION["token"] = $user->createToken(); + $_SESSION["token"] = $user->createToken($data["username"]); $_SESSION["username"] = $data["username"]; + $response->getBody()->write(json_encode(array("token" => $_SESSION["token"]))); return $response; } return $response->withStatus(401); @@ -297,7 +288,7 @@ $app->get("/user/isLoggedIn", function (Request $request, Response $response) if (empty($_SESSION["token"])) { // user is logged in but no token was created - $_SESSION["token"] = $user->createToken(); + $_SESSION["token"] = $user->createToken($_SESSION["username"]); return $response; } @@ -319,8 +310,7 @@ $app->get("/user/checkResetEmail/{email}", function (Request $request, Response if ($user->checkEmail($args["email"])) { // yay email does exist - $token = $user->sendResetEmail($args["email"]); - $_SESSION["resetToken"] = $token; + $_SESSION["resetToken"] = $user->sendResetEmail($args["email"]); $_SESSION["resetEmail"] = $args["email"]; return $response; } @@ -335,7 +325,7 @@ $app->get("/user/resendEmail", function (Request $request, Response $response) return $response->withStatus(401); } global $user; - $user->sendResetEmail($_SESSION["resetEmail"]); + $_SESSION["resetToken"] = $user->sendResetEmail($_SESSION["resetEmail"]); return $response; }); @@ -383,4 +373,10 @@ $app->post("/user/changePassword", function (Request $request, Response $respons return $response->withStatus(500); }); +$app->post("/projectData", function (Request $request, Response $response) +{ + $response->getBody()->write(json_encode(array("test" => "test"))); + return $response; +}); + $app->run(); diff --git a/dist/api/middleware.php b/dist/api/middleware.php new file mode 100644 index 0000000..b194905 --- /dev/null +++ b/dist/api/middleware.php @@ -0,0 +1,91 @@ +baseMiddleware($app); + $this->sameSiteConfig($app); + $this->jwtAuth($app); + $this->returnAsJSON($app); + } + + /** + * Base middleware + * @param App $app - Slim App + */ + function baseMiddleware(App $app): void + { + $app->addRoutingMiddleware(); + } + + /** + * SameSite Cookie Configuration + * @param App $app - Slim App + */ + function sameSiteConfig(App $app): void + { + $ssConfig = new SameSiteCookieConfiguration(["same_site" => "strict"]); + $app->add(new SameSiteCookieMiddleware($ssConfig)); + } + + /** + * Return all responses as JSON + * @param App $app - Slim App + */ + function returnAsJSON(App $app): void + { + $app->add(function ($request, $handler) + { + $response = $handler->handle($request); + return $response->withHeader("Content-Type", "application/json"); + }); + } + + /** + * JWT Authentication + * @param App $app - Slim App + */ + function jwtAuth(App $app): void + { + $jwtSecret = getSecretKey(); + $app->add(new JwtAuthentication([ + "rules" => [ + new RequestPathRule([ + "path" => ["/api/projectData", "/api/timeline/[a-z]*", "/api/user/testMethod"], + "ignore" => ["/api/contact", "/api/user/login", "/api/user/changePassword"] + ]), + new RequestMethodRule([ + "ignore" => ["OPTIONS", "GET"] + ]) + ], + "secret" => $jwtSecret, + "error" => function ($response) + { + session_destroy(); + $response->getBody()->write(json_encode(array("status" => "401", "message" => + "Unauthorized, please provide a valid token"))); + return $response->withStatus(401); + } + ])); + $app->addErrorMiddleware(true, true, true); + } + +} \ No newline at end of file diff --git a/dist/api/projectData.php b/dist/api/projectData.php index fc5bf68..74be93c 100644 --- a/dist/api/projectData.php +++ b/dist/api/projectData.php @@ -10,6 +10,10 @@ require_once "./config.php"; */ class projectData { + /** + * Get all project data + * @return array - Array of all project data or error message + */ function getProjectData(): array { $conn = dbConn(); diff --git a/dist/api/timelineData.php b/dist/api/timelineData.php index f34cd38..818a3d0 100644 --- a/dist/api/timelineData.php +++ b/dist/api/timelineData.php @@ -10,6 +10,10 @@ require_once "./config.php"; */ class timelineData { + /** + * Get all education data + * @return array - Array of all education data or error message + */ function getEduData(): array { $conn = dbConn(); @@ -26,6 +30,10 @@ class timelineData return array("errorMessage" => "Error, edu data not found"); } + /** + * Get all work data + * @return array - Array of all work data or error message + */ function getWorkData(): array { $conn = dbConn(); diff --git a/dist/api/user.php b/dist/api/user.php index 1cbb56e..d8093e4 100644 --- a/dist/api/user.php +++ b/dist/api/user.php @@ -1,5 +1,6 @@ prepare("SELECT * FROM users WHERE username = :username"); @@ -31,12 +38,31 @@ class user return false; } - function createToken(): string + /** + * Create a JWT token + * @param $username string - Username + * @return string - JWT token + */ + function createToken(string $username): string { - return uniqid("rpe-"); + $now = time(); + $future = strtotime('+6 hour',$now); + $secretKey = getSecretKey(); + $payload = [ + "jti"=>$username, + "iat"=>$now, + "exp"=>$future + ]; + + return JWT::encode($payload,$secretKey,"HS256"); } - function checkEmail($email): bool + /** + * Check if email is already in use + * @param string $email - Email to check + * @return bool - True if email exists, false if not + */ + function checkEmail(string $email): bool { $conn = dbConn(); $stmt = $conn->prepare("SELECT * FROM users WHERE email = :email"); @@ -52,11 +78,16 @@ class user } return false; } - + + /** + * Send a verification email to the user + * @param $email - email address of the user + * @return string - verification code + */ function sendResetEmail($email): string { //generate a random token and email the address - $token = $this->createToken(); + $token = uniqid("rpe-"); $headers1 = "From: noreply@rohitpai.co.uk\r\n"; $headers1 .= "MIME-Version: 1.0\r\n"; $headers1 .= "Content-Type: text/html; charset=UTF-8\r\n"; @@ -82,7 +113,13 @@ class user return $token; } - function changePassword($email, $password): bool + /** + * Change password for an email with new password + * @param $email string Email + * @param $password string Password + * @return bool - true if the password was changed, false if not + */ + function changePassword(string $email, string $password): bool { $conn = dbConn(); $stmt = $conn->prepare("UPDATE users SET password = :password WHERE email = :email"); @@ -96,4 +133,6 @@ class user } return false; } + + } \ No newline at end of file diff --git a/src/api/index.php b/src/api/index.php index d7a152a..2c657ca 100644 --- a/src/api/index.php +++ b/src/api/index.php @@ -1,4 +1,4 @@ -addRoutingMiddleware(); - -$ssConfig = new SameSiteCookieConfiguration(["same_site" => "strict"]); - -// add in same site cookie stuff -$app->add(new SameSiteCookieMiddleware($ssConfig)); - -// for error checking -$errorMiddleware = $app->addErrorMiddleware(true, true, true); // set base path for all routes $app->setBasePath("/api"); -// return all responses as JSON -/*$app->add(function($request, $handler) { - $response = $handler->handle($request); - return $response->withHeader("Content-Type", "application/json"); -});*/ +// Add middleware +new middleware($app); $timelineData = new timelineData(); $projectData = new projectData(); @@ -277,8 +267,9 @@ $app->post("/user/login", function (Request $request, Response $response) if ($user->checkUser($data["username"], $data["password"])) { // yay, user is logged in - $_SESSION["token"] = $user->createToken(); + $_SESSION["token"] = $user->createToken($data["username"]); $_SESSION["username"] = $data["username"]; + $response->getBody()->write(json_encode(array("token" => $_SESSION["token"]))); return $response; } return $response->withStatus(401); @@ -297,7 +288,7 @@ $app->get("/user/isLoggedIn", function (Request $request, Response $response) if (empty($_SESSION["token"])) { // user is logged in but no token was created - $_SESSION["token"] = $user->createToken(); + $_SESSION["token"] = $user->createToken($_SESSION["username"]); return $response; } @@ -319,8 +310,7 @@ $app->get("/user/checkResetEmail/{email}", function (Request $request, Response if ($user->checkEmail($args["email"])) { // yay email does exist - $token = $user->sendResetEmail($args["email"]); - $_SESSION["resetToken"] = $token; + $_SESSION["resetToken"] = $user->sendResetEmail($args["email"]); $_SESSION["resetEmail"] = $args["email"]; return $response; } @@ -335,7 +325,7 @@ $app->get("/user/resendEmail", function (Request $request, Response $response) return $response->withStatus(401); } global $user; - $user->sendResetEmail($_SESSION["resetEmail"]); + $_SESSION["resetToken"] = $user->sendResetEmail($_SESSION["resetEmail"]); return $response; }); @@ -383,4 +373,10 @@ $app->post("/user/changePassword", function (Request $request, Response $respons return $response->withStatus(500); }); +$app->post("/projectData", function (Request $request, Response $response) +{ + $response->getBody()->write(json_encode(array("test" => "test"))); + return $response; +}); + $app->run(); diff --git a/src/api/middleware.php b/src/api/middleware.php new file mode 100644 index 0000000..b194905 --- /dev/null +++ b/src/api/middleware.php @@ -0,0 +1,91 @@ +baseMiddleware($app); + $this->sameSiteConfig($app); + $this->jwtAuth($app); + $this->returnAsJSON($app); + } + + /** + * Base middleware + * @param App $app - Slim App + */ + function baseMiddleware(App $app): void + { + $app->addRoutingMiddleware(); + } + + /** + * SameSite Cookie Configuration + * @param App $app - Slim App + */ + function sameSiteConfig(App $app): void + { + $ssConfig = new SameSiteCookieConfiguration(["same_site" => "strict"]); + $app->add(new SameSiteCookieMiddleware($ssConfig)); + } + + /** + * Return all responses as JSON + * @param App $app - Slim App + */ + function returnAsJSON(App $app): void + { + $app->add(function ($request, $handler) + { + $response = $handler->handle($request); + return $response->withHeader("Content-Type", "application/json"); + }); + } + + /** + * JWT Authentication + * @param App $app - Slim App + */ + function jwtAuth(App $app): void + { + $jwtSecret = getSecretKey(); + $app->add(new JwtAuthentication([ + "rules" => [ + new RequestPathRule([ + "path" => ["/api/projectData", "/api/timeline/[a-z]*", "/api/user/testMethod"], + "ignore" => ["/api/contact", "/api/user/login", "/api/user/changePassword"] + ]), + new RequestMethodRule([ + "ignore" => ["OPTIONS", "GET"] + ]) + ], + "secret" => $jwtSecret, + "error" => function ($response) + { + session_destroy(); + $response->getBody()->write(json_encode(array("status" => "401", "message" => + "Unauthorized, please provide a valid token"))); + return $response->withStatus(401); + } + ])); + $app->addErrorMiddleware(true, true, true); + } + +} \ No newline at end of file diff --git a/src/api/projectData.php b/src/api/projectData.php index fc5bf68..74be93c 100644 --- a/src/api/projectData.php +++ b/src/api/projectData.php @@ -10,6 +10,10 @@ require_once "./config.php"; */ class projectData { + /** + * Get all project data + * @return array - Array of all project data or error message + */ function getProjectData(): array { $conn = dbConn(); diff --git a/src/api/timelineData.php b/src/api/timelineData.php index f34cd38..818a3d0 100644 --- a/src/api/timelineData.php +++ b/src/api/timelineData.php @@ -10,6 +10,10 @@ require_once "./config.php"; */ class timelineData { + /** + * Get all education data + * @return array - Array of all education data or error message + */ function getEduData(): array { $conn = dbConn(); @@ -26,6 +30,10 @@ class timelineData return array("errorMessage" => "Error, edu data not found"); } + /** + * Get all work data + * @return array - Array of all work data or error message + */ function getWorkData(): array { $conn = dbConn(); diff --git a/src/api/user.php b/src/api/user.php index 1cbb56e..d8093e4 100644 --- a/src/api/user.php +++ b/src/api/user.php @@ -1,5 +1,6 @@ prepare("SELECT * FROM users WHERE username = :username"); @@ -31,12 +38,31 @@ class user return false; } - function createToken(): string + /** + * Create a JWT token + * @param $username string - Username + * @return string - JWT token + */ + function createToken(string $username): string { - return uniqid("rpe-"); + $now = time(); + $future = strtotime('+6 hour',$now); + $secretKey = getSecretKey(); + $payload = [ + "jti"=>$username, + "iat"=>$now, + "exp"=>$future + ]; + + return JWT::encode($payload,$secretKey,"HS256"); } - function checkEmail($email): bool + /** + * Check if email is already in use + * @param string $email - Email to check + * @return bool - True if email exists, false if not + */ + function checkEmail(string $email): bool { $conn = dbConn(); $stmt = $conn->prepare("SELECT * FROM users WHERE email = :email"); @@ -52,11 +78,16 @@ class user } return false; } - + + /** + * Send a verification email to the user + * @param $email - email address of the user + * @return string - verification code + */ function sendResetEmail($email): string { //generate a random token and email the address - $token = $this->createToken(); + $token = uniqid("rpe-"); $headers1 = "From: noreply@rohitpai.co.uk\r\n"; $headers1 .= "MIME-Version: 1.0\r\n"; $headers1 .= "Content-Type: text/html; charset=UTF-8\r\n"; @@ -82,7 +113,13 @@ class user return $token; } - function changePassword($email, $password): bool + /** + * Change password for an email with new password + * @param $email string Email + * @param $password string Password + * @return bool - true if the password was changed, false if not + */ + function changePassword(string $email, string $password): bool { $conn = dbConn(); $stmt = $conn->prepare("UPDATE users SET password = :password WHERE email = :email"); @@ -96,4 +133,6 @@ class user } return false; } + + } \ No newline at end of file -- 2.43.0 From e0b3afd2627684c4ad021ad09339ac98510c58ee Mon Sep 17 00:00:00 2001 From: rodude123 Date: Sun, 9 Oct 2022 02:47:02 +0100 Subject: [PATCH 2/5] updated gitignore to propperly ignore the files Signed-off-by: rodude123 --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 1adac6c..4a652db 100644 --- a/.gitignore +++ b/.gitignore @@ -75,5 +75,5 @@ fabric.properties .env vendor/* node_modules/* -./src/api/config.php -./dist/api/config.php +src/api/config.php +!/dist/api/config.php -- 2.43.0 From d9702e4ed72471da43635ef3a08a2dfe861651a1 Mon Sep 17 00:00:00 2001 From: rodude123 Date: Sun, 9 Oct 2022 02:47:43 +0100 Subject: [PATCH 3/5] removed ignored file Signed-off-by: rodude123 --- dist/api/config.php | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 dist/api/config.php diff --git a/dist/api/config.php b/dist/api/config.php deleted file mode 100644 index 579fd7b..0000000 --- a/dist/api/config.php +++ /dev/null @@ -1,21 +0,0 @@ -getMessage(); - } -} \ No newline at end of file -- 2.43.0 From 4f46e2eb416d171a4187e1056dfbf6dad50bbfb5 Mon Sep 17 00:00:00 2001 From: rodude123 Date: Sun, 9 Oct 2022 02:48:09 +0100 Subject: [PATCH 4/5] updated ignore file Signed-off-by: rodude123 --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4a652db..edb4423 100644 --- a/.gitignore +++ b/.gitignore @@ -76,4 +76,4 @@ fabric.properties vendor/* node_modules/* src/api/config.php -!/dist/api/config.php +/dist/api/config.php -- 2.43.0 From 3d4789ff7f0559995edc3230cc40ece660974514 Mon Sep 17 00:00:00 2001 From: rodude123 Date: Sun, 9 Oct 2022 02:49:49 +0100 Subject: [PATCH 5/5] updated ignore file Signed-off-by: rodude123 --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index edb4423..42d443b 100644 --- a/.gitignore +++ b/.gitignore @@ -76,4 +76,4 @@ fabric.properties vendor/* node_modules/* src/api/config.php -/dist/api/config.php +dist/api/config.php -- 2.43.0