Compare commits
24 Commits
1a30b94863
...
400aeedb8f
| Author | SHA1 | Date |
|---|---|---|
|
|
400aeedb8f | |
|
|
023bf29e0b | |
|
|
8a404d371e | |
|
|
b56ac18229 | |
|
|
2bfbc3a75b | |
|
|
903013e306 | |
|
|
974c4a0cc3 | |
|
|
b3c75ba21f | |
|
|
9e77511702 | |
|
|
8efc8d53c4 | |
|
|
08024b301b | |
|
|
f238a41205 | |
|
|
97da159794 | |
|
|
1b188ec833 | |
|
|
33a33c8152 | |
|
|
e011d36743 | |
|
|
cc5bb633ec | |
|
|
f95b4c9df1 | |
|
|
789d3aaaf9 | |
|
|
58e71d9e80 | |
|
|
b19b6a2988 | |
|
|
f41c34b750 | |
|
|
ecfad09771 | |
|
|
93f786bc7e |
10
.env
10
.env
|
|
@ -52,3 +52,13 @@ OAUTH_ENCRYPTION_KEY=f1b7c279f7992205a0df45e295d07066
|
|||
###> nelmio/cors-bundle ###
|
||||
CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$'
|
||||
###< nelmio/cors-bundle ###
|
||||
|
||||
###> symfony/mercure-bundle ###
|
||||
# See https://symfony.com/doc/current/mercure.html#configuration
|
||||
# The URL of the Mercure hub, used by the app to publish updates (can be a local URL)
|
||||
MERCURE_URL=https://example.com/.well-known/mercure
|
||||
# The public URL of the Mercure hub, used by the browser to connect
|
||||
MERCURE_PUBLIC_URL=https://example.com/.well-known/mercure
|
||||
# The secret used to sign the JWTs
|
||||
MERCURE_JWT_SECRET="!ChangeThisMercureHubJWTSecretKey!"
|
||||
###< symfony/mercure-bundle ###
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="App\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mercure" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mercure-bundle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/firebase/php-jwt" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<xs:element name="framework" type="frameworkType"/>
|
||||
<xs:complexType name="commandType">
|
||||
<xs:all>
|
||||
<xs:element type="xs:string" name="name" minOccurs="1" maxOccurs="1"/>
|
||||
<xs:element type="xs:string" name="params" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element type="xs:string" name="help" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element type="optionsBeforeType" name="optionsBefore" minOccurs="0" maxOccurs="1"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="frameworkType">
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:string" name="extraData" minOccurs="0" maxOccurs="1"/>
|
||||
<xs:element type="commandType" name="command" maxOccurs="unbounded" minOccurs="0"/>
|
||||
<xs:element type="xs:string" name="help" minOccurs="0" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="name" use="required"/>
|
||||
<xs:attribute type="xs:string" name="invoke" use="required"/>
|
||||
<xs:attribute type="xs:string" name="alias" use="required"/>
|
||||
<xs:attribute type="xs:boolean" name="enabled" use="required"/>
|
||||
<xs:attribute type="xs:integer" name="version" use="required"/>
|
||||
<xs:attribute type="xs:string" name="frameworkId" use="optional"/>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="optionsBeforeType">
|
||||
<xs:sequence>
|
||||
<xs:element type="optionType" name="option" maxOccurs="unbounded" minOccurs="0"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:complexType name="optionType">
|
||||
<xs:sequence>
|
||||
<xs:element type="xs:string" name="help" minOccurs="0" maxOccurs="1"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute type="xs:string" name="name" use="required"/>
|
||||
<xs:attribute type="xs:string" name="shortcut" use="optional"/>
|
||||
<xs:attribute name="pattern" use="optional">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:string">
|
||||
<xs:enumeration value="space"/>
|
||||
<xs:enumeration value="equals"/>
|
||||
<xs:enumeration value="unknown"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:schema>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Easy_solution.iml" filepath="$PROJECT_DIR$/.idea/Easy_solution.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MessDetectorOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCSFixerOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/dotenv" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/form" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/password-hasher" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/intl" />
|
||||
<path value="$PROJECT_DIR$/vendor/paragonie/random_compat" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/monolog-bridge" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/asset" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/psr-http-message-bridge" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/ux-toggle-password" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/messenger" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
|
||||
<path value="$PROJECT_DIR$/vendor/masterminds/html5" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/config" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/oauth2-server" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/event" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/uri" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/oauth2-server-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/uri-interfaces" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
||||
<path value="$PROJECT_DIR$/vendor/nelmio/cors-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-server-middleware" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/container" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/link" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/clock" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-server-handler" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
|
||||
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
|
||||
<path value="$PROJECT_DIR$/vendor/nyholm/psr7" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
|
||||
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
|
||||
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
|
||||
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
|
||||
<path value="$PROJECT_DIR$/vendor/lcobucci/jwt" />
|
||||
<path value="$PROJECT_DIR$/vendor/lcobucci/clock" />
|
||||
<path value="$PROJECT_DIR$/vendor/twig/twig" />
|
||||
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/composer" />
|
||||
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php83" />
|
||||
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/browser-kit" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php84" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/dependency-injection" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/security-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/validator" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-icu" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/property-access" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/monolog-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/asset-mapper" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/runtime" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/doctrine-messenger" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/doctrine-bridge" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/options-resolver" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/twig-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
|
||||
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/expression-language" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/security-core" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/clock" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/mailer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/phpunit-bridge" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/security-csrf" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/string" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/serializer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/security-http" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/web-link" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/var-exporter" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/web-profiler-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/debug-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/orm" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/deprecations" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||
<path value="$PROJECT_DIR$/vendor/defuse/php-encryption" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/ux-turbo" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/stimulus-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/type-info" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/console" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpstan/phpdoc-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/process" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/persistence" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/framework-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/ux-icons" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/flex" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/sql-formatter" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/notifier" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/cache-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/migrations" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/property-info" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/collections" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/mercure" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/mercure-bundle" />
|
||||
<path value="$PROJECT_DIR$/vendor/firebase/php-jwt" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpUnit">
|
||||
<phpunit_settings>
|
||||
<PhpUnitSettings configuration_file_path="$PROJECT_DIR$/phpunit.xml.dist" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" use_configuration_file="true" />
|
||||
</phpunit_settings>
|
||||
</component>
|
||||
<component name="PsalmOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PHPUnit">
|
||||
<option name="directories">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/tests" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Symfony2PluginSettings">
|
||||
<option name="pluginEnabled" value="true" />
|
||||
<option name="lastServiceGeneratorLanguage" value="yaml" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -7,10 +7,12 @@
|
|||
"php": ">=8.2",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-openssl": "*",
|
||||
"doctrine/dbal": "^3",
|
||||
"doctrine/doctrine-bundle": "^2.14",
|
||||
"doctrine/doctrine-migrations-bundle": "^3.4",
|
||||
"doctrine/orm": "^3.3",
|
||||
"firebase/php-jwt": "^6.11",
|
||||
"league/oauth2-server-bundle": "^0.11.0",
|
||||
"nelmio/cors-bundle": "^2.5",
|
||||
"phpdocumentor/reflection-docblock": "^5.6",
|
||||
|
|
@ -27,6 +29,7 @@
|
|||
"symfony/http-client": "7.2.*",
|
||||
"symfony/intl": "7.2.*",
|
||||
"symfony/mailer": "7.2.*",
|
||||
"symfony/mercure-bundle": "^0.3.9",
|
||||
"symfony/mime": "7.2.*",
|
||||
"symfony/monolog-bundle": "^3.0",
|
||||
"symfony/notifier": "7.2.*",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,4 +17,5 @@ return [
|
|||
Symfony\UX\Icons\UXIconsBundle::class => ['all' => true],
|
||||
League\Bundle\OAuth2ServerBundle\LeagueOAuth2ServerBundle::class => ['all' => true],
|
||||
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MercureBundle\MercureBundle::class => ['all' => true],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIQ5VGud/OnzsCAggA
|
||||
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECH23Z4CwP/AxBIIEyCUA/sYfp1Vo
|
||||
x+pBPHs8EH5zW+oeCCqihANPGcYXHp3SusSQEA6jyEQz1GHEQF7nt5SxxqYTfe8D
|
||||
ovU2TsspUlycUcZhQQmtM6n2f375G9L2fvIhnOMvD34YvYQ0yhgkToS3h+pORpqb
|
||||
9abJbqkyTHSHOD4utSEaUnFapAQnKPWgFzYSjt4w6pVfX2AUZCXisC3QlcUh4782
|
||||
S62jIfqggMcDU2mfkBBUHE7z1syC5eqYwWEs2P1S1fvSYjpFv7L8LlkZY+6w/qgf
|
||||
IH1ht0A+rs6cQKILXW9yySqRfuumaGJtqQvlql4M7tb7zvDynVgN3/GQxm6oQmFB
|
||||
pFlNWINN7WmKqhRjnJBpKl5L1+s2EWpxBiHXXQLdznqzKyx3tPuLoeVh2S96NEy6
|
||||
f9380eDhNBYKdyUeZP+IBdwtV6U6vbwhtBQ53T9BQ6ykbKpRUm1fI4Y6AcVYW903
|
||||
KCkFR3j6pF4My41AMgcBSJ+GON/PEzIgIIDlYnM+7DVhlentY71Bhf9la7YSaFtx
|
||||
0r8d/CKdgGwPB2+QAEANOo0Z73RmovNRyadvZTcJqEgRC9R+DRbQHNYXN44TEhIU
|
||||
MZaFLTTZHEmWs0f4kf+UUo7RjUi5HdNCjuXErvKgVhtqMofeKc1p6fnNbBCrFYzs
|
||||
Knbwn+u2aLcI7LNLXaSWMOOGrbBw3g5FWObCxZ/FlNABp4yE+YT5YYeCLcemS/8n
|
||||
ZD0l3b2wkLK7dze0DB3TKv+wZoBHtl1s3RYm9UDjB8ejHSzzRMpLK514+Q8Qthx9
|
||||
IexC6hTzIG3wyjst98spb/6VQqDyA4TvMzW+pAA+9JgXyp7auHiU217nx5rSpdTe
|
||||
hWCyRgaBOP48W/ZoBjVxx81/voKixfvBZbYJSciw7K4iNRMjPXNg2BvCZZLZ9Ubd
|
||||
zLVCE15bzdGDZJis/VLawEFHZ1Urku9HfT4FhLxAweEc5VdnbdjEXIXqgf99VaK2
|
||||
V6xXWF9EQ1pVaavR+jzm0ZHs5Ltwnc095+Y9flmvzm+eD00Ftm1IyrfInMl6f8Sv
|
||||
gkxe1lxo6wbTE12CodhkH0woNd+y4K82ZSRzaTg6cUb+YTDKNAfoAnctghPe5+PX
|
||||
3j1ITAQeBFjVXckDrm8jeqF/gbcQYJwFjY0/wtl84gN/Ffs8DSTt1FYwsxgGew43
|
||||
L0KsVt/1Rd4Xb4czBRk7uUpR0U2R7iZ0yIrnGSh657tywpcn2thsJY4X6QjNRWNw
|
||||
yDg5Yrw10tIsLYJLJuxAauGjXbk23lelwnwn8EtMYPI2XtzGSS3b7uGXjTu2pncQ
|
||||
YVFbI/DxrRi3tyF7JLSC1mfNxikMfY6cPp489djDWC0iQVcltrHiHDkmMrloptE7
|
||||
tTUvPfBRNAbonMaXR+pSSQBlDkUMk6uNpk9EYIlLGg2WggOYnikEKsLoX19Mjg5M
|
||||
ZuX7fu2ETHJjvHBetMnQobtqKEGf5RJn+mdKBzia9ZAcjxhKRqYUCK8Qoi3mjvJa
|
||||
x+5idCj2etNJA5idmH50NSXSFbO69Au+LCj1zSikN6h+YgOjqwF0TPQ7Qw4qQQkH
|
||||
4NwYi6S4wCI13LyLVN1XTh9nn99Y/WnORyyegmAfQif1vbcPcfU6mY3VGK5tX2Yl
|
||||
NhLAyGw7m2xDDmIefpRi+w==
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
-----BEGIN ENCRYPTED PRIVATE KEY-----
|
||||
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIf5Dm9gHr5xICAggA
|
||||
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECAmIm56CqfdaBIIEyIeYoi/NL/yC
|
||||
EM3P0ZEesYY08FoEjaAonqDAFB2w8caOfSc2quZSij7zaDAjU5ehg7X/3kWqypUW
|
||||
F1bhMn5v3Lad6XOgXeTigYaLZBXshazuqnbqs9xBU00MPkwetl1CT4ATUzvEPPq1
|
||||
LOQ2FfEUfBZAR51PVYvKJwwctzYW42PNh8940XqskAs6kfWQ3qZPlnCRjQDfuKcI
|
||||
YhKeJz6cCYt5JHqBGC5mRiFkRqDe10gks0/yUCmds9MpKPLYKP9MrUs8QcxWpakf
|
||||
ypUMPM2mSik4U+D7Gdq7CqulqDPLm+8drKgUeq6wTgWwodpGnUe5FeG+cx4hxH5x
|
||||
fAKuP6gscvYk3p5ir138TVW4uEFehkBw7yHpqUqSjN5jIlmX634siYoNhWP6Ek32
|
||||
nl+gGUlITWSC6cewiqpL7IfQr+DDXpTPcN5Lu9+6rmh4P0XGE+J2a/tdXeK3xdMZ
|
||||
3MyFItGNIxklL+yuvRBJ2o4D5JRDhiSwmXdFR5WOJYN0SRKYkEnmjAAHnhK6eWLP
|
||||
bsD0tdUilZvyGmcPMXkM3HjfAQKqDldi8rmdqe8IJHpCKZ5twryy/eb1EArofN0U
|
||||
H9XIs/pdJldg2HTJVIen5iAONqMSB4LyxMUfXWnvg/qPazvgYZvKbTXyp0iVhJ77
|
||||
UcWyIO6xx/3BvnuO/eCgelu+eNQqI9UOMhVr7X0gGpXb88g+Gu8scrlWDVTM6o9P
|
||||
j1rOuAYaZX/69jGOmH3QqUkILcwkfevSuNUBgLOilh/mabR+tOfM2o6/8Z1Zd1PS
|
||||
nplYzvDs/Pib71PEF64DVCRlG2QioqV2MT7gOenShyZhZS4+oxJ3nWf9Z9n5jwDJ
|
||||
XSqkHRD8CDZZS0f1FOET1c+GZtoyfxGHdGyLM8shA6IRnxBoAKWVW8vdTfyPJFcy
|
||||
vq9gPvlrfyuREcRKeSnySzkAQbYLVH631tLcsbsd5yfyYS0o6BY1mNDi1j83Xfmp
|
||||
Or2a137ZKKTfRtSJybj+QOiBXMR8uJnR9HPjRQn8DrMYzcgv/kw48AIUy2+4sZIw
|
||||
cPxrtKFyhWIYSnHil4Ri/cENZApbbo1UQc4ktyjuyxyI20gx21vfaHWbx6GpUNwG
|
||||
H551tioa5P4cte4syOxMi89KRdCYKGgUTibhEfMODD6rA/l3W9PGINqOGu3Z2SxN
|
||||
4HGV4oJx6Nvw1vTq2phSVo3Qp9JyvO3FFE8oA/b+ElL0PoYjsLsNiKBxggPvZgKp
|
||||
nTOFYYUMQl1+6CUf2iSR0b8VLhRM5o9N+Xwp2D2SEjWZvMhIKQxxmwVd3aSn8ebQ
|
||||
CSW0lGFjltwc5FEvw1aNmhx7K1gSCMcBnSEx53ghLU5xCA+50g5brM1joZn3sQ2c
|
||||
WsY/dLNtfqlTnKSeVQKyLEZj6Xl9/KYyVg3yYt43HuSz3FAt6ekGloA9rVR3v7tZ
|
||||
m6tBWyOqQG4tnp8+V/2CMGnpq2VQABqxwZxpm5u+tbfSlonwrXpiy3/fgsYZJE02
|
||||
kVwNb4FPClKjyVZGRrWfITaS4Gxm+hDdfKVipunIzS+7MADwwYyibPVXyuCw1NTg
|
||||
pt89WCTt0csNNGcpd1m/rrH5J080fEHGXWpeobbTbeiYsK0+qeYQXEeMvE7lyFIP
|
||||
SzDJqo7z76xQc3dcBX8MNQ==
|
||||
-----END ENCRYPTED PRIVATE KEY-----
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwLRhFcrWQWeuGhgrFclT
|
||||
c08RTX52kl9XMXatgJi/mfa/o7lbZbhQfNzrMXVZFDTs97YTZXotZVwL1pI7yGtv
|
||||
bjbPNuhs+lvOSmWribIacYx47EqKeYhQ29rOYx7fnr+SvK10QZoFnT58tduQVrER
|
||||
79b+lcbqKMKNeI6zZeVdBrhstuI/PtXnM4kMHThaTz3iLbWkoDyl06VIMFVsvHpc
|
||||
HaPJsBH1I45M9l4gTfshknY3Dz5ESVd41XTH2c/PSa6geNUn5kpslCuxKv3DnmWE
|
||||
h+V87ASCIM7tKE6bc0eFQLKPQo52/TUWfDa8nFbeIrbsQJwq5VhYK21TANNFFL3g
|
||||
GwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwZehUUiAV9vMER+tCpKB
|
||||
lLr53bCV2z34r7Qg4gojciR1n7J6esptuLo/JMIYsU1EFmH8dIJ9guc/IufW7hDj
|
||||
iwB2l75brVJ+EG8RRN2R4/IlUXz01a56W+TgLGyVM9iNegfwrNQjEEr3WNnz878h
|
||||
0KQDsG3+kndh60pIuIiiEqG/yoO9C4enyL5XEDcsyKebb5PeCSTewgGm+DY7vj1F
|
||||
FSZMXxEnOQP/Symz8st1KS7DbbYma/OCkrAsZ+iHC1Ozis0D28uxcdyrPZi36bkV
|
||||
MKNST42uV86CTEan2yaHaynRUFNHC+bZjA+izOALtg3CyguOqrmL1LL5ID8Q1K8f
|
||||
jQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
|
|
@ -5,7 +5,7 @@ league_oauth2_server:
|
|||
encryption_key: '%env(resolve:OAUTH_ENCRYPTION_KEY)%'
|
||||
access_token_ttl: PT3H # 3 hours
|
||||
refresh_token_ttl: P1M # 1 month
|
||||
auth_code_ttl: PT10M # 10 minutes
|
||||
auth_code_ttl: PT3H # 10 minutes
|
||||
require_code_challenge_for_public_clients: false
|
||||
resource_server:
|
||||
public_key: '%env(resolve:OAUTH_PUBLIC_KEY)%'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
mercure:
|
||||
hubs:
|
||||
default:
|
||||
url: '%env(MERCURE_URL)%'
|
||||
public_url: '%env(MERCURE_PUBLIC_URL)%'
|
||||
jwt:
|
||||
secret: '%env(MERCURE_JWT_SECRET)%'
|
||||
publish: '*'
|
||||
|
|
@ -18,6 +18,17 @@ security:
|
|||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
security: false
|
||||
oauth_userinfo:
|
||||
pattern: ^/oauth2/userinfo
|
||||
stateless: true
|
||||
oauth2: true
|
||||
provider: app_user_provider
|
||||
oauth_revoke:
|
||||
pattern: ^/oauth2/revoke_tokens
|
||||
stateless: true
|
||||
auth_token:
|
||||
pattern: ^/token
|
||||
stateless: true
|
||||
api:
|
||||
pattern: ^/oauth/api
|
||||
security: true
|
||||
|
|
@ -32,9 +43,9 @@ security:
|
|||
enable_csrf: true
|
||||
default_target_path: app_index
|
||||
use_referer: true
|
||||
logout:
|
||||
path: app_logout
|
||||
target: app_login
|
||||
# logout:
|
||||
# path: app_logout
|
||||
# target: app_login
|
||||
|
||||
# activate different ways to authenticate
|
||||
# https://symfony.com/doc/current/security.html#the-firewall
|
||||
|
|
@ -46,7 +57,9 @@ security:
|
|||
# Note: Only the *first* access control that matches will be used
|
||||
access_control:
|
||||
- { path: ^/login, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/sso_logout, roles: IS_AUTHENTICATED_FULLY }
|
||||
- { path: ^/token, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/oauth2/revoke_tokens, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/oauth2/token, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/token, roles: PUBLIC_ACCESS }
|
||||
- { path: ^/authorize, roles: IS_AUTHENTICATED_REMEMBERED }
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ services:
|
|||
App\EventSubscriber\:
|
||||
resource: '../src/EventSubscriber/'
|
||||
tags: ['kernel.event_subscriber']
|
||||
App\EventSubscriber\ScopeResolveListener:
|
||||
tags:
|
||||
- { name: kernel.event_listener, event: league.oauth2_server.event.scope_resolve, method: onScopeResolve }
|
||||
League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface:
|
||||
class: App\Repository\AccessTokenRepository
|
||||
decorates: 'League\Bundle\OAuth2ServerBundle\Repository\AccessTokenRepository'
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
# please note that last definitions always *replace* previous ones
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250514091443 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE "user" ADD uuid UUID NOT NULL
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE "user" DROP uuid
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250514093759 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE "user" DROP uuid
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE "user" ADD uuid UUID NOT NULL
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250521124056 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250626124556 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE TABLE user_tab (id SERIAL NOT NULL, users_id INT NOT NULL, tab_open INT NOT NULL, PRIMARY KEY(id))
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE INDEX IDX_98F5228767B3B43D ON user_tab (users_id)
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab ADD CONSTRAINT FK_98F5228767B3B43D FOREIGN KEY (users_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab DROP CONSTRAINT FK_98F5228767B3B43D
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
DROP TABLE user_tab
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250626134726 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab RENAME COLUMN tab_open TO ip_address
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab RENAME COLUMN ip_address TO tab_open
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250626135125 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab ALTER ip_address TYPE VARCHAR(255)
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab ALTER ip_address TYPE INT
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250626145913 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab ADD tab_id VARCHAR(255) DEFAULT NULL
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab DROP tab_id
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250627073903 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE TABLE subscriptions (id SERIAL NOT NULL, users_id INT NOT NULL, PRIMARY KEY(id))
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE INDEX IDX_4778A0167B3B43D ON subscriptions (users_id)
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE subscriptions ADD CONSTRAINT FK_4778A0167B3B43D FOREIGN KEY (users_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE subscriptions DROP CONSTRAINT FK_4778A0167B3B43D
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
DROP TABLE subscriptions
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20250704091028 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
DROP SEQUENCE user_tab_id_seq CASCADE
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab DROP CONSTRAINT fk_98f5228767b3b43d
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
DROP TABLE user_tab
|
||||
SQL);
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SCHEMA public
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE SEQUENCE user_tab_id_seq INCREMENT BY 1 MINVALUE 1 START 1
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE TABLE user_tab (id SERIAL NOT NULL, users_id INT NOT NULL, ip_address VARCHAR(255) NOT NULL, tab_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
CREATE INDEX idx_98f5228767b3b43d ON user_tab (users_id)
|
||||
SQL);
|
||||
$this->addSql(<<<'SQL'
|
||||
ALTER TABLE user_tab ADD CONSTRAINT fk_98f5228767b3b43d FOREIGN KEY (users_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE
|
||||
SQL);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,15 +2,19 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
final class IndexController extends AbstractController
|
||||
{
|
||||
#[Route('/', name: 'app_index')]
|
||||
public function index(): Response
|
||||
public function index(Request $request, LoggerInterface $logger): Response
|
||||
{
|
||||
$logger->info("SESSION ID: " . $request->getSession()->getId());
|
||||
return $this->render('index/index.html.twig', [
|
||||
'controller_name' => 'IndexController',
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -2,41 +2,74 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Service\AccessTokenService;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class OAuth2Controller extends AbstractController
|
||||
{
|
||||
#[Route('/oauth/api/user', name: 'app_oauth_api_user')]
|
||||
public function oauthApiUser(): JsonResponse
|
||||
{
|
||||
/** @var User $user */
|
||||
$user = $this->getUser();
|
||||
return new JsonResponse([
|
||||
'message' => 'Authentification réussie !',
|
||||
'email' => $user->getEmail(),
|
||||
'name' => $user->getName()
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[Route('/oauth2/userinfo', name: 'userinfo', methods: ['GET'])]
|
||||
public function userinfo(): JsonResponse
|
||||
public function userinfo(Request $request): JsonResponse
|
||||
{
|
||||
$user = $this->getUser();
|
||||
|
||||
// dd($user);
|
||||
if (!$user) {
|
||||
return new JsonResponse(['error' => 'Unauthorized'], 401);
|
||||
}
|
||||
|
||||
return new JsonResponse([
|
||||
'sub' => $user->getId(),
|
||||
'username' => $user->getName(),
|
||||
'id' => $user->getId(),
|
||||
'name' => $user->getName(),
|
||||
'email' => $user->getEmail(),
|
||||
'roles' => $user->getRoles(),
|
||||
'surname' => $user->getSurname(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('.well-known/jwks.json', name: 'app_jwks', methods: ['GET'])]
|
||||
public function jwks(): Response
|
||||
{
|
||||
// Load the public key from the filesystem and use OpenSSL to parse it.
|
||||
$kernelDirectory = $this->getParameter('kernel.project_dir');
|
||||
$publicKey = openssl_pkey_get_public(file_get_contents($kernelDirectory . '/config/jwt/public.key'));
|
||||
$details = openssl_pkey_get_details($publicKey);
|
||||
$jwks = [
|
||||
'keys' => [
|
||||
[
|
||||
'kty' => 'RSA',
|
||||
'alg' => 'RS256',
|
||||
'use' => 'sig',
|
||||
'n' => strtr(rtrim(base64_encode($details['rsa']['n']), '='), '+/', '-_'),
|
||||
'e' => strtr(rtrim(base64_encode($details['rsa']['e']), '='), '+/', '-_'),
|
||||
],
|
||||
],
|
||||
];
|
||||
return $this->json($jwks);
|
||||
}
|
||||
|
||||
#[Route(path: '/oauth2/revoke_tokens', name: 'revoke_tokens', methods: ['POST'])]
|
||||
public function revokeTokens(Security $security, Request $request, AccessTokenService $accessTokenService, LoggerInterface $logger): Response{
|
||||
//Check if the user have valid access token
|
||||
$data = json_decode($request->getContent(), true);
|
||||
$userIdentifier = $data['user_identifier'];
|
||||
if (!$userIdentifier) {
|
||||
return new JsonResponse(["ERROR" => "User identifier is required"], Response::HTTP_BAD_REQUEST);
|
||||
}
|
||||
$accessTokenService->revokeTokens($userIdentifier);
|
||||
$logger->info("Revoke tokens successfully");
|
||||
|
||||
return new JsonResponse(["SUCCESS" => "Tokens revoked successfully"], Response::HTTP_OK);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,12 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Service\AccessTokenService;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
|
|
@ -35,10 +40,23 @@ class SecurityController extends AbstractController
|
|||
]);
|
||||
}
|
||||
|
||||
#[Route(path: '/logout', name: 'app_logout')]
|
||||
public function logout(): void
|
||||
#[Route(path: '/sso_logout', name: 'sso_logout')]
|
||||
public function ssoLogout(RequestStack $stack, LoggerInterface $logger, AccessTokenService $accessTokenService, Security $security): Response
|
||||
{
|
||||
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
|
||||
// Invalidate the session and revoke tokens
|
||||
try{
|
||||
if( $stack->getSession()->invalidate()){
|
||||
$accessTokenService->revokeTokens($security->getUser()->getUserIdentifier());
|
||||
$security->logout(false);
|
||||
$logger->info("Logout successfully");
|
||||
// Redirect back to the client (or to a “you are logged out” page)
|
||||
return $this->redirect('/');
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
$logger->log(LogLevel::ERROR, 'Error invalidating session: ' . $e->getMessage());
|
||||
}
|
||||
// If something goes wrong, redirect to the index page
|
||||
return $this->redirectToRoute('app_index');
|
||||
}
|
||||
|
||||
#[Route(path: '/consent', name: 'app_consent')]
|
||||
|
|
@ -59,4 +77,5 @@ class SecurityController extends AbstractController
|
|||
// For GET requests, just show the consent form
|
||||
return $this->render('security/consent.html.twig');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\Traits\AccessTokenTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\EntityTrait;
|
||||
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
|
||||
|
||||
|
||||
final class AccessToken implements AccessTokenEntityInterface
|
||||
{
|
||||
use AccessTokenTrait;
|
||||
use EntityTrait;
|
||||
use TokenEntityTrait;
|
||||
|
||||
|
||||
private function convertToJWT()
|
||||
{
|
||||
$this->initJwtConfiguration();
|
||||
|
||||
return $this->jwtConfiguration->builder()
|
||||
->permittedFor($this->getClient()->getIdentifier())
|
||||
->identifiedBy($this->getIdentifier())
|
||||
->issuedAt(new DateTimeImmutable())
|
||||
->canOnlyBeUsedAfter(new DateTimeImmutable())
|
||||
->expiresAt($this->getExpiryDateTime())
|
||||
->relatedTo((string) $this->getUserIdentifier())
|
||||
->withClaim('scopes', $this->getScopes())
|
||||
->withClaim('email', $this->getUserIdentifier())
|
||||
->getToken($this->jwtConfiguration->signer(), $this->jwtConfiguration->signingKey());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\SubscriptionsRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity(repositoryClass: SubscriptionsRepository::class)]
|
||||
class Subscriptions
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'subscriptions')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?User $users = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getUsers(): ?User
|
||||
{
|
||||
return $this->users;
|
||||
}
|
||||
|
||||
public function setUsers(?User $users): static
|
||||
{
|
||||
$this->users = $users;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
namespace App\Entity;
|
||||
|
||||
use App\Repository\UserRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
|
@ -53,6 +55,17 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||
#[ORM\Column(options: ['default' => false])]
|
||||
private ?bool $isDeleted = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Subscriptions>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: Subscriptions::class, mappedBy: 'users')]
|
||||
private Collection $subscriptions;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->subscriptions = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
|
|
@ -219,4 +232,34 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||
{
|
||||
return (string) $this->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Subscriptions>
|
||||
*/
|
||||
public function getSubscriptions(): Collection
|
||||
{
|
||||
return $this->subscriptions;
|
||||
}
|
||||
|
||||
public function addSubscription(Subscriptions $subscription): static
|
||||
{
|
||||
if (!$this->subscriptions->contains($subscription)) {
|
||||
$this->subscriptions->add($subscription);
|
||||
$subscription->setUsers($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeSubscription(Subscriptions $subscription): static
|
||||
{
|
||||
if ($this->subscriptions->removeElement($subscription)) {
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($subscription->getUsers() === $this) {
|
||||
$subscription->setUsers(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,4 +65,4 @@ class AuthorizationCodeSubscriber implements EventSubscriberInterface
|
|||
'league.oauth2_server.event.authorization_request_resolve' => 'onLeagueOauth2ServerEventAuthorizationRequestResolve',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace App\EventSubscriber;
|
||||
|
||||
use App\Service\ClientService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use League\Bundle\OAuth2ServerBundle\Event\ScopeResolveEvent;
|
||||
use League\Bundle\OAuth2ServerBundle\Repository\ScopeRepository;
|
||||
use League\Bundle\OAuth2ServerBundle\ValueObject\Scope;
|
||||
use League\Bundle\OAuth2ServerBundle\Model\Client;
|
||||
use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
final class ScopeResolveListener implements EventSubscriberInterface
|
||||
{
|
||||
private ClientRepositoryInterface $clientRepository;
|
||||
private LoggerInterface $logger;
|
||||
private ClientService $clientService;
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
public function __construct(ClientRepositoryInterface $clientRepository, LoggerInterface $logger, ClientService $clientService, EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
// Inject the client repository
|
||||
$this->clientRepository = $clientRepository;
|
||||
$this->clientService = $clientService;
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function onScopeResolve(ScopeResolveEvent $event): void
|
||||
{
|
||||
// Get the client ID from the event
|
||||
$client = $event->getClient();
|
||||
$clientIdentifier = $client->getIdentifier();
|
||||
|
||||
// Get the requested scopes from the event
|
||||
$requestedScopes = $event->getScopes();
|
||||
|
||||
// Prepare our final scopes collection
|
||||
$finalScopes = [];
|
||||
|
||||
// Add default scopes that everyone gets
|
||||
$defaultScopes = ['email', 'profile', 'openid'];
|
||||
foreach ($defaultScopes as $scope) {
|
||||
$finalScopes[] = new Scope($scope);
|
||||
}
|
||||
|
||||
$clientEntity = $this->entityManager->getRepository(Client::class)->findOneBy(['identifier' => $clientIdentifier]);
|
||||
|
||||
$finalScopes[] = new Scope('apps:'. $clientEntity->getName());
|
||||
|
||||
// Add client-specific scopes based on client identifier or name
|
||||
// switch ($clientIdentifier) {
|
||||
// case 'a712b3caede9588372b2a83947fae53e':
|
||||
// $finalScopes[] = new Scope('apps:easyexploit');
|
||||
// break;
|
||||
// case '14bbb1b1692ac3a45159e263e3e7ec67':
|
||||
// $finalScopes[] = new Scope('apps:client');
|
||||
// break;
|
||||
// case 'EasyMonithor':
|
||||
// $finalScopes[] = new Scope('apps:easymonithor');
|
||||
// break;
|
||||
// case 'EasyCheck':
|
||||
// $finalScopes[] = new Scope('apps:easycheck');
|
||||
// break;
|
||||
// // Add more cases as needed for other applications
|
||||
// }
|
||||
|
||||
// // If the client is an admin client, add admin scopes
|
||||
// if (str_contains($client->getName(), 'Admin')) {
|
||||
// $finalScopes[] = new Scope('apps:manage');
|
||||
// $finalScopes[] = new Scope('orgs:manage');
|
||||
// $finalScopes[] = new Scope('users:manage');
|
||||
// }
|
||||
|
||||
// Set the resolved scopes
|
||||
$event->setScopes(...$finalScopes);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
ScopeResolveEvent::class => 'onScopeResolve',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use League\Bundle\OAuth2ServerBundle\Repository\AccessTokenRepository as BaseAccessTokenRepository;
|
||||
use App\Entity\AccessToken as AccessTokenEntity;
|
||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
||||
|
||||
final class AccessTokenRepository implements AccessTokenRepositoryInterface
|
||||
{
|
||||
private AccessTokenRepositoryInterface $baseAccessTokenRepository;
|
||||
|
||||
public function __construct(AccessTokenRepositoryInterface $baseAccessTokenRepository)
|
||||
{
|
||||
$this->baseAccessTokenRepository = $baseAccessTokenRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null): AccessTokenEntityInterface
|
||||
{
|
||||
/** @var int|string|null $userIdentifier */
|
||||
$accessToken = new AccessTokenEntity();
|
||||
$accessToken->setClient($clientEntity);
|
||||
$accessToken->setUserIdentifier($userIdentifier);
|
||||
|
||||
foreach ($scopes as $scope) {
|
||||
$accessToken->addScope($scope);
|
||||
}
|
||||
|
||||
return $accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity): void
|
||||
{
|
||||
$this->baseAccessTokenRepository->persistNewAccessToken($accessTokenEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tokenId
|
||||
*/
|
||||
public function revokeAccessToken($tokenId): void
|
||||
{
|
||||
$this->baseAccessTokenRepository->revokeAccessToken($tokenId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $tokenId
|
||||
*/
|
||||
public function isAccessTokenRevoked($tokenId): bool
|
||||
{
|
||||
return $this->baseAccessTokenRepository->isAccessTokenRevoked($tokenId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Subscriptions;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Subscriptions>
|
||||
*/
|
||||
class SubscriptionsRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Subscriptions::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Subscriptions[] Returns an array of Subscriptions objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('s')
|
||||
// ->andWhere('s.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('s.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?Subscriptions
|
||||
// {
|
||||
// return $this->createQueryBuilder('s')
|
||||
// ->andWhere('s.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use League\Bundle\OAuth2ServerBundle\Model\AccessToken;
|
||||
|
||||
class AccessTokenService
|
||||
{
|
||||
|
||||
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
public function __construct(EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
public function revokeTokens(String $userIdentifier): void {
|
||||
$accessTokens = $this->entityManager->getRepository(AccessToken::class)->findBy(['userIdentifier' => $userIdentifier, 'revoked' => false]);
|
||||
foreach($accessTokens as $accessToken) {
|
||||
$accessToken->revoke();
|
||||
$this->entityManager->persist($accessToken);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
}
|
||||
|
||||
public function getUserFromToken(string $token)
|
||||
{
|
||||
$data = json_decode(base64_decode(strtr($token, '-_', '+/')), true);
|
||||
if (isset($data['user_identifier'])) {
|
||||
return $data['user_identifier'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -50,4 +50,13 @@ class CguUserService
|
|||
$cguUser->setIsAccepted(true);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
|
||||
//Function can only be called if the user has already accepted the CGU
|
||||
public function declineCgu(UserInterface $user, Cgu $cgu): void
|
||||
{
|
||||
$cguUser = $this->entityManager->getRepository(CguUser::class)->findOneBy(['users' => $user, 'cgu' => $cgu]);
|
||||
|
||||
$cguUser->setIsAccepted(false);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
use League\Bundle\OAuth2ServerBundle\Model\Client;
|
||||
|
||||
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
class ClientService{
|
||||
/**
|
||||
* Retrieves a Client entity by its identifier.
|
||||
*
|
||||
* @param string $identifier The identifier of the client.
|
||||
* @param EntityManagerInterface $entityManager The entity manager to use for database operations.
|
||||
* @return Client|null The Client entity or null if not found.
|
||||
*/
|
||||
|
||||
public function getClientIdentifier(String $identifier, EntityManagerInterface $entityManager): Client
|
||||
{
|
||||
return $entityManager->getRepository(Client::class)->findOneBy(['identifier' => $identifier]);
|
||||
}
|
||||
}
|
||||
21
symfony.lock
21
symfony.lock
|
|
@ -1,4 +1,13 @@
|
|||
{
|
||||
"doctrine/deprecations": {
|
||||
"version": "1.1",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "87424683adc81d7dc305eefec1fced883084aab9"
|
||||
}
|
||||
},
|
||||
"doctrine/doctrine-bundle": {
|
||||
"version": "2.14",
|
||||
"recipe": {
|
||||
|
|
@ -181,6 +190,18 @@
|
|||
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
||||
}
|
||||
},
|
||||
"symfony/mercure-bundle": {
|
||||
"version": "0.3",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "0.3",
|
||||
"ref": "528285147494380298f8f991ee8c47abebaf79db"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/mercure.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/messenger": {
|
||||
"version": "7.2",
|
||||
"recipe": {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,21 @@
|
|||
|
||||
{% block javascripts %}
|
||||
{% block importmap %}{{ importmap('app') }}{% endblock %}
|
||||
<script>
|
||||
const eventSource = new EventSource("{{ mercure('http://solutions-easy.moi/connect?userId='~ app.user.userIdentifier)|raw }}");
|
||||
if (!sessionStorage.getItem('tabId')) {
|
||||
sessionStorage.setItem('tabId', self.crypto.randomUUID ? self.crypto.randomUUID() : Math.random().toString(36).substr(2, 9));
|
||||
}
|
||||
const tabId = sessionStorage.getItem('tabId');
|
||||
console.log('Tab ID:', tabId);
|
||||
|
||||
fetch('/register-tab', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({ tabId: tabId })
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -23,7 +38,7 @@
|
|||
{{ include('elements/navbar.html.twig')}}
|
||||
|
||||
{% block body %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@
|
|||
<i >{{ ux_icon('bi:menu-up', {height: '20px', width: '20px'}) }}</i>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<a href="http://api.solutions-easy.moi"> tyet </a>
|
||||
<a href="http://client.solutions-easy.moi"> Client </a>
|
||||
{# <select class="form-control">
|
||||
<option>Exploit</options>
|
||||
<option>Monithor</options>
|
||||
|
|
@ -72,8 +72,8 @@
|
|||
</select> #}
|
||||
</div>
|
||||
</div>
|
||||
<a class="dropdown-item" style="padding-left: 8px;" href="#">
|
||||
<i class="me-2">{{ ux_icon('material-symbols:logout', {height: '20px', width: '20px'}) }}</i>
|
||||
<a class="dropdown-item" style="padding-left: 8px;" href="{{ path('sso_logout') }}">
|
||||
<i class="me-2">{{ ux_icon('material-symbols:logout', {height: '20px', width: '20px'}) }}</i>
|
||||
Deconnexion
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
{% if app.user %}
|
||||
<div class="mb-3">
|
||||
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
|
||||
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('sso_logout') }}">Logout</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'base.html.twig' %}
|
||||
{% extends 'publicBase.html.twig' %}
|
||||
|
||||
{% block title %} Consent {% endblock %}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue