fix(console): some bugs (#1538)

* fix feature pipe, only org check

* fix user, email update

* fix roles
This commit is contained in:
Max Peintner
2021-04-07 11:32:39 +02:00
committed by GitHub
parent f9286574a9
commit f0cc12238e
12 changed files with 57 additions and 40 deletions

View File

@@ -38,7 +38,8 @@
{{'POLICY.DATA.ALLOWREGISTER' | translate}} {{'POLICY.DATA.ALLOWREGISTER' | translate}}
</mat-slide-toggle> </mat-slide-toggle>
<ng-container *ngIf="(['login_policy.registration'] | hasFeature | async) == false; else regInfo"> <ng-container
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['login_policy.registration'] | hasFeature | async) == false; else regInfo">
<cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value: <cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value:
'login_policy.registration'})}} 'login_policy.registration'})}}
</cnsl-info-section> </cnsl-info-section>
@@ -72,13 +73,14 @@
<cnsl-form-field class="form-field" label="Access Code" required="true"> <cnsl-form-field class="form-field" label="Access Code" required="true">
<cnsl-label>{{'LOGINPOLICY.PASSWORDLESS' | translate}}</cnsl-label> <cnsl-label>{{'LOGINPOLICY.PASSWORDLESS' | translate}}</cnsl-label>
<mat-select [(ngModel)]="loginData.passwordlessType" <mat-select [(ngModel)]="loginData.passwordlessType"
[disabled]="disabled || (['login_policy.passwordless'] | hasFeature | async) == false"> [disabled]="disabled || (serviceType == PolicyComponentServiceType.MGMT && (['login_policy.passwordless'] | hasFeature | async) == false)">
<mat-option *ngFor="let pt of passwordlessTypes" [value]="pt"> <mat-option *ngFor="let pt of passwordlessTypes" [value]="pt">
{{'LOGINPOLICY.PASSWORDLESSTYPE.'+pt | translate}} {{'LOGINPOLICY.PASSWORDLESSTYPE.'+pt | translate}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</cnsl-form-field> </cnsl-form-field>
<ng-container *ngIf="(['login_policy.passwordless'] | hasFeature | async) == false"> <ng-container
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['login_policy.passwordless'] | hasFeature | async) == false">
<cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value: <cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value:
'login_policy.passwordless'})}} 'login_policy.passwordless'})}}
</cnsl-info-section> </cnsl-info-section>
@@ -94,7 +96,8 @@
<ng-container *ngIf="!isDefault"> <ng-container *ngIf="!isDefault">
<h3 class="subheader">{{ 'MFA.LIST.MULTIFACTORTITLE' | translate }}</h3> <h3 class="subheader">{{ 'MFA.LIST.MULTIFACTORTITLE' | translate }}</h3>
<p class="subdesc">{{ 'MFA.LIST.MULTIFACTORDESCRIPTION' | translate }}</p> <p class="subdesc">{{ 'MFA.LIST.MULTIFACTORDESCRIPTION' | translate }}</p>
<ng-container *ngIf="(['login_policy.factors'] | hasFeature | async) == false"> <ng-container
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['login_policy.factors'] | hasFeature | async) == false">
<cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value: 'login_policy.factors'})}} <cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value: 'login_policy.factors'})}}
</cnsl-info-section> </cnsl-info-section>
</ng-container> </ng-container>
@@ -105,29 +108,33 @@
<h3 class="subheader">{{ 'MFA.LIST.SECONDFACTORTITLE' | translate }}</h3> <h3 class="subheader">{{ 'MFA.LIST.SECONDFACTORTITLE' | translate }}</h3>
<p class="subdesc">{{ 'MFA.LIST.SECONDFACTORDESCRIPTION' | translate }}</p> <p class="subdesc">{{ 'MFA.LIST.SECONDFACTORDESCRIPTION' | translate }}</p>
<ng-container *ngIf="(['login_policy.factors'] | hasFeature | async) == false"> <ng-container
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['login_policy.factors'] | hasFeature | async) == false">
<cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value: 'login_policy.factors'})}} <cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value: 'login_policy.factors'})}}
</cnsl-info-section> </cnsl-info-section>
</ng-container> </ng-container>
<app-mfa-table [service]="service" [serviceType]="serviceType" <app-mfa-table [service]="service" [serviceType]="serviceType"
[componentType]="LoginMethodComponentType.SecondFactor" [componentType]="LoginMethodComponentType.SecondFactor"
[disabled]="([serviceType == PolicyComponentServiceType.ADMIN ? 'iam.policy.write' : serviceType == PolicyComponentServiceType.MGMT ? 'policy.write' : ''] | hasRole | async) == false || ((['login_policy.factors'] | hasFeature | async) == false)"> [disabled]="([serviceType == PolicyComponentServiceType.ADMIN ? 'iam.policy.write' : serviceType == PolicyComponentServiceType.MGMT ? 'policy.write' : ''] | hasRole | async) == false || (['login_policy.factors'] | hasFeature | async) == false">
</app-mfa-table> </app-mfa-table>
</ng-container> </ng-container>
<h3 class="subheader">{{'LOGINPOLICY.IDPS' | translate}}</h3> <h3 class="subheader">{{'LOGINPOLICY.IDPS' | translate}}</h3>
<ng-container *ngIf="(['login_policy.idp'] | hasFeature | async) == false"> <ng-container
*ngIf="serviceType == PolicyComponentServiceType.MGMT && (['login_policy.idp'] | hasFeature | async) == false">
<cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value: <cnsl-info-section type="WARN">{{'FEATURES.NOTAVAILABLE' | translate: ({value:
'login_policy.idp'})}} 'login_policy.idp'})}}
</cnsl-info-section> </cnsl-info-section>
</ng-container> </ng-container>
<div class="idps"> <div class="idps">
<div class="idp" [ngClass]="{'disabled': disabled || (['login_policy.idp'] | hasFeature | async) == false}" <div class="idp"
[ngClass]="{'disabled': disabled || (serviceType == PolicyComponentServiceType.MGMT && (['login_policy.idp'] | hasFeature | async) == false)}"
*ngFor="let idp of idps"> *ngFor="let idp of idps">
<button [disabled]="disabled || (['login_policy.idp'] | hasFeature | async) == false" mat-icon-button <button
(click)="removeIdp(idp)" class="rm"> [disabled]="disabled || (serviceType == PolicyComponentServiceType.MGMT && (['login_policy.idp'] | hasFeature | async) == false)"
mat-icon-button (click)="removeIdp(idp)" class="rm">
<mat-icon matTooltip="{{'ACTIONS.REMOVE' | translate}}"> <mat-icon matTooltip="{{'ACTIONS.REMOVE' | translate}}">
remove_circle</mat-icon> remove_circle</mat-icon>
</button> </button>
@@ -143,8 +150,8 @@
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="!disabled && (['login_policy.idp'] | hasFeature | async)" class="new-idp" (click)="openDialog()" <div *ngIf="!disabled && (serviceType == PolicyComponentServiceType.MGMT && (['login_policy.idp'] | hasFeature | async))"
matRipple> class="new-idp" (click)="openDialog()" matRipple>
<mat-icon>add</mat-icon> <mat-icon>add</mat-icon>
</div> </div>
</div> </div>

