From 7b0fefbe7e8bbd05e44a5b5eed77dac7e2af9355 Mon Sep 17 00:00:00 2001 From: lmarthins0 Date: Fri, 29 May 2026 13:03:24 -0300 Subject: [PATCH 01/10] Adicionando Dusk --- .env.example | 2 +- Dockerfile | 2 +- composer.json | 1 + composer.lock | 789 ++++++++++++++++----------- tests/Browser/ExampleTest.php | 21 + tests/Browser/IndexTest.php | 21 + tests/Browser/Pages/HomePage.php | 36 ++ tests/Browser/Pages/Page.php | 20 + tests/Browser/console/.gitignore | 2 + tests/Browser/screenshots/.gitignore | 2 + tests/Browser/source/.gitignore | 2 + tests/DuskTestCase.php | 48 ++ 12 files changed, 625 insertions(+), 321 deletions(-) create mode 100644 tests/Browser/ExampleTest.php create mode 100644 tests/Browser/IndexTest.php create mode 100644 tests/Browser/Pages/HomePage.php create mode 100644 tests/Browser/Pages/Page.php create mode 100644 tests/Browser/console/.gitignore create mode 100644 tests/Browser/screenshots/.gitignore create mode 100644 tests/Browser/source/.gitignore create mode 100644 tests/DuskTestCase.php diff --git a/.env.example b/.env.example index f4151ab..1657af6 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -APP_NAME=Laravel +APP_NAME=Webapps APP_ENV=local APP_KEY= APP_DEBUG=true diff --git a/Dockerfile b/Dockerfile index e2ba01e..4ac1040 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM uspdev/uspdev-php-apache:latest +FROM uspdev/uspdev-php-apache:8.4 RUN sed -i 's|/var/www/html|/var/www/html/public|' \ /etc/apache2/sites-available/000-default.conf diff --git a/composer.json b/composer.json index 66bf45f..f09a679 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ }, "require-dev": { "fakerphp/faker": "^1.23", + "laravel/dusk": "^8.6", "laravel/pail": "^1.2.2", "laravel/pint": "^1.24", "laravel/sail": "^1.41", diff --git a/composer.lock b/composer.lock index 3b55069..3296649 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": "d6be4e6317ddaa3171b03974e7f7b3fc", + "content-hash": "3713c13575d8b3c8931d4bfc577171bb", "packages": [ { "name": "brick/math", @@ -667,12 +667,12 @@ "version": "v7.0.5", "source": { "type": "git", - "url": "https://github.com/firebase/php-jwt.git", + "url": "https://github.com/googleapis/php-jwt.git", "reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/47ad26bab5e7c70ae8a6f08ed25ff83631121380", + "url": "https://api.github.com/repos/googleapis/php-jwt/zipball/47ad26bab5e7c70ae8a6f08ed25ff83631121380", "reference": "47ad26bab5e7c70ae8a6f08ed25ff83631121380", "shasum": "" }, @@ -721,8 +721,8 @@ "php" ], "support": { - "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v7.0.5" + "issues": "https://github.com/googleapis/php-jwt/issues", + "source": "https://github.com/googleapis/php-jwt/tree/v7.0.5" }, "time": "2026-04-01T20:38:03+00:00" }, @@ -861,16 +861,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.10.0", + "version": "7.10.4", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" + "reference": "aec528da477062d3af11f51e6b33402be233b21f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", - "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aec528da477062d3af11f51e6b33402be233b21f", + "reference": "aec528da477062d3af11f51e6b33402be233b21f", "shasum": "" }, "require": { @@ -888,8 +888,9 @@ "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "guzzle/client-integration-tests": "3.0.2", + "guzzlehttp/test-server": "^0.3.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -967,7 +968,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.10.0" + "source": "https://github.com/guzzle/guzzle/tree/7.10.4" }, "funding": [ { @@ -983,20 +984,20 @@ "type": "tidelift" } ], - "time": "2025-08-23T22:36:01+00:00" + "time": "2026-05-22T19:00:53+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.3.0", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "481557b130ef3790cf82b713667b43030dc9c957" + "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", - "reference": "481557b130ef3790cf82b713667b43030dc9c957", + "url": "https://api.github.com/repos/guzzle/promises/zipball/09e8a212562fb1fb6a512c4156ed71525969d6c2", + "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2", "shasum": "" }, "require": { @@ -1004,7 +1005,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25" + "phpunit/phpunit": "^8.5.52 || ^9.6.34" }, "type": "library", "extra": { @@ -1050,7 +1051,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.3.0" + "source": "https://github.com/guzzle/promises/tree/2.4.1" }, "funding": [ { @@ -1066,20 +1067,20 @@ "type": "tidelift" } ], - "time": "2025-08-22T14:34:08+00:00" + "time": "2026-05-20T22:57:30+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.9.0", + "version": "2.10.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884" + "reference": "a1bbdc172f32a25fe999965b65b6e71fd87da9ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/7d0ed42f28e42d61352a7a79de682e5e67fec884", - "reference": "7d0ed42f28e42d61352a7a79de682e5e67fec884", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a1bbdc172f32a25fe999965b65b6e71fd87da9ed", + "reference": "a1bbdc172f32a25fe999965b65b6e71fd87da9ed", "shasum": "" }, "require": { @@ -1094,9 +1095,9 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "0.9.0", + "http-interop/http-factory-tests": "1.1.0", "jshttp/mime-db": "1.54.0.1", - "phpunit/phpunit": "^8.5.44 || ^9.6.25" + "phpunit/phpunit": "^8.5.52 || ^9.6.34" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -1167,7 +1168,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.9.0" + "source": "https://github.com/guzzle/psr7/tree/2.10.2" }, "funding": [ { @@ -1183,20 +1184,20 @@ "type": "tidelift" } ], - "time": "2026-03-10T16:41:02+00:00" + "time": "2026-05-25T22:58:15+00:00" }, { "name": "guzzlehttp/uri-template", - "version": "v1.0.5", + "version": "v1.0.6", "source": { "type": "git", "url": "https://github.com/guzzle/uri-template.git", - "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1" + "reference": "eef7f87bab6f204eba3c39224d8075c70c637946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1", - "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/eef7f87bab6f204eba3c39224d8075c70c637946", + "reference": "eef7f87bab6f204eba3c39224d8075c70c637946", "shasum": "" }, "require": { @@ -1205,7 +1206,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25", + "phpunit/phpunit": "^8.5.52 || ^9.6.34", "uri-template/tests": "1.0.0" }, "type": "library", @@ -1253,7 +1254,7 @@ ], "support": { "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.0.5" + "source": "https://github.com/guzzle/uri-template/tree/v1.0.6" }, "funding": [ { @@ -1269,7 +1270,7 @@ "type": "tidelift" } ], - "time": "2025-08-22T14:27:06+00:00" + "time": "2026-05-23T22:00:21+00:00" }, { "name": "kyslik/column-sortable", @@ -1334,16 +1335,16 @@ }, { "name": "laravel/framework", - "version": "v12.56.0", + "version": "v12.61.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "dac16d424b59debb2273910dde88eb7050a2a709" + "reference": "1124062a1ca92d290c8bcb9b7f649920fa6816bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/dac16d424b59debb2273910dde88eb7050a2a709", - "reference": "dac16d424b59debb2273910dde88eb7050a2a709", + "url": "https://api.github.com/repos/laravel/framework/zipball/1124062a1ca92d290c8bcb9b7f649920fa6816bf", + "reference": "1124062a1ca92d290c8bcb9b7f649920fa6816bf", "shasum": "" }, "require": { @@ -1384,8 +1385,8 @@ "symfony/mailer": "^7.2.0", "symfony/mime": "^7.2.0", "symfony/polyfill-php83": "^1.33", - "symfony/polyfill-php84": "^1.33", - "symfony/polyfill-php85": "^1.33", + "symfony/polyfill-php84": "^1.34", + "symfony/polyfill-php85": "^1.34", "symfony/process": "^7.2.0", "symfony/routing": "^7.2.0", "symfony/uid": "^7.2.0", @@ -1552,20 +1553,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-03-26T14:51:54+00:00" + "time": "2026-05-26T23:41:33+00:00" }, { "name": "laravel/prompts", - "version": "v0.3.16", + "version": "v0.3.18", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2" + "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/11e7d5f93803a2190b00e145142cb00a33d17ad2", - "reference": "11e7d5f93803a2190b00e145142cb00a33d17ad2", + "url": "https://api.github.com/repos/laravel/prompts/zipball/a19af51bb144bf87f08397921fa619f85c7d4e72", + "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72", "shasum": "" }, "require": { @@ -1609,22 +1610,22 @@ "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.16" + "source": "https://github.com/laravel/prompts/tree/v0.3.18" }, - "time": "2026-03-23T14:35:33+00:00" + "time": "2026-05-19T00:47:18+00:00" }, { "name": "laravel/serializable-closure", - "version": "v2.0.10", + "version": "v2.0.13", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "870fc81d2f879903dfc5b60bf8a0f94a1609e669" + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/870fc81d2f879903dfc5b60bf8a0f94a1609e669", - "reference": "870fc81d2f879903dfc5b60bf8a0f94a1609e669", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce", + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce", "shasum": "" }, "require": { @@ -1672,20 +1673,20 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2026-02-20T19:59:49+00:00" + "time": "2026-04-16T14:03:50+00:00" }, { "name": "laravel/socialite", - "version": "v5.26.1", + "version": "v5.27.0", "source": { "type": "git", "url": "https://github.com/laravel/socialite.git", - "reference": "db6ec2ee967b7f06412c3a0cf1daaf072f4752a4" + "reference": "40e0757a75637c7b2dff05d3286b0d8fc25e5c0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/socialite/zipball/db6ec2ee967b7f06412c3a0cf1daaf072f4752a4", - "reference": "db6ec2ee967b7f06412c3a0cf1daaf072f4752a4", + "url": "https://api.github.com/repos/laravel/socialite/zipball/40e0757a75637c7b2dff05d3286b0d8fc25e5c0e", + "reference": "40e0757a75637c7b2dff05d3286b0d8fc25e5c0e", "shasum": "" }, "require": { @@ -1744,7 +1745,7 @@ "issues": "https://github.com/laravel/socialite/issues", "source": "https://github.com/laravel/socialite" }, - "time": "2026-03-29T14:50:53+00:00" + "time": "2026-04-24T14:05:47+00:00" }, { "name": "laravel/tinker", @@ -2003,16 +2004,16 @@ }, { "name": "league/flysystem", - "version": "3.33.0", + "version": "3.34.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "570b8871e0ce693764434b29154c54b434905350" + "reference": "2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/570b8871e0ce693764434b29154c54b434905350", - "reference": "570b8871e0ce693764434b29154c54b434905350", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e", + "reference": "2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e", "shasum": "" }, "require": { @@ -2080,9 +2081,9 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.33.0" + "source": "https://github.com/thephpleague/flysystem/tree/3.34.0" }, - "time": "2026-03-25T07:59:30+00:00" + "time": "2026-05-14T10:28:08+00:00" }, { "name": "league/flysystem-local", @@ -2552,16 +2553,16 @@ }, { "name": "nesbot/carbon", - "version": "3.11.3", + "version": "3.11.4", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "6a7e652845bb018c668220c2a545aded8594fbbf" + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/6a7e652845bb018c668220c2a545aded8594fbbf", - "reference": "6a7e652845bb018c668220c2a545aded8594fbbf", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", "shasum": "" }, "require": { @@ -2653,7 +2654,7 @@ "type": "tidelift" } ], - "time": "2026-03-11T17:23:39+00:00" + "time": "2026-04-07T09:57:54+00:00" }, { "name": "nette/schema", @@ -2724,16 +2725,16 @@ }, { "name": "nette/utils", - "version": "v4.1.3", + "version": "v4.1.4", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe" + "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/bb3ea637e3d131d72acc033cfc2746ee893349fe", - "reference": "bb3ea637e3d131d72acc033cfc2746ee893349fe", + "url": "https://api.github.com/repos/nette/utils/zipball/7da6c396d7ebe142bc857c20479d5e70a5e1aac7", + "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7", "shasum": "" }, "require": { @@ -2809,9 +2810,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.1.3" + "source": "https://github.com/nette/utils/tree/v4.1.4" }, - "time": "2026-02-13T03:05:33+00:00" + "time": "2026-05-11T20:49:54+00:00" }, { "name": "nikic/php-parser", @@ -3154,16 +3155,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.50", + "version": "3.0.52", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "aa6ad8321ed103dc3624fb600a25b66ebf78ec7b" + "reference": "2adaefc83df2ec548558307690f376dd7d4f4fce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/aa6ad8321ed103dc3624fb600a25b66ebf78ec7b", - "reference": "aa6ad8321ed103dc3624fb600a25b66ebf78ec7b", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2adaefc83df2ec548558307690f376dd7d4f4fce", + "reference": "2adaefc83df2ec548558307690f376dd7d4f4fce", "shasum": "" }, "require": { @@ -3244,7 +3245,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.50" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.52" }, "funding": [ { @@ -3260,7 +3261,7 @@ "type": "tidelift" } ], - "time": "2026-03-19T02:57:58+00:00" + "time": "2026-04-27T07:02:15+00:00" }, { "name": "psr/cache", @@ -3725,16 +3726,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.22", + "version": "v0.12.23", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "3be75d5b9244936dd4ac62ade2bfb004d13acf0f" + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/3be75d5b9244936dd4ac62ade2bfb004d13acf0f", - "reference": "3be75d5b9244936dd4ac62ade2bfb004d13acf0f", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4dcc0f08047d52bbde475eda481146fd8e27e1a4", + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4", "shasum": "" }, "require": { @@ -3798,9 +3799,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.22" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.23" }, - "time": "2026-03-22T23:03:24+00:00" + "time": "2026-05-23T13:41:31+00:00" }, { "name": "ralouphie/getallheaders", @@ -4076,16 +4077,16 @@ }, { "name": "spatie/laravel-package-tools", - "version": "1.93.0", + "version": "1.93.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "0d097bce95b2bf6802fb1d83e1e753b0f5a948e7" + "reference": "d5552849801f2642aea710557463234b59ef65eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/0d097bce95b2bf6802fb1d83e1e753b0f5a948e7", - "reference": "0d097bce95b2bf6802fb1d83e1e753b0f5a948e7", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d5552849801f2642aea710557463234b59ef65eb", + "reference": "d5552849801f2642aea710557463234b59ef65eb", "shasum": "" }, "require": { @@ -4125,7 +4126,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.0" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.1" }, "funding": [ { @@ -4133,20 +4134,20 @@ "type": "github" } ], - "time": "2026-02-21T12:49:54+00:00" + "time": "2026-05-19T14:06:37+00:00" }, { "name": "spatie/laravel-permission", - "version": "7.2.4", + "version": "7.4.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-permission.git", - "reference": "0a8ab4b84dc5efe23be9ddcd77951e10030c452d" + "reference": "ef42ecb781e5534d368a3853fa161e420ad51397" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/0a8ab4b84dc5efe23be9ddcd77951e10030c452d", - "reference": "0a8ab4b84dc5efe23be9ddcd77951e10030c452d", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/ef42ecb781e5534d368a3853fa161e420ad51397", + "reference": "ef42ecb781e5534d368a3853fa161e420ad51397", "shasum": "" }, "require": { @@ -4154,7 +4155,7 @@ "illuminate/container": "^12.0|^13.0", "illuminate/contracts": "^12.0|^13.0", "illuminate/database": "^12.0|^13.0", - "php": "^8.4", + "php": "^8.3", "spatie/laravel-package-tools": "^1.0" }, "require-dev": { @@ -4212,7 +4213,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-permission/issues", - "source": "https://github.com/spatie/laravel-permission/tree/7.2.4" + "source": "https://github.com/spatie/laravel-permission/tree/7.4.1" }, "funding": [ { @@ -4220,7 +4221,7 @@ "type": "github" } ], - "time": "2026-03-17T22:57:08+00:00" + "time": "2026-04-29T07:59:45+00:00" }, { "name": "symfony/clock", @@ -4301,16 +4302,16 @@ }, { "name": "symfony/console", - "version": "v7.4.8", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707" + "reference": "85095d2573eaefaf35e40b9513a9bf09f72cd217" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707", - "reference": "1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707", + "url": "https://api.github.com/repos/symfony/console/zipball/85095d2573eaefaf35e40b9513a9bf09f72cd217", + "reference": "85095d2573eaefaf35e40b9513a9bf09f72cd217", "shasum": "" }, "require": { @@ -4375,7 +4376,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.8" + "source": "https://github.com/symfony/console/tree/v7.4.13" }, "funding": [ { @@ -4395,20 +4396,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T13:54:39+00:00" + "time": "2026-05-24T08:56:14+00:00" }, { "name": "symfony/css-selector", - "version": "v8.0.8", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "8db1c00226a94d8ab6aa89d9224eeee91e2ea2ed" + "reference": "3665cfade90565430909b906394c73c8739e57d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/8db1c00226a94d8ab6aa89d9224eeee91e2ea2ed", - "reference": "8db1c00226a94d8ab6aa89d9224eeee91e2ea2ed", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/3665cfade90565430909b906394c73c8739e57d0", + "reference": "3665cfade90565430909b906394c73c8739e57d0", "shasum": "" }, "require": { @@ -4444,7 +4445,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v8.0.8" + "source": "https://github.com/symfony/css-selector/tree/v8.0.9" }, "funding": [ { @@ -4464,20 +4465,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.6.0", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", - "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", "shasum": "" }, "require": { @@ -4490,7 +4491,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -4515,7 +4516,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" }, "funding": [ { @@ -4526,12 +4527,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2026-04-13T15:52:40+00:00" }, { "name": "symfony/error-handler", @@ -4617,16 +4622,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v8.0.8", + "version": "v8.0.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6" + "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f662acc6ab22a3d6d716dcb44c381c6002940df6", - "reference": "f662acc6ab22a3d6d716dcb44c381c6002940df6", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0c3c1a17604c4dbbec4b93fe162c538482096e1f", + "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f", "shasum": "" }, "require": { @@ -4678,7 +4683,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.8" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.9" }, "funding": [ { @@ -4698,20 +4703,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.6.0", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", - "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/ccba7060602b7fed0b03c85bf025257f76d9ef32", + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32", "shasum": "" }, "require": { @@ -4725,7 +4730,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -4758,7 +4763,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.0" }, "funding": [ { @@ -4769,12 +4774,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2026-01-05T13:30:16+00:00" }, { "name": "symfony/finder", @@ -4846,16 +4855,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.4.8", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "9381209597ec66c25be154cbf2289076e64d1eab" + "reference": "bc354f47c62301e990b7874fa662326368508e2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9381209597ec66c25be154cbf2289076e64d1eab", - "reference": "9381209597ec66c25be154cbf2289076e64d1eab", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/bc354f47c62301e990b7874fa662326368508e2c", + "reference": "bc354f47c62301e990b7874fa662326368508e2c", "shasum": "" }, "require": { @@ -4904,7 +4913,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.4.8" + "source": "https://github.com/symfony/http-foundation/tree/v7.4.13" }, "funding": [ { @@ -4924,20 +4933,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-24T11:20:33+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.4.8", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "017e76ad089bac281553389269e259e155935e1a" + "reference": "9df847980c436451f4f51d1284491bb4356dd989" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/017e76ad089bac281553389269e259e155935e1a", - "reference": "017e76ad089bac281553389269e259e155935e1a", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9df847980c436451f4f51d1284491bb4356dd989", + "reference": "9df847980c436451f4f51d1284491bb4356dd989", "shasum": "" }, "require": { @@ -5023,7 +5032,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.4.8" + "source": "https://github.com/symfony/http-kernel/tree/v7.4.13" }, "funding": [ { @@ -5043,20 +5052,20 @@ "type": "tidelift" } ], - "time": "2026-03-31T20:57:01+00:00" + "time": "2026-05-27T08:31:43+00:00" }, { "name": "symfony/mailer", - "version": "v7.4.8", + "version": "v7.4.12", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "f6ea532250b476bfc1b56699b388a1bdbf168f62" + "reference": "5cefb712a25f320579615ba9e1942abaeade7dff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/f6ea532250b476bfc1b56699b388a1bdbf168f62", - "reference": "f6ea532250b476bfc1b56699b388a1bdbf168f62", + "url": "https://api.github.com/repos/symfony/mailer/zipball/5cefb712a25f320579615ba9e1942abaeade7dff", + "reference": "5cefb712a25f320579615ba9e1942abaeade7dff", "shasum": "" }, "require": { @@ -5107,7 +5116,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.4.8" + "source": "https://github.com/symfony/mailer/tree/v7.4.12" }, "funding": [ { @@ -5127,20 +5136,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-20T07:20:23+00:00" }, { "name": "symfony/mime", - "version": "v7.4.8", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "6df02f99998081032da3407a8d6c4e1dcb5d4379" + "reference": "a845722765c4f6b2ce88beaf4f4479975b186770" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/6df02f99998081032da3407a8d6c4e1dcb5d4379", - "reference": "6df02f99998081032da3407a8d6c4e1dcb5d4379", + "url": "https://api.github.com/repos/symfony/mime/zipball/a845722765c4f6b2ce88beaf4f4479975b186770", + "reference": "a845722765c4f6b2ce88beaf4f4479975b186770", "shasum": "" }, "require": { @@ -5196,7 +5205,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.4.8" + "source": "https://github.com/symfony/mime/tree/v7.4.13" }, "funding": [ { @@ -5216,20 +5225,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T14:11:46+00:00" + "time": "2026-05-23T16:22:37+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { @@ -5279,7 +5288,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { @@ -5299,20 +5308,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.33.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" + "reference": "e9247d281d694a5120554d9afaf54e070e88a603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603", + "reference": "e9247d281d694a5120554d9afaf54e070e88a603", "shasum": "" }, "require": { @@ -5361,7 +5370,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1" }, "funding": [ { @@ -5381,20 +5390,20 @@ "type": "tidelift" } ], - "time": "2025-06-27T09:58:17+00:00" + "time": "2026-05-26T05:58:03+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.33.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + "reference": "dc21118016c039a66235cf93d96b435ffb282412" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412", + "reference": "dc21118016c039a66235cf93d96b435ffb282412", "shasum": "" }, "require": { @@ -5448,7 +5457,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1" }, "funding": [ { @@ -5468,20 +5477,20 @@ "type": "tidelift" } ], - "time": "2024-09-10T14:38:51+00:00" + "time": "2026-05-25T15:22:23+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.0", + "version": "v1.38.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" + "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b", + "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b", "shasum": "" }, "require": { @@ -5533,7 +5542,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0" }, "funding": [ { @@ -5553,20 +5562,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-05-25T13:48:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.33.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", - "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/14c5439eec4ccff081ac14eca2dc57feb2a66d92", + "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92", "shasum": "" }, "require": { @@ -5618,7 +5627,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.1" }, "funding": [ { @@ -5638,20 +5647,20 @@ "type": "tidelift" } ], - "time": "2024-12-23T08:48:59+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", - "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { @@ -5702,7 +5711,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { @@ -5722,20 +5731,20 @@ "type": "tidelift" } ], - "time": "2025-01-02T08:10:11+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.33.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" + "reference": "8339098cae28673c15cce00d80734af0453054e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2", + "reference": "8339098cae28673c15cce00d80734af0453054e2", "shasum": "" }, "require": { @@ -5782,7 +5791,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1" }, "funding": [ { @@ -5802,20 +5811,20 @@ "type": "tidelift" } ], - "time": "2025-07-08T02:45:35+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.33.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", "shasum": "" }, "require": { @@ -5862,7 +5871,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" }, "funding": [ { @@ -5882,20 +5891,20 @@ "type": "tidelift" } ], - "time": "2025-06-24T13:30:11+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.33.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", "shasum": "" }, "require": { @@ -5942,7 +5951,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" }, "funding": [ { @@ -5962,20 +5971,20 @@ "type": "tidelift" } ], - "time": "2025-06-23T16:12:55+00:00" + "time": "2026-05-26T02:25:22+00:00" }, { "name": "symfony/polyfill-uuid", - "version": "v1.33.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", - "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", "shasum": "" }, "require": { @@ -6025,7 +6034,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.33.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" }, "funding": [ { @@ -6045,20 +6054,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/process", - "version": "v7.4.8", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "60f19cd3badc8de688421e21e4305eba50f8089a" + "reference": "f5804be144caceb570f6747519999636b664f24c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/60f19cd3badc8de688421e21e4305eba50f8089a", - "reference": "60f19cd3badc8de688421e21e4305eba50f8089a", + "url": "https://api.github.com/repos/symfony/process/zipball/f5804be144caceb570f6747519999636b664f24c", + "reference": "f5804be144caceb570f6747519999636b664f24c", "shasum": "" }, "require": { @@ -6090,7 +6099,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.4.8" + "source": "https://github.com/symfony/process/tree/v7.4.13" }, "funding": [ { @@ -6110,20 +6119,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-23T16:05:06+00:00" }, { "name": "symfony/routing", - "version": "v7.4.8", + "version": "v7.4.13", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "9608de9873ec86e754fb6c0a0fa7e5f1a960eb6b" + "reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/9608de9873ec86e754fb6c0a0fa7e5f1a960eb6b", - "reference": "9608de9873ec86e754fb6c0a0fa7e5f1a960eb6b", + "url": "https://api.github.com/repos/symfony/routing/zipball/3a162171bb008e5e0f15dce6581373a4c0e8390d", + "reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d", "shasum": "" }, "require": { @@ -6175,7 +6184,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.4.8" + "source": "https://github.com/symfony/routing/tree/v7.4.13" }, "funding": [ { @@ -6195,20 +6204,20 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-24T11:20:33+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.6.1", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d25d82433a80eba6aa0e6c24b61d7370d99e444a", + "reference": "d25d82433a80eba6aa0e6c24b61d7370d99e444a", "shasum": "" }, "require": { @@ -6226,7 +6235,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -6262,7 +6271,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.0" }, "funding": [ { @@ -6282,20 +6291,20 @@ "type": "tidelift" } ], - "time": "2025-07-15T11:30:57+00:00" + "time": "2026-03-28T09:44:51+00:00" }, { "name": "symfony/string", - "version": "v8.0.8", + "version": "v8.0.13", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ae9488f874d7603f9d2dfbf120203882b645d963" + "reference": "f2e3e4d33579350d1b12001ef2872f86b27ed3dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ae9488f874d7603f9d2dfbf120203882b645d963", - "reference": "ae9488f874d7603f9d2dfbf120203882b645d963", + "url": "https://api.github.com/repos/symfony/string/zipball/f2e3e4d33579350d1b12001ef2872f86b27ed3dc", + "reference": "f2e3e4d33579350d1b12001ef2872f86b27ed3dc", "shasum": "" }, "require": { @@ -6352,7 +6361,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.0.8" + "source": "https://github.com/symfony/string/tree/v8.0.13" }, "funding": [ { @@ -6372,20 +6381,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-05-23T18:05:53+00:00" }, { "name": "symfony/translation", - "version": "v8.0.8", + "version": "v8.0.10", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f" + "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f", - "reference": "27c03ae3940de24ba2f71cfdbac824f2aa1fdf2f", + "url": "https://api.github.com/repos/symfony/translation/zipball/f63e9342e12646a57c91ef8a366a4f9d8e557b67", + "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67", "shasum": "" }, "require": { @@ -6445,7 +6454,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v8.0.8" + "source": "https://github.com/symfony/translation/tree/v8.0.10" }, "funding": [ { @@ -6465,20 +6474,20 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-05-06T11:30:54+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.6.1", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "65a8bc82080447fae78373aa10f8d13b38338977" + "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977", - "reference": "65a8bc82080447fae78373aa10f8d13b38338977", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/0ab302977a952b42fd51475c4ebac81f8da0a95d", + "reference": "0ab302977a952b42fd51475c4ebac81f8da0a95d", "shasum": "" }, "require": { @@ -6491,7 +6500,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -6527,7 +6536,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.6.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.7.0" }, "funding": [ { @@ -6547,20 +6556,20 @@ "type": "tidelift" } ], - "time": "2025-07-15T13:41:35+00:00" + "time": "2026-01-05T13:30:16+00:00" }, { "name": "symfony/uid", - "version": "v7.4.8", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/uid.git", - "reference": "6883ebdf7bf6a12b37519dbc0df62b0222401b56" + "reference": "2676b524340abcfe4d6151ec698463cebafee439" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/6883ebdf7bf6a12b37519dbc0df62b0222401b56", - "reference": "6883ebdf7bf6a12b37519dbc0df62b0222401b56", + "url": "https://api.github.com/repos/symfony/uid/zipball/2676b524340abcfe4d6151ec698463cebafee439", + "reference": "2676b524340abcfe4d6151ec698463cebafee439", "shasum": "" }, "require": { @@ -6605,7 +6614,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/uid/tree/v7.4.8" + "source": "https://github.com/symfony/uid/tree/v7.4.9" }, "funding": [ { @@ -6625,7 +6634,7 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-04-30T15:19:22+00:00" }, { "name": "symfony/var-dumper", @@ -6771,16 +6780,16 @@ }, { "name": "uspdev/cadastros-auxiliares-client", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/uspdev/cadastros-auxiliares-client.git", - "reference": "d0c8d057b73cb48ff483c24982996a7d201ceeaa" + "reference": "a809913f1f484306c9219056b2aa31c19a711ece" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/uspdev/cadastros-auxiliares-client/zipball/d0c8d057b73cb48ff483c24982996a7d201ceeaa", - "reference": "d0c8d057b73cb48ff483c24982996a7d201ceeaa", + "url": "https://api.github.com/repos/uspdev/cadastros-auxiliares-client/zipball/a809913f1f484306c9219056b2aa31c19a711ece", + "reference": "a809913f1f484306c9219056b2aa31c19a711ece", "shasum": "" }, "require": { @@ -6809,22 +6818,22 @@ "description": "Laravel client for cadastros-auxiliares webservice endpoints", "support": { "issues": "https://github.com/uspdev/cadastros-auxiliares-client/issues", - "source": "https://github.com/uspdev/cadastros-auxiliares-client/tree/1.0.2" + "source": "https://github.com/uspdev/cadastros-auxiliares-client/tree/1.0.3" }, - "time": "2026-03-25T19:47:58+00:00" + "time": "2026-04-02T19:55:48+00:00" }, { "name": "uspdev/laravel-usp-theme", - "version": "2.8.27", + "version": "2.8.30", "source": { "type": "git", "url": "https://github.com/uspdev/laravel-usp-theme.git", - "reference": "75f09e02929d5588bd26f9ccad8f7b5300cb7162" + "reference": "a862e5ca192dd2f215f8f53dcbbfac89c8b81c2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/uspdev/laravel-usp-theme/zipball/75f09e02929d5588bd26f9ccad8f7b5300cb7162", - "reference": "75f09e02929d5588bd26f9ccad8f7b5300cb7162", + "url": "https://api.github.com/repos/uspdev/laravel-usp-theme/zipball/a862e5ca192dd2f215f8f53dcbbfac89c8b81c2b", + "reference": "a862e5ca192dd2f215f8f53dcbbfac89c8b81c2b", "shasum": "" }, "require": { @@ -6862,9 +6871,9 @@ "description": "usp theme for laravel", "support": { "issues": "https://github.com/uspdev/laravel-usp-theme/issues", - "source": "https://github.com/uspdev/laravel-usp-theme/tree/2.8.27" + "source": "https://github.com/uspdev/laravel-usp-theme/tree/2.8.30" }, - "time": "2026-03-27T14:35:42+00:00" + "time": "2026-05-08T17:37:30+00:00" }, { "name": "uspdev/senhaunica-socialite", @@ -7009,23 +7018,23 @@ }, { "name": "voku/portable-ascii", - "version": "2.0.3", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" + "reference": "8e1051fe39379367aecf014f41744ce7539a856f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", - "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/8e1051fe39379367aecf014f41744ce7539a856f", + "reference": "8e1051fe39379367aecf014f41744ce7539a856f", "shasum": "" }, "require": { - "php": ">=7.0.0" + "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + "phpunit/phpunit": "~8.5 || ~9.6 || ~10.5 || ~11.5" }, "suggest": { "ext-intl": "Use Intl for transliterator_transliterate() support" @@ -7055,7 +7064,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/2.0.3" + "source": "https://github.com/voku/portable-ascii/tree/2.1.1" }, "funding": [ { @@ -7079,7 +7088,7 @@ "type": "tidelift" } ], - "time": "2024-11-21T01:49:47+00:00" + "time": "2026-04-26T05:33:54+00:00" } ], "packages-dev": [ @@ -7268,18 +7277,92 @@ }, "time": "2025-04-30T06:54:44+00:00" }, + { + "name": "laravel/dusk", + "version": "v8.6.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/dusk.git", + "reference": "e7fd48762c6a82ad2cd311db07587aa2a97ce143" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/dusk/zipball/e7fd48762c6a82ad2cd311db07587aa2a97ce143", + "reference": "e7fd48762c6a82ad2cd311db07587aa2a97ce143", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-zip": "*", + "guzzlehttp/guzzle": "^7.5", + "illuminate/console": "^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", + "php": "^8.1", + "php-webdriver/webdriver": "^1.15.2", + "symfony/console": "^6.2|^7.0|^8.0", + "symfony/finder": "^6.2|^7.0|^8.0", + "symfony/process": "^6.2|^7.0|^8.0", + "vlucas/phpdotenv": "^5.2" + }, + "require-dev": { + "laravel/framework": "^10.0|^11.0|^12.0|^13.0", + "mockery/mockery": "^1.6", + "orchestra/testbench-core": "^8.19|^9.17|^10.8|^11.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.1|^11.0|^12.0.1", + "psy/psysh": "^0.11.12|^0.12", + "symfony/yaml": "^6.2|^7.0|^8.0" + }, + "suggest": { + "ext-pcntl": "Used to gracefully terminate Dusk when tests are running." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Dusk\\DuskServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Dusk\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Dusk provides simple end-to-end testing and browser automation.", + "keywords": [ + "laravel", + "testing", + "webdriver" + ], + "support": { + "issues": "https://github.com/laravel/dusk/issues", + "source": "https://github.com/laravel/dusk/tree/v8.6.0" + }, + "time": "2026-04-15T14:50:40+00:00" + }, { "name": "laravel/pail", - "version": "v1.2.6", + "version": "v1.2.7", "source": { "type": "git", "url": "https://github.com/laravel/pail.git", - "reference": "aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf" + "reference": "2f7d27dada8effc48b8c424445a69cca7007daaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pail/zipball/aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf", - "reference": "aa71a01c309e7f66bc2ec4fb1a59291b82eb4abf", + "url": "https://api.github.com/repos/laravel/pail/zipball/2f7d27dada8effc48b8c424445a69cca7007daaa", + "reference": "2f7d27dada8effc48b8c424445a69cca7007daaa", "shasum": "" }, "require": { @@ -7346,20 +7429,20 @@ "issues": "https://github.com/laravel/pail/issues", "source": "https://github.com/laravel/pail" }, - "time": "2026-02-09T13:44:54+00:00" + "time": "2026-05-20T22:24:57+00:00" }, { "name": "laravel/pint", - "version": "v1.29.0", + "version": "v1.29.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "bdec963f53172c5e36330f3a400604c69bf02d39" + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/bdec963f53172c5e36330f3a400604c69bf02d39", - "reference": "bdec963f53172c5e36330f3a400604c69bf02d39", + "url": "https://api.github.com/repos/laravel/pint/zipball/0770e9b7fafd50d4586881d456d6eb41c9247a80", + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80", "shasum": "" }, "require": { @@ -7370,14 +7453,14 @@ "php": "^8.2.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.94.2", - "illuminate/view": "^12.54.1", - "larastan/larastan": "^3.9.3", - "laravel-zero/framework": "^12.0.5", + "friendsofphp/php-cs-fixer": "^3.95.1", + "illuminate/view": "^12.56.0", + "larastan/larastan": "^3.9.6", + "laravel-zero/framework": "^12.1.0", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^2.4.0", "pestphp/pest": "^3.8.6", - "shipfastlabs/agent-detector": "^1.1.0" + "shipfastlabs/agent-detector": "^1.1.3" }, "bin": [ "builds/pint" @@ -7414,20 +7497,20 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2026-03-12T15:51:39+00:00" + "time": "2026-04-20T15:26:14+00:00" }, { "name": "laravel/sail", - "version": "v1.56.0", + "version": "v1.61.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "f43426bb42a1cb7a51a3861d9138063e54766d28" + "reference": "68ef35015630fe510432e63e11e21749006df688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/f43426bb42a1cb7a51a3861d9138063e54766d28", - "reference": "f43426bb42a1cb7a51a3861d9138063e54766d28", + "url": "https://api.github.com/repos/laravel/sail/zipball/68ef35015630fe510432e63e11e21749006df688", + "reference": "68ef35015630fe510432e63e11e21749006df688", "shasum": "" }, "require": { @@ -7477,7 +7560,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2026-04-01T15:17:32+00:00" + "time": "2026-05-23T23:33:57+00:00" }, { "name": "mockery/mockery", @@ -7624,23 +7707,23 @@ }, { "name": "nunomaduro/collision", - "version": "v8.9.2", + "version": "v8.9.4", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "6eb16883e74fd725ac64dbe81544c961ab448ba5" + "reference": "716af8f95a470e9094cfca09ed897b023be191a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/6eb16883e74fd725ac64dbe81544c961ab448ba5", - "reference": "6eb16883e74fd725ac64dbe81544c961ab448ba5", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/716af8f95a470e9094cfca09ed897b023be191a5", + "reference": "716af8f95a470e9094cfca09ed897b023be191a5", "shasum": "" }, "require": { "filp/whoops": "^2.18.4", "nunomaduro/termwind": "^2.4.0", "php": "^8.2.0", - "symfony/console": "^7.4.8 || ^8.0.4" + "symfony/console": "^7.4.8 || ^8.0.8" }, "conflict": { "laravel/framework": "<11.48.0 || >=14.0.0", @@ -7648,12 +7731,12 @@ }, "require-dev": { "brianium/paratest": "^7.8.5", - "larastan/larastan": "^3.9.3", - "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.2.0", - "laravel/pint": "^1.29.0", - "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.0.0", + "larastan/larastan": "^3.9.6", + "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.5.0", + "laravel/pint": "^1.29.1", + "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.2.1", "pestphp/pest": "^3.8.5 || ^4.4.3 || ^5.0.0", - "sebastian/environment": "^7.2.1 || ^8.0.4 || ^9.0.0" + "sebastian/environment": "^7.2.1 || ^8.0.4 || ^9.3.0" }, "type": "library", "extra": { @@ -7716,7 +7799,7 @@ "type": "patreon" } ], - "time": "2026-03-31T21:51:27+00:00" + "time": "2026-04-21T14:04:20+00:00" }, { "name": "phar-io/manifest", @@ -7836,6 +7919,72 @@ }, "time": "2022-02-21T01:04:05+00:00" }, + { + "name": "php-webdriver/webdriver", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/php-webdriver/php-webdriver.git", + "reference": "ac0662863aa120b4f645869f584013e4c4dba46a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-webdriver/php-webdriver/zipball/ac0662863aa120b4f645869f584013e4c4dba46a", + "reference": "ac0662863aa120b4f645869f584013e4c4dba46a", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-zip": "*", + "php": "^7.3 || ^8.0", + "symfony/polyfill-mbstring": "^1.12", + "symfony/process": "^5.0 || ^6.0 || ^7.0 || ^8.0" + }, + "replace": { + "facebook/webdriver": "*" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.20.0", + "ondram/ci-detector": "^4.0", + "php-coveralls/php-coveralls": "^2.4", + "php-mock/php-mock-phpunit": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpunit/phpunit": "^9.3", + "squizlabs/php_codesniffer": "^3.5", + "symfony/var-dumper": "^5.0 || ^6.0 || ^7.0 || ^8.0" + }, + "suggest": { + "ext-simplexml": "For Firefox profile creation" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Exception/TimeoutException.php" + ], + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP client for Selenium WebDriver. Previously facebook/webdriver.", + "homepage": "https://github.com/php-webdriver/php-webdriver", + "keywords": [ + "Chromedriver", + "geckodriver", + "php", + "selenium", + "webdriver" + ], + "support": { + "issues": "https://github.com/php-webdriver/php-webdriver/issues", + "source": "https://github.com/php-webdriver/php-webdriver/tree/1.16.0" + }, + "time": "2025-12-28T23:57:40+00:00" + }, { "name": "phpunit/php-code-coverage", "version": "11.0.12", @@ -8405,6 +8554,7 @@ "type": "github" } ], + "abandoned": true, "time": "2025-03-19T07:56:08+00:00" }, { @@ -8461,6 +8611,7 @@ "type": "github" } ], + "abandoned": true, "time": "2024-07-03T04:45:54+00:00" }, { @@ -9333,16 +9484,16 @@ }, { "name": "symfony/yaml", - "version": "v8.0.8", + "version": "v8.0.13", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "54174ab48c0c0f9e21512b304be17f8150ccf8f1" + "reference": "a1cdf99e359d5c001782a2db67a1fc71b2a5b34e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/54174ab48c0c0f9e21512b304be17f8150ccf8f1", - "reference": "54174ab48c0c0f9e21512b304be17f8150ccf8f1", + "url": "https://api.github.com/repos/symfony/yaml/zipball/a1cdf99e359d5c001782a2db67a1fc71b2a5b34e", + "reference": "a1cdf99e359d5c001782a2db67a1fc71b2a5b34e", "shasum": "" }, "require": { @@ -9384,7 +9535,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v8.0.8" + "source": "https://github.com/symfony/yaml/tree/v8.0.13" }, "funding": [ { @@ -9404,7 +9555,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-05-25T06:08:44+00:00" }, { "name": "theseer/tokenizer", @@ -9459,12 +9610,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.2" }, - "platform-dev": [], - "plugin-api-version": "2.6.0" + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/tests/Browser/ExampleTest.php b/tests/Browser/ExampleTest.php new file mode 100644 index 0000000..2d451fc --- /dev/null +++ b/tests/Browser/ExampleTest.php @@ -0,0 +1,21 @@ +browse(function (Browser $browser) { + $browser->visit('/') + ->assertSee('Laravel'); + }); + } +} diff --git a/tests/Browser/IndexTest.php b/tests/Browser/IndexTest.php new file mode 100644 index 0000000..c509e9a --- /dev/null +++ b/tests/Browser/IndexTest.php @@ -0,0 +1,21 @@ +browse(function (Browser $browser) { + $browser->visit('/') + ->assertSee('Webapps'); + }); + } +} diff --git a/tests/Browser/Pages/HomePage.php b/tests/Browser/Pages/HomePage.php new file mode 100644 index 0000000..45d9283 --- /dev/null +++ b/tests/Browser/Pages/HomePage.php @@ -0,0 +1,36 @@ + + */ + public function elements(): array + { + return [ + '@element' => '#selector', + ]; + } +} diff --git a/tests/Browser/Pages/Page.php b/tests/Browser/Pages/Page.php new file mode 100644 index 0000000..eb9a2de --- /dev/null +++ b/tests/Browser/Pages/Page.php @@ -0,0 +1,20 @@ + + */ + public static function siteElements(): array + { + return [ + '@element' => '#selector', + ]; + } +} diff --git a/tests/Browser/console/.gitignore b/tests/Browser/console/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/Browser/console/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Browser/screenshots/.gitignore b/tests/Browser/screenshots/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/Browser/screenshots/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Browser/source/.gitignore b/tests/Browser/source/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/tests/Browser/source/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php new file mode 100644 index 0000000..020699d --- /dev/null +++ b/tests/DuskTestCase.php @@ -0,0 +1,48 @@ +addArguments(collect([ + $this->shouldStartMaximized() ? '--start-maximized' : '--window-size=1920,1080', + '--disable-search-engine-choice-screen', + '--disable-smooth-scrolling', + ])->unless($this->hasHeadlessDisabled(), function (Collection $items) { + return $items->merge([ + '--disable-gpu', + '--headless=new', + ]); + })->all()); + + return RemoteWebDriver::create( + $_ENV['DUSK_DRIVER_URL'] ?? env('DUSK_DRIVER_URL') ?? 'http://localhost:9515', + DesiredCapabilities::chrome()->setCapability( + ChromeOptions::CAPABILITY, $options + ) + ); + } +} From d6053d7ae102750a9510264fdf60a89e2ca70347 Mon Sep 17 00:00:00 2001 From: lmarthins0 Date: Tue, 9 Jun 2026 07:44:40 -0300 Subject: [PATCH 02/10] adicinando senhaunica-faker ao docker --- docker-compose.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index ea57280..83ed824 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,6 +37,18 @@ services: - webapps-network shm_size: 2gb + senhaunica-faker: + image: uspdev/senhaunica-faker + container_name: webapps_senhaunica-faker + ports: + - "3141:3141" + environment: + - APP_URL=http://auth.local:3141 + networks: + webapps-network: + aliases: + - auth.local + networks: webapps-network: From 7474f08626bb49cf7f8c94eb7491896f6b3fcecf Mon Sep 17 00:00:00 2001 From: lmarthins0 Date: Wed, 10 Jun 2026 13:05:39 -0300 Subject: [PATCH 03/10] =?UTF-8?q?configura=C3=A7=C3=B5es=20de=20ambiente?= =?UTF-8?q?=20e=20inicio=20do=20desenvolvimento=20das=20integra=C3=A7?= =?UTF-8?q?=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Bucket/CreateBucketController.php | 44 ++++ .../Bucket/DeleteBucketController.php | 42 ++++ .../Bucket/TestConnectionBucketController.php | 17 ++ .../TestGwmariadbConnectionController.php | 22 ++ app/Http/Controllers/GwmariadbController.php | 86 +++++++ app/Http/Controllers/PortainerController.php | 64 +++++ app/Http/Controllers/ReuniaoController.php | 6 +- app/Http/Controllers/WebappController.php | 1 + app/Services/WebappService.php | 14 ++ composer.lock | 232 +++++++++--------- docker-compose.yml | 51 ++-- docker/db/init.sql | 3 + .../views/webapps/partials/form.blade.php | 17 +- resources/views/webapps/show.blade.php | 6 +- routes/web.php | 31 ++- 15 files changed, 483 insertions(+), 153 deletions(-) create mode 100644 app/Http/Controllers/Bucket/CreateBucketController.php create mode 100644 app/Http/Controllers/Bucket/DeleteBucketController.php create mode 100644 app/Http/Controllers/Bucket/TestConnectionBucketController.php create mode 100644 app/Http/Controllers/Gwmariadb/TestGwmariadbConnectionController.php create mode 100644 app/Http/Controllers/GwmariadbController.php create mode 100644 app/Http/Controllers/PortainerController.php create mode 100644 app/Services/WebappService.php create mode 100644 docker/db/init.sql diff --git a/app/Http/Controllers/Bucket/CreateBucketController.php b/app/Http/Controllers/Bucket/CreateBucketController.php new file mode 100644 index 0000000..dc9559a --- /dev/null +++ b/app/Http/Controllers/Bucket/CreateBucketController.php @@ -0,0 +1,44 @@ +getWebappById($appId); + $siteName = explode('.', $webapp->dominio)[0]; + + $s3Client = new S3Client([ + 'version' => 'latest', + 'region'=> 'us-east-1', + 'endpoint' => env('RUSTFS_URL'), // URL interna do Docker + 'use_path_style_endpoint' => true, + 'credentials' => [ + 'key' => env('RUSTFS_KEY'), + 'secret' => env('RUSTFS_SECRET'), + ], + ]); + + try { + + $s3Client->createBucket([ + 'Bucket' => $siteName, + ]); + + $webapp->bucket_name = $siteName; + $webapp->save(); + + return redirect("/webapps/{$webapp->id}"); + } catch (\Throwable $th) { + return "Erro: ". $th; + } + } +} diff --git a/app/Http/Controllers/Bucket/DeleteBucketController.php b/app/Http/Controllers/Bucket/DeleteBucketController.php new file mode 100644 index 0000000..cab8db2 --- /dev/null +++ b/app/Http/Controllers/Bucket/DeleteBucketController.php @@ -0,0 +1,42 @@ +getWebappById($appId); + + $s3Client = new S3Client([ + 'version' => 'latest', + 'region' => 'us-east-1', + 'endpoint' => env('RUSTFS_URL'), // URL interna do Docker + 'use_path_style_endpoint' => true, + 'credentials' => [ + 'key' => env('RUSTFS_KEY'), + 'secret' => env('RUSTFS_SECRET'), + ], + ]); + + try { + $s3Client->deleteBucket([ + 'Bucket' => $webapp->dominio + ]); + + $webapp->bucket_name = null; + $webapp->save(); + + return redirect("/webapps/{$webapp->id}"); + } catch (\Throwable $th) { + return "Erro."; + } + } +} diff --git a/app/Http/Controllers/Bucket/TestConnectionBucketController.php b/app/Http/Controllers/Bucket/TestConnectionBucketController.php new file mode 100644 index 0000000..c4b209d --- /dev/null +++ b/app/Http/Controllers/Bucket/TestConnectionBucketController.php @@ -0,0 +1,17 @@ + env('GWMARIADB_TOKEN'), + ])->get(env('GWMARIADB_URL')); + + return json_encode($response->json()); + } +} diff --git a/app/Http/Controllers/GwmariadbController.php b/app/Http/Controllers/GwmariadbController.php new file mode 100644 index 0000000..d4ecb0b --- /dev/null +++ b/app/Http/Controllers/GwmariadbController.php @@ -0,0 +1,86 @@ + 'listar_databases', + ]; + + $response = Http::withHeaders([ + 'X-Token' => env('GWMARIADB_TOKEN'), + ])->post(env('GWMARIADB_URL'), $payload); + + dd($response->json()); + } + + /** + * Show the form for creating a new resource. + */ + public function create() + { + // + } + + /** + * Store a newly created resource in storage. + */ + public function store(string $appId) + { + $webapp = (new WebappService())->getWebappById($appId); + $siteName = explode('.', $webapp->dominio)[0]; + + $payload = [ + 'action' => 'criar_database_usuario_privilegio', + 'nome' => $siteName + ]; + + $response = Http::withHeaders([ + 'X-Token' => env('GWMARIADB_TOKEN'), + ])->post(env('GWMARIADB_URL'), $payload); + + return var_dump($response->json()); + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit(string $id) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, string $id) + { + // + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + // + } +} diff --git a/app/Http/Controllers/PortainerController.php b/app/Http/Controllers/PortainerController.php new file mode 100644 index 0000000..41bf661 --- /dev/null +++ b/app/Http/Controllers/PortainerController.php @@ -0,0 +1,64 @@ +post(env('GWMARIADB_URL'), $payload); dd($response->json()); - } public function rustfs($app) @@ -40,7 +39,6 @@ public function rustfs($app) $s3Client->createBucket([ 'Bucket' => $app, ]); - } public function portainer() @@ -65,7 +63,7 @@ public function portainer() $endpointId = $endpoints[0]['Id']; -$yaml = <<<'YAML' + $yaml = <<<'YAML' services: app: image: ghcr.io/fflch/sites:1.0.9 @@ -102,7 +100,5 @@ public function portainer() $response->status(), $response->json() ?: $response->body() ); - - } } diff --git a/app/Http/Controllers/WebappController.php b/app/Http/Controllers/WebappController.php index 3e7c198..7b928ef 100644 --- a/app/Http/Controllers/WebappController.php +++ b/app/Http/Controllers/WebappController.php @@ -25,6 +25,7 @@ public function create(Webapp $webapp){ public function store(WebappRequest $request){ $validated = $request->validated(); $validated['user_id'] = auth()->user()->id; + $validated['dominio'] = $validated['dominio'] . '.fflch.usp.br'; $webapp = Webapp::create($validated); diff --git a/app/Services/WebappService.php b/app/Services/WebappService.php new file mode 100644 index 0000000..1bd8b94 --- /dev/null +++ b/app/Services/WebappService.php @@ -0,0 +1,14 @@ +>>>>>> 37f4f1fc7dc8a6946a3cc032feb774abe0e9b64a + "content-hash": "ee44a3977b47a8aee987e2ceaa0cdde9", "packages": [ { "name": "aws/aws-crt-php", @@ -66,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.384.0", + "version": "3.384.5", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "6de1120aa6138e8f007c3537be86c0e64337c53b" + "reference": "c7d34f2d60515bd0c307e462268f75877842da4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6de1120aa6138e8f007c3537be86c0e64337c53b", - "reference": "6de1120aa6138e8f007c3537be86c0e64337c53b", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c7d34f2d60515bd0c307e462268f75877842da4a", + "reference": "c7d34f2d60515bd0c307e462268f75877842da4a", "shasum": "" }, "require": { @@ -157,9 +153,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.384.0" + "source": "https://github.com/aws/aws-sdk-php/tree/3.384.5" }, - "time": "2026-06-02T18:23:32+00:00" + "time": "2026-06-08T18:25:02+00:00" }, { "name": "brick/math", @@ -1016,25 +1012,26 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.10.4", + "version": "7.11.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "aec528da477062d3af11f51e6b33402be233b21f" + "reference": "5af96f374e0ab4ebd747b8310888c99d3adb0a8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aec528da477062d3af11f51e6b33402be233b21f", - "reference": "aec528da477062d3af11f51e6b33402be233b21f", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/5af96f374e0ab4ebd747b8310888c99d3adb0a8c", + "reference": "5af96f374e0ab4ebd747b8310888c99d3adb0a8c", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^2.3", - "guzzlehttp/psr7": "^2.8", + "guzzlehttp/promises": "^2.5", + "guzzlehttp/psr7": "^2.11", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.24" }, "provide": { "psr/http-client-implementation": "1.0" @@ -1043,7 +1040,7 @@ "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "guzzle/client-integration-tests": "3.0.2", - "guzzlehttp/test-server": "^0.3.2", + "guzzlehttp/test-server": "^0.5", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" @@ -1123,7 +1120,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.10.4" + "source": "https://github.com/guzzle/guzzle/tree/7.11.1" }, "funding": [ { @@ -1139,24 +1136,25 @@ "type": "tidelift" } ], - "time": "2026-05-22T19:00:53+00:00" + "time": "2026-06-07T22:54:06+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.4.1", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2" + "reference": "4360e982f87f5f258bf872d094647791db2f4c8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/09e8a212562fb1fb6a512c4156ed71525969d6c2", - "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2", + "url": "https://api.github.com/repos/guzzle/promises/zipball/4360e982f87f5f258bf872d094647791db2f4c8e", + "reference": "4360e982f87f5f258bf872d094647791db2f4c8e", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0" + "php": "^7.2.5 || ^8.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", @@ -1206,7 +1204,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.4.1" + "source": "https://github.com/guzzle/promises/tree/2.5.0" }, "funding": [ { @@ -1222,27 +1220,29 @@ "type": "tidelift" } ], - "time": "2026-05-20T22:57:30+00:00" + "time": "2026-06-02T12:23:43+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.10.2", + "version": "2.11.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "a1bbdc172f32a25fe999965b65b6e71fd87da9ed" + "reference": "bbb5e61349fa5cb822b3e87842b951088b76b81f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/a1bbdc172f32a25fe999965b65b6e71fd87da9ed", - "reference": "a1bbdc172f32a25fe999965b65b6e71fd87da9ed", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/bbb5e61349fa5cb822b3e87842b951088b76b81f", + "reference": "bbb5e61349fa5cb822b3e87842b951088b76b81f", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" + "ralouphie/getallheaders": "^3.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.24" }, "provide": { "psr/http-factory-implementation": "1.0", @@ -1323,7 +1323,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.10.2" + "source": "https://github.com/guzzle/psr7/tree/2.11.0" }, "funding": [ { @@ -1339,7 +1339,7 @@ "type": "tidelift" } ], - "time": "2026-05-25T22:58:15+00:00" + "time": "2026-06-02T12:30:48+00:00" }, { "name": "guzzlehttp/uri-template", @@ -1490,16 +1490,16 @@ }, { "name": "laravel/framework", - "version": "v12.61.0", + "version": "v12.61.1", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "1124062a1ca92d290c8bcb9b7f649920fa6816bf" + "reference": "e8472ca9774452fe50841d9bdced060679f4d58d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/1124062a1ca92d290c8bcb9b7f649920fa6816bf", - "reference": "1124062a1ca92d290c8bcb9b7f649920fa6816bf", + "url": "https://api.github.com/repos/laravel/framework/zipball/e8472ca9774452fe50841d9bdced060679f4d58d", + "reference": "e8472ca9774452fe50841d9bdced060679f4d58d", "shasum": "" }, "require": { @@ -1708,7 +1708,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-05-26T23:41:33+00:00" + "time": "2026-06-04T14:22:52+00:00" }, { "name": "laravel/prompts", @@ -4359,16 +4359,16 @@ }, { "name": "spatie/laravel-permission", - "version": "7.4.1", + "version": "7.4.2", "source": { "type": "git", "url": "https://github.com/spatie/laravel-permission.git", - "reference": "ef42ecb781e5534d368a3853fa161e420ad51397" + "reference": "15a9daf02ba02d3ae77aaa6da582708231ef999b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/ef42ecb781e5534d368a3853fa161e420ad51397", - "reference": "ef42ecb781e5534d368a3853fa161e420ad51397", + "url": "https://api.github.com/repos/spatie/laravel-permission/zipball/15a9daf02ba02d3ae77aaa6da582708231ef999b", + "reference": "15a9daf02ba02d3ae77aaa6da582708231ef999b", "shasum": "" }, "require": { @@ -4434,7 +4434,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-permission/issues", - "source": "https://github.com/spatie/laravel-permission/tree/7.4.1" + "source": "https://github.com/spatie/laravel-permission/tree/7.4.2" }, "funding": [ { @@ -4442,24 +4442,24 @@ "type": "github" } ], - "time": "2026-04-29T07:59:45+00:00" + "time": "2026-05-30T19:21:26+00:00" }, { "name": "symfony/clock", - "version": "v8.0.8", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/clock.git", - "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3" + "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/b55a638b189a6faa875e0ccdb00908fb87af95b3", - "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3", + "url": "https://api.github.com/repos/symfony/clock/zipball/701ef4de9705d6c32292ebee5e8044094a09fbf6", + "reference": "701ef4de9705d6c32292ebee5e8044094a09fbf6", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "psr/clock": "^1.0" }, "provide": { @@ -4499,7 +4499,7 @@ "time" ], "support": { - "source": "https://github.com/symfony/clock/tree/v8.0.8" + "source": "https://github.com/symfony/clock/tree/v8.1.0" }, "funding": [ { @@ -4519,7 +4519,7 @@ "type": "tidelift" } ], - "time": "2026-03-30T15:14:47+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/console", @@ -4621,20 +4621,20 @@ }, { "name": "symfony/css-selector", - "version": "v8.0.9", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "3665cfade90565430909b906394c73c8739e57d0" + "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/3665cfade90565430909b906394c73c8739e57d0", - "reference": "3665cfade90565430909b906394c73c8739e57d0", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/dc0e2be45c9b5588c82414f02ac574b4b986abcd", + "reference": "dc0e2be45c9b5588c82414f02ac574b4b986abcd", "shasum": "" }, "require": { - "php": ">=8.4" + "php": ">=8.4.1" }, "type": "library", "autoload": { @@ -4666,7 +4666,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v8.0.9" + "source": "https://github.com/symfony/css-selector/tree/v8.1.0" }, "funding": [ { @@ -4686,7 +4686,7 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:51:42+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/deprecation-contracts", @@ -4843,20 +4843,21 @@ }, { "name": "symfony/event-dispatcher", - "version": "v8.0.9", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f" + "reference": "f249ae3f680958b6f1f9dd76e5747cf0695b4102" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0c3c1a17604c4dbbec4b93fe162c538482096e1f", - "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f249ae3f680958b6f1f9dd76e5747cf0695b4102", + "reference": "f249ae3f680958b6f1f9dd76e5747cf0695b4102", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { @@ -4904,7 +4905,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.9" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.1.0" }, "funding": [ { @@ -4924,7 +4925,7 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:51:42+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -5858,16 +5859,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.38.1", + "version": "v1.38.2", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92" + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/14c5439eec4ccff081ac14eca2dc57feb2a66d92", - "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", "shasum": "" }, "require": { @@ -5919,7 +5920,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" }, "funding": [ { @@ -5939,7 +5940,7 @@ "type": "tidelift" } ], - "time": "2026-05-26T12:51:13+00:00" + "time": "2026-05-27T06:59:30+00:00" }, { "name": "symfony/polyfill-php80", @@ -6027,16 +6028,16 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.38.1", + "version": "v1.38.2", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "8339098cae28673c15cce00d80734af0453054e2" + "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2", - "reference": "8339098cae28673c15cce00d80734af0453054e2", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/796a26abb75ce49f3a84433cd81bf1009d73d5f8", + "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8", "shasum": "" }, "require": { @@ -6083,7 +6084,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.2" }, "funding": [ { @@ -6103,7 +6104,7 @@ "type": "tidelift" } ], - "time": "2026-05-26T12:51:13+00:00" + "time": "2026-05-27T06:51:48+00:00" }, { "name": "symfony/polyfill-php84", @@ -6587,20 +6588,20 @@ }, { "name": "symfony/string", - "version": "v8.0.13", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f2e3e4d33579350d1b12001ef2872f86b27ed3dc" + "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f2e3e4d33579350d1b12001ef2872f86b27ed3dc", - "reference": "f2e3e4d33579350d1b12001ef2872f86b27ed3dc", + "url": "https://api.github.com/repos/symfony/string/zipball/afd5944f4005862d961efb85c8bbd5c523c4e3c9", + "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-intl-grapheme": "^1.33", "symfony/polyfill-intl-normalizer": "^1.0", @@ -6653,7 +6654,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v8.0.13" + "source": "https://github.com/symfony/string/tree/v8.1.0" }, "funding": [ { @@ -6673,24 +6674,24 @@ "type": "tidelift" } ], - "time": "2026-05-23T18:05:53+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/translation", - "version": "v8.0.10", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67" + "reference": "b2bd012ca28c4acae830ee1206a5b6e35dd99693" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/f63e9342e12646a57c91ef8a366a4f9d8e557b67", - "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67", + "url": "https://api.github.com/repos/symfony/translation/zipball/b2bd012ca28c4acae830ee1206a5b6e35dd99693", + "reference": "b2bd012ca28c4acae830ee1206a5b6e35dd99693", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/polyfill-mbstring": "^1.0", "symfony/translation-contracts": "^3.6.1" }, @@ -6746,7 +6747,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v8.0.10" + "source": "https://github.com/symfony/translation/tree/v8.1.0" }, "funding": [ { @@ -6766,7 +6767,7 @@ "type": "tidelift" } ], - "time": "2026-05-06T11:30:54+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/translation-contracts", @@ -7116,16 +7117,16 @@ }, { "name": "uspdev/laravel-usp-theme", - "version": "2.8.30", + "version": "2.8.31", "source": { "type": "git", "url": "https://github.com/uspdev/laravel-usp-theme.git", - "reference": "a862e5ca192dd2f215f8f53dcbbfac89c8b81c2b" + "reference": "b92895d08cd3caf36fc5e4b73cadcc424919ee10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/uspdev/laravel-usp-theme/zipball/a862e5ca192dd2f215f8f53dcbbfac89c8b81c2b", - "reference": "a862e5ca192dd2f215f8f53dcbbfac89c8b81c2b", + "url": "https://api.github.com/repos/uspdev/laravel-usp-theme/zipball/b92895d08cd3caf36fc5e4b73cadcc424919ee10", + "reference": "b92895d08cd3caf36fc5e4b73cadcc424919ee10", "shasum": "" }, "require": { @@ -7163,9 +7164,9 @@ "description": "usp theme for laravel", "support": { "issues": "https://github.com/uspdev/laravel-usp-theme/issues", - "source": "https://github.com/uspdev/laravel-usp-theme/tree/2.8.30" + "source": "https://github.com/uspdev/laravel-usp-theme/tree/2.8.31" }, - "time": "2026-05-08T17:37:30+00:00" + "time": "2026-06-03T19:05:14+00:00" }, { "name": "uspdev/senhaunica-socialite", @@ -7793,16 +7794,16 @@ }, { "name": "laravel/sail", - "version": "v1.61.0", + "version": "v1.62.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "68ef35015630fe510432e63e11e21749006df688" + "reference": "3aaeefc979f8ba6586fbc5b6e0b1b3638058f98e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/68ef35015630fe510432e63e11e21749006df688", - "reference": "68ef35015630fe510432e63e11e21749006df688", + "url": "https://api.github.com/repos/laravel/sail/zipball/3aaeefc979f8ba6586fbc5b6e0b1b3638058f98e", + "reference": "3aaeefc979f8ba6586fbc5b6e0b1b3638058f98e", "shasum": "" }, "require": { @@ -7852,7 +7853,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2026-05-23T23:33:57+00:00" + "time": "2026-05-27T04:02:01+00:00" }, { "name": "mockery/mockery", @@ -8846,7 +8847,6 @@ "type": "github" } ], - "abandoned": true, "time": "2025-03-19T07:56:08+00:00" }, { @@ -8903,7 +8903,6 @@ "type": "github" } ], - "abandoned": true, "time": "2024-07-03T04:45:54+00:00" }, { @@ -9776,27 +9775,28 @@ }, { "name": "symfony/yaml", - "version": "v8.0.13", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "a1cdf99e359d5c001782a2db67a1fc71b2a5b34e" + "reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/a1cdf99e359d5c001782a2db67a1fc71b2a5b34e", - "reference": "a1cdf99e359d5c001782a2db67a1fc71b2a5b34e", + "url": "https://api.github.com/repos/symfony/yaml/zipball/efb42bd2c6f4f3ccfd4683583449938b5fc146b0", + "reference": "efb42bd2c6f4f3ccfd4683583449938b5fc146b0", "shasum": "" }, "require": { - "php": ">=8.4", + "php": ">=8.4.1", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "symfony/console": "<7.4" }, "require-dev": { - "symfony/console": "^7.4|^8.0" + "symfony/console": "^7.4|^8.0", + "yaml/yaml-test-suite": "*" }, "bin": [ "Resources/bin/yaml-lint" @@ -9827,7 +9827,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v8.0.13" + "source": "https://github.com/symfony/yaml/tree/v8.1.0" }, "funding": [ { @@ -9847,7 +9847,7 @@ "type": "tidelift" } ], - "time": "2026-05-25T06:08:44+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "theseer/tokenizer", @@ -9909,9 +9909,5 @@ "php": "^8.2" }, "platform-dev": {}, -<<<<<<< HEAD "plugin-api-version": "2.9.0" -======= - "plugin-api-version": "2.6.0" ->>>>>>> 37f4f1fc7dc8a6946a3cc032feb774abe0e9b64a } diff --git a/docker-compose.yml b/docker-compose.yml index f8a122f..498b3c8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,6 +25,8 @@ services: MYSQL_ROOT_PASSWORD: webapps networks: - webapps-network + volumes: + - ./docker/db/init.sql:/docker-entrypoint-initdb.d/init.sql selenium: image: selenium/standalone-chrome @@ -47,22 +49,37 @@ services: aliases: - auth.local -networks: - webapps-network: + gwmariadb: + image: ghcr.io/fflch/gwmariadb:latest + container_name: webapps_gwmariadb + depends_on: + - mariadb + networks: + - webapps-network + environment: + TOKEN: 123 + DB_HOST: mariadb + DB_NAME: admin + DB_USER: admin + DB_PASS: admin + DB_PORT: 3306 rustfs: - image: rustfs/rustfs:latest - container_name: webapps_rustfs - ports: - - "9100:9000" # API S3 (para enviar arquivos com PHP) - - "9101:9001" # Console Web - environment: - - RUSTFS_VOLUMES=/data - - RUSTFS_ADDRESS=0.0.0.0:9000 - - RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001 - - RUSTFS_CONSOLE_ENABLE=true - # Defina aqui as chaves de acesso para a API e o Console - - RUSTFS_ACCESS_KEY=rustfsadmin - - RUSTFS_SECRET_KEY=rustfsadmin123 - networks: - - webapps-network \ No newline at end of file + image: rustfs/rustfs:latest + container_name: webapps_rustfs + ports: + - "9100:9000" # API S3 (para enviar arquivos com PHP) + - "9101:9001" # Console Web + environment: + - RUSTFS_VOLUMES=/data + - RUSTFS_ADDRESS=0.0.0.0:9000 + - RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001 + - RUSTFS_CONSOLE_ENABLE=true + # Defina aqui as chaves de acesso para a API e o Console + - RUSTFS_ACCESS_KEY=rustfsadmin + - RUSTFS_SECRET_KEY=rustfsadmin123 + networks: + - webapps-network + +networks: + webapps-network: \ No newline at end of file diff --git a/docker/db/init.sql b/docker/db/init.sql new file mode 100644 index 0000000..eed4f13 --- /dev/null +++ b/docker/db/init.sql @@ -0,0 +1,3 @@ +CREATE USER 'admin'@'%' IDENTIFIED BY 'admin'; +GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/resources/views/webapps/partials/form.blade.php b/resources/views/webapps/partials/form.blade.php index f21a958..1a21262 100644 --- a/resources/views/webapps/partials/form.blade.php +++ b/resources/views/webapps/partials/form.blade.php @@ -1,7 +1,11 @@
- +
+ + fflch.usp.br +
+
@@ -15,7 +19,9 @@ @@ -24,11 +30,12 @@
- tipo) == 'drupal') checked @endif>Drupal + tipo) == 'drupal') checked @endif>Drupal
tipo) == 'outro_app') checked @endif>Outro app + @if (old('tipo', $webapp->tipo) == 'outro_app') checked @endif>Outro app
@@ -67,4 +74,4 @@ function toggleGithubField() { margin-top: 5px; margin-bottom: -15px; } - \ No newline at end of file + diff --git a/resources/views/webapps/show.blade.php b/resources/views/webapps/show.blade.php index 3c56859..06965cf 100644 --- a/resources/views/webapps/show.blade.php +++ b/resources/views/webapps/show.blade.php @@ -17,12 +17,14 @@ Solicitante:

