fix(console): create login policy before adding a factor (#10202)

<!--
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

The api call for adding a mfa/2fa factor was running before creating a
login policy.

# How the Problems Are Solved

A new event emitter `beforeTypeAdd` is responsible for taking in a
callback, and then the parent component (login-policy) checks if a login
policy should be created, and then it is successfully created, calls the
callback.
The callback then adds the mfa/2fa factor as before.

# Additional Context

- Closes #9047

Co-authored-by: David Skewis <david@zitadel.com>
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
This commit is contained in:
Mahdi JafariRaviz
2025-10-16 06:12:07 -04:00
committed by GitHub
parent 00beaf6ddc
commit 381727e919
3 changed files with 43 additions and 32 deletions

View File

@@ -43,6 +43,7 @@ export class FactorTableComponent {
@Input() disabled: boolean = false;
@Input() list: Array<MultiFactorType | SecondFactorType> = [];
@Output() typeRemoved: EventEmitter<Promise<any>> = new EventEmitter();
@Output() beforeTypeAdd: EventEmitter<() => void> = new EventEmitter();
@Output() typeAdded: EventEmitter<Promise<any>> = new EventEmitter();
@ViewChild(MatPaginator) public paginator!: MatPaginator;
@@ -115,33 +116,35 @@ export class FactorTableComponent {
dialogRef.afterClosed().subscribe((mfaType: MultiFactorType | SecondFactorType) => {
if (mfaType) {
let request;
this.beforeTypeAdd.emit(() => {
let request;
if (this.serviceType === PolicyComponentServiceType.MGMT) {
if (this.componentType === LoginMethodComponentType.MultiFactor) {
const req = new MgmtAddMultiFactorToLoginPolicyRequest();
req.setType(mfaType as MultiFactorType);
request = (this.service as ManagementService).addMultiFactorToLoginPolicy(req);
} else if (this.componentType === LoginMethodComponentType.SecondFactor) {
const req = new MgmtAddSecondFactorToLoginPolicyRequest();
req.setType(mfaType as SecondFactorType);
request = (this.service as ManagementService).addSecondFactorToLoginPolicy(req);
if (this.serviceType === PolicyComponentServiceType.MGMT) {
if (this.componentType === LoginMethodComponentType.MultiFactor) {
const req = new MgmtAddMultiFactorToLoginPolicyRequest();
req.setType(mfaType as MultiFactorType);
request = (this.service as ManagementService).addMultiFactorToLoginPolicy(req);
} else if (this.componentType === LoginMethodComponentType.SecondFactor) {
const req = new MgmtAddSecondFactorToLoginPolicyRequest();
req.setType(mfaType as SecondFactorType);
request = (this.service as ManagementService).addSecondFactorToLoginPolicy(req);
}
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
if (this.componentType === LoginMethodComponentType.MultiFactor) {
const req = new AdminAddMultiFactorToLoginPolicyRequest();
req.setType(mfaType as MultiFactorType);
request = (this.service as AdminService).addMultiFactorToLoginPolicy(req);
} else if (this.componentType === LoginMethodComponentType.SecondFactor) {
const req = new AdminAddSecondFactorToLoginPolicyRequest();
req.setType(mfaType as SecondFactorType);
request = (this.service as AdminService).addSecondFactorToLoginPolicy(req);
}
}
} else if (this.serviceType === PolicyComponentServiceType.ADMIN) {
if (this.componentType === LoginMethodComponentType.MultiFactor) {
const req = new AdminAddMultiFactorToLoginPolicyRequest();
req.setType(mfaType as MultiFactorType);
request = (this.service as AdminService).addMultiFactorToLoginPolicy(req);
} else if (this.componentType === LoginMethodComponentType.SecondFactor) {
const req = new AdminAddSecondFactorToLoginPolicyRequest();
req.setType(mfaType as SecondFactorType);
request = (this.service as AdminService).addSecondFactorToLoginPolicy(req);
}
}
if (request) {
this.typeAdded.emit(request);
}
if (request) {
this.typeAdded.emit(request);
}
});
}
});
}

View File

@@ -55,6 +55,7 @@
[componentType]="LoginMethodComponentType.MultiFactor"
[list]="loginData.multiFactorsList"
(typeRemoved)="removeFactor($event)"
(beforeTypeAdd)="beforeAddFactor($event)"
(typeAdded)="addFactor($event)"
[disabled]="
loginData.passwordlessType === PasswordlessType.PASSWORDLESS_TYPE_NOT_ALLOWED ||
@@ -128,6 +129,7 @@
[componentType]="LoginMethodComponentType.SecondFactor"
[list]="loginData.secondFactorsList"
(typeRemoved)="removeFactor($event)"
(beforeTypeAdd)="beforeAddFactor($event)"
(typeAdded)="addFactor($event)"
[disabled]="
([

View File

@@ -341,15 +341,21 @@ export class LoginPolicyComponent implements OnInit, OnDestroy {
}
}
public addFactor(request: Promise<unknown>): void {
// create policy before types can be added
const task: Promise<unknown> = this.isDefault
? this.updateData().then(() => {
return request;
})
: request;
public beforeAddFactor(callback: () => void): void {
if (this.isDefault) {
// create policy before types can be added
this.updateData()
.then(() => callback())
.catch((error) => {
this.toast.showError(error);
});
} else {
callback();
}
}
task
public addFactor(request: Promise<unknown>): void {
request
.then(() => {
this.toast.showInfo('MFA.TOAST.ADDED', true);
setTimeout(() => {