diff --git a/psalm.xml b/psalm.xml index ddac7608..0eb366f7 100644 --- a/psalm.xml +++ b/psalm.xml @@ -44,6 +44,9 @@ + + + diff --git a/src/Forms/ClientForm.php b/src/Forms/ClientForm.php index 5387e316..9b43be51 100644 --- a/src/Forms/ClientForm.php +++ b/src/Forms/ClientForm.php @@ -17,12 +17,16 @@ namespace SimpleSAML\Module\oidc\Forms; use Exception; +use Nette\Forms\Container; use Nette\Forms\Form; use SimpleSAML\Auth\Source; use SimpleSAML\Module\oidc\ModuleConfig; use SimpleSAML\Module\oidc\Forms\Controls\CsrfProtection; use Traversable; +/** + * @psalm-suppress PropertyNotSetInConstructor Raised for $httpRequest which is marked as internal, so won't handle. + */ class ClientForm extends Form { protected const TYPE_ARRAY = 'array'; @@ -123,7 +127,7 @@ protected function validateByMatchingRegex( } } - public function getValues($returnType = null, ?array $controls = null): array + public function getValues(string|object|bool|null $returnType = null, ?array $controls = null): array { /** @var array $values */ $values = parent::getValues(self::TYPE_ARRAY); @@ -157,7 +161,7 @@ public function getValues($returnType = null, ?array $controls = null): array /** * @throws Exception */ - public function setDefaults($data, bool $erase = false): ClientForm + public function setDefaults(object|array $data, bool $erase = false): static { if (! is_array($data)) { if ($data instanceof Traversable) { @@ -187,7 +191,9 @@ public function setDefaults($data, bool $erase = false): ClientForm $scopes = is_array($data['scopes']) ? $data['scopes'] : []; $data['scopes'] = array_intersect($scopes, array_keys($this->getScopes())); - return parent::setDefaults($data, $erase); + parent::setDefaults($data, $erase); + + return $this; } /** @@ -203,7 +209,7 @@ protected function buildForm(): void $this->onValidate[] = $this->validateBackChannelLogoutUri(...); $this->setMethod('POST'); - $this->addComponent(new CsrfProtection('{oidc:client:csrf_error}'), Form::PROTECTOR_ID); + $this->addComponent(new CsrfProtection('{oidc:client:csrf_error}'), Form::ProtectorId); $this->addText('name', '{oidc:client:name}') ->setMaxLength(255) diff --git a/src/Forms/Controls/CsrfProtection.php b/src/Forms/Controls/CsrfProtection.php index f7b81dd6..1935b4a9 100644 --- a/src/Forms/Controls/CsrfProtection.php +++ b/src/Forms/Controls/CsrfProtection.php @@ -21,6 +21,7 @@ use Nette\InvalidStateException; use Nette\Utils\Random; use SimpleSAML\Session; +use Stringable; class CsrfProtection extends BaseCsrfProtection { @@ -32,7 +33,7 @@ class CsrfProtection extends BaseCsrfProtection /** * @throws Exception */ - public function __construct(object|string $errorMessage) + public function __construct(string|Stringable|null $errorMessage) { // Instead of calling CsrfProtection parent class constructor, go to it's parent (HiddenField), and call // its constructor. This is to avoid setting a Nette session in CsrfProtection parent, and use the SSP one. diff --git a/src/Utils/ClaimTranslatorExtractor.php b/src/Utils/ClaimTranslatorExtractor.php index fee1ebfb..e52fc404 100644 --- a/src/Utils/ClaimTranslatorExtractor.php +++ b/src/Utils/ClaimTranslatorExtractor.php @@ -197,7 +197,7 @@ public function addClaimSet(ClaimSetEntityInterface $claimSet): self { $scope = $claimSet->getScope(); - if (in_array($scope, $this->protectedClaims) && !empty($this->claimSets[$scope])) { + if (in_array($scope, $this->protectedClaims) && isset($this->claimSets[$scope])) { throw OidcServerException::serverError( sprintf("%s is a protected scope and is pre-defined by the OpenID Connect specification.", $scope) );