{{ $webapp->user->name }}

-

Bancos de dados (Mônica) +

Bancos de dados (Mônica) + Testar conexão
Implementar: 1) Criar um banco de dados para o dominio, 2) Criar um usuário, 3) Criar uma senha para esse usuário e guardar localmente, 4) Conceder as permissões necessárias para o usuário acessar o banco de dados criado 5) Testar a conexão do app com o banco de dados criado. 6) opção de deletar o banco de dados -

Configurar Bucket (Ricardo) +

Configurar Bucket (Ricardo) + Excluir bucket Implementar: 1) Criar um bucket para o dominio (ok), 2) Criar um usuário, 3) Criar uma senha para esse usuário e guardar localmente, 4) Conceder as permissões necessárias para o usuário acessar o bucket criado 5) Testar a conexão do app com o bucket criado. 6) opção de deletar o bucket diff --git a/routes/web.php b/routes/web.php index 86f8ad9..8359541 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,8 +1,14 @@ group(function () { + Route::get('/', [GwmariadbController::class, 'index']); + Route::get('/store/{webapp}', [GwmariadbController::class, 'store']); + Route::get('/delete/{webapp}', [GwmariadbController::class, 'destroy']); + Route::get('/testconnection', TestGwmariadbConnectionController::class); +}); + +Route::prefix('bucket')->group(function() { + Route::get('/store/{webapp}', CreateBucketController::class); + Route::get('/delete/{webapp}', DeleteBucketController::class); + Route::get('/test/{webapp}', TestConnectionBucketController::class); +}); \ No newline at end of file From b4fffc2d764911c949d178da589d403916b258d7 Mon Sep 17 00:00:00 2001 From: lmarthins0 Date: Fri, 12 Jun 2026 13:15:05 -0300 Subject: [PATCH 04/10] =?UTF-8?q?desenvolvimento=20integra=C3=A7=C3=A3o=20?= =?UTF-8?q?portainer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/PortainerController.php | 94 ++++++++++++++++++- app/Http/Controllers/ReuniaoController.php | 4 +- app/Http/Controllers/WebappController.php | 33 +++++-- .../WebappDockerConfigController.php | 39 ++++++++ app/Http/Requests/WebappDockerRequest.php | 39 ++++++++ app/Models/EnvVariables.php | 10 ++ app/Models/Webapp.php | 5 + app/Services/WebappService.php | 45 ++++++++- config/laravel-usp-theme.php | 6 ++ ...6_11_110604_create_env_variables_table.php | 32 +++++++ ...13503_add_dockertag_columns_to_webapps.php | 29 ++++++ .../views/webapps/dockerconfig.blade.php | 32 +++++++ .../views/webapps/editdockerconfig.blade.php | 64 +++++++++++++ .../partials/dockerconfigform.blade.php | 16 ++++ resources/views/webapps/show.blade.php | 55 +++++++---- routes/web.php | 27 ++++-- 16 files changed, 490 insertions(+), 40 deletions(-) create mode 100644 app/Http/Controllers/WebappDockerConfigController.php create mode 100644 app/Http/Requests/WebappDockerRequest.php create mode 100644 app/Models/EnvVariables.php create mode 100644 database/migrations/2026_06_11_110604_create_env_variables_table.php create mode 100644 database/migrations/2026_06_11_113503_add_dockertag_columns_to_webapps.php create mode 100644 resources/views/webapps/dockerconfig.blade.php create mode 100644 resources/views/webapps/editdockerconfig.blade.php create mode 100644 resources/views/webapps/partials/dockerconfigform.blade.php diff --git a/app/Http/Controllers/PortainerController.php b/app/Http/Controllers/PortainerController.php index 41bf661..8a4ac63 100644 --- a/app/Http/Controllers/PortainerController.php +++ b/app/Http/Controllers/PortainerController.php @@ -2,7 +2,11 @@ namespace App\Http\Controllers; +use App\Services\WebappService; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Http; +use Symfony\Component\Yaml\Yaml; +use Symfony\Component\Yaml\Inline; class PortainerController extends Controller { @@ -11,7 +15,33 @@ class PortainerController extends Controller */ public function index() { - // + $webapp = (new WebappService())->getWebappById(2); + $yaml = [ + 'services' => [ + 'app' => [ + 'image' => '', + 'restart' => 'unless-stopped', + 'ports' => '8888:80', + 'environment' => [ + 'APP_NAME' => 'TESTE', + 'DB_CONNECION' => 'sqlite', + 'APP_KEY' => 'base64:ZoysKy3Ypf5o5aObQFDLqD1H5E9gCsQL7cGWD43Mk1U=', + 'APP_ENV' => 'local', + 'APP_DEBUG' => 'true', + 'APP_URL' => 'http://192.168.0.95:8888/', + 'USP_THEME_SKIN' => 'fflch' + ], + 'entrypoint' => [ + 'sh', + '-c', + 'php artisan migrate --force && exec apache2-foreground' + ] + ] + ] + ]; + $parsedYaml = Yaml::dump($yaml, 4, 2); + $parsedYaml = str_replace("'-c'", "-c", $parsedYaml); + dd($parsedYaml); } /** @@ -25,9 +55,67 @@ public function create() /** * Store a newly created resource in storage. */ - public function store(Request $request) + public function store(string $webappId) { - // + $webapp = (new WebappService())->getWebappById($webappId); + + $portainerUrl = env('PORTAINER_URL'); + $username = env('PORTAINER_USERNAME'); + $password = env('PORTAINER_PASSWORD'); + + $auth = Http::post( + "{$portainerUrl}/api/auth", + [ + 'username' => $username, + 'password' => $password, + ] + ); + + $jwt = $auth->json('jwt'); + + $endpoints = Http::withToken($jwt) + ->get("{$portainerUrl}/api/endpoints") + ->json(); + $endpointId = $endpoints[0]['Id']; + + + $yaml = <<docker_tag}:{$webapp->tag_version} + restart: unless-stopped + ports: + - "8888:80" + environment: + APP_NAME: "TESTE" + DB_CONNECTION: "sqlite" + APP_KEY: "base64:ZoysKy3Ypf5o5aObQFDLqD1H5E9gCsQL7cGWD43Mk1U=" + APP_ENV: "local" + APP_DEBUG: "true" + APP_URL: "http://192.168.0.95:8888/" + USP_THEME_SKIN: "fflch" + entrypoint: + - sh + - -c + - | + php artisan migrate --force + exec apache2-foreground +YAML; + + + $response = Http::withToken($jwt) + ->post( + "{$portainerUrl}/api/stacks/create/standalone/string?endpointId={$endpointId}", + [ + 'Name' => 'sites', + 'StackFileContent' => $yaml, + ] + ); + + dd( + $response->status(), + $response->json() ?: $response->body() + ); } /** diff --git a/app/Http/Controllers/ReuniaoController.php b/app/Http/Controllers/ReuniaoController.php index d639760..5fb670a 100644 --- a/app/Http/Controllers/ReuniaoController.php +++ b/app/Http/Controllers/ReuniaoController.php @@ -63,10 +63,10 @@ public function portainer() $endpointId = $endpoints[0]['Id']; - $yaml = <<<'YAML' + $yaml = << $webapps]); } - - public function show(Webapp $webapp){ - return view('webapps.show', ['webapp' => $webapp]); + + public function show(Webapp $webapp) + { + //dd(($webapp->envVariables()->whereNotNull('value')->get()->isEmpty())); + if ($webapp->docker_tag == NULL && $webapp->tag_version == NULL): + $dockerStatus = 'not_configured'; + elseif ($webapp->docker_tag == NULL || $webapp->tag_version == NULL || empty($webapp->envVariables()->whereNotNull('value')->get())): + $dockerStatus = 'partial_configured'; + else: + $dockerStatus = 'configured'; + endif; + + $dockerStatus; + return view('webapps.show', [ + 'webapp' => $webapp, + 'dockerStatus' => $dockerStatus + ]); } - public function create(Webapp $webapp){ + public function create(Webapp $webapp) + { return view('webapps.create', ['webapp' => $webapp]); } - public function store(WebappRequest $request){ + public function store(WebappRequest $request) + { $validated = $request->validated(); $validated['user_id'] = auth()->user()->id; $validated['dominio'] = $validated['dominio'] . '.fflch.usp.br'; $webapp = Webapp::create($validated); - - session()->flash('alert-success','Solicitação enviada com sucesso. Aguarde a análise de um administrador'); + + session()->flash('alert-success', 'Solicitação enviada com sucesso. Aguarde a análise de um administrador'); return redirect('/'); } } diff --git a/app/Http/Controllers/WebappDockerConfigController.php b/app/Http/Controllers/WebappDockerConfigController.php new file mode 100644 index 0000000..71cf8f9 --- /dev/null +++ b/app/Http/Controllers/WebappDockerConfigController.php @@ -0,0 +1,39 @@ + $webapp + ]); + } + + public function store(WebappDockerRequest $request, Webapp $webapp) + { + (new WebappService())->setWebappDockerConfig($webapp, $request->validated()); + + return redirect("/webapps/{$webapp->id}"); + } + + public function edit(Webapp $webapp) + { + //dd($webapp->envVariables); + return view('webapps.editdockerconfig', [ + 'webapp' => $webapp, + ]); + } + + public function update(WebappDockerRequest $request, Webapp $webapp) + { + $webapp = (new WebappService())->updateWebappDockerConfig($webapp, $request->validated()); + return redirect("/webapps/{$webapp->id}/docker/edit"); + } +} diff --git a/app/Http/Requests/WebappDockerRequest.php b/app/Http/Requests/WebappDockerRequest.php new file mode 100644 index 0000000..abfe898 --- /dev/null +++ b/app/Http/Requests/WebappDockerRequest.php @@ -0,0 +1,39 @@ +|string> + */ + public function rules(): array + { + return [ + 'docker_tag' => 'required|string', + 'tag_version' => 'required|string', + 'env_variables' => 'required|string' + ]; + } + + public function messages(){ + return [ + 'docker_tag.required' => 'A tag docker é obrigatória.', + 'tag_version.required' => 'A versão da tag é obrigatória.', + 'env_variables.required' => 'As variáveis de ambiente são obrigatórias.', + ]; + } +} diff --git a/app/Models/EnvVariables.php b/app/Models/EnvVariables.php new file mode 100644 index 0000000..fe8017e --- /dev/null +++ b/app/Models/EnvVariables.php @@ -0,0 +1,10 @@ +belongsTo(User::class, 'user_id'); } + public function envVariables() + { + return $this->hasMany(EnvVariables::class); + } + } diff --git a/app/Services/WebappService.php b/app/Services/WebappService.php index 1bd8b94..2bdd948 100644 --- a/app/Services/WebappService.php +++ b/app/Services/WebappService.php @@ -2,13 +2,54 @@ namespace App\Services; +use App\Models\EnvVariables; use App\Models\Webapp; -class WebappService +class WebappService { function getWebappById(string $webappId): Webapp { $webapp = Webapp::find($webappId); return $webapp; } -} \ No newline at end of file + + function setWebappDockerConfig(Webapp $webapp, array $dockerData) + { + $webapp->docker_tag = $dockerData['docker_tag']; + $webapp->tag_version = $dockerData['tag_version']; + $webapp->save(); + + $env_variables = explode(',', $dockerData['env_variables']); + foreach ($env_variables as $env_variable): + EnvVariables::create([ + 'name' => $env_variable, + 'webapp_id' => $webapp->id + ]); + endforeach; + } + + function updateWebappDockerConfig(Webapp $webapp, array $dockerData): Webapp + { + $webapp->docker_tag = $dockerData['docker_tag']; + $webapp->tag_version = $dockerData['tag_version']; + $webapp->save(); + + $env_variables = json_decode($dockerData['env_variables']); + foreach ($env_variables as $env_variable): + if (EnvVariables::where('webapp_id', $webapp->id)->where('name', $env_variable->name)->exists() == false): + EnvVariables::create([ + 'name' => $env_variable->name, + 'value'=> $env_variable->value, + 'webapp_id' => $webapp->id + ]); + elseif (EnvVariables::where('webapp_id', $webapp->id)->where('name', $env_variable->name)->exists() == true): + $variable_to_update = EnvVariables::where('webapp_id', $webapp->id)->where('name', $env_variable->name)->first(); + $variable_to_update->update([ + 'value' => $env_variable->value + ]); + endif; + endforeach; + + return $webapp; + } +} diff --git a/config/laravel-usp-theme.php b/config/laravel-usp-theme.php index fa68f26..9975daa 100644 --- a/config/laravel-usp-theme.php +++ b/config/laravel-usp-theme.php @@ -19,6 +19,12 @@ 'url' => config('app.url') . '/webapps/create', // com caminho absoluto 'can' => 'user', ], + [ + 'text' => 'Dockers', + 'docker_menu' => [ + 'criar novo docker' => '/' + ] + ] ]; diff --git a/database/migrations/2026_06_11_110604_create_env_variables_table.php b/database/migrations/2026_06_11_110604_create_env_variables_table.php new file mode 100644 index 0000000..1a2472c --- /dev/null +++ b/database/migrations/2026_06_11_110604_create_env_variables_table.php @@ -0,0 +1,32 @@ +id(); + + $table->foreignId('webapp_id')->constrained(); + $table->string('name'); + $table->string('value')->nullable(); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('env_variables'); + } +}; diff --git a/database/migrations/2026_06_11_113503_add_dockertag_columns_to_webapps.php b/database/migrations/2026_06_11_113503_add_dockertag_columns_to_webapps.php new file mode 100644 index 0000000..da38cce --- /dev/null +++ b/database/migrations/2026_06_11_113503_add_dockertag_columns_to_webapps.php @@ -0,0 +1,29 @@ +string('docker_tag')->nullable(); + $table->string('tag_version')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('webapps', function (Blueprint $table) { + // + }); + } +}; diff --git a/resources/views/webapps/dockerconfig.blade.php b/resources/views/webapps/dockerconfig.blade.php new file mode 100644 index 0000000..580eabe --- /dev/null +++ b/resources/views/webapps/dockerconfig.blade.php @@ -0,0 +1,32 @@ +@extends('laravel-usp-theme::master') +@section('content') +
+
+

{{ $webapp->dominio }}

+

Configurar docker:

+
+
+
+ @method('post') + @csrf +
+ tag docker: + +
+
+ versão da tag: + +
+
+
+ Variáveis de ambiente: + +
+
Separe cara variável apenas por uma vírgula.
+
+ + +
+
+
+@endsection diff --git a/resources/views/webapps/editdockerconfig.blade.php b/resources/views/webapps/editdockerconfig.blade.php new file mode 100644 index 0000000..93a68c0 --- /dev/null +++ b/resources/views/webapps/editdockerconfig.blade.php @@ -0,0 +1,64 @@ +@extends('laravel-usp-theme::master') +@section('content') +
+
+

{{ $webapp->dominio }}

+

Atualizar configuração docker:

+
+
+
+ @method('put') + @csrf +
+ tag docker: + +
+
+ versão da tag: + +
+
+ @if ($webapp->envVariables) + @foreach ($webapp->envVariables as $env_variable) +
+ {{ $env_variable->name }}: + name }} type="text" + class="form-control w-50" value={{ old('value', $env_variable->value) }}> +
+ @endforeach + @endif +
+ + + +
+
+
+@endsection + +@section('javascripts_bottom') + +@endsection('javascripts_bottom') diff --git a/resources/views/webapps/partials/dockerconfigform.blade.php b/resources/views/webapps/partials/dockerconfigform.blade.php new file mode 100644 index 0000000..fdd37ae --- /dev/null +++ b/resources/views/webapps/partials/dockerconfigform.blade.php @@ -0,0 +1,16 @@ +
+ tag docker: + +
+
+ versão da tag: + +
+
+
+ Variáveis de ambiente: + +
+
Separe cara variável apenas por uma vírgula.
+
+ diff --git a/resources/views/webapps/show.blade.php b/resources/views/webapps/show.blade.php index 06965cf..2f65907 100644 --- a/resources/views/webapps/show.blade.php +++ b/resources/views/webapps/show.blade.php @@ -1,8 +1,7 @@ @extends('laravel-usp-theme::master') -@section("content") +@section('content') +