View File

@@ -56,8 +56,8 @@
<p class="desc"> <p class="desc">
{{'POLICY.IAM_POLICY.DESCRIPTION' | translate}}</p> {{'POLICY.IAM_POLICY.DESCRIPTION' | translate}}</p>
<cnsl-info-section class="warn"
<cnsl-info-section class="warn" *ngIf="(['password_complexity_policy'] | hasFeature | async) == false" *ngIf="type == PolicyGridType.ORG && (['password_complexity_policy'] | hasFeature | async) == false"
type="WARN"> type="WARN">
{{'FEATURES.NOTAVAILABLE' | translate: ({value: {{'FEATURES.NOTAVAILABLE' | translate: ({value:
'password_complexity_policy'})}} 'password_complexity_policy'})}}
@@ -66,7 +66,8 @@
<span class="fill-space"></span> <span class="fill-space"></span>
<div class="btn-wrapper"> <div class="btn-wrapper">
<ng-template appHasRole [appHasRole]="['iam.policy.write']"> <ng-template appHasRole [appHasRole]="['iam.policy.write']">
<button [disabled]="(['password_complexity_policy'] | hasFeature | async) == false" <button
[disabled]="type == PolicyGridType.ORG && (['password_complexity_policy'] | hasFeature | async) == false"
[routerLink]="[type == PolicyGridType.IAM ? '/iam' : type == PolicyGridType.ORG ? '/org' : '','policy', PolicyComponentType.IAM ]" [routerLink]="[type == PolicyGridType.IAM ? '/iam' : type == PolicyGridType.ORG ? '/org' : '','policy', PolicyComponentType.IAM ]"
mat-stroked-button>{{'POLICY.BTN_EDIT' | translate}}</button> mat-stroked-button>{{'POLICY.BTN_EDIT' | translate}}</button>
</ng-template> </ng-template>
@@ -117,7 +118,8 @@
<p class="desc"> <p class="desc">
{{'POLICY.LABEL.DESCRIPTION' | translate}}</p> {{'POLICY.LABEL.DESCRIPTION' | translate}}</p>
<cnsl-info-section class="warn" *ngIf="(['label_policy'] | hasFeature | async) == false" type="WARN"> <cnsl-info-section class="warn"
*ngIf="type == PolicyGridType.ORG && (['label_policy'] | hasFeature | async) == false" type="WARN">
{{'FEATURES.NOTAVAILABLE' | translate: ({value: {{'FEATURES.NOTAVAILABLE' | translate: ({value:
'label_policy'})}} 'label_policy'})}}
</cnsl-info-section> </cnsl-info-section>
@@ -127,7 +129,8 @@
<ng-template appHasRole [appHasRole]="['iam.policy.write']"> <ng-template appHasRole [appHasRole]="['iam.policy.write']">
<button <button
[routerLink]="[type == PolicyGridType.IAM ? '/iam' : type == PolicyGridType.ORG ? '/org' : '','policy', PolicyComponentType.LABEL ]" [routerLink]="[type == PolicyGridType.IAM ? '/iam' : type == PolicyGridType.ORG ? '/org' : '','policy', PolicyComponentType.LABEL ]"
mat-stroked-button [disabled]="(['label_policy'] | hasFeature | async) == false"> mat-stroked-button
[disabled]="type == PolicyGridType.ORG && (['label_policy'] | hasFeature | async) == false">
{{'POLICY.BTN_EDIT' | translate}}</button> {{'POLICY.BTN_EDIT' | translate}}</button>
</ng-template> </ng-template>
</div> </div>

