mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-03 12:52:16 +00:00
feat: specify login UI version on instance and apps (#9071)
# Which Problems Are Solved To be able to migrate or test the new login UI, admins might want to (temporarily) switch individual apps. At a later point admin might want to make sure all applications use the new login UI. # How the Problems Are Solved - Added a feature flag `` on instance level to require all apps to use the new login and provide an optional base url. - if the flag is enabled, all (OIDC) applications will automatically use the v2 login. - if disabled, applications can decide based on their configuration - Added an option on OIDC apps to use the new login UI and an optional base url. - Removed the requirement to use `x-zitadel-login-client` to be redirected to the login V2 and retrieve created authrequest and link them to SSO sessions. - Added a new "IAM_LOGIN_CLIENT" role to allow management of users, sessions, grants and more without `x-zitadel-login-client`. # Additional Changes None # Additional Context closes https://github.com/zitadel/zitadel/issues/8702
This commit is contained in:
@@ -147,6 +147,22 @@
|
||||
>
|
||||
{{ 'APP.OIDC.REFRESHTOKEN' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<mat-checkbox
|
||||
*ngIf="loginV2"
|
||||
color="primary"
|
||||
class="rt"
|
||||
[formControl]="loginV2"
|
||||
name="loginV2"
|
||||
matTooltip="{{ 'APP.LOGINV2DESC' | translate }}"
|
||||
>
|
||||
{{ 'APP.LOGINV2.USEV2' | translate }}
|
||||
</mat-checkbox>
|
||||
|
||||
<cnsl-form-field class="app-formfield">
|
||||
<cnsl-label>{{ 'APP.LOGINV2.BASEURL' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="loginV2BaseURL" />
|
||||
</cnsl-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { COMMA, ENTER, SPACE } from '@angular/cdk/keycodes';
|
||||
import { Location } from '@angular/common';
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation, signal } from '@angular/core';
|
||||
import { Component, OnDestroy, OnInit, signal } from '@angular/core';
|
||||
import { AbstractControl, FormControl, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { MatCheckboxChange } from '@angular/material/checkbox';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
@@ -21,6 +21,9 @@ import {
|
||||
APIConfig,
|
||||
App,
|
||||
AppState,
|
||||
LoginV1,
|
||||
LoginV2,
|
||||
LoginVersion,
|
||||
OIDCAppType,
|
||||
OIDCAuthMethodType,
|
||||
OIDCConfig,
|
||||
@@ -50,8 +53,8 @@ import {
|
||||
getAuthMethodFromPartialConfig,
|
||||
getPartialConfigFromAuthMethod,
|
||||
IMPLICIT_METHOD,
|
||||
PKCE_METHOD,
|
||||
PK_JWT_METHOD,
|
||||
PKCE_METHOD,
|
||||
POST_METHOD,
|
||||
} from '../authmethods';
|
||||
import { AuthMethodDialogComponent } from './auth-method-dialog/auth-method-dialog.component';
|
||||
@@ -182,6 +185,7 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
public currentSetting: string | undefined = this.settingsList[0].id;
|
||||
|
||||
public isNew = signal<boolean>(false);
|
||||
|
||||
constructor(
|
||||
private envSvc: EnvironmentService,
|
||||
public translate: TranslateService,
|
||||
@@ -203,6 +207,8 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
grantTypesList: [{ value: [], disabled: true }],
|
||||
appType: [{ value: '', disabled: true }],
|
||||
authMethodType: [{ value: '', disabled: true }],
|
||||
loginV2: [{ value: false, disabled: true }],
|
||||
loginV2BaseURL: [{ value: '', disabled: true }],
|
||||
});
|
||||
|
||||
this.oidcTokenForm = this.fb.group({
|
||||
@@ -430,6 +436,12 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
const inSecs = this.app.oidcConfig?.clockSkew.seconds + this.app.oidcConfig?.clockSkew.nanos / 100000;
|
||||
this.oidcTokenForm.controls['clockSkewSeconds'].setValue(inSecs);
|
||||
}
|
||||
if (this.app.oidcConfig?.loginVersion?.loginV1) {
|
||||
this.oidcForm.controls['loginV2'].setValue(false);
|
||||
} else if (this.app.oidcConfig?.loginVersion?.loginV2) {
|
||||
this.oidcForm.controls['loginV2'].setValue(true);
|
||||
this.oidcForm.controls['loginV2BaseURL'].setValue(this.app.oidcConfig.loginVersion.loginV2.baseUri);
|
||||
}
|
||||
if (this.app.oidcConfig) {
|
||||
this.oidcForm.patchValue(this.app.oidcConfig);
|
||||
this.oidcTokenForm.patchValue(this.app.oidcConfig);
|
||||
@@ -655,6 +667,15 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
req.setAuthMethodType(this.app.oidcConfig.authMethodType);
|
||||
req.setGrantTypesList(this.app.oidcConfig.grantTypesList);
|
||||
req.setAppType(this.app.oidcConfig.appType);
|
||||
const login = new LoginVersion();
|
||||
if (this.loginV2?.value) {
|
||||
const loginV2 = new LoginV2();
|
||||
loginV2.setBaseUri(this.loginV2BaseURL?.value);
|
||||
login.setLoginV2(loginV2);
|
||||
} else {
|
||||
login.setLoginV1(new LoginV1());
|
||||
}
|
||||
req.setLoginVersion(login);
|
||||
|
||||
// token
|
||||
req.setAccessTokenType(this.app.oidcConfig.accessTokenType);
|
||||
@@ -839,6 +860,14 @@ export class AppDetailComponent implements OnInit, OnDestroy {
|
||||
return this.oidcForm.get('authMethodType');
|
||||
}
|
||||
|
||||
public get loginV2(): FormControl<boolean> | null {
|
||||
return this.oidcForm.get('loginV2') as FormControl<boolean>;
|
||||
}
|
||||
|
||||
public get loginV2BaseURL(): AbstractControl | null {
|
||||
return this.oidcForm.get('loginV2BaseURL');
|
||||
}
|
||||
|
||||
public get apiAuthMethodType(): AbstractControl | null {
|
||||
return this.apiForm.get('authMethodType') as UntypedFormControl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user