{{ $webapp->dominio }}

-

{{ $webapp->dominio }}

- Justificativa:

{{ $webapp->justificativa }}

Tipo de solicitação: @@ -10,26 +9,50 @@ @if ($webapp->url_github) Repositório Github:

{{ $webapp->url_github }} Tag: - {{ $webapp->version ?? 'não informado'}}

+ {{ $webapp->version ?? 'não informado' }}

@endif Status:

{{ $webapp->status }}

Solicitante:

{{ $webapp->user->name }}

-

Bancos de dados (Mônica) - Testar conexão -
- Implementar: 1) Criar um banco de dados para o dominio, 2) Criar um usuário, 3) Criar uma senha para esse usuário e guardar localmente, 4) Conceder as permissões necessárias para o usuário acessar o banco de dados criado 5) Testar a conexão do app com o banco de dados criado. 6) opção de deletar o banco de dados + @switch($dockerStatus) + @case('not_configured') +

Cadastre a imagem docker e as variáveis de ambiente do app antes de configurar banco de dados, bucket e docker.

+ + Preparar docker + @break + + @case('partial_configured') +

Antes de criar o docker, banco de dados e bucket, os dados de configuração do docker devem estar todos + preenchidos. Verifique se todas as variáveis de ambiente, a tag da imagem e a versão da imagem estão + configuradas corretamente.

+ Configurações docker + @break + + @case('configured') + +

Configurar Docker (Augusto) + Editar configurações +
+ Implementar: 1) Model para variavéis de ambiente, 2) Escolher a tag do deploy 3) Configurar o serviço para usar as + variáveis de ambiente necessárias + +

Bancos de dados (Mônica) + Testar conexão +
+ Implementar: 1) Criar um banco de dados para o dominio, 2) Criar um usuário, 3) Criar uma senha para esse usuário e + guardar localmente, 4) Conceder as permissões necessárias para o usuário acessar o banco de dados criado 5) Testar a + conexão do app com o banco de dados criado. 6) opção de deletar o banco de dados -

Configurar Bucket (Ricardo) - Excluir bucket - Implementar: 1) Criar um bucket para o dominio (ok), 2) Criar um usuário, 3) Criar uma senha para esse usuário e guardar localmente, 4) Conceder as permissões necessárias para o usuário acessar o bucket criado 5) Testar a conexão do app com o bucket criado. 6) opção de deletar o bucket - +

Configurar Bucket (Ricardo) + Excluir bucket + Implementar: 1) Criar um bucket para o dominio (ok), 2) Criar um usuário, 3) Criar uma senha para esse usuário e + guardar localmente, 4) Conceder as permissões necessárias para o usuário acessar o bucket criado 5) Testar a conexão + do app com o bucket criado. 6) opção de deletar o bucket -

