Added in login feature to editor #21

Merged
rodude123 merged 1 commits from cms-login into master 2022-07-29 20:16:30 +01:00
31 changed files with 831 additions and 478 deletions

View File

@ -9,6 +9,7 @@
"http-interop/http-factory-guzzle": "^1.2",
"laminas/laminas-diactoros": "^2.6",
"laminas/laminas-httphandlerrunner": "^2.0",
"selective/samesite-cookie": "^0.3.0"
"selective/samesite-cookie": "^0.3.0",
"ext-json": "*"
}
}

487
composer.lock generated
View File

@ -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": "5aafeb561d1b79ead81458f3e265c0c1",
"content-hash": "5ddb974cba41098a51ddfa43a17c9520",
"packages": [
{
"name": "fig/http-message-util",
@ -64,16 +64,16 @@
},
{
"name": "guzzlehttp/psr7",
"version": "2.0.0",
"version": "2.4.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "1dc8d9cba3897165e16d12bb13d813afb1eb3fe7"
"reference": "13388f00956b1503577598873fffb5ae994b5737"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/1dc8d9cba3897165e16d12bb13d813afb1eb3fe7",
"reference": "1dc8d9cba3897165e16d12bb13d813afb1eb3fe7",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/13388f00956b1503577598873fffb5ae994b5737",
"reference": "13388f00956b1503577598873fffb5ae994b5737",
"shasum": ""
},
"require": {
@ -97,7 +97,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
"dev-master": "2.4-dev"
}
},
"autoload": {
@ -110,13 +110,34 @@
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "George Mponos",
"email": "gmponos@gmail.com",
"homepage": "https://github.com/gmponos"
},
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com",
"homepage": "https://github.com/Nyholm"
},
{
"name": "Márk Sági-Kazár",
"email": "mark.sagikazar@gmail.com",
"homepage": "https://github.com/sagikazarmark"
},
{
"name": "Tobias Schultze",
"email": "webmaster@tubo-world.de",
"homepage": "https://github.com/Tobion"
},
{
@ -138,9 +159,23 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.0.0"
"source": "https://github.com/guzzle/psr7/tree/2.4.0"
},
"time": "2021-06-30T20:03:07+00:00"
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://github.com/Nyholm",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
"type": "tidelift"
}
],
"time": "2022-06-20T21:43:11+00:00"
},
{
"name": "http-interop/http-factory-guzzle",
@ -202,46 +237,43 @@
},
{
"name": "laminas/laminas-diactoros",
"version": "2.6.0",
"version": "2.14.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-diactoros.git",
"reference": "7d2034110ae18afe05050b796a3ee4b3fe177876"
"reference": "6cb35f61913f06b2c91075db00f67cfd78869e28"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/7d2034110ae18afe05050b796a3ee4b3fe177876",
"reference": "7d2034110ae18afe05050b796a3ee4b3fe177876",
"url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6cb35f61913f06b2c91075db00f67cfd78869e28",
"reference": "6cb35f61913f06b2c91075db00f67cfd78869e28",
"shasum": ""
},
"require": {
"laminas/laminas-zendframework-bridge": "^1.0",
"php": "^7.3 || ~8.0.0",
"php": "^7.3 || ~8.0.0 || ~8.1.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0"
},
"conflict": {
"phpspec/prophecy": "<1.9.0"
"phpspec/prophecy": "<1.9.0",
"zendframework/zend-diactoros": "*"
},
"provide": {
"psr/http-factory-implementation": "1.0",
"psr/http-message-implementation": "1.0"
},
"replace": {
"zendframework/zend-diactoros": "^2.2.1"
},
"require-dev": {
"ext-curl": "*",
"ext-dom": "*",
"ext-gd": "*",
"ext-libxml": "*",
"http-interop/http-factory-tests": "^0.8.0",
"laminas/laminas-coding-standard": "~1.0.0",
"php-http/psr7-integration-tests": "^1.1",
"http-interop/http-factory-tests": "^0.9.0",
"laminas/laminas-coding-standard": "~2.3.0",
"php-http/psr7-integration-tests": "^1.1.1",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9.1",
"psalm/plugin-phpunit": "^0.14.0",
"vimeo/psalm": "^4.3"
"phpunit/phpunit": "^9.5",
"psalm/plugin-phpunit": "^0.17.0",
"vimeo/psalm": "^4.24.0"
},
"type": "library",
"extra": {
@ -300,34 +332,34 @@
"type": "community_bridge"
}
],
"time": "2021-05-18T14:41:54+00:00"
"time": "2022-07-28T12:23:48+00:00"
},
{
"name": "laminas/laminas-httphandlerrunner",
"version": "2.0.1",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-httphandlerrunner.git",
"reference": "477b8fc161bc59dca2dab90bb01b5bf57f90eea6"
"reference": "4d337cde83e6b901a4443b0ab5c3b97cbaa46413"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-httphandlerrunner/zipball/477b8fc161bc59dca2dab90bb01b5bf57f90eea6",
"reference": "477b8fc161bc59dca2dab90bb01b5bf57f90eea6",
"url": "https://api.github.com/repos/laminas/laminas-httphandlerrunner/zipball/4d337cde83e6b901a4443b0ab5c3b97cbaa46413",
"reference": "4d337cde83e6b901a4443b0ab5c3b97cbaa46413",
"shasum": ""
},
"require": {
"php": "^7.3 || ~8.0.0",
"php": "^7.3 || ~8.0.0 || ~8.1.0",
"psr/http-message": "^1.0",
"psr/http-message-implementation": "^1.0",
"psr/http-server-handler": "^1.0"
},
"require-dev": {
"laminas/laminas-coding-standard": "~2.3.0",
"laminas/laminas-diactoros": "^2.1.1",
"phpunit/phpunit": "^9.3",
"psalm/plugin-phpunit": "^0.15.1",
"vimeo/psalm": "^4.6"
"laminas/laminas-diactoros": "^2.8.0",
"phpunit/phpunit": "^9.5.9",
"psalm/plugin-phpunit": "^0.16.1",
"vimeo/psalm": "^4.10.0"
},
"type": "library",
"extra": {
@ -367,118 +399,121 @@
"type": "community_bridge"
}
],
"time": "2021-08-05T14:45:43+00:00"
"time": "2021-09-22T09:27:36+00:00"
},
{
"name": "laminas/laminas-zendframework-bridge",
"version": "1.3.0",
"name": "laravel/serializable-closure",
"version": "v1.2.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-zendframework-bridge.git",
"reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e"
"url": "https://github.com/laravel/serializable-closure.git",
"reference": "09f0e9fb61829f628205b7c94906c28740ff9540"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/13af2502d9bb6f7d33be2de4b51fb68c6cdb476e",
"reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540",
"reference": "09f0e9fb61829f628205b7c94906c28740ff9540",
"shasum": ""
},
"require": {
"php": "^7.3 || ^8.0"
"php": "^7.3|^8.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3",
"psalm/plugin-phpunit": "^0.15.1",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.6"
"pestphp/pest": "^1.18",
"phpstan/phpstan": "^0.12.98",
"symfony/var-dumper": "^5.3"
},
"type": "library",
"extra": {
"laminas": {
"module": "Laminas\\ZendFrameworkBridge"
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"files": [
"src/autoload.php"
],
"psr-4": {
"Laminas\\ZendFrameworkBridge\\": "src//"
"Laravel\\SerializableClosure\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
"MIT"
],
"description": "Alias legacy ZF class names to Laminas Project equivalents.",
"keywords": [
"ZendFramework",
"autoloading",
"laminas",
"zf"
],
"support": {
"forum": "https://discourse.laminas.dev/",
"issues": "https://github.com/laminas/laminas-zendframework-bridge/issues",
"rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom",
"source": "https://github.com/laminas/laminas-zendframework-bridge"
},
"funding": [
"authors": [
{
"url": "https://funding.communitybridge.org/projects/laminas-project",
"type": "community_bridge"
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
},
{
"name": "Nuno Maduro",
"email": "nuno@laravel.com"
}
],
"time": "2021-06-24T12:49:22+00:00"
"description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.",
"keywords": [
"closure",
"laravel",
"serializable"
],
"support": {
"issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure"
},
"time": "2022-05-16T17:09:47+00:00"
},
{
"name": "monolog/monolog",
"version": "2.3.2",
"version": "2.8.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "71312564759a7db5b789296369c1a264efc43aad"
"reference": "720488632c590286b88b80e62aa3d3d551ad4a50"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/71312564759a7db5b789296369c1a264efc43aad",
"reference": "71312564759a7db5b789296369c1a264efc43aad",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50",
"reference": "720488632c590286b88b80e62aa3d3d551ad4a50",
"shasum": ""
},
"require": {
"php": ">=7.2",
"psr/log": "^1.0.1"
"psr/log": "^1.0.1 || ^2.0 || ^3.0"
},
"provide": {
"psr/log-implementation": "1.0.0"
"psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
"doctrine/couchdb": "~1.0@dev",
"elasticsearch/elasticsearch": "^7",
"elasticsearch/elasticsearch": "^7 || ^8",
"ext-json": "*",
"graylog2/gelf-php": "^1.4.2",
"guzzlehttp/guzzle": "^7.4",
"guzzlehttp/psr7": "^2.2",
"mongodb/mongodb": "^1.8",
"php-amqplib/php-amqplib": "~2.4",
"php-console/php-console": "^3.1.3",
"phpspec/prophecy": "^1.6.1",
"php-amqplib/php-amqplib": "~2.4 || ^3",
"phpspec/prophecy": "^1.15",
"phpstan/phpstan": "^0.12.91",
"phpunit/phpunit": "^8.5",
"predis/predis": "^1.1",
"rollbar/rollbar": "^1.3",
"ruflin/elastica": ">=0.90 <7.0.1",
"swiftmailer/swiftmailer": "^5.3|^6.0"
"phpunit/phpunit": "^8.5.14",
"predis/predis": "^1.1 || ^2.0",
"rollbar/rollbar": "^1.3 || ^2 || ^3",
"ruflin/elastica": "^7",
"swiftmailer/swiftmailer": "^5.3|^6.0",
"symfony/mailer": "^5.4 || ^6",
"symfony/mime": "^5.4 || ^6"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
"ext-mbstring": "Allow to work properly with unicode symbols",
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
"ext-openssl": "Required to send log messages using SSL",
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"php-console/php-console": "Allow sending log messages to Google Chrome",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
@ -513,7 +548,7 @@
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
"source": "https://github.com/Seldaek/monolog/tree/2.3.2"
"source": "https://github.com/Seldaek/monolog/tree/2.8.0"
},
"funding": [
{
@ -525,7 +560,7 @@
"type": "tidelift"
}
],
"time": "2021-07-23T07:42:52+00:00"
"time": "2022-07-24T11:55:47+00:00"
},
{
"name": "nikic/fast-route",
@ -549,12 +584,12 @@
},
"type": "library",
"autoload": {
"psr-4": {
"FastRoute\\": "src/"
},
"files": [
"src/functions.php"
]
],
"psr-4": {
"FastRoute\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@ -579,16 +614,16 @@
},
{
"name": "nyholm/psr7",
"version": "1.4.1",
"version": "1.5.1",
"source": {
"type": "git",
"url": "https://github.com/Nyholm/psr7.git",
"reference": "2212385b47153ea71b1c1b1374f8cb5e4f7892ec"
"reference": "f734364e38a876a23be4d906a2a089e1315be18a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Nyholm/psr7/zipball/2212385b47153ea71b1c1b1374f8cb5e4f7892ec",
"reference": "2212385b47153ea71b1c1b1374f8cb5e4f7892ec",
"url": "https://api.github.com/repos/Nyholm/psr7/zipball/f734364e38a876a23be4d906a2a089e1315be18a",
"reference": "f734364e38a876a23be4d906a2a089e1315be18a",
"shasum": ""
},
"require": {
@ -640,7 +675,7 @@
],
"support": {
"issues": "https://github.com/Nyholm/psr7/issues",
"source": "https://github.com/Nyholm/psr7/tree/1.4.1"
"source": "https://github.com/Nyholm/psr7/tree/1.5.1"
},
"funding": [
{
@ -652,7 +687,7 @@
"type": "github"
}
],
"time": "2021-07-02T08:32:20+00:00"
"time": "2022-06-22T07:13:36+00:00"
},
{
"name": "nyholm/psr7-server",
@ -720,83 +755,18 @@
],
"time": "2021-05-12T11:11:27+00:00"
},
{
"name": "opis/closure",
"version": "3.6.2",
"source": {
"type": "git",
"url": "https://github.com/opis/closure.git",
"reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opis/closure/zipball/06e2ebd25f2869e54a306dda991f7db58066f7f6",
"reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6",
"shasum": ""
},
"require": {
"php": "^5.4 || ^7.0 || ^8.0"
},
"require-dev": {
"jeremeamia/superclosure": "^2.0",
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.6.x-dev"
}
},
"autoload": {
"psr-4": {
"Opis\\Closure\\": "src/"
},
"files": [
"functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marius Sarca",
"email": "marius.sarca@gmail.com"
},
{
"name": "Sorin Sarca",
"email": "sarca_sorin@hotmail.com"
}
],
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
"homepage": "https://opis.io/closure",
"keywords": [
"anonymous functions",
"closure",
"function",
"serializable",
"serialization",
"serialize"
],
"support": {
"issues": "https://github.com/opis/closure/issues",
"source": "https://github.com/opis/closure/tree/3.6.2"
},
"time": "2021-04-09T13:42:10+00:00"
},
{
"name": "php-di/invoker",
"version": "2.3.2",
"version": "2.3.3",
"source": {
"type": "git",
"url": "https://github.com/PHP-DI/Invoker.git",
"reference": "5214cbe5aad066022cd845dbf313f0e47aed928f"
"reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/5214cbe5aad066022cd845dbf313f0e47aed928f",
"reference": "5214cbe5aad066022cd845dbf313f0e47aed928f",
"url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/cd6d9f267d1a3474bdddf1be1da079f01b942786",
"reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786",
"shasum": ""
},
"require": {
@ -830,7 +800,7 @@
],
"support": {
"issues": "https://github.com/PHP-DI/Invoker/issues",
"source": "https://github.com/PHP-DI/Invoker/tree/2.3.2"
"source": "https://github.com/PHP-DI/Invoker/tree/2.3.3"
},
"funding": [
{
@ -838,25 +808,25 @@
"type": "github"
}
],
"time": "2021-07-30T15:05:32+00:00"
"time": "2021-12-13T09:22:56+00:00"
},
{
"name": "php-di/php-di",
"version": "6.3.4",
"version": "6.4.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-DI/PHP-DI.git",
"reference": "f53bcba06ab31b18e911b77c039377f4ccd1f7a5"
"reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/f53bcba06ab31b18e911b77c039377f4ccd1f7a5",
"reference": "f53bcba06ab31b18e911b77c039377f4ccd1f7a5",
"url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/ae0f1b3b03d8b29dff81747063cbfd6276246cc4",
"reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4",
"shasum": ""
},
"require": {
"opis/closure": "^3.5.5",
"php": ">=7.2.0",
"laravel/serializable-closure": "^1.0",
"php": ">=7.4.0",
"php-di/invoker": "^2.0",
"php-di/phpdoc-reader": "^2.0.1",
"psr/container": "^1.0"
@ -865,12 +835,12 @@
"psr/container-implementation": "^1.0"
},
"require-dev": {
"doctrine/annotations": "~1.2",
"doctrine/annotations": "~1.10",
"friendsofphp/php-cs-fixer": "^2.4",
"mnapoli/phpunit-easymock": "^1.2",
"ocramius/proxy-manager": "^2.0.2",
"ocramius/proxy-manager": "^2.11.2",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^8.5|^9.0"
"phpunit/phpunit": "^9.5"
},
"suggest": {
"doctrine/annotations": "Install it if you want to use annotations (version ~1.2)",
@ -878,12 +848,12 @@
},
"type": "library",
"autoload": {
"psr-4": {
"DI\\": "src/"
},
"files": [
"src/functions.php"
]
],
"psr-4": {
"DI\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@ -902,7 +872,7 @@
],
"support": {
"issues": "https://github.com/PHP-DI/PHP-DI/issues",
"source": "https://github.com/PHP-DI/PHP-DI/tree/6.3.4"
"source": "https://github.com/PHP-DI/PHP-DI/tree/6.4.0"
},
"funding": [
{
@ -914,7 +884,7 @@
"type": "tidelift"
}
],
"time": "2021-06-10T08:04:48+00:00"
"time": "2022-04-09T16:46:38+00:00"
},
{
"name": "php-di/phpdoc-reader",
@ -1014,20 +984,20 @@
},
{
"name": "psr/container",
"version": "1.1.1",
"version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
"reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
"url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
"reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
"shasum": ""
},
"require": {
"php": ">=7.2.0"
"php": ">=7.4.0"
},
"type": "library",
"autoload": {
@ -1056,9 +1026,9 @@
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
"source": "https://github.com/php-fig/container/tree/1.1.1"
"source": "https://github.com/php-fig/container/tree/1.1.2"
},
"time": "2021-03-05T17:36:06+00:00"
"time": "2021-11-05T16:50:12+00:00"
},
{
"name": "psr/http-factory",
@ -1284,30 +1254,30 @@
},
{
"name": "psr/log",
"version": "1.1.4",
"version": "3.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
"dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
"Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@ -1328,9 +1298,9 @@
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.4"
"source": "https://github.com/php-fig/log/tree/3.0.0"
},
"time": "2021-05-03T11:20:27+00:00"
"time": "2021-07-14T16:46:02+00:00"
},
{
"name": "ralouphie/getallheaders",
@ -1431,25 +1401,25 @@
},
{
"name": "slim/psr7",
"version": "1.4",
"version": "1.5",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim-Psr7.git",
"reference": "0dca983ca32a26f4a91fb11173b7b9eaee29e9d6"
"reference": "a47b43a8da7c0208b4c228af0cb29ea36080635a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim-Psr7/zipball/0dca983ca32a26f4a91fb11173b7b9eaee29e9d6",
"reference": "0dca983ca32a26f4a91fb11173b7b9eaee29e9d6",
"url": "https://api.github.com/repos/slimphp/Slim-Psr7/zipball/a47b43a8da7c0208b4c228af0cb29ea36080635a",
"reference": "a47b43a8da7c0208b4c228af0cb29ea36080635a",
"shasum": ""
},
"require": {
"fig/http-message-util": "^1.1.5",
"php": "^7.2 || ^8.0",
"php": "^7.3 || ^8.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0",
"ralouphie/getallheaders": "^3",
"symfony/polyfill-php80": "^1.22"
"ralouphie/getallheaders": "^3.0",
"symfony/polyfill-php80": "^1.23"
},
"provide": {
"psr/http-factory-implementation": "1.0",
@ -1460,10 +1430,11 @@
"ext-json": "*",
"http-interop/http-factory-tests": "^0.9.0",
"php-http/psr7-integration-tests": "dev-master",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^8.5 || ^9.5",
"squizlabs/php_codesniffer": "^3.6",
"weirdan/prophecy-shim": "^1.0 || ^2.0.2"
"phpspec/prophecy": "^1.14",
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/phpstan": "^0.12.99",
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3.6"
},
"type": "library",
"autoload": {
@ -1506,50 +1477,51 @@
],
"support": {
"issues": "https://github.com/slimphp/Slim-Psr7/issues",
"source": "https://github.com/slimphp/Slim-Psr7/tree/1.4"
"source": "https://github.com/slimphp/Slim-Psr7/tree/1.5"
},
"time": "2021-05-08T18:22:56+00:00"
"time": "2021-09-22T04:33:00+00:00"
},
{
"name": "slim/slim",
"version": "4.8.1",
"version": "4.10.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "c8934c35d9d98b1a1df9f99ee69b77a59e0aa820"
"reference": "0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/c8934c35d9d98b1a1df9f99ee69b77a59e0aa820",
"reference": "c8934c35d9d98b1a1df9f99ee69b77a59e0aa820",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0",
"reference": "0dfc7d2fdf2553b361d864d51af3fe8a6ad168b0",
"shasum": ""
},
"require": {
"ext-json": "*",
"nikic/fast-route": "^1.3",
"php": "^7.2 || ^8.0",
"php": "^7.4 || ^8.0",
"psr/container": "^1.0 || ^2.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0",
"psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0",
"psr/log": "^1.1"
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"require-dev": {
"adriansuter/php-autoload-override": "^1.2",
"ext-simplexml": "*",
"guzzlehttp/psr7": "^1.8",
"http-interop/http-factory-guzzle": "^1.0",
"laminas/laminas-diactoros": "^2.4",
"nyholm/psr7": "^1.4",
"nyholm/psr7-server": "^1.0.1",
"phpspec/prophecy": "^1.13",
"phpstan/phpstan": "^0.12.85",
"phpunit/phpunit": "^8.5.13 || ^9.3.8",
"guzzlehttp/psr7": "^2.1",
"httpsoft/http-message": "^1.0",
"httpsoft/http-server-request": "^1.0",
"laminas/laminas-diactoros": "^2.8",
"nyholm/psr7": "^1.5",
"nyholm/psr7-server": "^1.0",
"phpspec/prophecy": "^1.15",
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/phpstan": "^1.4",
"phpunit/phpunit": "^9.5",
"slim/http": "^1.2",
"slim/psr7": "^1.3",
"squizlabs/php_codesniffer": "^3.6",
"weirdan/prophecy-shim": "^1.0 || ^2.0.2"
"slim/psr7": "^1.5",
"squizlabs/php_codesniffer": "^3.6"
},
"suggest": {
"ext-simplexml": "Needed to support XML format in BodyParsingMiddleware",
@ -1622,35 +1594,37 @@
"type": "tidelift"
}
],
"time": "2021-06-29T19:41:06+00:00"
"time": "2022-03-14T14:18:23+00:00"
},
{
"name": "slim/slim-skeleton",
"version": "4.3.0",
"version": "4.4.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim-Skeleton.git",
"reference": "e3927652b1f008f1808b6fc2e9ac55f1b71021da"
"reference": "8a91d18b0a8e4623f1af9207e97477c7b8437f57"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim-Skeleton/zipball/e3927652b1f008f1808b6fc2e9ac55f1b71021da",
"reference": "e3927652b1f008f1808b6fc2e9ac55f1b71021da",
"url": "https://api.github.com/repos/slimphp/Slim-Skeleton/zipball/8a91d18b0a8e4623f1af9207e97477c7b8437f57",
"reference": "8a91d18b0a8e4623f1af9207e97477c7b8437f57",
"shasum": ""
},
"require": {
"ext-json": "*",
"monolog/monolog": "^2.2",
"php": "^7.2 || ^8.0",
"monolog/monolog": "^2.3",
"php": "^7.4 || ^8.0",
"php-di/php-di": "^6.3",
"slim/psr7": "^1.3",
"slim/slim": "^4.7"
"slim/psr7": "^1.5",
"slim/slim": "^4.9"
},
"require-dev": {
"jangregor/phpstan-prophecy": "^0.8.1",
"jangregor/phpstan-prophecy": "^1.0.0",
"phpspec/prophecy-phpunit": "^2.0",
"phpstan/extension-installer": "^1.1.0",
"phpstan/phpstan": "^0.12.80",
"phpunit/phpunit": "^8.0 || ^9.0"
"phpstan/phpstan": "^1.3",
"phpunit/phpunit": "^9.5.11",
"squizlabs/php_codesniffer": "^3.6"
},
"type": "library",
"autoload": {
@ -1684,22 +1658,22 @@
],
"support": {
"issues": "https://github.com/slimphp/Slim-Skeleton/issues",
"source": "https://github.com/slimphp/Slim-Skeleton/tree/4.3.0"
"source": "https://github.com/slimphp/Slim-Skeleton/tree/4.4.0"
},
"time": "2021-04-26T02:48:52+00:00"
"time": "2022-01-14T19:30:57+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.23.1",
"version": "v1.26.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be"
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be",
"reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
"reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
"shasum": ""
},
"require": {
@ -1708,7 +1682,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.23-dev"
"dev-main": "1.26-dev"
},
"thanks": {
"name": "symfony/polyfill",
@ -1716,12 +1690,12 @@
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [
"Resources/stubs"
]
@ -1753,7 +1727,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
},
"funding": [
{
@ -1769,7 +1743,7 @@
"type": "tidelift"
}
],
"time": "2021-07-28T13:41:28+00:00"
"time": "2022-05-10T07:21:04+00:00"
}
],
"packages-dev": [],
@ -1779,8 +1753,9 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"ext-pdo": "*"
"ext-pdo": "*",
"ext-json": "*"
},
"platform-dev": [],
"plugin-api-version": "2.2.0"
"plugin-api-version": "2.3.0"
}

