From 28f6da1a9a83f9d7193a6d0ec1798bcdeaff51ce Mon Sep 17 00:00:00 2001 From: = Date: Fri, 19 Jun 2026 05:53:19 +0000 Subject: [PATCH] Feat: Add OIDC config resolver and enhanced logging for app creation - Introduced `OidcConfigResolver` to streamline client secret checks based on app type. - Enhanced logging in `OidcService` to provide detailed insights during app creation and error handling. - Updated UI to conditionally display client secret based on app type. - Added placeholder image support for app logos. --- .../Applications/OIDC/OidcConfigResolver.php | 24 ++++++++++ .../Applications/OIDC/OidcService.php | 16 +++++++ app/Services/ConnectedAppService.php | 1 + public/images/app-icon-placeholder.png | Bin 0 -> 9261 bytes .../views/pages/apps/oidc/⚡create.blade.php | 43 ++++++++++-------- 5 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 app/Services/Applications/OIDC/OidcConfigResolver.php create mode 100644 public/images/app-icon-placeholder.png diff --git a/app/Services/Applications/OIDC/OidcConfigResolver.php b/app/Services/Applications/OIDC/OidcConfigResolver.php new file mode 100644 index 0000000..d43ce81 --- /dev/null +++ b/app/Services/Applications/OIDC/OidcConfigResolver.php @@ -0,0 +1,24 @@ +applicationType = $applicationType; + + return $this; + } + + public function hasClientSecret(): bool + { + return ApplicationTypeEnum::SPA !== $this->applicationType; + } +} diff --git a/app/Services/Applications/OIDC/OidcService.php b/app/Services/Applications/OIDC/OidcService.php index 3e8d72e..fd4cead 100644 --- a/app/Services/Applications/OIDC/OidcService.php +++ b/app/Services/Applications/OIDC/OidcService.php @@ -11,6 +11,7 @@ use App\Services\{ApplicationLogoUploader, ConnectedAppService}; use App\Services\Applications\OIDC\Factory\ClientCreationFactory; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Throwable; @@ -27,6 +28,10 @@ public function __construct( */ public function createApp(StoreOIDCAppData $data): CreatedApplicationData { + Log::info('Creating OIDC app', [ + 'name' => $data->name, + 'type' => $data->type, + ]); try { DB::beginTransaction(); $logo = $this->logoUploader->store($data->logo); @@ -47,12 +52,23 @@ public function createApp(StoreOIDCAppData $data): CreatedApplicationData // remove sensitive data $appData->settings = null; + Log::info('OIDC app created', [ + 'name' => $data->name, + 'type' => $data->type, + 'clientId' => isset($clientData->clientId), + 'clientSecret' => isset($clientData->clientSecret), + ]); + return new CreatedApplicationData( application: $appData, clientCredentials: $clientData, ); } catch (Throwable $e) { DB::rollBack(); + Log::error('Failed to create OIDC app', [ + 'name' => $data->name, + 'type' => $data->type, + ]); throw $e; } } diff --git a/app/Services/ConnectedAppService.php b/app/Services/ConnectedAppService.php index febdc94..5e9cffb 100644 --- a/app/Services/ConnectedAppService.php +++ b/app/Services/ConnectedAppService.php @@ -34,6 +34,7 @@ function () use ($data): ConnectedAppData { $data->toArray() ); + // Create a permission for this app $this->permissionService->add(ConnectedAppData::from($connectedApp), ConnectedAppPermissonEnum::Use); return ConnectedAppData::from($connectedApp); diff --git a/public/images/app-icon-placeholder.png b/public/images/app-icon-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..dc17eca3682a3461562b0a6e0e21caef0dc68d80 GIT binary patch literal 9261 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 MNL{X8)-vS(077XKjQ{`u literal 0 HcmV?d00001 diff --git a/resources/views/pages/apps/oidc/⚡create.blade.php b/resources/views/pages/apps/oidc/⚡create.blade.php index a52ceaf..0d3fa7e 100644 --- a/resources/views/pages/apps/oidc/⚡create.blade.php +++ b/resources/views/pages/apps/oidc/⚡create.blade.php @@ -7,8 +7,8 @@ use App\Livewire\Concerns\Choices\{ChoiceField, WithSearchableChoices}; use App\Livewire\Concerns\WithRepeaterFields; use App\Livewire\Forms\StoreOIDCAppForm; -use App\Services\{Applications\OIDC\OidcService, RoleService}; -use Livewire\Attributes\{Url}; +use App\Services\{Applications\OIDC\OidcConfigResolver, Applications\OIDC\OidcService, RoleService}; +use Livewire\Attributes\{Computed, Url}; use Livewire\Component; use Livewire\WithFileUploads; @@ -34,12 +34,14 @@ class extends Component { public ApplicationTypeEnum $applicationType; private RoleService $roleService; private OidcService $oidcService; + private OidcConfigResolver $configResolver; - public function boot(RoleService $roleService, OidcService $oidcService): void + public function boot(RoleService $roleService, OidcService $oidcService, OidcConfigResolver $configResolver): void { $this->roleService = $roleService; $this->oidcService = $oidcService; + $this->configResolver = $configResolver; } public function mount(): void @@ -60,6 +62,8 @@ public function save(bool $goBack = true): void function () { $data = StoreOIDCAppData::fromArray($this->applicationType, $this->form->pull()); $appdata = $this->oidcService->createApp($data); + + // Show the credentials $this->created = true; $this->clientId = $appdata->clientCredentials->clientId; $this->clientSecret = $appdata->clientCredentials->clientSecret; @@ -111,40 +115,43 @@ protected function choiceFields(): array ), ]; } + + #[Computed] + public function hasClientSecret(): bool + { + return $this->configResolver->for($this->applicationType)->hasClientSecret(); + } }; ?>
- @if($created && $clientId && $clientSecret) + @if($created)
- +

{{$app->name}}

- - - - - + @if($this->hasClientSecret) + + + @endif