Configurar Docker (Augusto) - Implementar: 1) Model para variavéis de ambiente, 2) Escolher a tag do deploy 3) Configurar o serviço para usar as variáveis de ambiente necessárias - -@endsection \ No newline at end of file + @default + @endswitch + @endsection diff --git a/routes/web.php b/routes/web.php index 8359541..aab494e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,6 +1,5 @@ group(function() { + Route::get('/', [WebappController::class, 'index']); + Route::get('/create', [WebappController::class, 'create']); + Route::post('/store', [WebappController::class, 'store']); + Route::get('/{webapp}', [WebappController::class, 'show']); + Route::get('/{webapp}/docker/create', [WebappDockerConfigController::class, 'create']); + Route::get('/{webapp}/docker/edit', [WebappDockerConfigController::class, 'edit']); + Route::post('/{webapp}/docker', [WebappDockerConfigController::class, 'store']); + Route::put('/{webapp}/docker/update', [WebappDockerConfigController::class, 'update']); +}); # reunião //Route::get('/portainer', [ReuniaoController::class, 'portainer']); @@ -27,7 +30,7 @@ //Route::get('/rustfs/{app}', [ReuniaoController::class, 'rustfs']); #Route::resource('gwmariadb', GwmariadbController::class); -Route::resource('portainer', PortainerController::class); +#Route::resource('portainer', PortainerController::class); Route::prefix('gwmariadb')->group(function () { Route::get('/', [GwmariadbController::class, 'index']); @@ -40,4 +43,10 @@ Route::get('/store/{webapp}', CreateBucketController::class); Route::get('/delete/{webapp}', DeleteBucketController::class); Route::get('/test/{webapp}', TestConnectionBucketController::class); +}); + +Route::prefix('portainer')->group(function() { + Route::get('/', [PortainerController::class, 'index']); + Route::get('/store', [PortainerController::class, 'store']); + Route::get('/update', [PortainerController::class, 'update']); }); \ No newline at end of file From 09a5983926d74ec76af1745e69f2404ee3ea07a8 Mon Sep 17 00:00:00 2001 From: lmarthins0 Date: Wed, 17 Jun 2026 13:26:22 -0300 Subject: [PATCH 05/10] =?UTF-8?q?desenvolvimento=20da=20integra=C3=A7?= =?UTF-8?q?=C3=A3o=20com=20o=20portainer=20para=20subir=20as=20aplica?= =?UTF-8?q?=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/DockerImageController.php | 59 +++++++ app/Http/Controllers/PortainerController.php | 160 +++++++++++++----- app/Http/Controllers/WebappController.php | 4 +- .../WebappDockerConfigController.php | 48 +++++- app/Http/Requests/DockerImageRequest.php | 41 +++++ .../Requests/DockerImageUpdateRequest.php | 39 +++++ .../Requests/WebappDockerImageRequest.php | 29 ++++ app/Http/Requests/WebappDockerRequest.php | 4 - app/Models/DockerImage.php | 10 ++ app/Models/Webapp.php | 5 + app/Services/DockerImageService.php | 57 +++++++ app/Services/WebappService.php | 19 +-- config/laravel-usp-theme.php | 18 +- ...6_15_150442_create_docker_images_table.php | 31 ++++ ...5_151114_add_image_id_column_to_webapp.php | 28 +++ ...155408_add_stack_id_column_to_webapps.php} | 3 +- resources/views/dockerimages/create.blade.php | 34 ++++ .../edit.blade.php} | 24 +-- resources/views/dockerimages/index.blade.php | 16 ++ resources/views/dockerimages/show.blade.php | 21 +++ resources/views/webapps/dockerimage.blade.php | 35 ++++ ...onfig.blade.php => envvariables.blade.php} | 29 +--- .../partials/dockerconfigform.blade.php | 16 -- resources/views/webapps/show.blade.php | 69 ++++---- routes/web.php | 15 +- 25 files changed, 650 insertions(+), 164 deletions(-) create mode 100644 app/Http/Controllers/DockerImageController.php create mode 100644 app/Http/Requests/DockerImageRequest.php create mode 100644 app/Http/Requests/DockerImageUpdateRequest.php create mode 100644 app/Http/Requests/WebappDockerImageRequest.php create mode 100644 app/Models/DockerImage.php create mode 100644 app/Services/DockerImageService.php create mode 100644 database/migrations/2026_06_15_150442_create_docker_images_table.php create mode 100644 database/migrations/2026_06_15_151114_add_image_id_column_to_webapp.php rename database/migrations/{2026_06_11_113503_add_dockertag_columns_to_webapps.php => 2026_06_17_155408_add_stack_id_column_to_webapps.php} (82%) create mode 100644 resources/views/dockerimages/create.blade.php rename resources/views/{webapps/dockerconfig.blade.php => dockerimages/edit.blade.php} (52%) create mode 100644 resources/views/dockerimages/index.blade.php create mode 100644 resources/views/dockerimages/show.blade.php create mode 100644 resources/views/webapps/dockerimage.blade.php rename resources/views/webapps/{editdockerconfig.blade.php => envvariables.blade.php} (60%) delete mode 100644 resources/views/webapps/partials/dockerconfigform.blade.php diff --git a/app/Http/Controllers/DockerImageController.php b/app/Http/Controllers/DockerImageController.php new file mode 100644 index 0000000..958dca1 --- /dev/null +++ b/app/Http/Controllers/DockerImageController.php @@ -0,0 +1,59 @@ +getAllDockerImages(); + return view('dockerimages.index', [ + 'docker_images' => $dockerImages + ]); + } + + public function show(DockerImage $dockerimage) + { + return view('dockerimages.show', [ + 'docker_image' => $dockerimage + ]); + } + + public function create() + { + return view('dockerimages.create'); + } + + public function store(DockerImageRequest $request) + { + $dockerImage = (new DockerImageService())->createDockerImage($request->validated()); + return redirect("/dockerimages/{$dockerImage->id}"); + } + + public function edit(DockerImage $dockerimage) + { + return view('dockerimages.edit', [ + 'docker_image' => $dockerimage + ]); + } + + public function update(DockerImageUpdateRequest $request, DockerImage $dockerimage) + { + $dockerImage = (new DockerImageService())->updateDockerImage($dockerimage, $request->validated()); + return redirect("/dockerimages/{$dockerImage->id}"); + } + + public function destroy(DockerImage $dockerimage) + { + $deleted = (new DockerImageService())->destroyDockerImage($dockerimage); + + if($deleted) { + return redirect("/dockerimages"); + } + } +} diff --git a/app/Http/Controllers/PortainerController.php b/app/Http/Controllers/PortainerController.php index 8a4ac63..78d14db 100644 --- a/app/Http/Controllers/PortainerController.php +++ b/app/Http/Controllers/PortainerController.php @@ -2,11 +2,11 @@ namespace App\Http\Controllers; +use App\Services\DockerImageService; use App\Services\WebappService; use Illuminate\Http\Request; use Illuminate\Support\Facades\Http; use Symfony\Component\Yaml\Yaml; -use Symfony\Component\Yaml\Inline; class PortainerController extends Controller { @@ -15,30 +15,31 @@ class PortainerController extends Controller */ public function index() { - $webapp = (new WebappService())->getWebappById(2); + $webapp = (new WebappService())->getWebappById(1); + $dockerImage = $webapp->dockerImage; + $env_variables = $webapp->envVariables; + + $environment = []; + foreach ($env_variables as $env_variable): + $environment[$env_variable->name] = $env_variable->value; + endforeach; + $yaml = [ 'services' => [ 'app' => [ - 'image' => '', + 'image' => "{$dockerImage->path}:{$dockerImage->tag}", 'restart' => 'unless-stopped', 'ports' => '8888:80', - 'environment' => [ - 'APP_NAME' => 'TESTE', - 'DB_CONNECION' => 'sqlite', - 'APP_KEY' => 'base64:ZoysKy3Ypf5o5aObQFDLqD1H5E9gCsQL7cGWD43Mk1U=', - 'APP_ENV' => 'local', - 'APP_DEBUG' => 'true', - 'APP_URL' => 'http://192.168.0.95:8888/', - 'USP_THEME_SKIN' => 'fflch' - ], + 'environment' => $environment, 'entrypoint' => [ - 'sh', - '-c', + 'sh', + '-c', 'php artisan migrate --force && exec apache2-foreground' ] ] ] ]; + $parsedYaml = Yaml::dump($yaml, 4, 2); $parsedYaml = str_replace("'-c'", "-c", $parsedYaml); dd($parsedYaml); @@ -58,6 +59,8 @@ public function create() public function store(string $webappId) { $webapp = (new WebappService())->getWebappById($webappId); + $dockerImage = $webapp->dockerImage; + $webappName = explode('.', $webapp->dominio)[0]; $portainerUrl = env('PORTAINER_URL'); $username = env('PORTAINER_USERNAME'); @@ -79,43 +82,48 @@ public function store(string $webappId) $endpointId = $endpoints[0]['Id']; - $yaml = <<docker_tag}:{$webapp->tag_version} - restart: unless-stopped - ports: - - "8888:80" - environment: - APP_NAME: "TESTE" - DB_CONNECTION: "sqlite" - APP_KEY: "base64:ZoysKy3Ypf5o5aObQFDLqD1H5E9gCsQL7cGWD43Mk1U=" - APP_ENV: "local" - APP_DEBUG: "true" - APP_URL: "http://192.168.0.95:8888/" - USP_THEME_SKIN: "fflch" - entrypoint: - - sh - - -c - - | - php artisan migrate --force - exec apache2-foreground -YAML; + $env_variables = $webapp->envVariables; + $environment = []; + foreach ($env_variables as $env_variable): + $environment[$env_variable->name] = $env_variable->value; + endforeach; + + $yaml = [ + 'services' => [ + 'app' => [ + 'image' => "{$dockerImage->path}:{$dockerImage->tag}", + 'restart' => 'unless-stopped', + 'ports' => ['8888:80'], + 'environment' => $environment, + 'entrypoint' => [ + 'sh', + '-c', + 'php artisan migrate --force && exec apache2-foreground' + ] + ] + ] + ]; + $parsedYaml = Yaml::dump($yaml, 4, 2); + $parsedYaml = str_replace("'-c'", "-c", $parsedYaml); $response = Http::withToken($jwt) ->post( "{$portainerUrl}/api/stacks/create/standalone/string?endpointId={$endpointId}", [ - 'Name' => 'sites', - 'StackFileContent' => $yaml, + 'Name' => $webappName, + 'StackFileContent' => $parsedYaml, ] ); - dd( - $response->status(), - $response->json() ?: $response->body() - ); + $responseDecoded = $response->json(); + $webapp->status = "Publicado"; + $webapp->stackId = $responseDecoded['Id']; + $webapp->save(); + + return redirect("/webapps/{$webapp->id}"); + + //dd($response->status(), $response->json() ?: $response->body()); } /** @@ -137,9 +145,73 @@ public function edit(string $id) /** * Update the specified resource in storage. */ - public function update(Request $request, string $id) + public function update(string $webappId) { - // + $webapp = (new WebappService())->getWebappById($webappId); + $dockerImage = $webapp->dockerImage; + $stackId = $webapp->stackId; + $webappName = explode('.', $webapp->dominio)[0]; + + $portainerUrl = env('PORTAINER_URL'); + $username = env('PORTAINER_USERNAME'); + $password = env('PORTAINER_PASSWORD'); + + $auth = Http::post( + "{$portainerUrl}/api/auth", + [ + 'username' => $username, + 'password' => $password, + ] + ); + + $jwt = $auth->json('jwt'); + + $endpoints = Http::withToken($jwt) + ->get("{$portainerUrl}/api/endpoints") + ->json(); + $endpointId = $endpoints[0]['Id']; + + + $env_variables = $webapp->envVariables; + $environment = []; + foreach ($env_variables as $env_variable): + $environment[$env_variable->name] = $env_variable->value; + endforeach; + + $yaml = [ + 'services' => [ + 'app' => [ + 'image' => "{$dockerImage->path}:{$dockerImage->tag}", + 'restart' => 'unless-stopped', + 'ports' => ['8888:80'], + 'environment' => $environment, + 'entrypoint' => [ + 'sh', + '-c', + 'php artisan migrate --force && exec apache2-foreground' + ] + ] + ] + ]; + + $parsedYaml = Yaml::dump($yaml, 4, 2); + $parsedYaml = str_replace("'-c'", "-c", $parsedYaml); + + $response = Http::withToken($jwt) + ->put( + "{$portainerUrl}/api/stacks/{$stackId}?endpointId={$endpointId}", + [ + 'Name' => $webappName, + 'StackFileContent' => $parsedYaml, + ] + ); + + return redirect("/webapps/{$webapp->id}"); + + dd( + $response->status(), + $response->json() ?: $response->body() + ); } /** diff --git a/app/Http/Controllers/WebappController.php b/app/Http/Controllers/WebappController.php index adc8e1a..70f9593 100644 --- a/app/Http/Controllers/WebappController.php +++ b/app/Http/Controllers/WebappController.php @@ -17,10 +17,8 @@ public function index() public function show(Webapp $webapp) { //dd(($webapp->envVariables()->whereNotNull('value')->get()->isEmpty())); - if ($webapp->docker_tag == NULL && $webapp->tag_version == NULL): + if ($webapp->docker_image_id == NULL): $dockerStatus = 'not_configured'; - elseif ($webapp->docker_tag == NULL || $webapp->tag_version == NULL || empty($webapp->envVariables()->whereNotNull('value')->get())): - $dockerStatus = 'partial_configured'; else: $dockerStatus = 'configured'; endif; diff --git a/app/Http/Controllers/WebappDockerConfigController.php b/app/Http/Controllers/WebappDockerConfigController.php index 71cf8f9..dd88429 100644 --- a/app/Http/Controllers/WebappDockerConfigController.php +++ b/app/Http/Controllers/WebappDockerConfigController.php @@ -2,38 +2,70 @@ namespace App\Http\Controllers; +use App\Http\Requests\WebappDockerImageRequest; use App\Models\Webapp; use App\Http\Requests\WebappDockerRequest; use App\Models\EnvVariables; +use App\Services\DockerImageService; use App\Services\WebappService; +use Illuminate\database\Eloquent\Collection; class WebappDockerConfigController extends Controller { public function create(Webapp $webapp) { - return view('webapps.dockerconfig', [ - 'webapp' => $webapp + $dockerImages = (new DockerImageService())->getAllDockerImages(); + return view('webapps.dockerimage', [ + 'webapp' => $webapp, + 'docker_images' => $dockerImages ]); } - public function store(WebappDockerRequest $request, Webapp $webapp) + public function store(WebappDockerImageRequest $request, Webapp $webapp) { - (new WebappService())->setWebappDockerConfig($webapp, $request->validated()); + (new WebappService())->setWebappDockerImage($webapp, $request->validated()); return redirect("/webapps/{$webapp->id}"); } public function edit(Webapp $webapp) { - //dd($webapp->envVariables); - return view('webapps.editdockerconfig', [ + $image_env_variables = (new DockerImageService())->getImageEnvVariables($webapp->docker_image_id); + $webapp_env_variables = EnvVariables::where('webapp_id', $webapp->id)->get(); + $env_variables = $this->mergeActiveEnvVariablesWebappAndDockerImage($webapp_env_variables, $image_env_variables); + //dd($image_env_variables, $webapp_env_variables, $env_variables); + return view('webapps.envvariables', [ 'webapp' => $webapp, + 'env_variables' => $env_variables ]); } public function update(WebappDockerRequest $request, Webapp $webapp) { - $webapp = (new WebappService())->updateWebappDockerConfig($webapp, $request->validated()); - return redirect("/webapps/{$webapp->id}/docker/edit"); + $webapp = (new WebappService())->setWebappEnvVariables($webapp, $request->validated()); + return redirect("/webapps/{$webapp->id}"); + } + + protected function mergeActiveEnvVariablesWebappAndDockerImage(mixed $webapp_env_variables, array $image_env_variables) + { + $env_variables = []; + if($webapp_env_variables) { + foreach ($webapp_env_variables as $webapp_variable) { + if (in_array($webapp_variable->name, $image_env_variables, true)) { + $env_variable['name'] = $webapp_variable->name; + $env_variable['value'] = $webapp_variable->value; + $env_variables[] = $env_variable; + $image_env_variables = array_diff($image_env_variables, [$image_env_variables[array_search($webapp_variable->name, $image_env_variables, true)]]); + } + } + } + + foreach ($image_env_variables as $image_variable) { + $env_variable['name'] = $image_variable; + $env_variable['value'] = null; + $env_variables[] = $env_variable; + } + + return $env_variables; } } diff --git a/app/Http/Requests/DockerImageRequest.php b/app/Http/Requests/DockerImageRequest.php new file mode 100644 index 0000000..8cc143d --- /dev/null +++ b/app/Http/Requests/DockerImageRequest.php @@ -0,0 +1,41 @@ +|string> + */ + public function rules(): array + { + return [ + 'name' => 'required|string', + 'path' => 'required|string', + 'tag' => 'required|string', + 'env_variables' => 'required|string' + ]; + } + + public function messages(){ + return [ + 'name.required' => 'O nome da imagem é obrigatório.', + 'path.required' => 'A tag docker é obrigatória.', + 'tag.required' => 'A versão da tag é obrigatória.', + 'env_variables.required' => 'As variáveis de ambiente são obrigatórias.', + ]; + } +} diff --git a/app/Http/Requests/DockerImageUpdateRequest.php b/app/Http/Requests/DockerImageUpdateRequest.php new file mode 100644 index 0000000..8ec19e3 --- /dev/null +++ b/app/Http/Requests/DockerImageUpdateRequest.php @@ -0,0 +1,39 @@ +|string> + */ + public function rules(): array + { + return [ + 'path' => 'required|string', + 'tag' => 'required|string', + 'env_variables' => 'required|string' + ]; + } + + public function messages(){ + return [ + 'path.required' => 'A tag docker é obrigatória.', + 'tag.required' => 'A versão da tag é obrigatória.', + 'env_variables.required' => 'As variáveis de ambiente são obrigatórias.', + ]; + } +} diff --git a/app/Http/Requests/WebappDockerImageRequest.php b/app/Http/Requests/WebappDockerImageRequest.php new file mode 100644 index 0000000..2ecc507 --- /dev/null +++ b/app/Http/Requests/WebappDockerImageRequest.php @@ -0,0 +1,29 @@ +|string> + */ + public function rules(): array + { + return [ + 'docker_image' => 'required' + ]; + } +} diff --git a/app/Http/Requests/WebappDockerRequest.php b/app/Http/Requests/WebappDockerRequest.php index abfe898..7b8b2af 100644 --- a/app/Http/Requests/WebappDockerRequest.php +++ b/app/Http/Requests/WebappDockerRequest.php @@ -23,16 +23,12 @@ public function authorize(): bool public function rules(): array { return [ - 'docker_tag' => 'required|string', - 'tag_version' => 'required|string', 'env_variables' => 'required|string' ]; } public function messages(){ return [ - 'docker_tag.required' => 'A tag docker é obrigatória.', - 'tag_version.required' => 'A versão da tag é obrigatória.', 'env_variables.required' => 'As variáveis de ambiente são obrigatórias.', ]; } diff --git a/app/Models/DockerImage.php b/app/Models/DockerImage.php new file mode 100644 index 0000000..b920c94 --- /dev/null +++ b/app/Models/DockerImage.php @@ -0,0 +1,10 @@ +hasMany(EnvVariables::class); } + public function dockerImage() + { + return $this->belongsTo(DockerImage::class); + } + } diff --git a/app/Services/DockerImageService.php b/app/Services/DockerImageService.php new file mode 100644 index 0000000..2fce7d9 --- /dev/null +++ b/app/Services/DockerImageService.php @@ -0,0 +1,57 @@ +env_variables); + return $env_variables; + } + + function createDockerImage(array $dockerImageData) + { + $dockerImage = new DockerImage(); + $dockerImage->name = $dockerImageData['name']; + $dockerImage->path = $dockerImageData['path']; + $dockerImage->tag = $dockerImageData['tag']; + $dockerImage->env_variables = $dockerImageData['env_variables']; + $dockerImage->save(); + + return $dockerImage; + } + + function updateDockerImage(DockerImage $dockerImage, array $dockerImageData): DockerImage + { + $dockerImage->update([ + 'path' => $dockerImageData['path'], + 'tag' => $dockerImageData['tag'], + 'env_variables' => $dockerImageData['env_variables'] + ]); + + return $dockerImage; + } + + function destroyDockerImage(DockerImage $dockerImage) + { + $dockerImage->delete(); + + return true; + } +} \ No newline at end of file diff --git a/app/Services/WebappService.php b/app/Services/WebappService.php index 2bdd948..74b04ce 100644 --- a/app/Services/WebappService.php +++ b/app/Services/WebappService.php @@ -13,27 +13,16 @@ function getWebappById(string $webappId): Webapp return $webapp; } - function setWebappDockerConfig(Webapp $webapp, array $dockerData) + function setWebappDockerImage(Webapp $webapp, array $dockerData) { - $webapp->docker_tag = $dockerData['docker_tag']; - $webapp->tag_version = $dockerData['tag_version']; + $webapp->docker_image_id = $dockerData['docker_image']; $webapp->save(); - $env_variables = explode(',', $dockerData['env_variables']); - foreach ($env_variables as $env_variable): - EnvVariables::create([ - 'name' => $env_variable, - 'webapp_id' => $webapp->id - ]); - endforeach; + return $webapp; } - function updateWebappDockerConfig(Webapp $webapp, array $dockerData): Webapp + function setWebappEnvVariables(Webapp $webapp, array $dockerData): Webapp { - $webapp->docker_tag = $dockerData['docker_tag']; - $webapp->tag_version = $dockerData['tag_version']; - $webapp->save(); - $env_variables = json_decode($dockerData['env_variables']); foreach ($env_variables as $env_variable): if (EnvVariables::where('webapp_id', $webapp->id)->where('name', $env_variable->name)->exists() == false): diff --git a/config/laravel-usp-theme.php b/config/laravel-usp-theme.php index 9975daa..9bf3e95 100644 --- a/config/laravel-usp-theme.php +++ b/config/laravel-usp-theme.php @@ -1,5 +1,16 @@ 'Imagens', + 'url' => '/dockerimages' + ], + [ + 'text' => 'Cadastrar nova imagem', + 'url' => '/dockerimages/create' + ] +]; + $menu = [ [ 'text' => ' Home', @@ -20,10 +31,9 @@ 'can' => 'user', ], [ - 'text' => 'Dockers', - 'docker_menu' => [ - 'criar novo docker' => '/' - ] + 'text' => 'Docker', + 'can' => 'admin', + 'submenu' => $dockerMenu ] ]; diff --git a/database/migrations/2026_06_15_150442_create_docker_images_table.php b/database/migrations/2026_06_15_150442_create_docker_images_table.php new file mode 100644 index 0000000..2a60fd9 --- /dev/null +++ b/database/migrations/2026_06_15_150442_create_docker_images_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('name')->unique(); + $table->string('path'); + $table->string('tag'); + $table->string('env_variables'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('docker_images'); + } +}; diff --git a/database/migrations/2026_06_15_151114_add_image_id_column_to_webapp.php b/database/migrations/2026_06_15_151114_add_image_id_column_to_webapp.php new file mode 100644 index 0000000..9820da4 --- /dev/null +++ b/database/migrations/2026_06_15_151114_add_image_id_column_to_webapp.php @@ -0,0 +1,28 @@ +foreignId('docker_image_id')->nullable()->constrained(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('webapp', function (Blueprint $table) { + // + }); + } +}; diff --git a/database/migrations/2026_06_11_113503_add_dockertag_columns_to_webapps.php b/database/migrations/2026_06_17_155408_add_stack_id_column_to_webapps.php similarity index 82% rename from database/migrations/2026_06_11_113503_add_dockertag_columns_to_webapps.php rename to database/migrations/2026_06_17_155408_add_stack_id_column_to_webapps.php index da38cce..e27ff31 100644 --- a/database/migrations/2026_06_11_113503_add_dockertag_columns_to_webapps.php +++ b/database/migrations/2026_06_17_155408_add_stack_id_column_to_webapps.php @@ -12,8 +12,7 @@ public function up(): void { Schema::table('webapps', function (Blueprint $table) { - $table->string('docker_tag')->nullable(); - $table->string('tag_version')->nullable(); + $table->string('stackId')->nullable()->unique(); }); } diff --git a/resources/views/dockerimages/create.blade.php b/resources/views/dockerimages/create.blade.php new file mode 100644 index 0000000..1ca5213 --- /dev/null +++ b/resources/views/dockerimages/create.blade.php @@ -0,0 +1,34 @@ +@extends('laravel-usp-theme::master') +@section('content') +
+
+

