From 1c2fc386ada5948ba051408edb22ef6cc556a527 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 15:23:39 +0200 Subject: [PATCH 01/11] rename 'profile' directory to 'user' --- docker/solid.conf | 4 ++-- www/{profile/index.php => user/profile.php} | 0 www/{profile => user}/storage.php | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename www/{profile/index.php => user/profile.php} (100%) rename www/{profile => user}/storage.php (100%) diff --git a/docker/solid.conf b/docker/solid.conf index a1634a3..df551b3 100644 --- a/docker/solid.conf +++ b/docker/solid.conf @@ -20,7 +20,7 @@ ServerName identity.solid.local ServerAlias *.solid.local - DocumentRoot /opt/solid/www/profile + DocumentRoot /opt/solid/www/user SSLEngine on SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem @@ -39,7 +39,7 @@ RewriteCond %{HTTP_HOST} ^id-([a-zA-Z0-9-]+)\.solid\.local$ [NC] # Example rewrite rule based on the first part of the hostname # This will redirect to /subdomain-content/first_part_of_hostname - RewriteRule ^(.+)$ index.php [QSA,L] + RewriteRule ^(.+)$ profile.php [QSA,L] # Extract the first part of the subdomain (before the first dot) RewriteCond %{HTTP_HOST} ^storage-([a-zA-Z0-9-]+)\.solid\.local$ [NC] diff --git a/www/profile/index.php b/www/user/profile.php similarity index 100% rename from www/profile/index.php rename to www/user/profile.php diff --git a/www/profile/storage.php b/www/user/storage.php similarity index 100% rename from www/profile/storage.php rename to www/user/storage.php From 4ee943914f1847c966fb95a9574e7178d6248e89 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 15:24:52 +0200 Subject: [PATCH 02/11] move session handling out of the user class --- lib/Session.php | 20 ++++++++++++++++++++ lib/User.php | 12 ------------ www/idp/index.php | 12 +++++++----- 3 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 lib/Session.php diff --git a/lib/Session.php b/lib/Session.php new file mode 100644 index 0000000..a65ceeb --- /dev/null +++ b/lib/Session.php @@ -0,0 +1,20 @@ + 24*60*60 // 1 day + ]); + $_SESSION['username'] = $email; + } + + public static function getLoggedInUser() { + session_start(); + if (!isset($_SESSION['username'])) { + return false; + } + return self::getUser($_SESSION['username']); + } + } diff --git a/lib/User.php b/lib/User.php index 22a2527..9613b81 100644 --- a/lib/User.php +++ b/lib/User.php @@ -247,24 +247,12 @@ public static function checkPassword($email, $password) { $result = $query->fetchAll(); if (sizeof($result) === 1) { if (password_verify($password, $result[0]['password'])) { - session_start([ - 'cookie_lifetime' => 24*60*60 // 1 day - ]); - $_SESSION['username'] = $email; return true; } } return false; } - public static function getLoggedInUser() { - session_start(); - if (!isset($_SESSION['username'])) { - return false; - } - return self::getUser($_SESSION['username']); - } - public static function userIdExists($userId) { Db::connect(); $query = Db::$pdo->prepare( diff --git a/www/idp/index.php b/www/idp/index.php index 4112334..196ece5 100644 --- a/www/idp/index.php +++ b/www/idp/index.php @@ -10,6 +10,7 @@ use Pdsinterop\PhpSolid\Server; use Pdsinterop\PhpSolid\ClientRegistration; use Pdsinterop\PhpSolid\User; + use Pdsinterop\PhpSolid\Session; use Pdsinterop\PhpSolid\Mailer; use Pdsinterop\PhpSolid\IpAttempts; use Pdsinterop\PhpSolid\JtiStore; @@ -36,7 +37,7 @@ break; case "/authorize": case "/authorize/": - $user = User::getLoggedInUser(); + $user = Session::getLoggedInUser(); if (!$user) { header("Location: /login/?redirect_uri=" . urlencode($_SERVER['REQUEST_URI'])); exit(); @@ -124,7 +125,7 @@ break; case "/dashboard": case "/dashboard/": - $user = User::getLoggedInUser(); + $user = Session::getLoggedInUser(); if (!$user) { header("Location: /login/"); exit(); @@ -133,7 +134,7 @@ break; case "/logout": case "/logout/": - $user = User::getLoggedInUser(); + $user = Session::getLoggedInUser(); if ($user) { session_destroy(); } @@ -161,7 +162,7 @@ break; case "/sharing": case "/sharing/": - $user = User::getLoggedInUser(); + $user = Session::getLoggedInUser(); if (!$user) { header("Location: /login/"); exit(); @@ -311,6 +312,7 @@ exit(); } if (User::checkPassword($_POST['username'], $_POST['password'])) { + Session::start($_POST['username']); if (!isset($_POST['redirect_uri']) || $_POST['redirect_uri'] === '') { header("Location: /dashboard/"); exit(); @@ -366,7 +368,7 @@ break; case "/api/sharing": case "/api/sharing/": - $user = User::getLoggedInUser(); + $user = Session::getLoggedInUser(); if (!$user) { header("HTTP/1.1 400 Bad request"); } else { From a1845d01df63846ddf5b87da2a2e3709d482cab6 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 15:25:09 +0200 Subject: [PATCH 03/11] typofix in table name --- lib/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/User.php b/lib/User.php index 9613b81..d897883 100644 --- a/lib/User.php +++ b/lib/User.php @@ -178,7 +178,7 @@ public static function getStorage($userId) { public static function setStorage($userId, $storageUrl) { Db::connect(); $query = Db::$pdo->prepare( - 'INSERT OR REPLACE INTO storage VALUES(:userId, :storageUrl)' + 'INSERT OR REPLACE INTO userStorage VALUES(:userId, :storageUrl)' ); $query->execute([ ':userId' => $userId, From 0152240bcede8599e9be05cfb8dd22aa77548afe Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 15:37:39 +0200 Subject: [PATCH 04/11] make sure we only use the first storage. added FIXME to support multiple storage pods --- tests/phpunit/UserTest.php | 256 ++++++++++++++++++++++++++++++++++ tests/phpunit/test-config.php | 4 + www/user/profile.php | 5 +- 3 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/UserTest.php diff --git a/tests/phpunit/UserTest.php b/tests/phpunit/UserTest.php new file mode 100644 index 0000000..9cc2be1 --- /dev/null +++ b/tests/phpunit/UserTest.php @@ -0,0 +1,256 @@ +add(new \DateInterval('P120M')); + $statements = [ + 'DROP TABLE IF EXISTS allowedClients', + 'DROP TABLE IF EXISTS userStorage', + 'DROP TABLE IF EXISTS verify', + 'DROP TABLE IF EXISTS users', + 'CREATE TABLE IF NOT EXISTS allowedClients ( + userId VARCHAR(255) NOT NULL PRIMARY KEY, + clientId VARCHAR(255) NOT NULL + )', + 'CREATE TABLE IF NOT EXISTS userStorage ( + userId VARCHAR(255) NOT NULL PRIMARY KEY, + storageUrl VARCHAR(255) NOT NULL + )', + 'CREATE TABLE IF NOT EXISTS verify ( + code VARCHAR(255) NOT NULL PRIMARY KEY, + data TEXT NOT NULL + )', + 'CREATE TABLE IF NOT EXISTS users ( + user_id VARCHAR(255) NOT NULL PRIMARY KEY, + email TEXT NOT NULL, + password TEXT NOT NULL, + data TEXT + )', + 'INSERT INTO verify VALUES("test1", \'{"expires": 0, "hello": "world", "code": "test1"}\')', + 'INSERT INTO verify VALUES("test2", \'{"expires": ' . $futureTimestamp->getTimestamp() . ', "hello": "world", "code": "test2"}\')' + ]; + + Db::connect(); + try { + // create tables + foreach($statements as $statement){ + Db::$pdo->exec($statement); + } + } catch(\PDOException $e) { + echo $e->getMessage(); + } + } + + public function testSaveVerifyToken() { + $beforeExpires = new \DateTime(); + $beforeExpires->add(new \DateInterval('PT29M')); + + $afterExpires = new \DateTime(); + $afterExpires->add(new \DateInterval('PT31M')); + $token = User::saveVerifyToken("verify", [ + "hello" => "world" + ]); + $this->assertTrue($token['expires'] > $beforeExpires->getTimestamp()); + $this->assertTrue($token['expires'] < $afterExpires->getTimestamp()); + + $storedToken = User::getVerifyToken($token['code']); + $this->assertEquals($storedToken['hello'], "world"); + } + + public function testSavePasswordResetToken() { + $beforeExpires = new \DateTime(); + $beforeExpires->add(new \DateInterval('PT29M')); + + $afterExpires = new \DateTime(); + $afterExpires->add(new \DateInterval('PT31M')); + $token = User::saveVerifyToken("verify", [ + "hello" => "world" + ]); + $this->assertTrue($token['expires'] > $beforeExpires->getTimestamp()); + $this->assertTrue($token['expires'] < $afterExpires->getTimestamp()); + + $storedToken = User::getVerifyToken($token['code']); + $this->assertEquals($storedToken['hello'], "world"); + } + + public function testSaveAccountDeleteToken() { + $beforeExpires = new \DateTime(); + $beforeExpires->add(new \DateInterval('PT29M')); + + $afterExpires = new \DateTime(); + $afterExpires->add(new \DateInterval('PT31M')); + $token = User::saveVerifyToken("verify", [ + "hello" => "world" + ]); + $this->assertTrue($token['expires'] > $beforeExpires->getTimestamp()); + $this->assertTrue($token['expires'] < $afterExpires->getTimestamp()); + + $storedToken = User::getVerifyToken($token['code']); + $this->assertEquals($storedToken['hello'], "world"); + } + + public function testExpiredToken() { + $token = User::getVerifyToken("test1"); + $this->assertFalse($token); + } + + public function testNonExpiredToken() { + $token = User::getVerifyToken("test2"); + $this->assertEquals($token['hello'], "world"); + } + + public function testCreateUser() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + $this->assertEquals($createdUser['email'], "user@example.com"); + $this->assertTrue(isset($createdUser['webId'])); + $this->assertTrue(isset($createdUser['userId'])); + $this->assertTrue(strlen($createdUser['userId']) === 32); + + $canLogIn = User::checkPassword($newUser['email'], $newUser['password']); + $this->assertTrue($canLogIn); + } + + public function testGetUser() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user2@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + + $userByEmail = User::getUser($newUser['email']); + $this->assertEquals($userByEmail['webId'], $createdUser['webId']); + $this->assertEquals($userByEmail['hello'], 'world'); + $this->assertTrue(isset($userByEmail['allowedClients'])); + $this->assertEquals($userByEmail['issuer'], "https://solid.example.com"); + } + + public function testGetUserById() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user3@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + + $userById = User::getUserById($createdUser['userId']); + $this->assertEquals($userById['webId'], $createdUser['webId']); + $this->assertEquals($userById['hello'], 'world'); + $this->assertTrue(isset($userById['allowedClients'])); + $this->assertEquals($userById['issuer'], "https://solid.example.com"); + } + + public function testSetPasswordNonExistingUser() { + $result = User::setUserPassword("not_here@example.com", "hello123!@#ABC"); + $this->assertFalse($result); + } + + public function testSetWeakPassword() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user4@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + $result = User::setUserPassword($newUser['email'], "a"); + $this->assertFalse($result); + } + + public function testLogin() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user5@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + + $canLogIn = User::checkPassword($newUser['email'], $newUser['password']); + $this->assertTrue($canLogIn); + } + + public function testLoginFailed() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user6@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + + $canLogIn = User::checkPassword($newUser['email'], "something else"); + $this->assertFalse($canLogIn); + } + + public function testSetStrongPassword() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user7@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + + $result = User::setUserPassword($newUser['email'], "this is a strong password because it is long enough"); + $this->assertTrue($result); + } + + public function testLoginAfterChange() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user8@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + $canLogIn = User::checkPassword($newUser['email'], $newUser['password']); + $this->assertTrue($canLogIn); + + $newPassword = "this is a strong password because it is long enough"; + $result = User::setUserPassword($newUser['email'], $newPassword); + $this->assertTrue($result); + + $canLogIn = User::checkPassword($newUser['email'], "something else"); + $this->assertFalse($canLogIn); + + $canLogIn = User::checkPassword($newUser['email'], $newUser['password']); + $this->assertFalse($canLogIn); + + $canLogIn = User::checkPassword($newUser['email'], $newPassword); + $this->assertTrue($canLogIn); + } + + public function testUserStorage() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user9@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + $storageUrl = "https://storage.example.com"; + User::setStorage($createdUser['userId'], $storageUrl); + + $savedStorage = User::getStorage($createdUser['userId']); + + $this->assertTrue(in_array($storageUrl, $savedStorage)); + + $user = User::getUser($newUser['email']); + $this->assertTrue(in_array($storageUrl, $user['storage'])); + } + + // @TODO Write tests for these functions: + // userIdExists + // userEmailExists + // deleteAccount + // cleanupTokens +} diff --git a/tests/phpunit/test-config.php b/tests/phpunit/test-config.php index c917c6c..e634ab1 100644 --- a/tests/phpunit/test-config.php +++ b/tests/phpunit/test-config.php @@ -3,3 +3,7 @@ const DBPATH = ":memory:"; const TRUSTED_IPS = ['127.0.0.100']; +const BANNED_PASSWORDS = []; +const MINIMUM_PASSWORD_ENTROPY = 10; +const BASEDOMAIN = "solid.example.com"; +const BASEURL = "https://solid.example.com"; \ No newline at end of file diff --git a/www/user/profile.php b/www/user/profile.php index f3d1a0c..c18e534 100644 --- a/www/user/profile.php +++ b/www/user/profile.php @@ -23,9 +23,12 @@ $userId = preg_replace("/^id-/", "", $idPart); $user = User::getUserById($userId); - if (!isset($user['storage'])) { + if (!isset($user['storage']) || !$user['storage']) { $user['storage'] = "https://storage-" . $userId . "." . BASEDOMAIN . "/"; } + if (is_array($user['storage'])) { // empty array is already handled + $user['storage'] = array_values($user['storage'])[0]; // FIXME: Handle multiple storage pods + } if (!isset($user['issuer'])) { $user['issuer'] = BASEURL; } From df1197c34d7165e54513a6db1825844c4bc762a8 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 15:46:32 +0200 Subject: [PATCH 05/11] get user from session --- lib/Session.php | 4 ++-- lib/User.php | 3 +++ www/idp/index.php | 10 +++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/Session.php b/lib/Session.php index a65ceeb..4711287 100644 --- a/lib/Session.php +++ b/lib/Session.php @@ -7,7 +7,7 @@ public static function start($username) { session_start([ 'cookie_lifetime' => 24*60*60 // 1 day ]); - $_SESSION['username'] = $email; + $_SESSION['username'] = $username; } public static function getLoggedInUser() { @@ -15,6 +15,6 @@ public static function getLoggedInUser() { if (!isset($_SESSION['username'])) { return false; } - return self::getUser($_SESSION['username']); + return $_SESSION['username']; } } diff --git a/lib/User.php b/lib/User.php index d897883..2b108d4 100644 --- a/lib/User.php +++ b/lib/User.php @@ -187,6 +187,9 @@ public static function setStorage($userId, $storageUrl) { } public static function getUser($email) { + if (!isset($email)) { + return false; + } Db::connect(); $query = Db::$pdo->prepare( 'SELECT user_id, data FROM users WHERE email=:email' diff --git a/www/idp/index.php b/www/idp/index.php index 196ece5..5b6517e 100644 --- a/www/idp/index.php +++ b/www/idp/index.php @@ -37,7 +37,7 @@ break; case "/authorize": case "/authorize/": - $user = Session::getLoggedInUser(); + $user = User::getUser(Session::getLoggedInUser()); if (!$user) { header("Location: /login/?redirect_uri=" . urlencode($_SERVER['REQUEST_URI'])); exit(); @@ -125,7 +125,7 @@ break; case "/dashboard": case "/dashboard/": - $user = Session::getLoggedInUser(); + $user = User::getUser(Session::getLoggedInUser()); if (!$user) { header("Location: /login/"); exit(); @@ -134,7 +134,7 @@ break; case "/logout": case "/logout/": - $user = Session::getLoggedInUser(); + $user = User::getUser(Session::getLoggedInUser()); if ($user) { session_destroy(); } @@ -162,7 +162,7 @@ break; case "/sharing": case "/sharing/": - $user = Session::getLoggedInUser(); + $user = User::getUser(Session::getLoggedInUser()); if (!$user) { header("Location: /login/"); exit(); @@ -368,7 +368,7 @@ break; case "/api/sharing": case "/api/sharing/": - $user = Session::getLoggedInUser(); + $user = User::getUser(Session::getLoggedInUser()); if (!$user) { header("HTTP/1.1 400 Bad request"); } else { From de0de1abfb893e5cdb1e71fcc6bf0eddba2f89af Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 15:54:00 +0200 Subject: [PATCH 06/11] add user exists tests --- tests/phpunit/UserTest.php | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/UserTest.php b/tests/phpunit/UserTest.php index 9cc2be1..7b5b51d 100644 --- a/tests/phpunit/UserTest.php +++ b/tests/phpunit/UserTest.php @@ -248,9 +248,41 @@ public function testUserStorage() { $this->assertTrue(in_array($storageUrl, $user['storage'])); } + public function testUserExistsById() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user10@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + + $userExists = User::userIdExists($createdUser['userId']); + $this->assertTrue($userExists); + } + + public function testUserDoesNotExistsById() { + $userExists = User::userIdExists("foo"); + $this->assertFalse($userExists); + } + + public function testUserExistsByEmail() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user11@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + + $userExists = User::userEmailExists($newUser['email']); + $this->assertTrue($userExists); + } + + public function testUserDoesNotExistsByEmail() { + $userExists = User::userIdExists("foo@example.com"); + $this->assertFalse($userExists); + } + // @TODO Write tests for these functions: - // userIdExists - // userEmailExists // deleteAccount // cleanupTokens } From 96c0327fea62a78eacc4e4879764a3488429ef3b Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 16:15:14 +0200 Subject: [PATCH 07/11] completed user test class --- tests/phpunit/UserTest.php | 74 +++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/UserTest.php b/tests/phpunit/UserTest.php index 7b5b51d..b61faeb 100644 --- a/tests/phpunit/UserTest.php +++ b/tests/phpunit/UserTest.php @@ -278,11 +278,77 @@ public function testUserExistsByEmail() { } public function testUserDoesNotExistsByEmail() { - $userExists = User::userIdExists("foo@example.com"); + $userExists = User::userEmailExists("foo@example.com"); $this->assertFalse($userExists); } + + public function testAllowClientForUser() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user11@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + + $clientId = "12345"; + $result = User::allowClientForUser($clientId, $createdUser['userId']); + $this->assertTrue($result); + + $allowedClients = User::getAllowedClients($createdUser['userId']); + $this->assertTrue(in_array($clientId, $allowedClients)); + + $user = User::getUser($newUser['email']); + $this->assertTrue(in_array($clientId, $user['allowedClients'])); + } + + public function testDeleteAccount() { + $newUser = [ + "password" => "hello123!@#ABC", + "email" => "user11@example.com", + "hello" => "world" + ]; + $createdUser = User::createUser($newUser); + $clientId = "12345"; + $result = User::allowClientForUser($clientId, $createdUser['userId']); + + $this->assertTrue(User::userIdExists($createdUser['userId'])); + $this->assertTrue(User::userEmailExists($newUser['email'])); + $allowedClients = User::getAllowedClients($createdUser['userId']); + $this->assertTrue(in_array($clientId, $allowedClients)); + + User::deleteAccount($newUser['email']); + + $this->assertFalse(User::userIdExists($createdUser['userId'])); + $this->assertFalse(User::userEmailExists($newUser['email'])); + $allowedClients = User::getAllowedClients($createdUser['userId']); + $this->assertEmpty($allowedClients); + } + + public function testCleanup() { + // empty the verify table first so we have dependable numbers + $query = Db::$pdo->prepare('DELETE FROM verify WHERE NOT code=""'); + $query->execute(); + + $token1 = User::saveVerifyToken("verify", [ + "hello" => "world", + "expires" => time() - 10 + ]); + $token2 = User::saveVerifyToken("verify", [ + "hello" => "world", + "expires" => time() - 10 + ]); + $query = Db::$pdo->prepare('SELECT count(*) AS count FROM verify'); + $query->execute(); + $result = $query->fetchAll(); + $beforeCleanup = $result[0]['count']; + $this->assertEquals(2, $beforeCleanup); - // @TODO Write tests for these functions: - // deleteAccount - // cleanupTokens + User::cleanupTokens(); + $query = Db::$pdo->prepare('SELECT count(*) AS count FROM verify'); + $query->execute(); + $result = $query->fetchAll(); + $afterCleanup = $result[0]['count']; + + $this->assertEquals(0, $afterCleanup); + } } From 9c989d8765bc6cce909f036f182123d954b7f0b0 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 16:16:16 +0200 Subject: [PATCH 08/11] updated TODO --- TODO | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 0e4659a..8e014c9 100644 --- a/TODO +++ b/TODO @@ -65,13 +65,14 @@ - [v] IpAttempts - [v] Util - [v] PasswordValidator +- [v] User - [ ] Mailer - [ ] MailTemplateGenerator - [ ] MailTemplates - [ ] Server -- [ ] SolidNotifications -- [ ] SolidPubSub - [ ] StorageServer -- [ ] User +- [-] Session +- [-] SolidNotifications +- [-] SolidPubSub - [-] Middleware - [-] Db From d26af8f5998b5d6655a227b6719fbeaa21b7aed2 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 16:20:49 +0200 Subject: [PATCH 09/11] phpstan fix --- www/idp/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/idp/index.php b/www/idp/index.php index 5b6517e..c8dfc16 100644 --- a/www/idp/index.php +++ b/www/idp/index.php @@ -66,10 +66,10 @@ \Lcobucci\JWT\Signer\Key\InMemory::plainText($keys['privateKey'] )); + $token = $jwtConfig->parser()->parse($_GET['request']); if (isset($_GET['nonce'])) { $_SESSION['nonce'] = $_GET['nonce']; } else if (isset($_GET['request'])) { - $token = $jwtConfig->parser()->parse($_GET['request']); $_SESSION['nonce'] = $token->claims()->get('nonce'); } From 378abf4eac827e0a0e8a43e0ff7202f6d74bc29b Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 16:28:03 +0200 Subject: [PATCH 10/11] Revert "phpstan fix" This reverts commit d26af8f5998b5d6655a227b6719fbeaa21b7aed2. --- www/idp/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/idp/index.php b/www/idp/index.php index c8dfc16..5b6517e 100644 --- a/www/idp/index.php +++ b/www/idp/index.php @@ -66,10 +66,10 @@ \Lcobucci\JWT\Signer\Key\InMemory::plainText($keys['privateKey'] )); - $token = $jwtConfig->parser()->parse($_GET['request']); if (isset($_GET['nonce'])) { $_SESSION['nonce'] = $_GET['nonce']; } else if (isset($_GET['request'])) { + $token = $jwtConfig->parser()->parse($_GET['request']); $_SESSION['nonce'] = $token->claims()->get('nonce'); } From 5a9623df708ee3002b96ac9b5be21b7c1e55dbb0 Mon Sep 17 00:00:00 2001 From: Yvo Brevoort Date: Mon, 7 Jul 2025 16:32:22 +0200 Subject: [PATCH 11/11] check for token --- www/idp/index.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/idp/index.php b/www/idp/index.php index 5b6517e..10ba492 100644 --- a/www/idp/index.php +++ b/www/idp/index.php @@ -74,7 +74,9 @@ } if (!isset($getVars["redirect_uri"])) { - $getVars['redirect_uri'] = $token->claims()->get("redirect_uri"); + if (isset($token)) { + $getVars['redirect_uri'] = $token->claims()->get("redirect_uri"); + } } }