Enhance client management by adding PKCE option and refactoring client retrieval
Some checks failed
🧪✨ Tests Workflow / 🧪 ✨ Database Migrations (push) Has been cancelled
🧪✨ Tests Workflow / 🛡️ 🔒 Library Audit (push) Has been cancelled
🧪✨ Tests Workflow / 🛡️ 🔒 License Check (push) Has been cancelled
🧪✨ Tests Workflow / 📝 ✨ Code Lint (push) Has been cancelled
🧪✨ Tests Workflow / 🐙 🔍 Code Sniffer (push) Has been cancelled
🧪✨ Tests Workflow / 🧪 ✅ Unit Tests (push) Has been cancelled

- Introduced a boolean parameter to `askForClient` method to allow retrieval of all clients.
- Updated client creation process to include an option for requiring PKCE for Authorization Code grants.
- Refactored related code for improved clarity and functionality.
This commit is contained in:
2026-02-08 00:01:08 -05:00
parent f28d8f2ec8
commit 75757f1403
5 changed files with 34 additions and 20 deletions

View File

@@ -28,13 +28,22 @@ abstract class Command extends \Symfony\Component\Console\Command\Command implem
/** /**
* @param ClimateOutput $output * @param ClimateOutput $output
* @param ClimateOutput|ArgvInput $input * @param ClimateOutput|ArgvInput $input
* @param bool $allClients
* @return Client | null * @return Client | null
*/ */
protected function askForClient(ClimateOutput $output, ClimateOutput|ArgvInput $input): ?Client protected function askForClient(
{ ClimateOutput $output,
/** @var Collection<Client> $clients */ ClimateOutput|ArgvInput $input,
$clients = Client::whereJsonContains('grant_types', 'authorization_code') bool $allClients = false
->get(['id', 'name']); ): ?Client {
if ($allClients) {
/** @var Collection<Client> $clients */
$clients = Client::all(['id', 'name']);
} else {
/** @var Collection<Client> $clients */
$clients = Client::whereJsonContains('grant_types', 'authorization_code')
->get(['id', 'name']);
}
if ($clients->isEmpty()) { if ($clients->isEmpty()) {
$output->error('No OAuth clients available.'); $output->error('No OAuth clients available.');

View File

@@ -40,19 +40,22 @@ class CreateClient extends \Siteworxpro\App\Cli\Commands\Command
$grantsEnum[] = ClientGrantAlias::from($grant); $grantsEnum[] = ClientGrantAlias::from($grant);
} }
$question = $this->helper->ask( $isExternal = false;
$input, if (in_array('authorization_code', $grants)) {
$output, $question = $this->helper->ask(
new \Symfony\Component\Console\Question\ConfirmationQuestion( $input,
'External Client (Require PKCE)? (y/N): ', $output,
false, new \Symfony\Component\Console\Question\ConfirmationQuestion(
'/^(y|yes)/i' 'Require PKCE for Authorization Code grant? (y/N): ',
) false,
); '/^(y|yes)/i'
)
);
$isExternal = $question === 'y' || $question === true;
}
$command = new CreateClientCommand($clientName, $grantsEnum, $clientDescription, $isExternal);
$command = new CreateClientCommand($clientName, $grantsEnum, $clientDescription);
try { try {
/** @var Client $client */ /** @var Client $client */
$client = CommandBus::handle($command); $client = CommandBus::handle($command);

View File

@@ -14,7 +14,7 @@ class DeleteClient extends Command
{ {
public function __invoke(ClimateOutput|ArgvInput $input, $output): int public function __invoke(ClimateOutput|ArgvInput $input, $output): int
{ {
$client = $this->askForClient($output, $input); $client = $this->askForClient($output, $input, true);
if ($client === null) { if ($client === null) {
$output->red('No client selected, aborting.'); $output->red('No client selected, aborting.');

View File

@@ -10,6 +10,7 @@ readonly class CreateClient extends Command
* @param string $clientName * @param string $clientName
* @param array<ClientGrant | mixed> $clientGrants * @param array<ClientGrant | mixed> $clientGrants
* @param string $clientDescription * @param string $clientDescription
* @param bool $isExternal
*/ */
public function __construct( public function __construct(
private string $clientName, private string $clientName,

View File

@@ -5,16 +5,17 @@ declare(strict_types=1);
namespace Siteworxpro\App\EventListeners; namespace Siteworxpro\App\EventListeners;
use Siteworxpro\App\Attributes\Events\ListensFor; use Siteworxpro\App\Attributes\Events\ListensFor;
use Siteworxpro\App\Events\AccessToken\Issued as IssuedEvent;
use Siteworxpro\App\Models\AuditLog; use Siteworxpro\App\Models\AuditLog;
use Siteworxpro\App\Models\Enums\AuditLogAction; use Siteworxpro\App\Models\Enums\AuditLogAction;
#[ListensFor(\Siteworxpro\App\Events\AccessToken\Issued::class)] #[ListensFor(IssuedEvent::class)]
class AccessTokenIssuedListener extends Listener class AccessTokenIssuedListener extends Listener
{ {
/** /**
* Handle the event. * Handle the event.
* *
* @param string | \Siteworxpro\App\Events\AccessToken\Issued $event * @param string | IssuedEvent $event
* @param array $payload * @param array $payload
* @return AuditLog|null * @return AuditLog|null
*/ */
@@ -24,7 +25,7 @@ class AccessTokenIssuedListener extends Listener
$event = $payload[0] ?? null; $event = $payload[0] ?? null;
} }
if (!$event instanceof \Siteworxpro\App\Events\AccessToken\Issued) { if (!$event instanceof IssuedEvent) {
return null; return null;
} }