4
dist/api/.htaccess vendored Normal file
View File

@ -0,0 +1,4 @@
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

96
dist/api/index.php vendored
View File

@ -1,4 +1,5 @@
<?php
session_start();
////////////////// Index file //////////////
/// Creates base routes and runs ///
@ -8,13 +9,16 @@ session_start();
require "../vendor/autoload.php";
include "timelineData.php";
include "projectData.php";
include "user.php";
use api\projectData;
use api\timelineData;
use api\user;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Selective\SameSiteCookie\SameSiteCookieConfiguration;
use Slim\Factory\AppFactory;
use Selective\SameSiteCookie\SameSiteCookieMiddleware;
use Slim\Handlers\Strategies\RequestHandler;
// Start slim
$app = AppFactory::create();
@ -29,42 +33,38 @@ $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');
});
$timelineData = new timelineData();
$projectData = new projectData();
$user = new user();
$app->get("/timelineData/{timeline}", function (Request $request, Response $response, array $args)
{
global $timelineData;
$json = $result = "";
//check if route is available if it is get the data
//otherwise return an error
if($args["timeline"] == "edu")
{
$result = $timelineData->getEduData();
}
else if($args["timeline"] == "work")
{
$result = $timelineData->getWorkData();
}
else
{
$result = array(array("errorMessage" => "Error, timeline data not found"));
return $response->getBody()->write(json_encode($timelineData->getEduData()));
}
$json = json_encode($result);
$response->getBody()->write($json);
//if it is an error give a 404 code since it can't find the data
if(array_key_exists("errorMessage", $result))
if($args["timeline"] == "work")
{
$response = $response->withStatus(404);
return $response->getBody()->write(json_encode($timelineData->getWorkData()));
}
//use content type json to indicate json data on frontend.
return $response->withHeader("Content-Type", "application/json");
// something went wrong
$response->getBody()->write(json_encode(array("errorMessage" => "Error, timeline data not found")));
return $response->withStatus(404);
});
$app->get('/projectData', function (Request $request, Response $response)
@ -83,7 +83,7 @@ $app->get('/projectData', function (Request $request, Response $response)
}
//use content type json to indicate json data on frontend.
return $response->withHeader("Content-Type", "application/json");
return $response;
});
$app->post('/contact', function (Request $request, Response $response)
@ -92,20 +92,19 @@ $app->post('/contact', function (Request $request, Response $response)
if(empty($data["fName"]) || empty($data["lName"]) || empty($data["email"]) || empty($data["subject"]) || empty($data["message"]))
{
$response->getBody()->write(json_encode(array("errorMessage" => "Please fill out all the fields")));
$response = $response->withStatus(400);
return $response->withHeader("Content-Type", "application/json");
return $response->withStatus(400);
}
if (!filter_var($data["email"], FILTER_VALIDATE_EMAIL))
{
$response->getBody()->write(json_encode(array("errorMessage" => "Email is not the correct format")));
$response = $response->withStatus(400);
return $response->withHeader("Content-Type", "application/json");
return $response;
}
// email form filler/conatcter
$headers1 = "From: noreply@rohitpai.tech\r\n";
$headers1 .= "Reply-To: rohit@rohitpai.tech\r\n";
$headers1 = "From: noreply@rohitpai.co.uk\r\n";
$headers1 .= "Reply-To: rohit@rohitpai.co.uk\r\n";
$headers1 .= "MIME-Version: 1.0\r\n";
$headers1 .= "Content-Type: text/html; charset=UTF-8\r\n";
@ -176,7 +175,7 @@ $app->post('/contact', function (Request $request, Response $response)
</table>
<br>
<hr>
<p>Regards, <br> Rohit Pai <br> <a href=\"mailto:rohit@rohitpai.tech\">rohit@rohitpai.tech</a>
<p>Regards, <br> Rohit Pai <br> <a href=\"mailto:rohit@rohitpai.co.uk\">rohit@rohitpai.co.uk</a>
</body>
</html>
";
@ -184,7 +183,7 @@ $app->post('/contact', function (Request $request, Response $response)
mail($data["email"], $data["subject"], $message1, $headers1);
// email to me
$headers2 = "From: noreply@rohitpai.tech\r\n";
$headers2 = "From: noreply@rohitpai.co.uk\r\n";
$headers2 .= "Reply-To: {$data['email']}\r\n";
$headers2 .= "MIME-Version: 1.0\r\n";
$headers2 .= "Content-Type: text/html; charset=UTF-8\r\n";
@ -256,8 +255,51 @@ $app->post('/contact', function (Request $request, Response $response)
</html>
";
mail("rohit@rohitpai.tech", "{$data['fName']} {$data['lName']} filled in the form", $message2, $headers2);
mail("rohit@rohitpai.co.uk", "{$data['fName']} {$data['lName']} filled in the form", $message2, $headers2);
return $response->withStatus(201);
});
$app->post('/user/login', function (Request $request, Response $response) {
global $user;
// get request data
$data = $request->getParsedBody();
if (empty($data["username"]) || empty($data["password"]))
{
// uh oh user sent empty data
return $response->withStatus(400);
}
if ($user->checkUser($data["username"], $data["password"]))
{
// yay user is logged in
$_SESSION["token"] = $user->createToken();
$_SESSION["username"] = $data["username"];
return $response;
}
return $response->withStatus(401);
});
$app->get('/user/isLoggedIn', function (Request $request, Response $response) {
global $user;
if (empty($_SESSION["token"]) && empty($_SESSION["username"]))
{
// uh oh user not logged in
return $response->withStatus(401);
}
if (empty($_SESSION["token"]))
{
// user is logged in but no token was created
$_SESSION["token"] = $user->createToken();
return $response;
}
return $response->getBody()->write(json_encode(array("token" => $_SESSION["token"])));
});
$app->run();

View File

@ -10,7 +10,7 @@ require_once "./config.php";
*/
class projectData
{
function getProjectData()
function getProjectData(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT title, isMainProject, information, imgLocation, projectLink, githubLink FROM projects order by date LIMIT 4;");
@ -23,9 +23,6 @@ class projectData
{
return $result;
}
else
{
return array(array("errorMessage" => "Error, project data not found"));
}
return array("errorMessage" => "Error, project data not found");
}
}

View File

@ -10,7 +10,7 @@ require_once "./config.php";
*/
class timelineData
{
function getEduData()
function getEduData(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT DATE_FORMAT(startPeriod, '%b, %Y') as startPeriod, DATE_FORMAT(endPeriod, '%b, %Y') as endPeriod, grade, course FROM edu ORDER BY startPeriod DESC;");
@ -23,13 +23,10 @@ class timelineData
{
return $result;
}
else
{
return array("errorMessage" => "Error, edu data not found");
}
}
function getWorkData()
function getWorkData(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT DATE_FORMAT(startPeriod, '%b, %Y') as startPeriod, DATE_FORMAT(endPeriod, '%b, %Y') as endPeriod, companyName, area, title FROM work ORDER BY work.startPeriod DESC;");
@ -42,11 +39,8 @@ class timelineData
{
return $result;
}
else
{
return array("errorMessage" => "Error, work data not found");
}
}
}

38
dist/api/user.php vendored Normal file
View File

@ -0,0 +1,38 @@
<?php
namespace api;
use PDO;
require_once "./config.php";
/**
* User Class
* Define all functions which either check, update or delete user data
*/
class user
{
function checkUser($username, $password): bool
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT * FROM users WHERE username = :username");
$stmt->bindParam(":username", $username);
$stmt->execute();
// set the resulting array to associative
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($result)
{
if (password_verify($password, $result[0]["password"]))
{
return true;
}
return false;
}
return false;
}
function createToken(): string
{
return uniqid("rpe-");
}
}

2
dist/css/main.css vendored

File diff suppressed because one or more lines are too long

1
dist/editor/css/main.css vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/editor/editor.html vendored Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Editor</title></head><body><h1>Editor</h1><script src="js/editor.js"></script></body></html>

1
dist/editor/index.html vendored Normal file
View File

@ -0,0 +1 @@
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Editor</title><link rel="stylesheet" href="css/main.css"></head><body><main><div id="login"><h1>Login To Editor</h1><form action="" method="POST"><div class="formControl"><label for="username">Username</label> <input type="text" id="username" name="username" required></div><div class="formControl"><label for="password">Password</label> <input type="password" id="password" name="password" required></div><div class="error hidden" id="loginError"><button class="close" type="button">&times;</button><div></div></div><input type="submit" value="Submit"></form></div></main><script src="js/index.js"></script></body></html>

1
dist/editor/js/editor.js vendored Normal file
View File

@ -0,0 +1 @@
document.addEventListener("DOMContentLoaded",(e=>{fetch("/api/user/isLoggedIn").then((e=>{e.ok||(window.location.href="./")}))}));

1
dist/editor/js/index.js vendored Normal file
View File

@ -0,0 +1 @@
function showErrorMessage(e){document.querySelector("#loginError").classList.remove("hidden"),document.querySelector("#loginError div").innerText=e}document.addEventListener("DOMContentLoaded",(e=>{fetch("/api/user/isLoggedIn").then((e=>{e.ok&&(window.location.href="./editor.html")}))})),document.querySelector("#login form").addEventListener("submit",(e=>{e.preventDefault();let r=new FormData;if(e.target.username.value.length>0&&e.target.password.value.length>0)return r.append("username",e.target.username.value),r.append("password",e.target.password.value),void fetch("/api/user/login",{method:"POST",body:r}).then((e=>{e.ok?window.location.href="./editor.html":400!==e.status?(document.querySelector("#loginError").classList.remove("hidden"),document.querySelector("#loginError div").innerHTML="Invalid username or password"):showErrorMessage("Please type in a username and password.")}));document.querySelector("#loginError").classList.remove("hidden"),document.querySelector("#loginError div").innerHTML="Please type in a username and password"})),document.querySelector("#loginError .close").addEventListener("click",(()=>document.querySelector("#loginError").classList.toggle("hidden")));

1
dist/editor/js/main.js vendored Normal file
View File

@ -0,0 +1 @@
function showErrorMessage(e){document.querySelector("#loginError").classList.remove("hidden"),document.querySelector("#loginError div").innerText=e}document.addEventListener("DOMContentLoaded",(e=>{fetch("/api/user/isLoggedIn").then((e=>{e.ok&&(window.location.href="./editor.html")}))})),document.querySelector("#login form").addEventListener("submit",(e=>{e.preventDefault();let r=new FormData;if(e.target.username.value.length>0&&e.target.password.value.length>0)return r.append("username",e.target.username.value),r.append("password",e.target.password.value),void fetch("/api/user/login",{method:"POST",body:r}).then((e=>{e.ok?window.location.href="./editor.html":400!==e.status?(document.querySelector("#loginError").classList.remove("hidden"),document.querySelector("#loginError div").innerHTML="Invalid username or password"):showErrorMessage("Please type in a username and password.")}));document.querySelector("#loginError").classList.remove("hidden"),document.querySelector("#loginError div").innerHTML="Please type in a username and password"})),document.querySelector("#loginError .close").addEventListener("click",(()=>document.querySelector("#loginError").classList.toggle("hidden")));

2
dist/index.html vendored

File diff suppressed because one or more lines are too long

View File

@ -8,16 +8,16 @@ const github = (process.env.github) ? true : false;
gulp.task("minifyHTML", () =>
{
return gulp.src("src/*.html" )
return gulp.src("src/**/*.html" )
.pipe(htmlMin({collapseWhitespace: true}))
.pipe(gulp.dest("dist"));
.pipe(gulp.dest("dist/"));
});
gulp.task("minifyCSS", () =>
{
return gulp.src("src/css/main.css")
return gulp.src("src/**/main.css")
.pipe(cssMin({compatibility: "ie8"}))
.pipe(gulp.dest("dist/css"));
.pipe(gulp.dest("dist/"));
});
gulp.task("minifyJS", () =>
@ -30,11 +30,11 @@ gulp.task("minifyJS", () =>
};
}
return gulp.src("src/js/*.js")
return gulp.src("src/**/*.js")
.on("error", createErrorHandler("gulp.src"))
.pipe(terser())
.on("error", createErrorHandler("terser"))
.pipe(gulp.dest("dist/js"))
.pipe(gulp.dest("dist/"))
.on("error", createErrorHandler("gulp.dest"));
});
@ -46,18 +46,15 @@ gulp.task("movePHPFiles", () =>
gulp.task("watchFiles", () =>
{
gulp.watch("src/*.html", gulp.task("minifyHTML"));
gulp.watch("src/css/*.css", gulp.task("minifyCSS"));
gulp.watch("src/js/*.js", gulp.task("minifyJS"));
gulp.watch("src/**/*.html", gulp.task("minifyHTML"));
gulp.watch("src/**/*.css", gulp.task("minifyCSS"));
gulp.watch("src/**/*.js", gulp.task("minifyJS"));
gulp.watch("src/api/*.php", gulp.task("movePHPFiles"))
});
gulp.task("browserSync", () =>
{
browserSync.init({
// server: {
// baseDir: "dist"
// },
proxy: "https://rohitpai.co.uk/",
serveStatic: ["./dist"]
@ -76,6 +73,3 @@ gulp.task("default", async () =>
(gulp.series(gulp.parallel("watchFiles", "browserSync"))());
}
});
//gulp.task("default", gulp.series(gulp.parallel("watchFiles", "browserSync")));

14
package-lock.json generated
View File

@ -20,6 +20,7 @@
"jest": "^27.2.0",
"normalize.css": "^8.0.1",
"require": "^2.4.20",
"source-map-generator": "^0.8.0",
"vinyl-ftp": "^0.6.1"
}
},
@ -9310,6 +9311,14 @@
"node": ">=0.10.0"
}
},
"node_modules/source-map-generator": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz",
"integrity": "sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA==",
"engines": {
"node": ">= 10"
}
},
"node_modules/source-map-resolve": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
@ -17973,6 +17982,11 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"source-map-generator": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/source-map-generator/-/source-map-generator-0.8.0.tgz",
"integrity": "sha512-psgxdGMwl5MZM9S3FWee4EgsEaIjahYV5AzGnwUvPhWeITz/j6rKpysQHlQ4USdxvINlb8lKfWGIXwfkrgtqkA=="
},
"source-map-resolve": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",

