mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-01 03:52:14 +00:00
fix(console): Implement generic feature toggle (#9516)
This PR implements a component which is used to render the feature settings in a generic way. All features besides`loginV2` and `improvedPerformance` are rendered. Note: The feature flags are not autogenerated as the console needs descriptions for the respective features and there are multiple types where additional fields like text input is required Closes #9090 --------- Co-authored-by: conblem <[email protected]>
This commit is contained in:
@@ -20,389 +20,13 @@
|
||||
|
||||
<cnsl-card *ngIf="toggleStates && featureData">
|
||||
<div class="features">
|
||||
<div class="feature-row" *ngIf="toggleStates.loginDefaultOrg">
|
||||
<span>{{ 'SETTING.FEATURES.LOGINDEFAULTORG' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleStates.loginDefaultOrg.state"
|
||||
(change)="validateAndSave()"
|
||||
name="displayview"
|
||||
aria-label="Display View"
|
||||
>
|
||||
<mat-button-toggle [value]="ToggleState.INHERITED">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
|
||||
<i
|
||||
class="info-i las la-question-circle"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
|
||||
></i>
|
||||
<div
|
||||
*ngIf="
|
||||
!!featureData.loginDefaultOrg?.enabled &&
|
||||
(featureData.loginDefaultOrg?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.loginDefaultOrg?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot enabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="
|
||||
!featureData.loginDefaultOrg?.enabled &&
|
||||
(featureData.loginDefaultOrg?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.loginDefaultOrg?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot disabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.DISABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.ENABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.FEATURES.LOGINDEFAULTORG_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<div class="feature-row" *ngIf="toggleStates.oidcLegacyIntrospection">
|
||||
<span>{{ 'SETTING.FEATURES.OIDCLEGACYINTROSPECTION' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleStates.oidcLegacyIntrospection.state"
|
||||
(change)="validateAndSave()"
|
||||
name="displayview"
|
||||
aria-label="Display View"
|
||||
>
|
||||
<mat-button-toggle [value]="ToggleState.INHERITED">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
|
||||
<i
|
||||
class="info-i las la-question-circle"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
|
||||
></i>
|
||||
<div
|
||||
*ngIf="
|
||||
!!featureData.oidcLegacyIntrospection?.enabled &&
|
||||
(featureData.oidcLegacyIntrospection?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.oidcLegacyIntrospection?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot enabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="
|
||||
!featureData.oidcLegacyIntrospection?.enabled &&
|
||||
(featureData.oidcLegacyIntrospection?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.oidcLegacyIntrospection?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot disabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.DISABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.ENABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.FEATURES.OIDCLEGACYINTROSPECTION_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<div class="feature-row" *ngIf="toggleStates.oidcTokenExchange">
|
||||
<span>{{ 'SETTING.FEATURES.OIDCTOKENEXCHANGE' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleStates.oidcTokenExchange.state"
|
||||
(change)="validateAndSave()"
|
||||
name="displayview"
|
||||
aria-label="Display View"
|
||||
>
|
||||
<mat-button-toggle [value]="ToggleState.INHERITED">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
|
||||
<i
|
||||
class="info-i las la-question-circle"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
|
||||
></i>
|
||||
<div
|
||||
*ngIf="
|
||||
!!featureData.oidcTokenExchange?.enabled &&
|
||||
(featureData.oidcTokenExchange?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.oidcTokenExchange?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot enabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="
|
||||
!featureData.oidcTokenExchange?.enabled &&
|
||||
(featureData.oidcTokenExchange?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.oidcTokenExchange?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot disabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.DISABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.ENABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.FEATURES.OIDCTOKENEXCHANGE_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<div class="feature-row" *ngIf="toggleStates.oidcTriggerIntrospectionProjections">
|
||||
<span>{{ 'SETTING.FEATURES.OIDCTRIGGERINTROSPECTIONPROJECTIONS' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleStates.oidcTriggerIntrospectionProjections.state"
|
||||
(change)="validateAndSave()"
|
||||
name="displayview"
|
||||
aria-label="Display View"
|
||||
>
|
||||
<mat-button-toggle [value]="ToggleState.INHERITED">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
|
||||
<i
|
||||
class="info-i las la-question-circle"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
|
||||
></i>
|
||||
<div
|
||||
*ngIf="
|
||||
!!featureData.oidcTriggerIntrospectionProjections?.enabled &&
|
||||
(featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot enabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="
|
||||
!featureData.oidcTriggerIntrospectionProjections?.enabled &&
|
||||
(featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot disabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.DISABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.ENABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.FEATURES.OIDCTRIGGERINTROSPECTIONPROJECTIONS_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<div class="feature-row" *ngIf="toggleStates.userSchema">
|
||||
<span>{{ 'SETTING.FEATURES.USERSCHEMA' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleStates.userSchema.state"
|
||||
(change)="validateAndSave()"
|
||||
name="displayview"
|
||||
aria-label="Display View"
|
||||
>
|
||||
<mat-button-toggle [value]="ToggleState.INHERITED">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
|
||||
<i
|
||||
class="info-i las la-question-circle"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
|
||||
></i>
|
||||
<div
|
||||
*ngIf="
|
||||
!!featureData.userSchema?.enabled &&
|
||||
(featureData.userSchema?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.userSchema?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot enabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="
|
||||
!featureData.userSchema?.enabled &&
|
||||
(featureData.userSchema?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.userSchema?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot disabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.DISABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.ENABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.FEATURES.USERSCHEMA_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<div class="feature-row" *ngIf="toggleStates.actions">
|
||||
<span>{{ 'SETTING.FEATURES.ACTIONS' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleStates.actions.state"
|
||||
(change)="validateAndSave()"
|
||||
name="displayview"
|
||||
aria-label="Display View"
|
||||
>
|
||||
<mat-button-toggle [value]="ToggleState.INHERITED">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
|
||||
<i
|
||||
class="info-i las la-question-circle"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
|
||||
></i>
|
||||
<div
|
||||
*ngIf="
|
||||
!!featureData.actions?.enabled &&
|
||||
(featureData.actions?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.actions?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot enabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="
|
||||
!featureData.actions?.enabled &&
|
||||
(featureData.actions?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.actions?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot disabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.DISABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.ENABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<cnsl-info-section class="feature-info">{{ 'SETTING.FEATURES.ACTIONS_DESCRIPTION' | translate }}</cnsl-info-section>
|
||||
</div>
|
||||
|
||||
<div class="feature-row" *ngIf="toggleStates.oidcSingleV1SessionTermination">
|
||||
<span>{{ 'SETTING.FEATURES.OIDCSINGLEV1SESSIONTERMINATION' | translate }}</span>
|
||||
<div class="row">
|
||||
<mat-button-toggle-group
|
||||
class="theme-toggle"
|
||||
class="buttongroup"
|
||||
[(ngModel)]="toggleStates.oidcSingleV1SessionTermination.state"
|
||||
(change)="validateAndSave()"
|
||||
name="displayview"
|
||||
aria-label="Display View"
|
||||
>
|
||||
<mat-button-toggle [value]="ToggleState.INHERITED">
|
||||
<div class="toggle-row">
|
||||
<span>{{ 'SETTING.FEATURES.STATES.INHERITED' | translate }}</span>
|
||||
<i
|
||||
class="info-i las la-question-circle"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITED_DESCRIPTION' | translate }}"
|
||||
></i>
|
||||
<div
|
||||
*ngIf="
|
||||
!!featureData.oidcSingleV1SessionTermination?.enabled &&
|
||||
(featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot enabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.ENABLED' | translate }}"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="
|
||||
!featureData.oidcSingleV1SessionTermination?.enabled &&
|
||||
(featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_SYSTEM ||
|
||||
featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_UNSPECIFIED)
|
||||
"
|
||||
class="current-dot disabled"
|
||||
matTooltip="{{ 'SETTING.FEATURES.INHERITEDINDICATOR_DESCRIPTION.DISABLED' | translate }}"
|
||||
></div>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.DISABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.DISABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
<mat-button-toggle [value]="ToggleState.ENABLED">
|
||||
<div class="toggle-row">
|
||||
<span> {{ 'SETTING.FEATURES.STATES.ENABLED' | translate }}</span>
|
||||
</div>
|
||||
</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
</div>
|
||||
<cnsl-info-section class="feature-info">{{
|
||||
'SETTING.FEATURES.OIDCSINGLEV1SESSIONTERMINATION_DESCRIPTION' | translate
|
||||
}}</cnsl-info-section>
|
||||
</div>
|
||||
<cnsl-feature-toggle
|
||||
*ngFor="let key of toggleStateKeys"
|
||||
[featureData]="featureData"
|
||||
[toggleStates]="toggleStates"
|
||||
[toggleStateKey]="key"
|
||||
(toggleChange)="validateAndSave()"
|
||||
></cnsl-feature-toggle>
|
||||
</div>
|
||||
</cnsl-card>
|
||||
</div>
|
||||
|
||||
@@ -11,30 +11,46 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
|
||||
import { CardModule } from 'src/app/modules/card/card.module';
|
||||
import { InfoSectionModule } from 'src/app/modules/info-section/info-section.module';
|
||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||
import { Source } from 'src/app/proto/generated/zitadel/feature/v2beta/feature_pb';
|
||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||
import { FeatureService } from 'src/app/services/feature.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { FeatureToggleComponent } from '../feature-toggle/feature-toggle.component';
|
||||
import { NewFeatureService } from 'src/app/services/new-feature.service';
|
||||
import {
|
||||
GetInstanceFeaturesResponse,
|
||||
SetInstanceFeaturesRequest,
|
||||
} from 'src/app/proto/generated/zitadel/feature/v2/instance_pb';
|
||||
SetInstanceFeaturesRequestSchema,
|
||||
} from '@zitadel/proto/zitadel/feature/v2/instance_pb';
|
||||
import { FeatureFlag, Source } from '@zitadel/proto/zitadel/feature/v2/feature_pb';
|
||||
import { MessageInitShape } from '@bufbuild/protobuf';
|
||||
|
||||
enum ToggleState {
|
||||
export enum ToggleState {
|
||||
ENABLED = 'ENABLED',
|
||||
DISABLED = 'DISABLED',
|
||||
INHERITED = 'INHERITED',
|
||||
}
|
||||
|
||||
// TODO: to add a new feature, add the key here and in the FEATURE_KEYS array
|
||||
const FEATURE_KEYS: ToggleStateKeys[] = [
|
||||
'actions',
|
||||
'consoleUseV2UserApi',
|
||||
'debugOidcParentError',
|
||||
'disableUserTokenEvent',
|
||||
'enableBackChannelLogout',
|
||||
// 'improvedPerformance',
|
||||
'loginDefaultOrg',
|
||||
// 'loginV2',
|
||||
'oidcLegacyIntrospection',
|
||||
'oidcSingleV1SessionTermination',
|
||||
'oidcTokenExchange',
|
||||
'oidcTriggerIntrospectionProjections',
|
||||
'permissionCheckV2',
|
||||
'userSchema',
|
||||
// 'webKey',
|
||||
];
|
||||
|
||||
type FeatureState = { source: Source; state: ToggleState };
|
||||
type ToggleStates = {
|
||||
loginDefaultOrg?: FeatureState;
|
||||
oidcTriggerIntrospectionProjections?: FeatureState;
|
||||
oidcLegacyIntrospection?: FeatureState;
|
||||
userSchema?: FeatureState;
|
||||
oidcTokenExchange?: FeatureState;
|
||||
actions?: FeatureState;
|
||||
oidcSingleV1SessionTermination?: FeatureState;
|
||||
export type ToggleStateKeys = Exclude<keyof GetInstanceFeaturesResponse, 'details' | '$typeName' | '$unknown'>;
|
||||
|
||||
export type ToggleStates = {
|
||||
[key in ToggleStateKeys]: FeatureState;
|
||||
};
|
||||
|
||||
@Component({
|
||||
@@ -51,6 +67,7 @@ type ToggleStates = {
|
||||
InfoSectionModule,
|
||||
MatTooltipModule,
|
||||
HasRoleModule,
|
||||
FeatureToggleComponent,
|
||||
],
|
||||
standalone: true,
|
||||
selector: 'cnsl-features',
|
||||
@@ -58,14 +75,14 @@ type ToggleStates = {
|
||||
styleUrls: ['./features.component.scss'],
|
||||
})
|
||||
export class FeaturesComponent {
|
||||
protected featureData: GetInstanceFeaturesResponse.AsObject | undefined;
|
||||
protected featureData: GetInstanceFeaturesResponse | undefined;
|
||||
|
||||
protected toggleStates: ToggleStates | undefined;
|
||||
protected Source: any = Source;
|
||||
protected ToggleState: any = ToggleState;
|
||||
|
||||
constructor(
|
||||
private featureService: FeatureService,
|
||||
private featureService: NewFeatureService,
|
||||
private breadcrumbService: BreadcrumbService,
|
||||
private toast: ToastService,
|
||||
) {
|
||||
@@ -78,140 +95,57 @@ export class FeaturesComponent {
|
||||
];
|
||||
this.breadcrumbService.setBreadcrumb(breadcrumbs);
|
||||
|
||||
this.getFeatures(true);
|
||||
this.getFeatures();
|
||||
}
|
||||
|
||||
public validateAndSave() {
|
||||
this.featureService.resetInstanceFeatures().then(() => {
|
||||
const req = new SetInstanceFeaturesRequest();
|
||||
let changed = false;
|
||||
const req: MessageInitShape<typeof SetInstanceFeaturesRequestSchema> = {
|
||||
actions: this.toggleStates?.actions?.state === ToggleState.ENABLED,
|
||||
consoleUseV2UserApi: this.toggleStates?.consoleUseV2UserApi?.state === ToggleState.ENABLED,
|
||||
debugOidcParentError: this.toggleStates?.debugOidcParentError?.state === ToggleState.ENABLED,
|
||||
disableUserTokenEvent: this.toggleStates?.disableUserTokenEvent?.state === ToggleState.ENABLED,
|
||||
enableBackChannelLogout: this.toggleStates?.enableBackChannelLogout?.state === ToggleState.ENABLED,
|
||||
loginDefaultOrg: this.toggleStates?.loginDefaultOrg?.state === ToggleState.ENABLED,
|
||||
oidcLegacyIntrospection: this.toggleStates?.oidcLegacyIntrospection?.state === ToggleState.ENABLED,
|
||||
oidcSingleV1SessionTermination: this.toggleStates?.oidcSingleV1SessionTermination?.state === ToggleState.ENABLED,
|
||||
oidcTokenExchange: this.toggleStates?.oidcTokenExchange?.state === ToggleState.ENABLED,
|
||||
oidcTriggerIntrospectionProjections:
|
||||
this.toggleStates?.oidcTriggerIntrospectionProjections?.state === ToggleState.ENABLED,
|
||||
permissionCheckV2: this.toggleStates?.permissionCheckV2?.state === ToggleState.ENABLED,
|
||||
userSchema: this.toggleStates?.userSchema?.state === ToggleState.ENABLED,
|
||||
// webKey: this.toggleStates?.webKey?.state === ToggleState.ENABLED,
|
||||
};
|
||||
|
||||
console.log(this.toggleStates);
|
||||
this.featureService
|
||||
.setInstanceFeatures(req)
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.SET', true);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
if (this.toggleStates?.loginDefaultOrg?.state !== ToggleState.INHERITED) {
|
||||
req.setLoginDefaultOrg(this.toggleStates?.loginDefaultOrg?.state === ToggleState.ENABLED);
|
||||
changed = true;
|
||||
}
|
||||
if (this.toggleStates?.oidcTriggerIntrospectionProjections?.state !== ToggleState.INHERITED) {
|
||||
req.setOidcTriggerIntrospectionProjections(
|
||||
this.toggleStates?.oidcTriggerIntrospectionProjections?.state === ToggleState.ENABLED,
|
||||
);
|
||||
changed = true;
|
||||
}
|
||||
if (this.toggleStates?.oidcLegacyIntrospection?.state !== ToggleState.INHERITED) {
|
||||
req.setOidcLegacyIntrospection(this.toggleStates?.oidcLegacyIntrospection?.state === ToggleState.ENABLED);
|
||||
changed = true;
|
||||
}
|
||||
if (this.toggleStates?.userSchema?.state !== ToggleState.INHERITED) {
|
||||
req.setUserSchema(this.toggleStates?.userSchema?.state === ToggleState.ENABLED);
|
||||
changed = true;
|
||||
}
|
||||
if (this.toggleStates?.oidcTokenExchange?.state !== ToggleState.INHERITED) {
|
||||
req.setOidcTokenExchange(this.toggleStates?.oidcTokenExchange?.state === ToggleState.ENABLED);
|
||||
changed = true;
|
||||
}
|
||||
if (this.toggleStates?.actions?.state !== ToggleState.INHERITED) {
|
||||
req.setActions(this.toggleStates?.actions?.state === ToggleState.ENABLED);
|
||||
changed = true;
|
||||
}
|
||||
if (this.toggleStates?.oidcSingleV1SessionTermination?.state !== ToggleState.INHERITED) {
|
||||
req.setOidcSingleV1SessionTermination(
|
||||
this.toggleStates?.oidcSingleV1SessionTermination?.state === ToggleState.ENABLED,
|
||||
);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
this.featureService
|
||||
.setInstanceFeatures(req)
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.SET', true);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
private getFeatures() {
|
||||
this.featureService.getInstanceFeatures().then((instanceFeaturesResponse) => {
|
||||
this.featureData = instanceFeaturesResponse;
|
||||
this.toggleStates = this.createToggleStates(this.featureData);
|
||||
});
|
||||
}
|
||||
|
||||
private getFeatures(inheritance: boolean) {
|
||||
this.featureService.getInstanceFeatures(inheritance).then((instanceFeaturesResponse) => {
|
||||
this.featureData = instanceFeaturesResponse.toObject();
|
||||
console.log(this.featureData);
|
||||
private createToggleStates(featureData: GetInstanceFeaturesResponse): ToggleStates {
|
||||
const toggleStates: Partial<ToggleStates> = {};
|
||||
|
||||
this.toggleStates = {
|
||||
loginDefaultOrg: {
|
||||
source: this.featureData.loginDefaultOrg?.source || Source.SOURCE_SYSTEM,
|
||||
state:
|
||||
this.featureData.loginDefaultOrg?.source === Source.SOURCE_SYSTEM ||
|
||||
this.featureData.loginDefaultOrg?.source === Source.SOURCE_UNSPECIFIED
|
||||
? ToggleState.INHERITED
|
||||
: !!this.featureData.loginDefaultOrg?.enabled
|
||||
? ToggleState.ENABLED
|
||||
: ToggleState.DISABLED,
|
||||
},
|
||||
oidcTriggerIntrospectionProjections: {
|
||||
source: this.featureData.oidcTriggerIntrospectionProjections?.source || Source.SOURCE_SYSTEM,
|
||||
state:
|
||||
this.featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_SYSTEM ||
|
||||
this.featureData.oidcTriggerIntrospectionProjections?.source === Source.SOURCE_UNSPECIFIED
|
||||
? ToggleState.INHERITED
|
||||
: !!this.featureData.oidcTriggerIntrospectionProjections?.enabled
|
||||
? ToggleState.ENABLED
|
||||
: ToggleState.DISABLED,
|
||||
},
|
||||
oidcLegacyIntrospection: {
|
||||
source: this.featureData.oidcLegacyIntrospection?.source || Source.SOURCE_SYSTEM,
|
||||
state:
|
||||
this.featureData.oidcLegacyIntrospection?.source === Source.SOURCE_SYSTEM ||
|
||||
this.featureData.oidcLegacyIntrospection?.source === Source.SOURCE_UNSPECIFIED
|
||||
? ToggleState.INHERITED
|
||||
: !!this.featureData.oidcLegacyIntrospection?.enabled
|
||||
? ToggleState.ENABLED
|
||||
: ToggleState.DISABLED,
|
||||
},
|
||||
userSchema: {
|
||||
source: this.featureData.userSchema?.source || Source.SOURCE_SYSTEM,
|
||||
state:
|
||||
this.featureData.userSchema?.source === Source.SOURCE_SYSTEM ||
|
||||
this.featureData.userSchema?.source === Source.SOURCE_UNSPECIFIED
|
||||
? ToggleState.INHERITED
|
||||
: !!this.featureData.userSchema?.enabled
|
||||
? ToggleState.ENABLED
|
||||
: ToggleState.DISABLED,
|
||||
},
|
||||
oidcTokenExchange: {
|
||||
source: this.featureData.oidcTokenExchange?.source || Source.SOURCE_SYSTEM,
|
||||
state:
|
||||
this.featureData.oidcTokenExchange?.source === Source.SOURCE_SYSTEM ||
|
||||
this.featureData.oidcTokenExchange?.source === Source.SOURCE_UNSPECIFIED
|
||||
? ToggleState.INHERITED
|
||||
: !!this.featureData.oidcTokenExchange?.enabled
|
||||
? ToggleState.ENABLED
|
||||
: ToggleState.DISABLED,
|
||||
},
|
||||
actions: {
|
||||
source: Source.SOURCE_SYSTEM,
|
||||
state:
|
||||
this.featureData.actions?.source === Source.SOURCE_SYSTEM ||
|
||||
this.featureData.actions?.source === Source.SOURCE_UNSPECIFIED
|
||||
? ToggleState.INHERITED
|
||||
: !!this.featureData.actions?.enabled
|
||||
? ToggleState.ENABLED
|
||||
: ToggleState.DISABLED,
|
||||
},
|
||||
oidcSingleV1SessionTermination: {
|
||||
source: this.featureData.oidcSingleV1SessionTermination?.source || Source.SOURCE_SYSTEM,
|
||||
state:
|
||||
this.featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_SYSTEM ||
|
||||
this.featureData.oidcSingleV1SessionTermination?.source === Source.SOURCE_UNSPECIFIED
|
||||
? ToggleState.INHERITED
|
||||
: !!this.featureData.oidcSingleV1SessionTermination?.enabled
|
||||
? ToggleState.ENABLED
|
||||
: ToggleState.DISABLED,
|
||||
},
|
||||
FEATURE_KEYS.forEach((key) => {
|
||||
// TODO: Fix this type cast as not all keys are present as FeatureFlag
|
||||
const feature = featureData[key] as unknown as FeatureFlag;
|
||||
toggleStates[key] = {
|
||||
source: feature?.source || Source.SYSTEM,
|
||||
state: !!feature?.enabled ? ToggleState.ENABLED : ToggleState.DISABLED,
|
||||
};
|
||||
});
|
||||
|
||||
return toggleStates as ToggleStates;
|
||||
}
|
||||
|
||||
public resetSettings(): void {
|
||||
@@ -220,11 +154,15 @@ export class FeaturesComponent {
|
||||
.then(() => {
|
||||
this.toast.showInfo('POLICY.TOAST.RESETSUCCESS', true);
|
||||
setTimeout(() => {
|
||||
this.getFeatures(true);
|
||||
this.getFeatures();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
|
||||
public get toggleStateKeys() {
|
||||
return Object.keys(this.toggleStates ?? {});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user