fix(FE): allow only enabled factors to be displayed on user page (#9313)

# Which Problems Are Solved

- Hides for users MFA options are not allowed by org policy.
- Fix for "ng test" across "console"

# How the Problems Are Solved

- Before displaying MFA options we call "listMyMultiFactors" from parent
component to filter MFA allowed by org

# Additional Changes

- Dependency Injection was fixed around ng unit tests

# Additional Context

admin view
<img width="698" alt="Screenshot 2025-02-06 at 00 26 50"
src="https://github.com/user-attachments/assets/1b642c8a-a640-4bdd-a1ca-bde70c263567"
/>
user view
<img width="751" alt="Screenshot 2025-02-06 at 00 27 16"
src="https://github.com/user-attachments/assets/e1c99907-3226-46ce-b8bc-e993af4b4cae"
/>
test
<img width="1500" alt="Screenshot 2025-02-06 at 00 01 36"
src="https://github.com/user-attachments/assets/d2d8ead1-9f0f-4916-a2fc-f4db9c71cfa8"
/>

The issue: https://github.com/zitadel/zitadel/issues/9176
The bug report:
https://discord.com/channels/927474939156643850/1307006457815896094

---------

Co-authored-by: a k <[email protected]>
Co-authored-by: a k <[email protected]>
Co-authored-by: a k <[email protected]>
Co-authored-by: Ramon <[email protected]>
This commit is contained in:
AnthonyKot
2025-06-04 09:26:53 +00:00
committed by GitHub
co-authored by a k a k a k Ramon
parent 1a80e26502
commit 839c761357
27 changed files with 411 additions and 204 deletions
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OrgDomainsComponent } from './org-domains.component';
import { DomainsComponent } from './domains.component';
describe('OrgDomainsComponent', () => {
let component: OrgDomainsComponent;
let fixture: ComponentFixture<OrgDomainsComponent>;
let component: DomainsComponent;
let fixture: ComponentFixture<DomainsComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [OrgDomainsComponent],
declarations: [DomainsComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(OrgDomainsComponent);
fixture = TestBed.createComponent(DomainsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FilterUserComponent } from './filter-user.component';
import { FilterProjectComponent } from './filter-project.component';
describe('FilterUserComponent', () => {
let component: FilterUserComponent;
let fixture: ComponentFixture<FilterUserComponent>;
let component: FilterProjectComponent;
let fixture: ComponentFixture<FilterProjectComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [FilterUserComponent],
declarations: [FilterProjectComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(FilterUserComponent);
fixture = TestBed.createComponent(FilterProjectComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,8 +1,49 @@
import { Component, ElementRef, NgZone } from '@angular/core';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { InputDirective } from './input.directive';
import { Platform } from '@angular/cdk/platform';
import { NgControl, NgForm, FormGroupDirective } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
import { AutofillMonitor } from '@angular/cdk/text-field';
import { MatFormField } from '@angular/material/form-field';
import { MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input';
import { of } from 'rxjs';
import { By } from '@angular/platform-browser';
@Component({
template: `<input appInputDirective />`,
})
class TestHostComponent {}
describe('InputDirective', () => {
let fixture: ComponentFixture<TestHostComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [InputDirective, TestHostComponent],
providers: [
{ provide: ElementRef, useValue: new ElementRef(document.createElement('input')) },
Platform,
{ provide: NgControl, useValue: null },
{ provide: NgForm, useValue: null },
{ provide: FormGroupDirective, useValue: null },
ErrorStateMatcher,
{ provide: MAT_INPUT_VALUE_ACCESSOR, useValue: null },
{
provide: AutofillMonitor,
useValue: { monitor: () => of(), stopMonitoring: () => {} },
},
NgZone,
{ provide: MatFormField, useValue: null },
],
}).compileComponents();
fixture = TestBed.createComponent(TestHostComponent);
fixture.detectChanges();
});
it('should create an instance', () => {
const directive = new InputDirective();
expect(directive).toBeTruthy();
const directiveEl = fixture.debugElement.query(By.directive(InputDirective));
expect(directiveEl).toBeTruthy();
});
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { AvatarComponent } from './avatar.component';
import { LabelComponent } from './label.component';
describe('AvatarComponent', () => {
let component: AvatarComponent;
let fixture: ComponentFixture<AvatarComponent>;
let component: LabelComponent;
let fixture: ComponentFixture<LabelComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [AvatarComponent],
declarations: [LabelComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AvatarComponent);
fixture = TestBed.createComponent(LabelComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -2,14 +2,12 @@ import { Component, Injector, Input, OnDestroy, OnInit, Type } from '@angular/co
import { AbstractControl, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { Duration } from 'google-protobuf/google/protobuf/duration_pb';
import { firstValueFrom, forkJoin, from, Observable, of, Subject, take } from 'rxjs';
import { forkJoin, from, of, Subject, take } from 'rxjs';
import {
GetLoginPolicyResponse as AdminGetLoginPolicyResponse,
UpdateLoginPolicyRequest,
UpdateLoginPolicyResponse,
} from 'src/app/proto/generated/zitadel/admin_pb';
import {
AddCustomLoginPolicyRequest,
GetLoginPolicyResponse as MgmtGetLoginPolicyResponse,
UpdateCustomLoginPolicyRequest,
} from 'src/app/proto/generated/zitadel/management_pb';
@@ -24,8 +22,7 @@ import { InfoSectionType } from '../../info-section/info-section.component';
import { WarnDialogComponent } from '../../warn-dialog/warn-dialog.component';
import { PolicyComponentServiceType } from '../policy-component-types.enum';
import { LoginMethodComponentType } from './factor-table/factor-table.component';
import { catchError, map, takeUntil } from 'rxjs/operators';
import { error } from 'console';
import { map, takeUntil } from 'rxjs/operators';
import { LoginPolicyService } from '../../../services/login-policy.service';
const minValueValidator = (minValue: number) => (control: AbstractControl) => {
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { LoginPolicyComponent } from './login-policy.component';
import { MessageTextsComponent } from './message-texts.component';
describe('LoginPolicyComponent', () => {
let component: LoginPolicyComponent;
let fixture: ComponentFixture<LoginPolicyComponent>;
let component: MessageTextsComponent;
let fixture: ComponentFixture<MessageTextsComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [LoginPolicyComponent],
declarations: [MessageTextsComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginPolicyComponent);
fixture = TestBed.createComponent(MessageTextsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { PasswordComplexityPolicyComponent } from './password-complexity-policy.component';
import { NotificationPolicyComponent } from './notification-policy.component';
describe('PasswordComplexityPolicyComponent', () => {
let component: PasswordComplexityPolicyComponent;
let fixture: ComponentFixture<PasswordComplexityPolicyComponent>;
let component: NotificationPolicyComponent;
let fixture: ComponentFixture<NotificationPolicyComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [PasswordComplexityPolicyComponent],
declarations: [NotificationPolicyComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PasswordComplexityPolicyComponent);
fixture = TestBed.createComponent(NotificationPolicyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { PasswordDialogComponent } from './password-dialog-sms-provider.component';
import { PasswordDialogSMSProviderComponent } from './password-dialog-sms-provider.component';
describe('PasswordDialogComponent', () => {
let component: PasswordDialogComponent;
let fixture: ComponentFixture<PasswordDialogComponent>;
let component: PasswordDialogSMSProviderComponent;
let fixture: ComponentFixture<PasswordDialogSMSProviderComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [PasswordDialogComponent],
declarations: [PasswordDialogSMSProviderComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(PasswordDialogComponent);
fixture = TestBed.createComponent(PasswordDialogSMSProviderComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ProviderOAuthComponent } from './provider-oauth.component';
import { ProviderGithubESComponent } from './provider-github-es.component';
describe('ProviderOAuthComponent', () => {
let component: ProviderOAuthComponent;
let fixture: ComponentFixture<ProviderOAuthComponent>;
let component: ProviderGithubESComponent;
let fixture: ComponentFixture<ProviderGithubESComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ProviderOAuthComponent],
declarations: [ProviderGithubESComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProviderOAuthComponent);
fixture = TestBed.createComponent(ProviderGithubESComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ProviderGoogleComponent } from './provider-google.component';
import { ProviderGitlabSelfHostedComponent } from './provider-gitlab-self-hosted.component';
describe('ProviderGoogleComponent', () => {
let component: ProviderGoogleComponent;
let fixture: ComponentFixture<ProviderGoogleComponent>;
let component: ProviderGitlabSelfHostedComponent;
let fixture: ComponentFixture<ProviderGitlabSelfHostedComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ProviderGoogleComponent],
declarations: [ProviderGitlabSelfHostedComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProviderGoogleComponent);
fixture = TestBed.createComponent(ProviderGitlabSelfHostedComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ProviderGoogleComponent } from './provider-google.component';
import { ProviderGitlabComponent } from './provider-gitlab.component';
describe('ProviderGoogleComponent', () => {
let component: ProviderGoogleComponent;
let fixture: ComponentFixture<ProviderGoogleComponent>;
let component: ProviderGitlabComponent;
let fixture: ComponentFixture<ProviderGitlabComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ProviderGoogleComponent],
declarations: [ProviderGitlabComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProviderGoogleComponent);
fixture = TestBed.createComponent(ProviderGitlabComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { ShowKeyDialogComponent } from './show-key-dialog.component';
import { ShowTokenDialogComponent } from './show-token-dialog.component';
describe('ShowKeyDialogComponent', () => {
let component: ShowKeyDialogComponent;
let fixture: ComponentFixture<ShowKeyDialogComponent>;
let component: ShowTokenDialogComponent;
let fixture: ComponentFixture<ShowTokenDialogComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ShowKeyDialogComponent],
declarations: [ShowTokenDialogComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ShowKeyDialogComponent);
fixture = TestBed.createComponent(ShowTokenDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
@@ -1,19 +1,19 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IdpTableComponent } from './smtp-table.component';
import { SMTPTableComponent } from './smtp-table.component';
describe('UserTableComponent', () => {
let component: IdpTableComponent;
let fixture: ComponentFixture<IdpTableComponent>;
let component: SMTPTableComponent;
let fixture: ComponentFixture<SMTPTableComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [IdpTableComponent],
declarations: [SMTPTableComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(IdpTableComponent);
fixture = TestBed.createComponent(SMTPTableComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});