Files
zitadel/console/src/app/modules/policies/oidc-webkeys/oidc-webkeys.component.ts
T
RamonandGitHub 23f0cd0ade chore(console): remove all console eslint warnings (#11853)
<!--
Please inform yourself about the contribution guidelines on submitting a
PR here:
https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr.
Take note of how PR/commit titles should be written and replace the
template texts in the sections below. Don't remove any of the sections.
It is important that the commit history clearly shows what is changed
and why.
Important: By submitting a contribution you agree to the terms from our
Licensing Policy as described here:
https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions.
-->

# Which Problems Are Solved

When running the nx target @zitadel/console:lint-check-ng currently
there are a lot of eslint warnings.

# How the Problems Are Solved

Removed unused variables, imports etc.

# Additional Changes

# Additional Context
2026-04-07 09:28:22 +00:00

177 lines
5.5 KiB
TypeScript

import { ChangeDetectionStrategy, Component, DestroyRef, signal } from '@angular/core';
import { WebKeysService } from 'src/app/services/webkeys.service';
import { firstValueFrom, Observable, ObservedValueOf, shareReplay, Subject, switchMap } from 'rxjs';
import { catchError, map, startWith } from 'rxjs/operators';
import { ToastService } from 'src/app/services/toast.service';
import { MessageInitShape } from '@bufbuild/protobuf';
import { OidcWebKeysCreateComponent } from './oidc-webkeys-create/oidc-webkeys-create.component';
import { TimestampToDatePipe } from 'src/app/pipes/timestamp-to-date-pipe/timestamp-to-date.pipe';
import { MatDialog } from '@angular/material/dialog';
import { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CreateWebKeyRequestSchema } from '@zitadel/proto/zitadel/webkey/v2/webkey_service_pb';
import { RSAHasher, RSABits, ECDSACurve, State, WebKey } from '@zitadel/proto/zitadel/webkey/v2/key_pb';
const CACHE_WARNING_MS = 5 * 60 * 1000; // 5 minutes
@Component({
selector: 'cnsl-oidc-webkeys',
templateUrl: './oidc-webkeys.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
})
export class OidcWebKeysComponent {
protected readonly refresh = new Subject<true>();
protected readonly webKeys$: Observable<WebKey[]>;
protected readonly inactiveWebKeys$: Observable<WebKey[]>;
protected readonly nextWebKeyCandidate$: Observable<WebKey | undefined>;
protected readonly activateLoading = signal(false);
protected readonly createLoading = signal(false);
constructor(
private readonly webKeysService: WebKeysService,
private readonly toast: ToastService,
private readonly timestampToDatePipe: TimestampToDatePipe,
private readonly dialog: MatDialog,
private readonly destroyRef: DestroyRef,
) {
const webKeys$ = this.getWebKeys().pipe(shareReplay({ refCount: true, bufferSize: 1 }));
this.webKeys$ = webKeys$.pipe(map((webKeys) => webKeys.filter((webKey) => webKey.state !== State.INACTIVE)));
this.inactiveWebKeys$ = webKeys$.pipe(map((webKeys) => webKeys.filter((webKey) => webKey.state === State.INACTIVE)));
this.nextWebKeyCandidate$ = this.getNextWebKeyCandidate(this.webKeys$);
}
private getWebKeys() {
return this.refresh.pipe(
startWith(true),
switchMap(() => {
return this.webKeysService.ListWebKeys();
}),
map(({ webKeys }) => webKeys),
catchError(async (err) => {
this.toast.showError(err);
return [];
}),
);
}
private getNextWebKeyCandidate(webKeys$: Observable<WebKey[]>) {
return webKeys$.pipe(
map((webKeys) => {
if (webKeys.length < 2) {
return undefined;
}
const [webKey, nextWebKey] = webKeys;
if (webKey.state !== State.ACTIVE) {
return undefined;
}
if (nextWebKey.state !== State.INITIAL) {
return undefined;
}
return nextWebKey;
}),
);
}
protected async createWebKey(event: ObservedValueOf<OidcWebKeysCreateComponent['ngSubmit']>) {
try {
this.createLoading.set(true);
const req = !event
? this.createEd25519()
: 'curve' in event
? this.createEcdsa(event.curve)
: this.createRsa(event.bits, event.hasher);
await this.webKeysService.CreateWebKey(req);
this.refresh.next(true);
} catch (error) {
this.toast.showError(error);
} finally {
this.createLoading.set(false);
}
}
private createEd25519(): MessageInitShape<typeof CreateWebKeyRequestSchema> {
return {
key: {
case: 'ed25519',
value: {},
},
};
}
private createEcdsa(curve: ECDSACurve): MessageInitShape<typeof CreateWebKeyRequestSchema> {
return {
key: {
case: 'ecdsa',
value: {
curve,
},
},
};
}
private createRsa(bits: RSABits, hasher: RSAHasher): MessageInitShape<typeof CreateWebKeyRequestSchema> {
return {
key: {
case: 'rsa',
value: {
bits,
hasher,
},
},
};
}
protected async deleteWebKey(row: WebKey) {
try {
await this.webKeysService.DeleteWebKey(row.id);
this.refresh.next(true);
} catch (err) {
this.toast.showError(err);
}
}
protected async activateWebKey(nextWebKey: WebKey) {
try {
this.activateLoading.set(true);
const creationDate = this.timestampToDatePipe.transform(nextWebKey.creationDate);
if (!creationDate) {
// noinspection ExceptionCaughtLocallyJS
throw new Error('Invalid creation date');
}
const diffToCurrentTime = Date.now() - creationDate.getTime();
if (diffToCurrentTime < CACHE_WARNING_MS && !(await this.openCacheWarnDialog())) {
return;
}
await this.webKeysService.ActivateWebKey(nextWebKey.id);
this.refresh.next(true);
} catch (error) {
this.toast.showError(error);
} finally {
this.activateLoading.set(false);
}
}
private openCacheWarnDialog() {
const dialogRef = this.dialog.open(WarnDialogComponent, {
data: {
confirmKey: 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.ACTIVATE',
cancelKey: 'ACTIONS.CANCEL',
titleKey: 'Web Key is less then 5 min old',
descriptionKey: 'DESCRIPTIONS.SETTINGS.WEB_KEYS.TABLE.NOTE',
},
width: '400px',
});
const obs = dialogRef.afterClosed().pipe(map(Boolean), takeUntilDestroyed(this.destroyRef));
return firstValueFrom(obs);
}
}