View File

@ -23,6 +23,7 @@
"jest": "^27.2.0",
"normalize.css": "^8.0.1",
"require": "^2.4.20",
"source-map-generator": "^0.8.0",
"vinyl-ftp": "^0.6.1"
}
}

View File

@ -1,4 +1,5 @@
<?php
session_start();
////////////////// Index file //////////////
/// Creates base routes and runs ///
@ -8,13 +9,16 @@ session_start();
require "../vendor/autoload.php";
include "timelineData.php";
include "projectData.php";
include "user.php";
use api\projectData;
use api\timelineData;
use api\user;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Selective\SameSiteCookie\SameSiteCookieConfiguration;
use Slim\Factory\AppFactory;
use Selective\SameSiteCookie\SameSiteCookieMiddleware;
use Slim\Handlers\Strategies\RequestHandler;
// Start slim
$app = AppFactory::create();
@ -29,42 +33,38 @@ $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');
});
$timelineData = new timelineData();
$projectData = new projectData();
$user = new user();
$app->get("/timelineData/{timeline}", function (Request $request, Response $response, array $args)
{
global $timelineData;
$json = $result = "";
//check if route is available if it is get the data
//otherwise return an error
if($args["timeline"] == "edu")
{
$result = $timelineData->getEduData();
}
else if($args["timeline"] == "work")
{
$result = $timelineData->getWorkData();
}
else
{
$result = array(array("errorMessage" => "Error, timeline data not found"));
return $response->getBody()->write(json_encode($timelineData->getEduData()));
}
$json = json_encode($result);
$response->getBody()->write($json);
//if it is an error give a 404 code since it can't find the data
if(array_key_exists("errorMessage", $result))
if($args["timeline"] == "work")
{
$response = $response->withStatus(404);
return $response->getBody()->write(json_encode($timelineData->getWorkData()));
}
//use content type json to indicate json data on frontend.
return $response->withHeader("Content-Type", "application/json");
// something went wrong
$response->getBody()->write(json_encode(array("errorMessage" => "Error, timeline data not found")));
return $response->withStatus(404);
});
$app->get('/projectData', function (Request $request, Response $response)
@ -83,7 +83,7 @@ $app->get('/projectData', function (Request $request, Response $response)
}
//use content type json to indicate json data on frontend.
return $response->withHeader("Content-Type", "application/json");
return $response;
});
$app->post('/contact', function (Request $request, Response $response)
@ -92,15 +92,14 @@ $app->post('/contact', function (Request $request, Response $response)
if(empty($data["fName"]) || empty($data["lName"]) || empty($data["email"]) || empty($data["subject"]) || empty($data["message"]))
{
$response->getBody()->write(json_encode(array("errorMessage" => "Please fill out all the fields")));
$response = $response->withStatus(400);
return $response->withHeader("Content-Type", "application/json");
return $response->withStatus(400);
}
if (!filter_var($data["email"], FILTER_VALIDATE_EMAIL))
{
$response->getBody()->write(json_encode(array("errorMessage" => "Email is not the correct format")));
$response = $response->withStatus(400);
return $response->withHeader("Content-Type", "application/json");
return $response;
}
// email form filler/conatcter
@ -260,4 +259,47 @@ $app->post('/contact', function (Request $request, Response $response)
return $response->withStatus(201);
});
$app->post('/user/login', function (Request $request, Response $response) {
global $user;
// get request data
$data = $request->getParsedBody();
if (empty($data["username"]) || empty($data["password"]))
{
// uh oh user sent empty data
return $response->withStatus(400);
}
if ($user->checkUser($data["username"], $data["password"]))
{
// yay user is logged in
$_SESSION["token"] = $user->createToken();
$_SESSION["username"] = $data["username"];
return $response;
}
return $response->withStatus(401);
});
$app->get('/user/isLoggedIn', function (Request $request, Response $response) {
global $user;
if (empty($_SESSION["token"]) && empty($_SESSION["username"]))
{
// uh oh user not logged in
return $response->withStatus(401);
}
if (empty($_SESSION["token"]))
{
// user is logged in but no token was created
$_SESSION["token"] = $user->createToken();
return $response;
}
return $response->getBody()->write(json_encode(array("token" => $_SESSION["token"])));
});
$app->run();

View File

@ -10,7 +10,7 @@ require_once "./config.php";
*/
class projectData
{
function getProjectData()
function getProjectData(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT title, isMainProject, information, imgLocation, projectLink, githubLink FROM projects order by date LIMIT 4;");
@ -23,9 +23,6 @@ class projectData
{
return $result;
}
else
{
return array(array("errorMessage" => "Error, project data not found"));
}
return array("errorMessage" => "Error, project data not found");
}
}

View File

@ -10,7 +10,7 @@ require_once "./config.php";
*/
class timelineData
{
function getEduData()
function getEduData(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT DATE_FORMAT(startPeriod, '%b, %Y') as startPeriod, DATE_FORMAT(endPeriod, '%b, %Y') as endPeriod, grade, course FROM edu ORDER BY startPeriod DESC;");
@ -23,13 +23,10 @@ class timelineData
{
return $result;
}
else
{
return array("errorMessage" => "Error, edu data not found");
}
}
function getWorkData()
function getWorkData(): array
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT DATE_FORMAT(startPeriod, '%b, %Y') as startPeriod, DATE_FORMAT(endPeriod, '%b, %Y') as endPeriod, companyName, area, title FROM work ORDER BY work.startPeriod DESC;");
@ -42,11 +39,8 @@ class timelineData
{
return $result;
}
else
{
return array("errorMessage" => "Error, work data not found");
}
}
}

