This commit is contained in:
Bastian Wagner
2026-07-15 17:59:25 +02:00
parent 7a6e08d2c5
commit ba7029ac7b
10 changed files with 469 additions and 76 deletions

View File

@@ -61,7 +61,7 @@ interface CreatedOidcClient extends OidcClient {
</label>
<label class="check-row">
<input type="checkbox" formControlName="firstParty">
First-Party Client
First-Party Client (Consent ueberspringen)
</label>
<label class="check-row">
<input type="checkbox" formControlName="includeGroups">
@@ -76,6 +76,7 @@ interface CreatedOidcClient extends OidcClient {
<div class="secret-box">
<strong>Client Secret</strong>
<code>{{ createdSecret() }}</code>
<small>Dieses Secret wird nur einmal angezeigt.</small>
</div>
}
</article>
@@ -128,7 +129,7 @@ interface CreatedOidcClient extends OidcClient {
</label>
<label class="check-row">
<input type="checkbox" formControlName="firstParty">
First-Party Client
First-Party Client (Consent ueberspringen)
</label>
<label class="check-row">
<input type="checkbox" formControlName="includeGroups">
@@ -162,6 +163,11 @@ interface CreatedOidcClient extends OidcClient {
<button type="button" class="secondary-action" (click)="toggle(client)">
{{ client.enabled ? 'Deaktivieren' : 'Aktivieren' }}
</button>
@if (canRotateSecret(client)) {
<button type="button" class="secondary-action" (click)="rotateSecret(client)">Secret rotieren</button>
} @else {
<span class="muted-action">Public Client ohne Secret</span>
}
<button type="button" class="danger-action" (click)="delete(client)">Loeschen</button>
</div>
}
@@ -252,6 +258,39 @@ export class AdminOidcClientsComponent implements OnInit {
.subscribe({ next: () => this.load(), error: (error) => this.message.set(apiErrorMessage(error)) });
}
canRotateSecret(client: OidcClient): boolean {
return client.tokenEndpointAuthMethod !== 'none';
}
rotateSecret(client: OidcClient): void {
const confirmed = window.confirm(
'Das Client Secret wird neu erzeugt und nur einmal angezeigt. Bestehende Apps muessen danach das neue Secret verwenden.',
);
if (!confirmed) {
return;
}
this.loading.set(true);
this.failed.set(false);
this.message.set('');
this.createdSecret.set('');
this.http
.post<CreatedOidcClient>(`${this.apiBaseUrl}/admin/oidc/clients/${client.id}/secret/rotate`, {})
.subscribe({
next: (updatedClient) => {
this.createdSecret.set(updatedClient.clientSecret ?? '');
this.message.set('Client Secret wurde rotiert.');
this.load();
},
error: (error) => {
this.failed.set(true);
this.message.set(apiErrorMessage(error));
this.loading.set(false);
},
complete: () => this.loading.set(false),
});
}
startEdit(client: OidcClient): void {
this.failed.set(false);
this.message.set('');

View File

@@ -383,6 +383,14 @@ code {
gap: 8px;
}
.muted-action {
align-items: center;
color: #637083;
display: inline-flex;
font-size: 0.9rem;
min-height: 38px;
}
.inline-form {
align-items: end;
display: flex;