mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-06 12:47:37 +00:00
fix: disable user action if viewer (#2737)
This commit is contained in:
parent
f7743834b0
commit
a9035def0f
@ -1,7 +1,8 @@
|
||||
<form [formGroup]="profileForm" *ngIf="profileForm" (ngSubmit)="submitForm()">
|
||||
<div class="user-form-content">
|
||||
<div class="user-form-content inner">
|
||||
<button class="camera-wrapper" type="button" (click)="showEditImage ? openUploadDialog() : null">
|
||||
<button [disabled]="user && disabled" class="camera-wrapper" type="button"
|
||||
(click)="showEditImage ? openUploadDialog() : null">
|
||||
<div class="i-wrapper" *ngIf="showEditImage">
|
||||
<i class="las la-camera"></i>
|
||||
</div>
|
||||
@ -16,7 +17,7 @@
|
||||
<cnsl-label>{{ 'USER.PROFILE.USERNAME' | translate }}</cnsl-label>
|
||||
<input cnslInput formControlName="userName" />
|
||||
</cnsl-form-field>
|
||||
<button type="button" color="primary" mat-stroked-button class="edit"
|
||||
<button [disabled]="user && disabled" type="button" color="primary" mat-stroked-button class="edit"
|
||||
(click)="changeUsername()">{{'USER.PROFILE.CHANGEUSERNAME' |
|
||||
translate}}</button>
|
||||
</div>
|
||||
|
@ -16,25 +16,20 @@ export class DetailFormComponent implements OnDestroy, OnChanges {
|
||||
@Input() public preferredLoginName: string = '';
|
||||
@Input() public username!: string;
|
||||
@Input() public user!: Human.AsObject;
|
||||
@Input() public disabled: boolean = false;
|
||||
@Input() public disabled: boolean = true;
|
||||
@Input() public genders: Gender[] = [];
|
||||
@Input() public languages: string[] = ['de', 'en'];
|
||||
@Output() public submitData: EventEmitter<Profile.AsObject> = new EventEmitter<Profile.AsObject>();
|
||||
@Output() public changedLanguage: EventEmitter<string> = new EventEmitter<string>();
|
||||
@Output() public changeUsernameClicked: EventEmitter<void> = new EventEmitter();
|
||||
|
||||
|
||||
public profileForm!: FormGroup;
|
||||
|
||||
private sub: Subscription = new Subscription();
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private dialog: MatDialog,
|
||||
) {
|
||||
constructor(private fb: FormBuilder, private dialog: MatDialog) {
|
||||
this.profileForm = this.fb.group({
|
||||
userName: [{ value: '', disabled: true }, [
|
||||
Validators.required,
|
||||
]],
|
||||
userName: [{ value: '', disabled: true }, [Validators.required]],
|
||||
firstName: [{ value: '', disabled: this.disabled }, Validators.required],
|
||||
lastName: [{ value: '', disabled: this.disabled }, Validators.required],
|
||||
nickName: [{ value: '', disabled: this.disabled }],
|
||||
@ -46,9 +41,7 @@ export class DetailFormComponent implements OnDestroy, OnChanges {
|
||||
|
||||
public ngOnChanges(): void {
|
||||
this.profileForm = this.fb.group({
|
||||
userName: [{ value: '', disabled: true }, [
|
||||
Validators.required,
|
||||
]],
|
||||
userName: [{ value: '', disabled: true }, [Validators.required]],
|
||||
firstName: [{ value: '', disabled: this.disabled }, Validators.required],
|
||||
lastName: [{ value: '', disabled: this.disabled }, Validators.required],
|
||||
nickName: [{ value: '', disabled: this.disabled }],
|
||||
@ -60,7 +53,7 @@ export class DetailFormComponent implements OnDestroy, OnChanges {
|
||||
this.profileForm.patchValue({ userName: this.username, ...this.user.profile });
|
||||
|
||||
if (this.preferredLanguage) {
|
||||
this.sub = this.preferredLanguage.valueChanges.subscribe(value => {
|
||||
this.sub = this.preferredLanguage.valueChanges.subscribe((value) => {
|
||||
this.changedLanguage.emit(value);
|
||||
});
|
||||
}
|
||||
@ -86,7 +79,7 @@ export class DetailFormComponent implements OnDestroy, OnChanges {
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
dialogRef.afterClosed().subscribe((resp) => {
|
||||
if (resp) {
|
||||
}
|
||||
});
|
||||
@ -114,5 +107,4 @@ export class DetailFormComponent implements OnDestroy, OnChanges {
|
||||
public get preferredLanguage(): AbstractControl | null {
|
||||
return this.profileForm.get('preferredLanguage');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,53 +1,53 @@
|
||||
<cnsl-card title="{{'USER.PASSWORDLESS.TITLE' | translate}}"
|
||||
description="{{'USER.PASSWORDLESS.DESCRIPTION' | translate}}">
|
||||
<button card-actions mat-icon-button (click)="getPasswordless()" class="icon-button" matTooltip="{{'ACTIONS.REFRESH' | translate}}">
|
||||
<mat-icon class="icon">refresh</mat-icon>
|
||||
description="{{'USER.PASSWORDLESS.DESCRIPTION' | translate}}">
|
||||
<button card-actions mat-icon-button (click)="getPasswordless()" class="icon-button"
|
||||
matTooltip="{{'ACTIONS.REFRESH' | translate}}">
|
||||
<mat-icon class="icon">refresh</mat-icon>
|
||||
</button>
|
||||
<cnsl-refresh-table [hideRefresh]="true" [loading]="loading$ | async" [dataSize]="dataSource?.data?.length ?? 0">
|
||||
<table class="table" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.PASSWORDLESS.NAME' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let mfa"><span *ngIf="mfa?.name" class="centered">
|
||||
{{ mfa?.name }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="state">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.PASSWORDLESS.TABLESTATE' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let mfa"><span class="centered">
|
||||
{{'USER.PASSWORDLESS.STATE.'+ mfa.state | translate}}
|
||||
<i matTooltip="verified" *ngIf="mfa.state === AuthFactorState.AUTH_FACTOR_STATE_READY"
|
||||
class="verified las la-check-circle"></i>
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.PASSWORDLESS.TABLEACTIONS' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let mfa">
|
||||
<button matTooltip="{{'ACTIONS.REMOVE' | translate}}" color="warn" mat-icon-button
|
||||
(click)="deletePasswordless(mfa.id)">
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</cnsl-refresh-table>
|
||||
<div class="add-row">
|
||||
<button [disabled]="user && disabled" class="button" (click)="sendPasswordlessRegistration()" mat-raised-button
|
||||
color="primary" matTooltip="{{'ACTIONS.NEW' | translate}}">
|
||||
{{'USER.PASSWORDLESS.SEND' | translate}}
|
||||
<i class="icon las la-paper-plane"></i>
|
||||
</button>
|
||||
<cnsl-refresh-table [hideRefresh]="true" [loading]="loading$ | async"
|
||||
[dataSize]="dataSource?.data?.length ?? 0">
|
||||
<table class="table" mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.PASSWORDLESS.NAME' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let mfa"><span *ngIf="mfa?.name" class="centered">
|
||||
{{ mfa?.name }}
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="state">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.PASSWORDLESS.TABLESTATE' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let mfa"><span class="centered">
|
||||
{{'USER.PASSWORDLESS.STATE.'+ mfa.state | translate}}
|
||||
<i matTooltip="verified" *ngIf="mfa.state === AuthFactorState.AUTH_FACTOR_STATE_READY"
|
||||
class="verified las la-check-circle"></i>
|
||||
</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'USER.PASSWORDLESS.TABLEACTIONS' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let mfa">
|
||||
<button matTooltip="{{'ACTIONS.REMOVE' | translate}}" color="warn" mat-icon-button
|
||||
(click)="deletePasswordless(mfa.id)">
|
||||
<i class="las la-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr class="highlight" mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</cnsl-refresh-table>
|
||||
<div class="add-row">
|
||||
<button class="button" (click)="sendPasswordlessRegistration()" mat-raised-button color="primary"
|
||||
matTooltip="{{'ACTIONS.NEW' | translate}}">
|
||||
{{'USER.PASSWORDLESS.SEND' | translate}}
|
||||
<i class="icon las la-paper-plane"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<div class="spinner-container" *ngIf="loading$ | async">
|
||||
<mat-spinner diameter="50"></mat-spinner>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<div class="spinner-container" *ngIf="loading$ | async">
|
||||
<mat-spinner diameter="50"></mat-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</cnsl-card>
|
@ -10,10 +10,10 @@ import { ToastService } from 'src/app/services/toast.service';
|
||||
|
||||
export interface WebAuthNOptions {
|
||||
challenge: string;
|
||||
rp: { name: string, id: string; };
|
||||
user: { name: string, id: string, displayName: string; };
|
||||
rp: { name: string; id: string };
|
||||
user: { name: string; id: string; displayName: string };
|
||||
pubKeyCredParams: any;
|
||||
authenticatorSelection: { userVerification: string; };
|
||||
authenticatorSelection: { userVerification: string };
|
||||
timeout: number;
|
||||
attestation: string;
|
||||
}
|
||||
@ -25,6 +25,7 @@ export interface WebAuthNOptions {
|
||||
})
|
||||
export class PasswordlessComponent implements OnInit, OnDestroy {
|
||||
@Input() public user!: User.AsObject;
|
||||
@Input() public disabled: boolean = true;
|
||||
public displayedColumns: string[] = ['name', 'state', 'actions'];
|
||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||
@ -36,9 +37,7 @@ export class PasswordlessComponent implements OnInit, OnDestroy {
|
||||
public AuthFactorState: any = AuthFactorState;
|
||||
public error: string = '';
|
||||
|
||||
constructor(private service: ManagementService,
|
||||
private toast: ToastService,
|
||||
private dialog: MatDialog) { }
|
||||
constructor(private service: ManagementService, private toast: ToastService, private dialog: MatDialog) {}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.getPasswordless();
|
||||
@ -49,12 +48,15 @@ export class PasswordlessComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public getPasswordless(): void {
|
||||
this.service.listHumanPasswordless(this.user.id).then(passwordless => {
|
||||
this.dataSource = new MatTableDataSource(passwordless.resultList);
|
||||
this.dataSource.sort = this.sort;
|
||||
}).catch(error => {
|
||||
this.error = error.message;
|
||||
});
|
||||
this.service
|
||||
.listHumanPasswordless(this.user.id)
|
||||
.then((passwordless) => {
|
||||
this.dataSource = new MatTableDataSource(passwordless.resultList);
|
||||
this.dataSource.sort = this.sort;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.error = error.message;
|
||||
});
|
||||
}
|
||||
|
||||
public deletePasswordless(id?: string): void {
|
||||
@ -68,23 +70,29 @@ export class PasswordlessComponent implements OnInit, OnDestroy {
|
||||
width: '400px',
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(resp => {
|
||||
dialogRef.afterClosed().subscribe((resp) => {
|
||||
if (resp && id) {
|
||||
this.service.removeHumanPasswordless(id, this.user.id).then(() => {
|
||||
this.toast.showInfo('USER.TOAST.PASSWORDLESSREMOVED', true);
|
||||
this.getPasswordless();
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
this.service
|
||||
.removeHumanPasswordless(id, this.user.id)
|
||||
.then(() => {
|
||||
this.toast.showInfo('USER.TOAST.PASSWORDLESSREMOVED', true);
|
||||
this.getPasswordless();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public sendPasswordlessRegistration(): void {
|
||||
this.service.sendPasswordlessRegistration(this.user.id).then(() => {
|
||||
this.toast.showInfo('USER.TOAST.PASSWORDLESSREGISTRATIONSENT');
|
||||
}).catch(error => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
this.service
|
||||
.sendPasswordlessRegistration(this.user.id)
|
||||
.then(() => {
|
||||
this.toast.showInfo('USER.TOAST.PASSWORDLESSREGISTRATIONSENT');
|
||||
})
|
||||
.catch((error) => {
|
||||
this.toast.showError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -87,7 +87,8 @@
|
||||
</cnsl-card>
|
||||
</ng-template>
|
||||
|
||||
<cnsl-passwordless *ngIf="user && user.human" [user]="user"></cnsl-passwordless>
|
||||
<cnsl-passwordless *ngIf="user && user.human" [user]="user" [disabled]="(canWrite$ | async) === false">
|
||||
</cnsl-passwordless>
|
||||
|
||||
<cnsl-user-mfa *ngIf="user && user.human" [user]="user"></cnsl-user-mfa>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user