38
src/api/user.php Normal file
View File

@ -0,0 +1,38 @@
<?php
namespace api;
use PDO;
require_once "./config.php";
/**
* User Class
* Define all functions which either check, update or delete user data
*/
class user
{
function checkUser($username, $password): bool
{
$conn = dbConn();
$stmt = $conn->prepare("SELECT * FROM users WHERE username = :username");
$stmt->bindParam(":username", $username);
$stmt->execute();
// set the resulting array to associative
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($result)
{
if (password_verify($password, $result[0]["password"]))
{
return true;
}
return false;
}
return false;
}
function createToken(): string
{
return uniqid("rpe-");
}
}

View File

@ -66,96 +66,6 @@ div#sayHello #contactForm{
gap: 1em;
}
#contactForm .formControl {
width: 100%;
}
#contactForm input[type="submit"] {
margin-top: 1em;
align-self: flex-start;
}
#contactForm .formControl input:not([type="submit"]), #contactForm .formControl textarea {
width: 100%;
border: 4px solid var(--primaryDefault);
background: none;
outline: none;
-webkit-border-radius: 1em;
-moz-border-radius: 1em;
border-radius: 0.5em;
padding: 0 0.5em;
}
#contactForm .formControl textarea {
padding: 0.5em;
}
#contactForm .formControl input:not([type="submit"]).invalid:invalid, #contactForm .formControl textarea.invalid:invalid {
border: 4px solid var(--errorDefault);
}
#contactForm .formControl input:not([type="submit"]).invalid:invalid:focus, #contactForm .formControl textarea.invalid:invalid:focus {
border: 4px solid var(--errorHover);
box-shadow: 0 4px 2px 0 var(--mutedBlack);
}
#contactForm .formControl input:not([type="submit"]):focus, #contactForm .formControl textarea:focus {
border: 4px solid var(--primaryHover);
}
#contactForm .formControl input:not([type="submit"]) {
height: 3em;
}
#contactForm .flName {
display: flex;
flex-direction: row;
gap: 1em;
}
#contactForm .formControl {
width: 100%;
}
#contactForm input[type="submit"] {
margin-top: 1em;
align-self: flex-start;
}
#contactForm .formControl input:not([type="submit"]), #contactForm .formControl textarea {
width: 100%;
border: 4px solid var(--primaryDefault);
background: none;
outline: none;
-webkit-border-radius: 1em;
-moz-border-radius: 1em;
border-radius: 0.5em;
padding: 0 0.5em;
}
#contactForm .formControl textarea {
padding: 0.5em;
}
#contactForm .formControl input:not([type="submit"]).invalid:invalid, #contactForm .formControl textarea.invalid:invalid {
border: 4px solid var(--errorDefault);
}
#contactForm .formControl input:not([type="submit"]).invalid:invalid:focus, #contactForm .formControl textarea.invalid:invalid:focus {
border: 4px solid var(--errorHover);
box-shadow: 0 4px 2px 0 var(--mutedBlack);
}
#contactForm .formControl input:not([type="submit"]):focus, #contactForm .formControl textarea:focus {
border: 4px solid var(--primaryHover);
}
#contactForm .formControl input:not([type="submit"]) {
height: 3em;
}
div.message {
background: var(--primaryDefault);
color: #FFFFFF;

View File

@ -10,34 +10,6 @@
@import "contact.css";
@import "footer.css";
/****** Root Style ******/
:root {
/* Colours */
--mainHue: 79;
--mainSat: 62%;
--mainLight: 51%;
--primaryDefault: hsla(var(--mainHue), var(--mainSat), var(--mainLight), 1);
--primaryHover: hsla(var(--mainHue), var(--mainSat), calc(var(--mainLight) - 10%), 1);
--timelineItemBrdr: hsla(var(--mainHue), var(--mainSat), calc(var(--mainLight) - 20%), 1);
--errorDefault: hsla(0, calc(var(--mainSat) + 10%),calc(var(--mainLight) + 10%), 1);
--errorHover: hsla(0, calc(var(--mainSat) + 10%), calc(var(--mainLight) - 10%), 1);
--grey: hsla(0, 0%, 39%, 1);
--notAvailableDefault: hsla(0, 0%, 39%, 1);
--notAvailableHover: hsla(0, 0%,32%, 1);
--mutedGrey: hsla(0, 0%, 78%, 1);
--mutedBlack: hsla(0, 0%, 0%, 0.25);
--navBack: hsla(0, 0%, 30%, 1);
/* Font Sizes */
--titleFS: 2.25rem;
--generalFS: 1.125rem;
--headingFS: 1.5rem;
}
*{
box-sizing: border-box;
}
/**** Media Queries *****/
@media screen and (max-width: 90em) {

View File

@ -1,4 +1,33 @@
/*** Template Styles ****/
/*** Template Styles ***/
/*** Root Style ***/
:root {
/* Colours */
--mainHue: 80;
--mainSat: 60%;
--mainLight: 50%;
--primaryDefault: hsla(var(--mainHue), var(--mainSat), var(--mainLight), 1);
--primaryHover: hsla(var(--mainHue), var(--mainSat), calc(var(--mainLight) - 10%), 1);
--timelineItemBrdr: hsla(var(--mainHue), var(--mainSat), calc(var(--mainLight) - 20%), 1);
--errorDefault: hsla(0, calc(var(--mainSat) + 10%),calc(var(--mainLight) + 10%), 1);
--errorHover: hsla(0, calc(var(--mainSat) + 10%), calc(var(--mainLight) - 10%), 1);
--grey: hsla(0, 0%, 39%, 1);
--notAvailableDefault: hsla(0, 0%, 39%, 1);
--notAvailableHover: hsla(0, 0%,32%, 1);
--mutedGrey: hsla(0, 0%, 78%, 1);
--mutedBlack: hsla(0, 0%, 0%, 0.25);
--navBack: hsla(0, 0%, 30%, 1);
/* Font Sizes */
--titleFS: 2.25rem;
--generalFS: 1.125rem;
--headingFS: 1.5rem;
}
*{
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
@ -88,6 +117,89 @@ a.btn:active, form input[type="submit"]:active {
text-shadow: 0 6px 4px var(--mutedBlack);
}
form .formControl {
width: 100%;
}
form input[type="submit"] {
margin-top: 1em;
align-self: flex-start;
}
form .formControl input:not([type="submit"]), form .formControl textarea {
width: 100%;
border: 4px solid var(--primaryDefault);
background: none;
outline: none;
-webkit-border-radius: 1em;
-moz-border-radius: 1em;
border-radius: 0.5em;
padding: 0 0.5em;
}
form .formControl textarea {
padding: 0.5em;
}
form .formControl input:not([type="submit"]).invalid:invalid, form .formControl textarea.invalid:invalid {
border: 4px solid var(--errorDefault);
}
form .formControl input:not([type="submit"]).invalid:invalid:focus, form .formControl textarea.invalid:invalid:focus {
border: 4px solid var(--errorHover);
box-shadow: 0 4px 2px 0 var(--mutedBlack);
}
form .formControl input:not([type="submit"]):focus, form .formControl textarea:focus {
border: 4px solid var(--primaryHover);
}
form .formControl input:not([type="submit"]) {
height: 3em;
}
form .formControl {
width: 100%;
}
form input[type="submit"] {
margin-top: 1em;
align-self: flex-start;
}
form .formControl input:not([type="submit"]), form .formControl textarea {
width: 100%;
border: 4px solid var(--primaryDefault);
background: none;
outline: none;
-webkit-border-radius: 1em;
-moz-border-radius: 1em;
border-radius: 0.5em;
padding: 0 0.5em;
}
form .formControl textarea {
padding: 0.5em;
}
form .formControl input:not([type="submit"]).invalid:invalid, form .formControl textarea.invalid:invalid {
border: 4px solid var(--errorDefault);
}
form .formControl input:not([type="submit"]).invalid:invalid:focus, form .formControl textarea.invalid:invalid:focus {
border: 4px solid var(--errorHover);
box-shadow: 0 4px 2px 0 var(--mutedBlack);
}
form .formControl input:not([type="submit"]):focus, form .formControl textarea:focus {
border: 4px solid var(--primaryHover);
}
form .formControl input:not([type="submit"]) {
height: 3em;
}
section#about, section#curriculumVitae h1 {
padding: 0 5rem;
}

100
src/editor/css/login.css Normal file
View File

@ -0,0 +1,100 @@
/*** Login Styles ***/
h1 {
text-transform: none;
}
html, body {
height: 100%;
}
main {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-image: radial-gradient(var(--primaryDefault), hsl(80, 50%, 30%));
}
div#login {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #FFFFFF;
padding: 2em 5em;
-webkit-border-radius: 1em;
-moz-border-radius: 1em;
border-radius: 1em;
box-shadow: 0 6px 4px 0 var(--mutedBlack);
}
div#login form {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 1em;
}
div#login #password {
font-family: Verdana, serif;
letter-spacing: 0.125em;
}
div#login input[type=submit]{
margin: 0;
}
div.error {
background: var(--errorDefault);
color: #FFFFFF;
padding: 0.5em 0.8em;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
align-self: flex-start;
flex-direction: row-reverse;
position: relative;
height: 75px;
visibility: visible;
overflow: hidden;
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
-ms-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
opacity: 1;
margin-top: 1em;
}
div.error button {
border: none;
background: none;
outline: none;
cursor: pointer;
color: #FFFFFF;
font-size: 1.25rem;
margin-top: -5px;
position: absolute;
transform: translate(0, 0);
transform-origin: 0 0;
right: 10px;
top: 10px;
}
div.error.hidden {
opacity: 0;
visibility: hidden;
height: 0;
margin: 0;
padding: 0;
}
div.error button:hover {
text-shadow: -1px 2px var(--mutedBlack);
}