Adicionar nova imagem:

+
+
+
+ @method('post') + @csrf +
+ Nome da imagem: + +
+
+ Imagem docker: + +
+
+ Versão imagem: + +
+
+
+ Variáveis de ambiente necessárias para a imagem: + +
+
Separe cara variável apenas por uma vírgula.
+
+ +
+
+
+@endsection diff --git a/resources/views/webapps/dockerconfig.blade.php b/resources/views/dockerimages/edit.blade.php similarity index 52% rename from resources/views/webapps/dockerconfig.blade.php rename to resources/views/dockerimages/edit.blade.php index 580eabe..6531c60 100644 --- a/resources/views/webapps/dockerconfig.blade.php +++ b/resources/views/dockerimages/edit.blade.php @@ -1,31 +1,31 @@ @extends('laravel-usp-theme::master') @section('content') -
+
-

{{ $webapp->dominio }}

-

Configurar docker:

+

Atualize a imagem: {{ $docker_image->name }}

-
- @method('post') + + @method('patch') @csrf
- tag docker: - + Imagem docker: +
- versão da tag: - + Versão imagem: +
- Variáveis de ambiente: - + Variáveis de ambiente necessárias para a imagem: +
Separe cara variável apenas por uma vírgula.
-
diff --git a/resources/views/dockerimages/index.blade.php b/resources/views/dockerimages/index.blade.php new file mode 100644 index 0000000..5b5cd59 --- /dev/null +++ b/resources/views/dockerimages/index.blade.php @@ -0,0 +1,16 @@ +@extends('laravel-usp-theme::master') +@section('content') +
+
+

