fix(console): cleanup structure, role guard, paginated requests, cleanup policies, toast i18n, view timestamp, preloading strategy, maennchenfindings, fix passwordchange (#483)

* routes, move grid to list comopnent

* rename app list component, move to project sub

* add owned-project-detail child module

* seperate pipes

* set password validators only if needed

* create org initialize without pwd

* no caps

* self xss message

* fix user table

* fix project member paginator

* fix project members pagination, user grant pag

* move project grants, fix imports

* fix owned project detail imports

* use pipe and directives

* ng content bindings, rem custom schemas

* i18n, fix error toast parameter

* toast i18n

* side background

* fix: sequence, add timestamp

* audit

* fix metanav background

* org domain label

* cleanup policy component

* shorten user grant roles, mk cols visible as bind

* move user components, show otp only if available

* preload modules

* fix password change

* fix org create buttons

* class css
This commit is contained in:
Max Peintner
2020-07-16 15:13:36 +02:00
committed by GitHub
parent 2a3ecc0c6a
commit 4f3ccbfad0
125 changed files with 807 additions and 614 deletions
@@ -89,8 +89,8 @@ export class UserCreateComponent implements OnDestroy {
this.toast.showInfo('USER.TOAST.CREATED', true);
this.router.navigate(['users', data.getId()]);
})
.catch(data => {
this.toast.showError(data.message);
.catch(error => {
this.toast.showError(error);
});
}
@@ -129,7 +129,7 @@
<app-auth-user-mfa *ngIf="user"></app-auth-user-mfa>
</div>
<metainfo *ngIf="user" class="side">
<div *ngIf="user" class="side" metainfo>
<div class="details">
<div class="row" *ngIf="user?.preferredLoginName">
<span class="first">Preferred Loginname:</span>
@@ -138,5 +138,5 @@
</div>
<app-changes [changeType]="ChangeType.MYUSER" [id]="user.id"></app-changes>
</metainfo>
</div>
</app-meta-layout>
@@ -69,8 +69,8 @@ export class AuthUserDetailComponent implements OnDestroy {
this.toast.showInfo('USER.TOAST.SAVED', true);
this.user = Object.assign(this.user, data.toObject());
})
.catch(data => {
this.toast.showError(data.message);
.catch(error => {
this.toast.showError(error);
});
}
@@ -144,8 +144,8 @@ export class AuthUserDetailComponent implements OnDestroy {
this.toast.showInfo('USER.TOAST.PHONESAVED', true);
this.user.phone = data.toObject().phone;
this.phoneEditState = false;
}).catch(data => {
this.toast.showError(data);
}).catch(error => {
this.toast.showError(error);
this.phoneEditState = false;
});
}
@@ -153,8 +153,8 @@ export class AuthUserDetailComponent implements OnDestroy {
private async getData(): Promise<void> {
this.userService.GetMyUser().then(user => {
this.user = user.toObject();
}).catch(err => {
this.toast.showError(err);
}).catch(error => {
this.toast.showError(error);
});
}
@@ -15,7 +15,8 @@
<p class="row" *ngIf="error">{{error}}</p>
</div>
<div class="add-row">
<button (click)="addOTP()" mat-stroked-button color="primary" matTooltip="{{'ACTIONS.NEW' | translate}}">
<button *ngIf="otpAvailable" (click)="addOTP()" mat-stroked-button color="primary"
matTooltip="{{'ACTIONS.NEW' | translate}}">
<mat-icon svgIcon="mdi_radar"></mat-icon>{{'USER.MFA.OTP' | translate}}
</button>
</div>
@@ -21,6 +21,7 @@ export class AuthUserMfaComponent implements OnInit, OnDestroy {
public MFAState: any = MFAState;
public error: string = '';
public otpAvailable: boolean = false;
constructor(private userService: AuthUserService, private toast: ToastService, private dialog: MatDialog) { }
public ngOnInit(): void {
@@ -55,6 +56,10 @@ export class AuthUserMfaComponent implements OnInit, OnDestroy {
public getOTP(): void {
this.userService.GetMyMfas().then(mfas => {
this.mfaSubject.next(mfas.toObject().mfasList);
const index = mfas.toObject().mfasList.findIndex(mfa => mfa.type === MfaType.MFATYPE_OTP);
if (index === -1) {
this.otpAvailable = true;
}
}).catch(error => {
console.error(error);
this.error = error.message;
@@ -84,7 +84,7 @@ export class PasswordComponent implements OnInit {
});
} else {
this.passwordForm = this.fb.group({
currentPassword: ['', validators],
currentPassword: ['', Validators.required],
newPassword: ['', validators],
confirmPassword: ['', [...validators, passwordConfirmValidator]],
});
@@ -96,8 +96,8 @@ export class PasswordComponent implements OnInit {
this.mgmtUserService.SetInitialPassword(userId, this.password.value).then((data: any) => {
this.toast.showInfo('USER.TOAST.INITIALPASSWORDSET', true);
window.history.back();
}).catch(data => {
this.toast.showError(data.message);
}).catch(error => {
this.toast.showError(error);
});
}
}
@@ -110,8 +110,8 @@ export class PasswordComponent implements OnInit {
.ChangeMyPassword(this.currentPassword.value, this.newPassword.value).then((data: any) => {
this.toast.showInfo('USER.TOAST.PASSWORDCHANGED', true);
window.history.back();
}).catch(data => {
this.toast.showError(data.message);
}).catch(error => {
this.toast.showError(error);
});
}
}
@@ -125,7 +125,7 @@ export class PasswordComponent implements OnInit {
}
public get currentPassword(): AbstractControl | null {
return this.passwordForm.get('newPassword');
return this.passwordForm.get('currentPassword');
}
public get confirmPassword(): AbstractControl | null {
@@ -1,5 +1,6 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard } from 'src/app/guards/auth.guard';
import { RoleGuard } from 'src/app/guards/role.guard';
import { AuthUserDetailComponent } from './auth-user-detail/auth-user-detail.component';
@@ -10,15 +11,17 @@ const routes: Routes = [
{
path: 'me',
component: AuthUserDetailComponent,
canActivate: [AuthGuard],
},
{
path: 'me/password',
component: PasswordComponent,
canActivate: [AuthGuard],
},
{
path: ':id',
component: UserDetailComponent,
canActivate: [RoleGuard],
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['user.read'],
},
@@ -26,7 +29,7 @@ const routes: Routes = [
{
path: ':id/password',
component: PasswordComponent,
canActivate: [RoleGuard],
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['user.write'],
},
@@ -1,12 +1,15 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule, NO_ERRORS_SCHEMA } from '@angular/core';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatTableModule } from '@angular/material/table';
import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core';
import { QRCodeModule } from 'angularx-qrcode';
@@ -14,19 +17,20 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { CardModule } from 'src/app/modules/card/card.module';
import { ChangesModule } from 'src/app/modules/changes/changes.module';
import { MetaLayoutModule } from 'src/app/modules/meta-layout/meta-layout.module';
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { UserGrantsModule } from 'src/app/modules/user-grants/user-grants.module';
import { PipesModule } from 'src/app/pipes/pipes.module';
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe.module';
import { AuthUserDetailComponent } from './auth-user-detail/auth-user-detail.component';
import { AuthUserMfaComponent } from './auth-user-detail/auth-user-mfa/auth-user-mfa.component';
import { CodeDialogComponent } from './auth-user-detail/code-dialog/code-dialog.component';
import { DialogOtpComponent } from './auth-user-detail/dialog-otp/dialog-otp.component';
import { ThemeSettingComponent } from './auth-user-detail/theme-setting/theme-setting.component';
import { DetailFormModule } from './detail-form/detail-form.module';
import { PasswordComponent } from './password/password.component';
import { ThemeSettingComponent } from './theme-setting/theme-setting.component';
import { UserDetailRoutingModule } from './user-detail-routing.module';
import { UserDetailComponent } from './user-detail/user-detail.component';
import { UserMfaComponent } from './user-mfa/user-mfa.component';
import { UserMfaComponent } from './user-detail/user-mfa/user-mfa.component';
@NgModule({
declarations: [
@@ -49,18 +53,21 @@ import { UserMfaComponent } from './user-mfa/user-mfa.component';
MatDialogModule,
QRCodeModule,
MetaLayoutModule,
PipesModule,
HasRolePipeModule,
MatFormFieldModule,
UserGrantsModule,
MatInputModule,
MatButtonModule,
MatIconModule,
CardModule,
MatProgressSpinnerModule,
MatProgressBarModule,
MatTooltipModule,
HasRoleModule,
TranslateModule,
MatTableModule,
MatPaginatorModule,
SharedModule,
],
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
})
export class UserDetailModule { }
@@ -143,12 +143,13 @@
<app-card *ngIf="user?.id" title="{{ 'GRANTS.USER.TITLE' | translate }}"
description="{{'GRANTS.USER.DESCRIPTION' | translate }}">
<app-user-grants [userId]="user.id" [allowCreate]="['user.grant.write'] | hasRole"
[allowDelete]="['user.grant.delete'] | hasRole"></app-user-grants>
<app-user-grants [userId]="user.id" [allowCreate]="['user.grant.write'] | hasRole | async"
[displayedColumns]="['select', 'projectId', 'creationDate', 'changeDate', 'roleNamesList']"
[allowDelete]="['user.grant.delete'] | hasRole | async"></app-user-grants>
</app-card>
</div>
<metainfo *ngIf="user" class="side">
<div *ngIf="user" class="side" metainfo>
<div class="details">
<div class="row" *ngIf="user?.preferredLoginName">
<span class="first">Preferred Loginname:</span>
@@ -157,5 +158,5 @@
</div>
<app-changes [changeType]="ChangeType.USER" [id]="user.id"></app-changes>
</metainfo>
</div>
</app-meta-layout>
@@ -51,14 +51,14 @@ export class UserListComponent implements OnDestroy {
}
public changePage(event: PageEvent): void {
this.getData(event.pageSize, event.pageIndex);
this.getData(event.pageSize, event.pageIndex * event.pageSize);
}
public deactivateSelectedUsers(): void {
Promise.all(this.selection.selected.map(value => {
return this.userService.DeactivateUser(value.id);
})).then(() => {
this.toast.showInfo('Selected Users deactivated');
this.toast.showInfo('USER.TOAST.SELECTEDDEACTIVATED', true);
this.getData(10, 0);
});
}
@@ -67,7 +67,7 @@ export class UserListComponent implements OnDestroy {
Promise.all(this.selection.selected.map(value => {
return this.userService.ReactivateUser(value.id);
})).then(() => {
this.toast.showInfo('Selected Users reactivated');
this.toast.showInfo('USER.TOAST.SELECTEDREACTIVATED', true);
this.getData(10, 0);
});
}
@@ -13,6 +13,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { AvatarModule } from 'src/app/modules/avatar/avatar.module';
import { CardModule } from 'src/app/modules/card/card.module';
import { SharedModule } from 'src/app/modules/shared/shared.module';
import { UserListRoutingModule } from './user-list-routing.module';
import { UserListComponent } from './user-list.component';
@@ -39,6 +40,7 @@ import { UserListComponent } from './user-list.component';
MatCheckboxModule,
MatTooltipModule,
TranslateModule,
SharedModule,
],
exports: [
UserListComponent,
@@ -1,27 +0,0 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RoleGuard } from 'src/app/guards/role.guard';
import { AuthGuard } from '../../guards/auth.guard';
const routes: Routes = [
{
path: 'all',
loadChildren: () => import('src/app/pages/users/user-list/user-list.module').then(m => m.UserListModule),
canActivate: [AuthGuard, RoleGuard],
data: {
roles: ['user.read'],
},
},
{
path: '',
loadChildren: () => import('src/app/pages/users/user-detail/user-detail.module').then(m => m.UserDetailModule),
canActivate: [AuthGuard],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class UsersRoutingModule { }
@@ -1,13 +0,0 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { UsersRoutingModule } from './users-routing.module';
@NgModule({
declarations: [],
imports: [
CommonModule,
UsersRoutingModule,
],
})
export class UsersModule { }