diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..b4f29cc53 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,61 @@ +{ + "name": "BeWelcome Rox (Docker Master)", + "dockerComposeFile": [ + "../docker-compose.yml", + "../docker-compose.override.yml.dist" + ], + "service": "php", + "workspaceFolder": "/srv/bewelcome", + "overrideCommand": false, + "forwardPorts": [80, 1080, 9306, 9308], + "portsAttributes": { + "80": { + "label": "BeWelcome App (Nginx)", + "onAutoForward": "openBrowser" + }, + "1080": { + "label": "MailPit Web UI", + "onAutoForward": "notify" + }, + "9306": { + "label": "Manticore MySQL protocol", + "onAutoForward": "silent" + }, + "9308": { + "label": "Manticore HTTP API", + "onAutoForward": "silent" + } + }, + "postCreateCommand": "bzip2 -ckd docker/languages.sql.bz2 > docker/db/languages.sql && bzip2 -ckd docker/words.sql.bz2 > docker/db/words.sql", + "hostRequirements": { + "cpus": 2, + "memory": "4gb", + "storage": "32gb" + }, + "customizations": { + "vscode": { + "extensions": [ + "bmewburn.vscode-intelephense-client", + "xdebug.php-debug", + "symfony-vscode.symfony-vscode", + "bradlc.vscode-tailwindcss", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "mikestead.dotenv", + "ms-azuretools.vscode-docker", + "GitHub.vscode-pull-request-github" + ], + "settings": { + "php.suggest.basic": false, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[php]": { + "editor.defaultFormatter": "bmewburn.vscode-intelephense-client" + }, + "intelephense.environment.phpVersion": "8.4.0", + "intelephense.files.maxSize": 5000000, + "xdebug.remote_enable": true + } + } + } +} diff --git a/.env b/.env index aff1f5bf6..982e9d766 100644 --- a/.env +++ b/.env @@ -50,3 +50,7 @@ JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem JWT_PASSPHRASE=02567efd63a56b25644e9b52815ce880 ###< lexik/jwt-authentication-bundle ### + +SYMFONY_TRUSTED_PROXIES=REMOTE_ADDR + +SYMFONY_TRUSTED_PROXIES=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..277d997c8 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +* text=auto +*.sh text eol=lf +bin/console text eol=lf +.env text eol=lf diff --git a/Dockerfile b/Dockerfile index 6002873c6..52e0f7f95 100644 --- a/Dockerfile +++ b/Dockerfile @@ -184,7 +184,12 @@ FROM bewelcome_php AS bewelcome_php_dev # build for production ARG NODE_ENV=production +COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ + RUN set -eux; \ apk add --no-cache \ make \ - mysql-client + mysql-client; \ + install-php-extensions xdebug + +COPY docker/php/conf.d/bewelcome.xdebug.ini $PHP_INI_DIR/conf.d/xdebug.ini diff --git a/behat.yml.dist b/behat.yml.dist index 5d70c2369..a22342f44 100644 --- a/behat.yml.dist +++ b/behat.yml.dist @@ -2,7 +2,7 @@ default: suites: default: contexts: - - 'Alex\MailCatcher\Behat\MailCatcherContext': ~ + - 'Consensus\Behat\MailpitExtension\Context\MailpitContext': ~ - 'App\Tests\Behat\DatabaseContext': ~ - 'App\Tests\Behat\RefreshTokenContext': ~ - 'App\Tests\Behat\SecurityContext': ~ @@ -19,11 +19,10 @@ default: symfony: ~ 'Behatch\Extension': ~ 'FriendsOfBehat\SymfonyExtension': ~ - 'Alex\MailCatcher\Behat\MailCatcherExtension\Extension': - url: http://mailcatcher - purge_before_scenario: true + 'Consensus\Behat\MailpitExtension': + base_url: http://mailer:80 localhost: extensions: - 'Alex\MailCatcher\Behat\MailCatcherExtension\Extension': - url: http://localhost:1080 + 'Consensus\Behat\MailpitExtension': + base_url: http://localhost:1080 diff --git a/composer.json b/composer.json index 57a319c18..8ccba4ffb 100644 --- a/composer.json +++ b/composer.json @@ -92,9 +92,9 @@ "symfony/symfony": "*" }, "require-dev": { - "alexandresalome/mailcatcher": "^1.3", "behat/behat": "^3.7", "behatch/contexts": "^3.3", + "consensus/behat-mailpit-extension": "dev-main", "dama/doctrine-test-bundle": "^6.3", "doctrine/data-fixtures": "^1.3", "fakerphp/faker": "^v1.14.1", diff --git a/composer.lock b/composer.lock index 6f483e659..aba197169 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": "80a687a6d3730b9e6a6074d478692314", + "content-hash": "88d5cf29600904fc5515b08b93a7a89c", "packages": [ { "name": "amphp/amp", @@ -11519,109 +11519,6 @@ ], "time": "2026-05-24T10:45:48+00:00" }, - { - "name": "symfony/serializer", - "version": "v5.4.45", - "source": { - "type": "git", - "url": "https://github.com/symfony/serializer.git", - "reference": "460c5df9fb6c39d10d5b7f386e4feae4b6370221" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/460c5df9fb6c39d10d5b7f386e4feae4b6370221", - "reference": "460c5df9fb6c39d10d5b7f386e4feae4b6370221", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "doctrine/annotations": "<1.12", - "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", - "symfony/dependency-injection": "<4.4", - "symfony/property-access": "<5.4", - "symfony/property-info": "<5.4.24|>=6,<6.2.11", - "symfony/uid": "<5.3", - "symfony/yaml": "<4.4" - }, - "require-dev": { - "doctrine/annotations": "^1.12|^2", - "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", - "symfony/cache": "^4.4|^5.0|^6.0", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/filesystem": "^4.4|^5.0|^6.0", - "symfony/form": "^4.4|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/mime": "^4.4|^5.0|^6.0", - "symfony/property-access": "^5.4.26|^6.3", - "symfony/property-info": "^5.4.24|^6.2.11", - "symfony/uid": "^5.3|^6.0", - "symfony/validator": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0", - "symfony/var-exporter": "^4.4|^5.0|^6.0", - "symfony/yaml": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/cache-implementation": "For using the metadata cache.", - "symfony/config": "For using the XML mapping loader.", - "symfony/mime": "For using a MIME type guesser within the DataUriNormalizer.", - "symfony/property-access": "For using the ObjectNormalizer.", - "symfony/property-info": "To deserialize relations.", - "symfony/var-exporter": "For using the metadata compiler.", - "symfony/yaml": "For using the default YAML mapping loader." - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Serializer\\": "" - }, - "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": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/serializer/tree/v5.4.45" - }, - "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": "2024-09-25T14:11:13+00:00" - }, { "name": "symfony/service-contracts", "version": "v2.5.4", @@ -13574,48 +13471,6 @@ } ], "packages-dev": [ - { - "name": "alexandresalome/mailcatcher", - "version": "v1.4.1", - "target-dir": "Alex/MailCatcher", - "source": { - "type": "git", - "url": "https://github.com/alexandresalome/mailcatcher.git", - "reference": "90ee943e91021a065f8ff9ed8e3f7b7d8ae7256d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/alexandresalome/mailcatcher/zipball/90ee943e91021a065f8ff9ed8e3f7b7d8ae7256d", - "reference": "90ee943e91021a065f8ff9ed8e3f7b7d8ae7256d", - "shasum": "" - }, - "require": { - "ext-json": "*", - "php": ">=5.3.3", - "symfony/dom-crawler": "~2.3 || ~3.0 || ~4.0 || ~5.0 || ~6.0 || ~7.0" - }, - "require-dev": { - "behat/behat": "~3.0", - "phpunit/phpunit": "~4.6", - "swiftmailer/swiftmailer": "~5.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "Alex\\MailCatcher": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A library to access MailCatcher", - "support": { - "issues": "https://github.com/alexandresalome/mailcatcher/issues", - "source": "https://github.com/alexandresalome/mailcatcher/tree/v1.4.1" - }, - "time": "2024-03-29T15:42:38+00:00" - }, { "name": "behat/behat", "version": "v3.32.0", @@ -14079,6 +13934,57 @@ ], "time": "2022-02-24T20:20:32+00:00" }, + { + "name": "consensus/behat-mailpit-extension", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://gitlab.com/consensus.enterprises/misc/behat-mailpit-extension.git", + "reference": "89d3f16e07afb950d3b7836f6efce6a6526348a8" + }, + "dist": { + "type": "zip", + "url": "https://gitlab.com/api/v4/projects/consensus%2Eenterprises%2Fmisc%2Fbehat-mailpit-extension/repository/archive.zip?sha=89d3f16e07afb950d3b7836f6efce6a6526348a8", + "reference": "89d3f16e07afb950d3b7836f6efce6a6526348a8", + "shasum": "" + }, + "require": { + "behat/behat": "^3.14", + "friends-of-behat/mink-extension": "^2.7", + "guzzlehttp/guzzle": "^7.0", + "php": "^8.0" + }, + "require-dev": { + "squizlabs/php_codesniffer": "^3.0" + }, + "default-branch": true, + "type": "package", + "autoload": { + "psr-4": { + "Consensus\\Behat\\MailpitExtension\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-3.0-or-later" + ], + "authors": [ + { + "name": "Christopher Gervais", + "email": "christopher@consensus.enterprises" + }, + { + "name": "Scott Zhu Reeves", + "email": "scott@consensus.enterprises" + } + ], + "description": "Behat Mailpit Extension", + "support": { + "issues": "https://gitlab.com/consensus.enterprises/misc/behat-mailpit-extension/-/issues", + "source": "https://gitlab.com/consensus.enterprises/misc/behat-mailpit-extension/-/tree/main" + }, + "time": "2025-06-10T14:21:03+00:00" + }, { "name": "dama/doctrine-test-bundle", "version": "v6.7.5", @@ -14644,6 +14550,218 @@ ], "time": "2021-12-11T16:25:08+00:00" }, + { + "name": "guzzlehttp/guzzle", + "version": "7.15.4", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "994a8a073c61d9c2282155e7671c0bc14bba19da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/994a8a073c61d9c2282155e7671c0bc14bba19da", + "reference": "994a8a073c61d9c2282155e7671c0bc14bba19da", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^2.5.2", + "guzzlehttp/psr7": "^2.13", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.25" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.3", + "guzzlehttp/test-server": "^0.7", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.52 || ^9.6.34", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "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" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.15.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2026-08-24T09:16:39+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "cde49999552d185d64715fe9c1f77a2aadd2f9f1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/cde49999552d185d64715fe9c1f77a2aadd2f9f1", + "reference": "cde49999552d185d64715fe9c1f77a2aadd2f9f1", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.52 || ^9.6.34" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "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": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.5.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2026-08-24T09:11:28+00:00" + }, { "name": "hamcrest/hamcrest-php", "version": "v2.1.1", @@ -17570,7 +17688,9 @@ ], "aliases": [], "minimum-stability": "RC", - "stability-flags": {}, + "stability-flags": { + "consensus/behat-mailpit-extension": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -17590,7 +17710,7 @@ }, "platform-dev": {}, "platform-overrides": { - "php": "8.2" + "php": "8.3" }, "plugin-api-version": "2.9.0" } diff --git a/config/services.yaml b/config/services.yaml index acddb15f7..ab6463e53 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -40,6 +40,9 @@ services: # makes classes in src/ available to be used as services # this creates a service per class whose id is the fully-qualified class name + App\Form\DataTransformer\: + resource: '../src/Form/DataTransformer/*' + App\: resource: '../src/*' exclude: '../src/{DependencyInjection,Entity,Migrations,Model/MemberDataExtractor/DoctrineExtractor.php,Twig,Tests,Kernel.php}' diff --git a/docker-compose.yml b/docker-compose.yml index 8f8f29efb..6b00322b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -60,7 +60,10 @@ services: - ./data:/var/lib/manticore mailer: - image: tophfr/mailcatcher + image: axllent/mailpit + environment: + MP_SMTP_BIND_ADDR: "0.0.0.0:25" + MP_UI_BIND_ADDR: "0.0.0.0:80" volumes: db-data: {} diff --git a/docker/php/conf.d/bewelcome.xdebug.ini b/docker/php/conf.d/bewelcome.xdebug.ini new file mode 100644 index 000000000..cb05a630c --- /dev/null +++ b/docker/php/conf.d/bewelcome.xdebug.ini @@ -0,0 +1,6 @@ +; Xdebug configuration for development +; Disabled by default for performance. To enable, you can set XDEBUG_MODE=debug +xdebug.mode=off +xdebug.client_host=host.docker.internal +xdebug.start_with_request=yes +xdebug.discover_client_host=1