Imagens docker:

+
+
+ +
+
+ +@endsection \ No newline at end of file diff --git a/resources/views/dockerimages/show.blade.php b/resources/views/dockerimages/show.blade.php new file mode 100644 index 0000000..9e0b1c9 --- /dev/null +++ b/resources/views/dockerimages/show.blade.php @@ -0,0 +1,21 @@ +@extends('laravel-usp-theme::master') +@section('content') +
+
+

{{ $docker_image->name }}

+
+
+
+ @method('delete') + @csrf +

Nome da imagem: {{ $docker_image->name }}

+

Imagem docker: {{ $docker_image->path}}

+

Versão da imagem: {{ $docker_image->tag }}

+

Variáveis de ambiente da imagem: {{ $docker_image->env_variables }}

+ + editar + +
+
+
+@endsection diff --git a/resources/views/webapps/dockerimage.blade.php b/resources/views/webapps/dockerimage.blade.php new file mode 100644 index 0000000..360bb45 --- /dev/null +++ b/resources/views/webapps/dockerimage.blade.php @@ -0,0 +1,35 @@ +@extends('laravel-usp-theme::master') +@section('content') +
+
+

{{ $webapp->dominio }}

+

Configurar docker:

+
+
+
+ @method('post') + @csrf +
+ +
+ +
+
+
+@endsection + +@section('javascripts_bottom') + +@endsection('javascripts_bottom') diff --git a/resources/views/webapps/editdockerconfig.blade.php b/resources/views/webapps/envvariables.blade.php similarity index 60% rename from resources/views/webapps/editdockerconfig.blade.php rename to resources/views/webapps/envvariables.blade.php index 93a68c0..7b1ef01 100644 --- a/resources/views/webapps/editdockerconfig.blade.php +++ b/resources/views/webapps/envvariables.blade.php @@ -3,36 +3,25 @@

{{ $webapp->dominio }}

-

Atualizar configuração docker:

+

Configure as variáveis de ambiente da aplicação:

-
- @method('put') + + @method('post') @csrf -
- tag docker: - -
-
- versão da tag: - -
- @if ($webapp->envVariables) - @foreach ($webapp->envVariables as $env_variable) + @if ($env_variables) + @foreach ($env_variables as $env_variable)
- {{ $env_variable->name }}: - name }} type="text" - class="form-control w-50" value={{ old('value', $env_variable->value) }}> + {{ $env_variable['name'] }}: +
@endforeach @endif
-
@@ -41,7 +30,7 @@ class="form-control w-50" value={{ old('value', $env_variable->value) }}> @section('javascripts_bottom') -@endsection