ÇA FONCTIONNE
This commit is contained in:
parent
33a33c8152
commit
1b188ec833
|
|
@ -5,6 +5,9 @@
|
|||
<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" />
|
||||
|
|
|
|||
|
|
@ -161,6 +161,9 @@
|
|||
<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" />
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@
|
|||
<project version="4">
|
||||
<component name="Symfony2PluginSettings">
|
||||
<option name="pluginEnabled" value="true" />
|
||||
<option name="lastServiceGeneratorLanguage" value="yaml" />
|
||||
</component>
|
||||
</project>
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
"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",
|
||||
|
|
|
|||
|
|
@ -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": "0146b1350b6329146b85a9251521ffed",
|
||||
"content-hash": "ec18ea9254732e2793a2fc5e0e6919aa",
|
||||
"packages": [
|
||||
{
|
||||
"name": "composer/semver",
|
||||
|
|
@ -1438,6 +1438,69 @@
|
|||
],
|
||||
"time": "2025-03-06T22:45:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "firebase/php-jwt",
|
||||
"version": "v6.11.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/firebase/php-jwt.git",
|
||||
"reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66",
|
||||
"reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psr/cache": "^2.0||^3.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-sodium": "Support EdDSA (Ed25519) signatures",
|
||||
"paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Firebase\\JWT\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Neuman Vong",
|
||||
"email": "neuman+pear@twilio.com",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Anant Narayanan",
|
||||
"email": "anant@php.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.",
|
||||
"homepage": "https://github.com/firebase/php-jwt",
|
||||
"keywords": [
|
||||
"jwt",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/firebase/php-jwt/issues",
|
||||
"source": "https://github.com/firebase/php-jwt/tree/v6.11.1"
|
||||
},
|
||||
"time": "2025-04-09T20:32:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "lcobucci/clock",
|
||||
"version": "3.3.1",
|
||||
|
|
@ -5259,6 +5322,173 @@
|
|||
],
|
||||
"time": "2025-04-04T09:50:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mercure",
|
||||
"version": "v0.6.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mercure.git",
|
||||
"reference": "304cf84609ef645d63adc65fc6250292909a461b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mercure/zipball/304cf84609ef645d63adc65fc6250292909a461b",
|
||||
"reference": "304cf84609ef645d63adc65fc6250292909a461b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1.3",
|
||||
"symfony/deprecation-contracts": "^2.0|^3.0|^4.0",
|
||||
"symfony/http-client": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/http-foundation": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/polyfill-php80": "^1.22",
|
||||
"symfony/web-link": "^4.4|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"lcobucci/jwt": "^3.4|^4.0|^5.0",
|
||||
"symfony/event-dispatcher": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/http-kernel": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/phpunit-bridge": "^5.2|^6.0|^7.0",
|
||||
"symfony/stopwatch": "^4.4|^5.0|^6.0|^7.0",
|
||||
"twig/twig": "^2.0|^3.0|^4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/stopwatch": "Integration with the profiler performances"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/dunglas/mercure",
|
||||
"name": "dunglas/mercure"
|
||||
},
|
||||
"branch-alias": {
|
||||
"dev-main": "0.6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Mercure\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kévin Dunglas",
|
||||
"email": "dunglas@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Mercure Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"mercure",
|
||||
"push",
|
||||
"sse",
|
||||
"updates"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/symfony/mercure/issues",
|
||||
"source": "https://github.com/symfony/mercure/tree/v0.6.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/dunglas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/mercure",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-04-08T12:51:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mercure-bundle",
|
||||
"version": "v0.3.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mercure-bundle.git",
|
||||
"reference": "77435d740b228e9f5f3f065b6db564f85f2cdb64"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mercure-bundle/zipball/77435d740b228e9f5f3f065b6db564f85f2cdb64",
|
||||
"reference": "77435d740b228e9f5f3f065b6db564f85f2cdb64",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"lcobucci/jwt": "^3.4|^4.0|^5.0",
|
||||
"php": ">=7.1.3",
|
||||
"symfony/config": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/dependency-injection": "^4.4|^5.4|^6.0|^7.0",
|
||||
"symfony/http-kernel": "^4.4|^5.0|^6.0|^7.0",
|
||||
"symfony/mercure": "^0.6.1",
|
||||
"symfony/web-link": "^4.4|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.3.7|^5.0|^6.0|^7.0",
|
||||
"symfony/stopwatch": "^4.3.7|^5.0|^6.0|^7.0",
|
||||
"symfony/ux-turbo": "*",
|
||||
"symfony/var-dumper": "^4.3.7|^5.0|^6.0|^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/messenger": "To use the Messenger integration"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "0.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Bundle\\MercureBundle\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kévin Dunglas",
|
||||
"email": "dunglas@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony MercureBundle",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"mercure",
|
||||
"push",
|
||||
"sse",
|
||||
"updates"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/symfony/mercure-bundle/issues",
|
||||
"source": "https://github.com/symfony/mercure-bundle/tree/v0.3.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/dunglas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/mercure-bundle",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-05-31T09:07:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/messenger",
|
||||
"version": "v7.2.6",
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ security:
|
|||
stateless: true
|
||||
oauth2: true
|
||||
provider: app_user_provider
|
||||
oauth_revoke:
|
||||
pattern: ^/oauth2/revoke_tokens
|
||||
stateless: true
|
||||
auth_token:
|
||||
pattern: ^/token
|
||||
stateless: true
|
||||
|
|
@ -40,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
|
||||
|
|
@ -54,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 }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
|
||||
use Firebase\JWT\JWT;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
#[AsCommand(name: 'app:listen-subscription', description: 'Listen to Mercure subscriptions')]
|
||||
class ListenSubscritptionCommand extends Command{
|
||||
|
||||
public function __construct(
|
||||
private HttpClientInterface $httpClient
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int{
|
||||
$tab = [
|
||||
'user' => 'charles',
|
||||
'remoteAddr' => 'rawsfsda'
|
||||
];
|
||||
$key = "!ChangeThisMercureHubJWTSecretKey!";
|
||||
$payload = [
|
||||
'mercure' => [
|
||||
'publish' => ['*'],
|
||||
'subscribe' => ['*'],
|
||||
'payload' => $tab
|
||||
],
|
||||
];
|
||||
|
||||
$jwt = JWT::encode($payload, $key, 'HS256');
|
||||
try{
|
||||
$response = $this->httpClient->request('GET', $_ENV['MERCURE_URL'] . '/subscriptions', [
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $jwt,
|
||||
'Content-Type' => 'application/ld+json',
|
||||
]
|
||||
]);
|
||||
$data = json_decode($response->getContent(), true);
|
||||
$subscriptions = $this->getSubscription($data);
|
||||
$encodedSubscriptions = json_encode($subscriptions, JSON_PRETTY_PRINT);
|
||||
$section = $output->section();
|
||||
$section2 = $output->section();
|
||||
$section->writeln('<info>Active Subscriptions:</info>');
|
||||
$section2->writeln($encodedSubscriptions);
|
||||
return Command::SUCCESS;
|
||||
}catch (\Throwable $e){
|
||||
$output->writeln('<error>Error fetching subscriptions: ' . $e->getMessage() . '</error>');
|
||||
return Command::FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
private function getSubscription(array $data): array {
|
||||
$subscriptions = [];
|
||||
foreach ($data['subscriptions'] as $sub) {
|
||||
if ($sub['active']) {
|
||||
$subscriptions[] = [
|
||||
'topic' => $sub['topic'],
|
||||
'user' => $sub['payload']['user'] ?? null,
|
||||
'remoteAddr' => $sub['payload']['remoteAddr'] ?? null,
|
||||
];
|
||||
}
|
||||
}
|
||||
return $subscriptions;
|
||||
}
|
||||
|
||||
private function getUserFromSubscription(array $subscription): ?string {
|
||||
$parts = parse_url($subscription['topic']);
|
||||
$userIdentifier = null;
|
||||
if (isset($parts['query'])) {
|
||||
parse_str($parts['query'], $query);
|
||||
if (isset($query['userId'])) {
|
||||
$userIdentifier = $query['userId'];
|
||||
}
|
||||
}
|
||||
return $userIdentifier;
|
||||
}
|
||||
|
||||
private function addSubscriptionToDb(array $subscription): void {
|
||||
// try{
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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,20 +2,24 @@
|
|||
|
||||
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 League\Bundle\OAuth2ServerBundle\Security\Authentication\Token\OAuth2Token;
|
||||
use League\Bundle\OAuth2ServerBundle\Model\AccessToken;
|
||||
use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class OAuth2Controller extends AbstractController
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
#[Route('/oauth2/userinfo', name: 'userinfo', methods: ['GET'])]
|
||||
public function userinfo(Request $request): JsonResponse
|
||||
{
|
||||
|
|
@ -53,4 +57,19 @@ class OAuth2Controller extends AbstractController
|
|||
];
|
||||
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,14 @@
|
|||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Service\AccessTokenService;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use SessionHandlerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
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 +42,43 @@ 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.');
|
||||
|
||||
try{
|
||||
$logger->info("SESSION ID: " . $stack->getSession()->getId());
|
||||
// dd($stack->getSession());
|
||||
|
||||
if( $stack->getSession()->invalidate()){
|
||||
// $accessTokenService->revokeTokens();
|
||||
$security->logout(false);
|
||||
$logger->info("Session invalidated successfully");
|
||||
} else {
|
||||
$logger->info("Session already invalidated or not started");
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
$logger->log(LogLevel::ERROR, 'Error invalidating session: ' . $e->getMessage());
|
||||
}
|
||||
// try{
|
||||
// $security->logout(false);
|
||||
// }catch (\Exception $e){
|
||||
// $logger->log(LogLevel::ERROR, 'Error during logout: ' . $e->getMessage());
|
||||
// }
|
||||
// $security->logout(false);
|
||||
// try{
|
||||
// $logger->info("Destruction de la session");
|
||||
// $sessionHandler->destroy("089gn04mts0iiiskfji8sjqr15");
|
||||
// }catch(\Exception $e){
|
||||
// // Log the error if needed
|
||||
// $logger->error("Erreur lors de la destruction de la session". $e->getMessage());
|
||||
// }
|
||||
$logger->info("Logout successfully");
|
||||
// Redirect back to the client (or to a “you are logged out” page)
|
||||
// $redirect = $request->query->get('redirect_uri', '/');
|
||||
return $this->redirect('/');
|
||||
// return new JsonResponse(["SUCCESS" => "Tokens revoked successfully"], Response::HTTP_OK);
|
||||
|
||||
}
|
||||
|
||||
#[Route(path: '/consent', name: 'app_consent')]
|
||||
|
|
@ -59,4 +99,6 @@ class SecurityController extends AbstractController
|
|||
// For GET requests, just show the consent form
|
||||
return $this->render('security/consent.html.twig');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
|
|||
|
||||
final class AccessTokenRepository implements AccessTokenRepositoryInterface
|
||||
{
|
||||
private BaseAccessTokenRepository $baseAccessTokenRepository;
|
||||
private AccessTokenRepositoryInterface $baseAccessTokenRepository;
|
||||
|
||||
public function __construct(BaseAccessTokenRepository $baseAccessTokenRepository)
|
||||
public function __construct(AccessTokenRepositoryInterface $baseAccessTokenRepository)
|
||||
{
|
||||
$this->baseAccessTokenRepository = $baseAccessTokenRepository;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,37 @@
|
|||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Repository\UsersOrganizationsRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use League\Bundle\OAuth2ServerBundle\Model\AccessToken;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
class AccessTokenService
|
||||
{
|
||||
|
||||
|
||||
public function __construct()
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
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>
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@
|
|||
</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>
|
||||
Deconnexion
|
||||
</a>
|
||||
{# <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>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
{% block body %}
|
||||
|
||||
{% if app.user %}
|
||||
<div class="mb-3">
|
||||
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{# {% if app.user %}#}
|
||||
{# <div class="mb-3">#}
|
||||
{# You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>#}
|
||||
{# </div>#}
|
||||
{# {% endif %}#}
|
||||
{% endblock %}
|
||||
|
|
|
|||
Loading…
Reference in New Issue