8
src/editor/css/main.css Normal file
View File

@ -0,0 +1,8 @@
/******** Imports *******/
@import "/node_modules/normalize.css/normalize.css";
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&family=Share+Tech+Mono&family=Source+Sans+Pro:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700;1,900&display=swap");
/*local imports*/
@import "../../css/templateStyles.css";
@import "login.css";
/*other styles*/

12
src/editor/editor.html Normal file
View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Editor</title>
</head>
<body>
<h1>Editor</h1>
<script src="js/editor.js"></script>
</body>
</html>

36
src/editor/index.html Normal file
View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Editor</title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<main>
<div id="login">
<h1>Login To Editor</h1>
<form action="" method="POST">
<div class="formControl">
<label for="username">Username</label>
<input type="text" id="username" name="username" required>
</div>
<div class="formControl">
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
</div>
<div class="error hidden" id="loginError">
<button class="close" type="button">&times;</button>
<div></div>
</div>
<input type="submit" value="Submit">
</form>
</div>
</main>
<script src="js/index.js"></script>
</body>
</html>

12
src/editor/js/editor.js Normal file
View File

@ -0,0 +1,12 @@
document.addEventListener('DOMContentLoaded', e =>
{
// check if the user is logged in, if not redirect to login
fetch('/api/user/isLoggedIn').then(res =>
{
if (!res.ok)
{
window.location.href = './';
}
});
})

54
src/editor/js/index.js Normal file
View File

@ -0,0 +1,54 @@
document.addEventListener("DOMContentLoaded", e =>
{
// check if the user is logged in and if so load the editor
fetch("/api/user/isLoggedIn").then(res =>
{
if (res.ok)
{
window.location.href = "./editor.html";
}
});
});
function showErrorMessage(message)
{
document.querySelector("#loginError").classList.remove("hidden");
document.querySelector("#loginError div").innerText = message;
}
document.querySelector("#login form").addEventListener("submit", e =>
{
e.preventDefault();
let loginData = new FormData();
if (e.target.username.value.length > 0 && e.target.password.value.length > 0)
{
loginData.append("username", e.target.username.value);
loginData.append("password", e.target.password.value);
fetch("/api/user/login",
{
method: "POST",
body: loginData
}).then(res =>
{
if (res.ok)
{
window.location.href = "./editor.html";
return;
}
if (res.status === 400)
{
showErrorMessage("Please type in a username and password.");
return;
}
document.querySelector("#loginError").classList.remove("hidden");
document.querySelector("#loginError div").innerHTML = "Invalid username or password";
});
return;
}
document.querySelector("#loginError").classList.remove("hidden");
document.querySelector("#loginError div").innerHTML = "Please type in a username and password";
});
document.querySelector("#loginError .close").addEventListener("click", () =>
document.querySelector("#loginError").classList.toggle("hidden"));