diff --git a/.idea/php.xml b/.idea/php.xml
index f324872..a85fe78 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -10,6 +10,7 @@
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 44f71f7..d20f43f 100644
--- a/composer.json
+++ b/composer.json
@@ -12,8 +12,10 @@
"symfony/console": "6.2.*",
"symfony/dotenv": "6.2.*",
"symfony/flex": "^2",
+ "symfony/form": "6.2.*",
"symfony/framework-bundle": "6.2.*",
"symfony/runtime": "6.2.*",
+ "symfony/twig-bundle": "6.2.*",
"symfony/yaml": "6.2.*"
},
"config": {
diff --git a/composer.lock b/composer.lock
index b80edba..dec32d7 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": "e707d27f7e6fa82fb6046c64e6e5195b",
+ "content-hash": "df0df0b7db58f124685c7471026977fb",
"packages": [
{
"name": "psr/cache",
@@ -1209,6 +1209,110 @@
],
"time": "2023-02-18T08:03:15+00:00"
},
+ {
+ "name": "symfony/form",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/form.git",
+ "reference": "751efa84f868337c63e29560c02cff7ae27d874b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/form/zipball/751efa84f868337c63e29560c02cff7ae27d874b",
+ "reference": "751efa84f868337c63e29560c02cff7ae27d874b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/event-dispatcher": "^5.4|^6.0",
+ "symfony/options-resolver": "^5.4|^6.0",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-icu": "^1.21",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/property-access": "^5.4|^6.0",
+ "symfony/service-contracts": "^1.1|^2|^3"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<5.4.3",
+ "symfony/console": "<5.4",
+ "symfony/dependency-injection": "<5.4",
+ "symfony/doctrine-bridge": "<5.4.21|>=6,<6.2.7",
+ "symfony/error-handler": "<5.4",
+ "symfony/framework-bundle": "<5.4",
+ "symfony/http-kernel": "<5.4",
+ "symfony/translation": "<5.4",
+ "symfony/translation-contracts": "<1.1.7",
+ "symfony/twig-bridge": "<5.4.21|>=6,<6.2.7"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.0|^2.0",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/html-sanitizer": "^6.1",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4|^6.0",
+ "symfony/intl": "^5.4|^6.0",
+ "symfony/security-core": "^6.2",
+ "symfony/security-csrf": "^5.4|^6.0",
+ "symfony/translation": "^5.4|^6.0",
+ "symfony/uid": "^5.4|^6.0",
+ "symfony/validator": "^5.4|^6.0",
+ "symfony/var-dumper": "^5.4|^6.0"
+ },
+ "suggest": {
+ "symfony/security-core": "For hashing users passwords.",
+ "symfony/security-csrf": "For protecting forms against CSRF attacks.",
+ "symfony/twig-bridge": "For templating with Twig.",
+ "symfony/validator": "For form validation."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Form\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Allows to easily create, process and reuse HTML forms",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/form/tree/v6.2.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-31T11:20:06+00:00"
+ },
{
"name": "symfony/framework-bundle",
"version": "v6.2.9",
@@ -1549,6 +1653,73 @@
],
"time": "2023-04-13T16:41:43+00:00"
},
+ {
+ "name": "symfony/options-resolver",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/options-resolver.git",
+ "reference": "aa0e85b53bbb2b4951960efd61d295907eacd629"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/aa0e85b53bbb2b4951960efd61d295907eacd629",
+ "reference": "aa0e85b53bbb2b4951960efd61d295907eacd629",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.1|^3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\OptionsResolver\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an improved replacement for the array_replace PHP function",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "config",
+ "configuration",
+ "options"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/options-resolver/tree/v6.2.7"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-14T08:44:56+00:00"
+ },
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.27.0",
@@ -1630,6 +1801,93 @@
],
"time": "2022-11-03T14:55:06+00:00"
},
+ {
+ "name": "symfony/polyfill-intl-icu",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-icu.git",
+ "reference": "a3d9148e2c363588e05abbdd4ee4f971f0a5330c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/a3d9148e2c363588e05abbdd4ee4f971f0a5330c",
+ "reference": "a3d9148e2c363588e05abbdd4ee4f971f0a5330c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance and support of other locales than \"en\""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Icu\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ],
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's ICU-related data and classes",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "icu",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.27.0",
@@ -1797,6 +2055,175 @@
],
"time": "2022-11-03T14:55:06+00:00"
},
+ {
+ "name": "symfony/property-access",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/property-access.git",
+ "reference": "2ad1e0a07b8cab3e09905659d14f3b248e916374"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/property-access/zipball/2ad1e0a07b8cab3e09905659d14f3b248e916374",
+ "reference": "2ad1e0a07b8cab3e09905659d14f3b248e916374",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/property-info": "^5.4|^6.0"
+ },
+ "require-dev": {
+ "symfony/cache": "^5.4|^6.0"
+ },
+ "suggest": {
+ "psr/cache-implementation": "To cache access methods."
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\PropertyAccess\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides functions to read and write from/to an object or array using a simple string notation",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "access",
+ "array",
+ "extraction",
+ "index",
+ "injection",
+ "object",
+ "property",
+ "property-path",
+ "reflection"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/property-access/tree/v6.2.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-14T15:00:05+00:00"
+ },
+ {
+ "name": "symfony/property-info",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/property-info.git",
+ "reference": "400a019b7c05030599fd15f02b3d4ce287631732"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/property-info/zipball/400a019b7c05030599fd15f02b3d4ce287631732",
+ "reference": "400a019b7c05030599fd15f02b3d4ce287631732",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/string": "^5.4|^6.0"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "<5.2",
+ "phpdocumentor/type-resolver": "<1.5.1",
+ "symfony/dependency-injection": "<5.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.10.4|^2",
+ "phpdocumentor/reflection-docblock": "^5.2",
+ "phpstan/phpdoc-parser": "^1.0",
+ "symfony/cache": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/serializer": "^5.4|^6.0"
+ },
+ "suggest": {
+ "phpdocumentor/reflection-docblock": "To use the PHPDoc",
+ "psr/cache-implementation": "To cache results",
+ "symfony/doctrine-bridge": "To use Doctrine metadata",
+ "symfony/serializer": "To use Serializer metadata"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\PropertyInfo\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kévin Dunglas",
+ "email": "dunglas@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Extracts information about PHP class' properties using metadata of popular sources",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "doctrine",
+ "phpdoc",
+ "property",
+ "symfony",
+ "type",
+ "validator"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/property-info/tree/v6.2.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-14T15:00:05+00:00"
+ },
{
"name": "symfony/routing",
"version": "v6.2.8",
@@ -2135,6 +2562,296 @@
],
"time": "2023-03-20T16:06:02+00:00"
},
+ {
+ "name": "symfony/translation-contracts",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/translation-contracts.git",
+ "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dfec258b9dd17a6b24420d464c43bffe347441c8",
+ "reference": "dfec258b9dd17a6b24420d464c43bffe347441c8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "suggest": {
+ "symfony/translation-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.3-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Translation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to translation",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/translation-contracts/tree/v3.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-01T10:32:47+00:00"
+ },
+ {
+ "name": "symfony/twig-bridge",
+ "version": "v6.2.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/twig-bridge.git",
+ "reference": "30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927",
+ "reference": "30e3ad6ae749b2d2700ecf9b4a1a9d5c96b18927",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "symfony/translation-contracts": "^1.1|^2|^3",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "<3.2.2",
+ "phpdocumentor/type-resolver": "<1.4.0",
+ "symfony/console": "<5.4",
+ "symfony/form": "<6.2.7",
+ "symfony/http-foundation": "<5.4",
+ "symfony/http-kernel": "<6.2",
+ "symfony/mime": "<6.2",
+ "symfony/translation": "<5.4",
+ "symfony/workflow": "<5.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.12|^2",
+ "egulias/email-validator": "^2.1.10|^3|^4",
+ "league/html-to-markdown": "^5.0",
+ "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
+ "symfony/asset": "^5.4|^6.0",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/finder": "^5.4|^6.0",
+ "symfony/form": "^6.2.7",
+ "symfony/html-sanitizer": "^6.1",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/http-kernel": "^6.2",
+ "symfony/intl": "^5.4|^6.0",
+ "symfony/mime": "^6.2",
+ "symfony/polyfill-intl-icu": "~1.0",
+ "symfony/property-info": "^5.4|^6.0",
+ "symfony/routing": "^5.4|^6.0",
+ "symfony/security-acl": "^2.8|^3.0",
+ "symfony/security-core": "^5.4|^6.0",
+ "symfony/security-csrf": "^5.4|^6.0",
+ "symfony/security-http": "^5.4|^6.0",
+ "symfony/serializer": "^6.2",
+ "symfony/stopwatch": "^5.4|^6.0",
+ "symfony/translation": "^5.4|^6.0",
+ "symfony/web-link": "^5.4|^6.0",
+ "symfony/workflow": "^5.4|^6.0",
+ "symfony/yaml": "^5.4|^6.0",
+ "twig/cssinliner-extra": "^2.12|^3",
+ "twig/inky-extra": "^2.12|^3",
+ "twig/markdown-extra": "^2.12|^3"
+ },
+ "suggest": {
+ "symfony/asset": "For using the AssetExtension",
+ "symfony/expression-language": "For using the ExpressionExtension",
+ "symfony/finder": "",
+ "symfony/form": "For using the FormExtension",
+ "symfony/html-sanitizer": "For using the HtmlSanitizerExtension",
+ "symfony/http-kernel": "For using the HttpKernelExtension",
+ "symfony/routing": "For using the RoutingExtension",
+ "symfony/security-core": "For using the SecurityExtension",
+ "symfony/security-csrf": "For using the CsrfExtension",
+ "symfony/security-http": "For using the LogoutUrlExtension",
+ "symfony/stopwatch": "For using the StopwatchExtension",
+ "symfony/translation": "For using the TranslationExtension",
+ "symfony/var-dumper": "For using the DumpExtension",
+ "symfony/web-link": "For using the WebLinkExtension",
+ "symfony/yaml": "For using the YamlExtension"
+ },
+ "type": "symfony-bridge",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Bridge\\Twig\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides integration for Twig with various Symfony components",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/twig-bridge/tree/v6.2.8"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-03-31T09:14:44+00:00"
+ },
+ {
+ "name": "symfony/twig-bundle",
+ "version": "v6.2.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/twig-bundle.git",
+ "reference": "8bb562655c6ae4b8fae9cf72077591f38b961566"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/8bb562655c6ae4b8fae9cf72077591f38b961566",
+ "reference": "8bb562655c6ae4b8fae9cf72077591f38b961566",
+ "shasum": ""
+ },
+ "require": {
+ "composer-runtime-api": ">=2.1",
+ "php": ">=8.1",
+ "symfony/config": "^6.1",
+ "symfony/dependency-injection": "^6.1",
+ "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/http-kernel": "^6.2",
+ "symfony/twig-bridge": "^6.2",
+ "twig/twig": "^2.13|^3.0.4"
+ },
+ "conflict": {
+ "symfony/framework-bundle": "<5.4",
+ "symfony/translation": "<5.4"
+ },
+ "require-dev": {
+ "doctrine/annotations": "^1.10.4|^2",
+ "symfony/asset": "^5.4|^6.0",
+ "symfony/expression-language": "^5.4|^6.0",
+ "symfony/finder": "^5.4|^6.0",
+ "symfony/form": "^5.4|^6.0",
+ "symfony/framework-bundle": "^5.4|^6.0",
+ "symfony/routing": "^5.4|^6.0",
+ "symfony/stopwatch": "^5.4|^6.0",
+ "symfony/translation": "^5.4|^6.0",
+ "symfony/web-link": "^5.4|^6.0",
+ "symfony/yaml": "^5.4|^6.0"
+ },
+ "type": "symfony-bundle",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Bundle\\TwigBundle\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides a tight integration of Twig into the Symfony full-stack framework",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/twig-bundle/tree/v6.2.7"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-14T08:44:56+00:00"
+ },
{
"name": "symfony/var-dumper",
"version": "v6.2.8",
@@ -2370,6 +3087,82 @@
}
],
"time": "2023-02-16T09:57:23+00:00"
+ },
+ {
+ "name": "twig/twig",
+ "version": "v3.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/twigphp/Twig.git",
+ "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15",
+ "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "^1.8",
+ "symfony/polyfill-mbstring": "^1.3"
+ },
+ "require-dev": {
+ "psr/container": "^1.0",
+ "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.5-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Twig\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com",
+ "homepage": "http://fabien.potencier.org",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
+ {
+ "name": "Armin Ronacher",
+ "email": "armin.ronacher@active-4.com",
+ "role": "Project Founder"
+ }
+ ],
+ "description": "Twig, the flexible, fast, and secure template language for PHP",
+ "homepage": "https://twig.symfony.com",
+ "keywords": [
+ "templating"
+ ],
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/v3.5.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-08T07:49:20+00:00"
}
],
"packages-dev": [],
diff --git a/config/bundles.php b/config/bundles.php
index 49d3fb6..bdd37ac 100644
--- a/config/bundles.php
+++ b/config/bundles.php
@@ -2,4 +2,5 @@
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
+ Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
];
diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml
new file mode 100644
index 0000000..f9f4cc5
--- /dev/null
+++ b/config/packages/twig.yaml
@@ -0,0 +1,6 @@
+twig:
+ default_path: '%kernel.project_dir%/templates'
+
+when@test:
+ twig:
+ strict_variables: true
diff --git a/src/Controller/IndexController.php b/src/Controller/IndexController.php
new file mode 100644
index 0000000..1f7c6e7
--- /dev/null
+++ b/src/Controller/IndexController.php
@@ -0,0 +1,74 @@
+render('success.html.twig', []);
+ }
+
+ #[Route('/fail', name: 'app_default_form_fail')]
+ public function form_fail() {
+
+ return $this->render('fail.html.twig', []);
+ }
+
+ #[Route('/', name: 'app_default_form')]
+ public function form(Request $request): Response
+ {
+ $wireguardRequest = new WireguardRequest();
+ $wireguardRequest->setAuthToken(sha1(random_bytes(255)));
+
+ $form = $this->createFormBuilder($wireguardRequest)
+ ->add('email', EmailType::class)
+ //->add('publicKey', TextType::class)
+ ->add('submit', SubmitType::class)
+ ->getForm();
+
+ $form->handleRequest($request);
+
+ if ($form->isSubmitted() && $form->isValid()) {
+ // $form->getData() holds the submitted values
+ // but, the original `$task` variable has also been updated
+ $wireguardRequest->setEmail($form->get('email')->getData());
+
+ if(str_ends_with($wireguardRequest->getEmail(), '@chaospott.de')) {
+
+ $model = new \App\Model\RequestsSqlite();
+ $model->addRequest($wireguardRequest);
+
+ // send E-Mail
+ return $this->redirectToRoute('app_default_form_success');
+ } else {
+
+ return $this->redirectToRoute('app_default_form_fail');
+ }
+
+ // ... perform some action, such as saving the task to the database
+
+ //return $this->redirectToRoute('task_success');
+ }
+
+
+ return $this->render('wireguardRequest.html.twig', [
+ 'form' => $form,
+ ]);
+ }
+
+
+}
diff --git a/src/Entity/WireguardRequest.php b/src/Entity/WireguardRequest.php
new file mode 100644
index 0000000..d48cf66
--- /dev/null
+++ b/src/Entity/WireguardRequest.php
@@ -0,0 +1,59 @@
+modify('+30 minute');
+
+ $this->validUntil = $dt;
+ }
+
+ public function setEmail($email):self
+ {
+
+ $this->email = $email;
+ return $this;
+ }
+
+ public function getEmail():String
+ {
+ return $this->email;
+ }
+
+ public function setPublicKey($publicKey):self
+ {
+
+ $this->publicKey = $publicKey;
+ return $this;
+ }
+
+ public function getPublicKey():String
+ {
+ return $this->publicKey;
+ }
+
+ public function setAuthToken($authToken):self
+ {
+
+ $this->authToken = $authToken;
+ return $this;
+ }
+
+ public function getAuthToken():String
+ {
+ return $this->authToken;
+ }
+
+ public function getValidUntil():\DateTime
+ {
+ return $this->validUntil;
+ }
+}
diff --git a/src/Model/RequestsSqlite.php b/src/Model/RequestsSqlite.php
new file mode 100644
index 0000000..c9f7255
--- /dev/null
+++ b/src/Model/RequestsSqlite.php
@@ -0,0 +1,62 @@
+db = new \SQLite3('Requests.db');
+
+ if(!$db_existed) $this->initializeDatabase();
+
+ return $this;
+ }
+
+ private function initializeDatabase() {
+ $query = '
+ CREATE TABLE requests
+ (
+ ID INT PRIMARY KEY NOT NULL,
+ Email TEXT NOT NULL,
+ AuthToken TEXT NOT NULL,
+ ValidUntil TEXT NOT NULL,
+ PublicKey TEXT
+ )
+ ';
+
+ return $this->query($query);
+ }
+
+ private function query($query) {
+
+ $ret = $this->db->exec($query);
+ if(!$ret) {
+ throw new \Exception($this->db->lastErrorMsg());
+ } else {
+ return true;
+ }
+ }
+
+ public function addRequest(WireguardRequest $wireguardRequest) {
+
+ $query = '
+ INSERT INTO requests (AuthToken, ValidUntil, Email) VALUES
+ (
+ '.$wireguardRequest->getAuthToken().',
+ '.$wireguardRequest->getValidUntil().',
+ '.$wireguardRequest->getEmail().'
+ );
+ ';
+
+ return $this->query($query);
+ }
+
+ // TODO implement update validate ect
+}
diff --git a/symfony.lock b/symfony.lock
index 318d41b..f9d69e4 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -54,5 +54,18 @@
"config/packages/routing.yaml",
"config/routes.yaml"
]
+ },
+ "symfony/twig-bundle": {
+ "version": "6.2",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "5.4",
+ "ref": "bb2178c57eee79e6be0b297aa96fc0c0def81387"
+ },
+ "files": [
+ "config/packages/twig.yaml",
+ "templates/base.html.twig"
+ ]
}
}
diff --git a/templates/base.html.twig b/templates/base.html.twig
new file mode 100644
index 0000000..d4f83f7
--- /dev/null
+++ b/templates/base.html.twig
@@ -0,0 +1,19 @@
+
+
+
+
+ {% block title %}Welcome!{% endblock %}
+
+ {# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #}
+ {% block stylesheets %}
+ {{ encore_entry_link_tags('app') }}
+ {% endblock %}
+
+ {% block javascripts %}
+ {{ encore_entry_script_tags('app') }}
+ {% endblock %}
+
+
+ {% block body %}{% endblock %}
+
+
diff --git a/templates/fail.html.twig b/templates/fail.html.twig
new file mode 100644
index 0000000..cce2f4f
--- /dev/null
+++ b/templates/fail.html.twig
@@ -0,0 +1,3 @@
+Fehler
+
+Das automatisierte Erstellen einer Wireguard Config ist nur mit einer '@chaospott.de' Adresse möglich
diff --git a/templates/success.html.twig b/templates/success.html.twig
new file mode 100644
index 0000000..cc2473c
--- /dev/null
+++ b/templates/success.html.twig
@@ -0,0 +1,7 @@
+Erfolgreich
+
+Du hast eine E-Mail auf deine '@chaospott.de' E-Mail Adresse erhalten. In dieser klicke auf den Authentifizierungslink und du erhältst eine gültige Wireguard Konfiguration für deinen Rechner
+
+DEBUG: Link da E-Mail noch nicht implementiert:
+
+htttp://
diff --git a/templates/wireguardRequest.html.twig b/templates/wireguardRequest.html.twig
new file mode 100644
index 0000000..aa23674
--- /dev/null
+++ b/templates/wireguardRequest.html.twig
@@ -0,0 +1,2 @@
+{# templates/wireguardRequest.html.twig #}
+{{ form(form) }}