View File

@@ -17,7 +17,7 @@
item.details.changeDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' item.details.changeDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'
}}</span> }}</span>
<span class="name" *ngIf="item.projectName">{{ item.projectName }}</span> <span class="name" *ngIf="item.projectName">{{ item.projectName }}</span>
<span class="description" *ngIf="item.resourceOwnerName">{{item.resourceOwnerName}}</span> <span class="description" *ngIf="item.projectOwnerName">{{item.projectOwnerName}}</span>
<span *ngIf="item.details.creationDate" class="created">{{'PROJECT.PAGES.CREATEDON' | translate}} <span *ngIf="item.details.creationDate" class="created">{{'PROJECT.PAGES.CREATEDON' | translate}}
{{ item.details.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' {{ item.details.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'
}}</span> }}</span>
@@ -25,8 +25,6 @@
</div> </div>
<template [ngTemplateOutlet]="toggleButton" [ngTemplateOutletContext]="{key: item}"></template> <template [ngTemplateOutlet]="toggleButton" [ngTemplateOutletContext]="{key: item}"></template>
</div> </div>
</div> </div>
@@ -42,7 +40,7 @@
item.details.changeDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' item.details.changeDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'
}}</span> }}</span>
<span class="name" *ngIf="item.projectName">{{ item.projectName }}</span> <span class="name" *ngIf="item.projectName">{{ item.projectName }}</span>
<span class="description" *ngIf="item.resourceOwnerName">{{item.resourceOwnerName}}</span> <span class="description" *ngIf="item.projectOwnerName">{{item.projectOwnerName}}</span>
<span *ngIf="item.details.creationDate" class="created">{{'PROJECT.PAGES.CREATEDON' | translate}} <span *ngIf="item.details.creationDate" class="created">{{'PROJECT.PAGES.CREATEDON' | translate}}
{{ item.details.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}</span> {{ item.details.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm' }}</span>
<span class="fill-space"></span> <span class="fill-space"></span>

View File

@@ -37,20 +37,21 @@
<ng-container matColumnDef="resourceOwnerName"> <ng-container matColumnDef="resourceOwnerName">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.TABLE.RESOURCEOWNER' | translate }} </th> <th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.TABLE.RESOURCEOWNER' | translate }} </th>
<td class="pointer" mat-cell *matCellDef="let project"> <td class="pointer" mat-cell *matCellDef="let project">
{{project.resourceOwnerName}} </td> {{project.projectOwnerName}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="state"> <ng-container matColumnDef="state">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.TABLE.STATE' | translate }} </th> <th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.TABLE.STATE' | translate }} </th>
<td mat-cell *matCellDef="let project"><span <td mat-cell *matCellDef="let project"><span *ngIf="project.state">{{'PROJECT.STATE.'+project.state
*ngIf="project.state">{{'PROJECT.STATE.'+project.state | translate}}</span></td> | translate}}</span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="creationDate"> <ng-container matColumnDef="creationDate">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.TABLE.CREATIONDATE' | translate }} </th> <th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.TABLE.CREATIONDATE' | translate }} </th>
<td mat-cell *matCellDef="let project"> <td mat-cell *matCellDef="let project">
<span <span *ngIf="project.details.creationDate">{{project.details.creationDate | timestampToDate |
*ngIf="project.creationDate">{{project.creationDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'}}</span> localizedDate:
'EEE dd. MMM, HH:mm'}}</span>
</td> </td>
</ng-container> </ng-container>
@@ -58,8 +59,9 @@
<ng-container matColumnDef="changeDate"> <ng-container matColumnDef="changeDate">
<th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.TABLE.CHANGEDATE' | translate }} </th> <th mat-header-cell *matHeaderCellDef> {{ 'PROJECT.TABLE.CHANGEDATE' | translate }} </th>
<td mat-cell *matCellDef="let project"> <td mat-cell *matCellDef="let project">
<span <span *ngIf="project.details.changeDate">
*ngIf="project.changeDate">{{project.changeDate | timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'}}</span> {{project.details.changeDate
| timestampToDate | localizedDate: 'EEE dd. MMM, HH:mm'}}</span>
</td> </td>
</ng-container> </ng-container>

View File

@@ -101,6 +101,7 @@ export class GrantedProjectListComponent implements OnInit, OnDestroy {
this.grid = false; this.grid = false;
} }
this.dataSource.data = this.grantedProjectList; this.dataSource.data = this.grantedProjectList;
console.log(resp.resultList);
this.loadingSubject.next(false); this.loadingSubject.next(false);
}).catch(error => { }).catch(error => {

View File

@@ -37,7 +37,7 @@
<ng-container *ngIf="currentCreateStep === STEPS"> <ng-container *ngIf="currentCreateStep === STEPS">
<h1>{{'PROJECT.GRANT.CREATE.SEL_ROLES' | translate}}</h1> <h1>{{'PROJECT.GRANT.CREATE.SEL_ROLES' | translate}}</h1>
<ng-container <ng-container
*ngIf="(projectId && (context === UserGrantContext.OWNED_PROJECT || ((context === UserGrantContext.USER || context === UserGrantContext.NONE) && $any(project)?.id == undefined)))"> *ngIf="$any(project)?.id && (context === UserGrantContext.OWNED_PROJECT || context === UserGrantContext.USER || context === UserGrantContext.NONE)">
<app-card> <app-card>
<app-project-roles (changedSelection)="selectRoles($event)" [projectId]="projectId"> <app-project-roles (changedSelection)="selectRoles($event)" [projectId]="projectId">
</app-project-roles> </app-project-roles>
@@ -45,11 +45,11 @@
</ng-container> </ng-container>
<ng-container <ng-container
*ngIf="(context === UserGrantContext.GRANTED_PROJECT || ((context === UserGrantContext.USER || context === UserGrantContext.NONE) && $any(project)?.id)) && grantRolesKeyList"> *ngIf="$any(project)?.projectId && (context === UserGrantContext.GRANTED_PROJECT || context === UserGrantContext.USER || context === UserGrantContext.NONE) && grantedRoleKeysList">
<cnsl-form-field class="form-field" appearance="outline"> <cnsl-form-field class="form-field" appearance="outline">
<cnsl-label>{{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }}</cnsl-label> <cnsl-label>{{ 'PROJECT.GRANT.ROLENAMESLIST' | translate }}</cnsl-label>
<mat-select multiple (selectionChange)="rolesList = $event.value"> <mat-select multiple (selectionChange)="rolesList = $event.value">
<mat-option *ngFor="let role of grantRolesKeyList" [value]="role"> <mat-option *ngFor="let role of grantedRoleKeysList" [value]="role">
{{role}} {{role}}
</mat-option> </mat-option>
</mat-select> </mat-select>

View File

@@ -37,7 +37,7 @@ export class UserGrantCreateComponent implements OnDestroy {
public UserGrantContext: any = UserGrantContext; public UserGrantContext: any = UserGrantContext;
public grantRolesKeyList: string[] = []; public grantedRoleKeysList: string[] = [];
public user!: User.AsObject; public user!: User.AsObject;
public UserTarget: any = UserTarget; public UserTarget: any = UserTarget;
@@ -66,7 +66,7 @@ export class UserGrantCreateComponent implements OnDestroy {
this.context = UserGrantContext.GRANTED_PROJECT; this.context = UserGrantContext.GRANTED_PROJECT;
this.mgmtService.getGrantedProjectByID(this.projectId, this.grantId).then(resp => { this.mgmtService.getGrantedProjectByID(this.projectId, this.grantId).then(resp => {
if (resp.grantedProject?.grantedRoleKeysList) { if (resp.grantedProject?.grantedRoleKeysList) {
this.grantRolesKeyList = resp.grantedProject?.grantedRoleKeysList; this.grantedRoleKeysList = resp.grantedProject?.grantedRoleKeysList;
} }
}).catch((error: any) => { }).catch((error: any) => {
this.toast.showError(error); this.toast.showError(error);
@@ -139,10 +139,11 @@ export class UserGrantCreateComponent implements OnDestroy {
}); });
break; break;
case UserGrantContext.NONE: case UserGrantContext.NONE:
console.log('none');
let tempGrantId; let tempGrantId;
if ((this.project as GrantedProject.AsObject)?.projectId) { if ((this.project as GrantedProject.AsObject)?.grantId) {
tempGrantId = (this.project as GrantedProject.AsObject).projectId; tempGrantId = (this.project as GrantedProject.AsObject).grantId;
} }
this.userService.addUserGrant( this.userService.addUserGrant(
@@ -158,13 +159,13 @@ export class UserGrantCreateComponent implements OnDestroy {
}); });
break; break;
} }
} }
public selectProject(project: Project.AsObject | GrantedProject.AsObject | any): void { public selectProject(project: Project.AsObject | GrantedProject.AsObject | any): void {
this.project = project; this.project = project;
this.projectId = project.id || project.projectId; this.projectId = project.id || project.projectId;
this.grantRolesKeyList = project.roleKeysList ?? [];
this.grantedRoleKeysList = project.grantedRoleKeysList ?? [];
} }
public selectUser(user: User.AsObject): void { public selectUser(user: User.AsObject): void {

View File

@@ -85,7 +85,7 @@ export class AuthUserDetailComponent implements OnDestroy {
public saveEmail(email: string): void { public saveEmail(email: string): void {
this.userService this.userService
.setMyPhone(email).then(() => { .setMyEmail(email).then(() => {
this.toast.showInfo('USER.TOAST.EMAILSAVED', true); this.toast.showInfo('USER.TOAST.EMAILSAVED', true);
if (this.user.human) { if (this.user.human) {
const mailToSet = new Email(); const mailToSet = new Email();

View File

@@ -90,6 +90,7 @@ export class UserDetailComponent implements OnInit {
this.user.human.profile.firstName, this.user.human.profile.firstName,
this.user.human.profile.lastName, this.user.human.profile.lastName,
this.user.human.profile.nickName, this.user.human.profile.nickName,
this.user.human.profile.displayName,
this.user.human.profile.preferredLanguage, this.user.human.profile.preferredLanguage,
this.user.human.profile.gender) this.user.human.profile.gender)
.then(() => { .then(() => {

View File

@@ -230,7 +230,7 @@ export class GrpcAuthService {
*/ */
public canUseFeature(features: string[] | RegExp[]): Observable<boolean> { public canUseFeature(features: string[] | RegExp[]): Observable<boolean> {
if (features && features.length > 0) { if (features && features.length > 0) {
return this.zitadelPermissions.pipe(switchMap(zFeatures => of(this.hasFeature(zFeatures, features)))); return this.zitadelFeatures.pipe(switchMap(zFeatures => of(this.hasFeature(zFeatures, features))));
} else { } else {
return of(false); return of(false);
} }

View File

@@ -919,6 +919,7 @@ export class ManagementService {
firstName?: string, firstName?: string,
lastName?: string, lastName?: string,
nickName?: string, nickName?: string,
displayName?: string,
preferredLanguage?: string, preferredLanguage?: string,
gender?: Gender gender?: Gender
): Promise<UpdateHumanProfileResponse.AsObject> { ): Promise<UpdateHumanProfileResponse.AsObject> {
@@ -933,6 +934,9 @@ export class ManagementService {
if (nickName) { if (nickName) {
req.setNickName(nickName); req.setNickName(nickName);
} }
if (displayName) {
req.setDisplayName(displayName);
}
if (gender) { if (gender) {
req.setGender(gender); req.setGender(gender);
} }

View File

@@ -3,5 +3,5 @@
"mgmtServiceUrl": "https://api.zitadel.io", "mgmtServiceUrl": "https://api.zitadel.io",
"adminServiceUrl":"https://api.zitadel.io", "adminServiceUrl":"https://api.zitadel.io",
"issuer": "https://issuer.zitadel.io", "issuer": "https://issuer.zitadel.io",
"clientid": "100992085175427532@zitadel" "clientid": "69234247558357051@zitadel"
} }