feat(console): show available login methods on user pages (#5055)

Shows all possible login methods on the user detail pages

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Max Peintner
2023-01-17 17:02:22 +01:00
committed by GitHub
parent 0316c2c187
commit 650122070d
12 changed files with 49 additions and 4 deletions

View File

@@ -33,8 +33,8 @@
</div>
<div class="info-wrapper width">
<p class="info-row-title">{{ 'USER.PAGES.LOGINNAMES' | translate }}</p>
<div class="copy-row" *ngFor="let login of user?.loginNamesList">
<p class="info-row-title">{{ 'USER.PAGES.LOGINMETHODS' | translate }}</p>
<div class="copy-row" *ngFor="let login of loginMethods">
<button
[disabled]="copied === login"
[matTooltip]="(copied !== login ? 'ACTIONS.COPY' : 'ACTIONS.COPIED') | translate"

View File

@@ -3,6 +3,7 @@ import { App, AppState } from 'src/app/proto/generated/zitadel/app_pb';
import { IDP, IDPState } from 'src/app/proto/generated/zitadel/idp_pb';
import { InstanceDetail, State } from 'src/app/proto/generated/zitadel/instance_pb';
import { Org, OrgState } from 'src/app/proto/generated/zitadel/org_pb';
import { LoginPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
import { GrantedProject, Project, ProjectGrantState, ProjectState } from 'src/app/proto/generated/zitadel/project_pb';
import { User, UserState } from 'src/app/proto/generated/zitadel/user_pb';
@@ -19,6 +20,7 @@ export class InfoRowComponent {
@Input() public idp!: IDP.AsObject;
@Input() public project!: Project.AsObject;
@Input() public grantedProject!: GrantedProject.AsObject;
@Input() public loginPolicy?: LoginPolicy.AsObject;
public UserState: any = UserState;
public State: any = State;
@@ -31,4 +33,19 @@ export class InfoRowComponent {
public copied: string = '';
constructor() {}
public get loginMethods(): Set<string> {
const methods = this.user?.loginNamesList;
let email: string = '';
let phone: string = '';
if (this.loginPolicy) {
if (!this.loginPolicy?.disableLoginWithEmail && this.user.human?.email?.email) {
email = this.user.human?.email?.email;
}
if (!this.loginPolicy?.disableLoginWithPhone && this.user.human?.phone?.phone) {
phone = this.user.human?.phone?.phone;
}
}
return new Set([email, phone, ...methods].filter((method) => !!method));
}
}

View File

@@ -8,7 +8,7 @@
(backRouterLink)="(['/'])"
>
<span *ngIf="!loading && !user">{{ 'USER.PAGES.NOUSER' | translate }}</span>
<cnsl-info-row topContent *ngIf="user" [user]="user"></cnsl-info-row>
<cnsl-info-row topContent *ngIf="user" [user]="user" [loginPolicy]="loginPolicy"></cnsl-info-row>
</cnsl-top-view>
<div *ngIf="loading" class="max-width-container">

View File

@@ -20,6 +20,7 @@ import { ToastService } from 'src/app/services/toast.service';
import { Buffer } from 'buffer';
import { EditDialogComponent, EditDialogType } from './edit-dialog/edit-dialog.component';
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
import { LoginPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
@Component({
selector: 'cnsl-auth-user-detail',
@@ -58,6 +59,7 @@ export class AuthUserDetailComponent implements OnDestroy {
},
];
public currentSetting: string | undefined = this.settingsList[0].id;
public loginPolicy?: LoginPolicy.AsObject;
constructor(
public translate: TranslateService,
@@ -93,6 +95,12 @@ export class AuthUserDetailComponent implements OnDestroy {
this.userService.getSupportedLanguages().then((lang) => {
this.languages = lang.languagesList;
});
this.userService.getMyLoginPolicy().then((policy) => {
if (policy.policy) {
this.loginPolicy = policy.policy;
}
});
}
private changeSelection(small: boolean): void {

View File

@@ -33,7 +33,7 @@
</button>
</ng-template>
</ng-template>
<cnsl-info-row topContent *ngIf="user" [user]="user"></cnsl-info-row>
<cnsl-info-row topContent *ngIf="user" [user]="user" [loginPolicy]="loginPolicy"></cnsl-info-row>
</cnsl-top-view>
<div *ngIf="loading" class="max-width-container">

View File

@@ -20,6 +20,7 @@ import { ToastService } from 'src/app/services/toast.service';
import { Buffer } from 'buffer';
import { EditDialogComponent, EditDialogType } from '../auth-user-detail/edit-dialog/edit-dialog.component';
import { ResendEmailDialogComponent } from '../auth-user-detail/resend-email-dialog/resend-email-dialog.component';
import { LoginPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
const GENERAL: SidenavSetting = { id: 'general', i18nKey: 'USER.SETTINGS.GENERAL' };
const GRANTS: SidenavSetting = { id: 'grants', i18nKey: 'USER.SETTINGS.USERGRANTS' };
@@ -58,6 +59,7 @@ export class UserDetailComponent implements OnInit {
public settingsList: SidenavSetting[] = [GENERAL, GRANTS, MEMBERSHIPS, METADATA];
public currentSetting: string | undefined = 'general';
public loginPolicy?: LoginPolicy.AsObject;
constructor(
public translate: TranslateService,
@@ -137,6 +139,12 @@ export class UserDetailComponent implements OnInit {
public ngOnInit(): void {
this.refreshUser();
this.mgmtUserService.getLoginPolicy().then((policy) => {
if (policy.policy) {
this.loginPolicy = policy.policy;
}
});
}
public changeUsername(): void {

View File

@@ -30,6 +30,8 @@ import {
GetMyEmailResponse,
GetMyLabelPolicyRequest,
GetMyLabelPolicyResponse,
GetMyLoginPolicyRequest,
GetMyLoginPolicyResponse,
GetMyPasswordComplexityPolicyRequest,
GetMyPasswordComplexityPolicyResponse,
GetMyPhoneRequest,
@@ -487,6 +489,11 @@ export class GrpcAuthService {
return this.grpcService.auth.getSupportedLanguages(req, null).then((resp) => resp.toObject());
}
public getMyLoginPolicy(): Promise<GetMyLoginPolicyResponse.AsObject> {
const req = new GetMyLoginPolicyRequest();
return this.grpcService.auth.getMyLoginPolicy(req, null).then((resp) => resp.toObject());
}
public removeMyPhone(): Promise<RemoveMyPhoneResponse.AsObject> {
return this.grpcService.auth.removeMyPhone(new RemoveMyPhoneRequest(), null).then((resp) => resp.toObject());
}

View File

@@ -231,6 +231,7 @@
"CREATE": "Erstellen",
"MY": "Meine Informationen",
"LOGINNAMES": "Login-Namen",
"LOGINMETHODS": "Anmeldemethoden",
"LOGINNAMESDESC": "Mit diesen Namen kannst Du Dich anmelden.",
"NOUSER": "Kein Benutzer",
"REACTIVATE": "Reaktivieren",

View File

@@ -231,6 +231,7 @@
"CREATE": "Create",
"MY": "My Information",
"LOGINNAMES": "Login names",
"LOGINMETHODS": "Login methods",
"LOGINNAMESDESC": "These are your login names:",
"NOUSER": "No associated user.",
"REACTIVATE": "Reactivate",

View File

@@ -231,6 +231,7 @@
"CREATE": "Créer",
"MY": "Mes informations",
"LOGINNAMES": "Noms de connexion",
"LOGINMETHODS": "Méthodes de connexion",
"LOGINNAMESDESC": "Ce sont vos noms de connexion",
"NOUSER": "Aucun utilisateur associé.",
"REACTIVATE": "Réactiver",

View File

@@ -231,6 +231,7 @@
"CREATE": "Crea",
"MY": "Le mie informazioni",
"LOGINNAMES": "Loginnames",
"LOGINMETHODS": "Metodi di accesso",
"LOGINNAMESDESC": "Questi sono i nomi di accesso:",
"NOUSER": "Nessun utente associato.",
"REACTIVATE": "Riattiva",

View File

@@ -231,6 +231,7 @@
"CREATE": "创建",
"MY": "我的信息",
"LOGINNAMES": "登录名称",
"LOGINMETHODS": "登录方式",
"LOGINNAMESDESC": "这些是您的登录名:",
"NOUSER": "没有关联的用户。",
"REACTIVATE": "重新启用",