Compare commits
1 Commits
main
...
c4po_mhg_1
Author | SHA1 | Date |
---|---|---|
|
389fcf480b |
|
@ -1,5 +1,5 @@
|
|||
<div class="pentest-table">
|
||||
<table [nbTreeGrid]="dataSource" nbsort>
|
||||
<table [nbTreeGrid]="dataSource">
|
||||
<!--ToDo: Add the click event to every td manually except the actions column actions-->
|
||||
<tr nbTreeGridHeaderRow *nbTreeGridHeaderRowDef="columns"></tr>
|
||||
<tr nbTreeGridRow *nbTreeGridRowDef="let pentest; columns: columns"
|
||||
|
@ -45,7 +45,7 @@
|
|||
{{ 'pentest.findings&comments' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let pentest" (click)="onClickRouteToObjectivePentest(pentest.data)">
|
||||
<div fxLayout="row" fxLayoutGap="0.5rem" fxLayoutAlign="start start">
|
||||
<div fxLayout="row" fxLayoutGap="0.5rem" fxLayoutAlign="center center">
|
||||
<app-findig-widget [numberOfFindings]="pentest.data['findingIds'] ? pentest.data['findingIds'].length : 0"></app-findig-widget>
|
||||
<span> / </span>
|
||||
<app-comment-widget [numberOfComments]="pentest.data['commentIds'] ? pentest.data['commentIds'].length : 0"></app-comment-widget>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
import {NbGetters, NbSortDirection, NbSortRequest, NbTreeGridDataSource, NbTreeGridDataSourceBuilder} from '@nebular/theme';
|
||||
import {NbGetters, NbTreeGridDataSource, NbTreeGridDataSourceBuilder} from '@nebular/theme';
|
||||
import {ObjectiveEntry, Pentest, transformPentestsToObjectiveEntries} from '@shared/models/pentest.model';
|
||||
import {PentestService} from '@shared/services/api/pentest.service';
|
||||
import {Store} from '@ngxs/store';
|
||||
|
@ -15,6 +15,7 @@ import * as FA from '@fortawesome/free-solid-svg-icons';
|
|||
import {DialogService} from '@shared/services/dialog-service/dialog.service';
|
||||
import {NotificationService, PopupType} from '@shared/services/toaster-service/notification.service';
|
||||
import {Project} from '@shared/models/project.model';
|
||||
import {sortDescending} from '@shared/functions/sort-names.function';
|
||||
|
||||
@UntilDestroy()
|
||||
@Component({
|
||||
|
@ -25,7 +26,6 @@ import {Project} from '@shared/models/project.model';
|
|||
export class ObjectiveTableComponent implements OnInit {
|
||||
// HTML only
|
||||
readonly fa = FA;
|
||||
// use ban and check
|
||||
|
||||
loading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||
columns: Array<ObjectiveColumns> = [
|
||||
|
@ -71,12 +71,6 @@ export class ObjectiveTableComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
this.loadPentestData();
|
||||
this.changeSortTable()
|
||||
this.dataSource.sort({column: ObjectiveColumns.TEST_ID, direction: NbSortDirection.DESCENDING});
|
||||
}
|
||||
|
||||
private changeSortTable(): void {
|
||||
this.dataSource.sort({column: ObjectiveColumns.TEST_ID, direction: NbSortDirection.DESCENDING});
|
||||
}
|
||||
|
||||
loadPentestData(): void {
|
||||
|
@ -87,8 +81,12 @@ export class ObjectiveTableComponent implements OnInit {
|
|||
untilDestroyed(this)
|
||||
).subscribe({
|
||||
next: (pentests: Pentest[]) => {
|
||||
this.pentests$.next(pentests);
|
||||
this.data = transformPentestsToObjectiveEntries(pentests);
|
||||
// Sort data without before adding as table data source
|
||||
const sortedPentests = pentests.sort((a: Pentest, b: Pentest) =>
|
||||
sortDescending(a.refNumber.toLowerCase(), b.refNumber.toLowerCase())
|
||||
);
|
||||
this.pentests$.next(sortedPentests);
|
||||
this.data = transformPentestsToObjectiveEntries(sortedPentests);
|
||||
this.dataSource.setData(this.data, this.getters);
|
||||
this.loading$.next(false);
|
||||
},
|
||||
|
|
|
@ -11,7 +11,12 @@
|
|||
{{ 'comment.title' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let comment">
|
||||
{{ comment.data['title'] }}
|
||||
<span *ngIf=" comment.data['title'].length < 200; else cutTitle">
|
||||
{{ comment.data['title'] }}
|
||||
</span>
|
||||
<ng-template #cutTitle>
|
||||
{{ comment.data['title'].slice(0, 200) + '...' }}
|
||||
</ng-template>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Description -->
|
||||
|
@ -20,7 +25,12 @@
|
|||
{{ 'comment.description' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let comment">
|
||||
{{ comment.data['description'] }}
|
||||
<span *ngIf=" comment.data['description'].length < 200; else cutDescription">
|
||||
{{ comment.data['description'] }}
|
||||
</span>
|
||||
<ng-template #cutDescription>
|
||||
{{ comment.data['description'].slice(0, 200) + '...' }}
|
||||
</ng-template>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Actions -->
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@import '../../../../assets/@theme/styles/themes';
|
||||
@import '../../../../assets/@theme/styles/_text-overflow.scss';
|
||||
|
||||
.comment-table {
|
||||
margin-right: 2rem;
|
||||
|
|
|
@ -11,7 +11,12 @@
|
|||
{{ 'finding.title' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let finding">
|
||||
{{ finding.data['title'] }}
|
||||
<span *ngIf=" finding.data['title'].length < 200; else cutTitle">
|
||||
{{ finding.data['title'] }}
|
||||
</span>
|
||||
<ng-template #cutTitle>
|
||||
{{ finding.data['title'].slice(0, 200) + '...' }}
|
||||
</ng-template>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Severity -->
|
||||
|
@ -31,7 +36,12 @@
|
|||
{{ 'finding.description' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let finding">
|
||||
{{ finding.data['description'] }}
|
||||
<span *ngIf=" finding.data['description'].length < 200; else cutDescription">
|
||||
{{ finding.data['description'] }}
|
||||
</span>
|
||||
<ng-template #cutDescription>
|
||||
{{ finding.data['description'].slice(0, 200) + '...' }}
|
||||
</ng-template>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Impact -->
|
||||
|
@ -40,7 +50,12 @@
|
|||
{{ 'finding.impact' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let finding">
|
||||
{{ finding.data['impact'] }}
|
||||
<span *ngIf=" finding.data['impact'].length < 200; else cutImpact">
|
||||
{{ finding.data['impact'] }}
|
||||
</span>
|
||||
<ng-template #cutImpact>
|
||||
{{ finding.data['impact'].slice(0, 200) + '...' }}
|
||||
</ng-template>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Actions -->
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@import '../../../../assets/@theme/styles/themes';
|
||||
@import '../../../../assets/@theme/styles/_text-overflow.scss';
|
||||
|
||||
.finding-table {
|
||||
margin-right: 2rem;
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
"languageLabel": "Sprache ändern:",
|
||||
"password": {
|
||||
"title": "Passwort ändern:",
|
||||
"button" : "Passwort ändern",
|
||||
"old": "Altes Passwort",
|
||||
"new": "Neues Passwort",
|
||||
"confirmNew": "Neues Passwort bestätigen",
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
"languageLabel": "Change language:",
|
||||
"password": {
|
||||
"title": "Change password:",
|
||||
"button" : "Change password",
|
||||
"old": "Old password",
|
||||
"new": "New password",
|
||||
"confirmNew": "Confirm new password",
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export function sortDescending(nameOne: string, nameTwo: string): number {
|
||||
return nameOne === nameTwo ? 0 : (nameOne > nameTwo ? 1 : -1);
|
||||
}
|
|
@ -11,16 +11,15 @@
|
|||
class="form-field"
|
||||
[status]="passwordFormGroup.get('oldPassword').dirty ? (passwordFormGroup.get('oldPassword').invalid ? 'danger' : 'basic') : 'basic'"
|
||||
placeholder="{{'******'}}">
|
||||
<button nbSuffix nbButton ghost class="form-field-button" (click)="toggleShowOldPassword()">
|
||||
<button nbSuffix nbButton ghost class="form-field-button" (click)="toggleShowOldPassword()" [disabled]="passwordFormGroup.get('oldPassword').disabled">
|
||||
<fa-icon [icon]="showOldPassword ? fa.faEye : fa.faEyeSlash"></fa-icon>
|
||||
</button>
|
||||
<!-- FIXME: when the bug (https://github.com/angular/components/issues/7739) is fixed -->
|
||||
<ng-template *ngIf="passwordFormGroup.get('oldPassword').dirty">
|
||||
<ng-container *ngIf="oldPasswordCtrl.dirty">
|
||||
<span class="error-text"
|
||||
*ngIf="passwordFormGroup.get('oldPassword')?.hasError('required')">
|
||||
*ngIf="oldPasswordCtrl.hasError('required')">
|
||||
{{'profile.password.validationMessage.passwordRequired' | translate}}
|
||||
</span>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</nb-form-field>
|
||||
<div fxLayout="column" fxLayoutGap="2rem">
|
||||
<!--New password-->
|
||||
|
@ -34,18 +33,17 @@
|
|||
class="form-field"
|
||||
[status]="passwordFormGroup.get('newPassword').dirty ? (passwordFormGroup.get('newPassword').invalid ? 'danger' : 'basic') : 'basic'"
|
||||
placeholder="{{'******'}}">
|
||||
<button nbSuffix nbButton ghost class="form-field-button" (click)="toggleShowNewPasswords()">
|
||||
<button nbSuffix nbButton ghost class="form-field-button" (click)="toggleShowNewPasswords()" [disabled]="passwordFormGroup.get('newPassword').disabled">
|
||||
<fa-icon [icon]="showNewPasswords ? fa.faEye : fa.faEyeSlash"></fa-icon>
|
||||
</button>
|
||||
<!-- FIXME: when the bug (https://github.com/angular/components/issues/7739) is fixed -->
|
||||
<ng-template *ngIf="passwordFormGroup.get('newPassword').dirty">
|
||||
<ng-container *ngIf="newPasswordCtrl.dirty">
|
||||
<span class="error-text"
|
||||
*ngIf="passwordFormGroup.get('newPassword')?.hasError('required')">
|
||||
*ngIf="newPasswordCtrl.hasError('required')">
|
||||
{{'profile.password.validationMessage.passwordRequired' | translate}}
|
||||
</span>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</nb-form-field>
|
||||
<!--New password-->
|
||||
<!--Confirm new password-->
|
||||
<nb-form-field class="password-form-field">
|
||||
<label for="confirmNewPassword" class="label">
|
||||
{{'profile.password.confirmNew' | translate}}
|
||||
|
@ -56,13 +54,12 @@
|
|||
class="form-field"
|
||||
[status]="passwordFormGroup.get('confirmNewPassword').dirty ? (passwordFormGroup.get('confirmNewPassword').invalid ? 'danger' : 'basic') : 'basic'"
|
||||
placeholder="{{'******'}}">
|
||||
<!-- FIXME: when the bug (https://github.com/angular/components/issues/7739) is fixed -->
|
||||
<ng-template *ngIf="passwordFormGroup.get('confirmNewPassword').dirty">
|
||||
<ng-container *ngIf="confirmNewPasswordCtrl.dirty">
|
||||
<span class="error-text"
|
||||
*ngIf="passwordFormGroup.get('confirmNewPassword')?.hasError('required')">
|
||||
*ngIf="confirmNewPasswordCtrl.hasError('required')">
|
||||
{{'profile.password.validationMessage.passwordRequired' | translate}}
|
||||
</span>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</nb-form-field>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.form-field:disabled {
|
||||
background-color: nb-theme(color-basic-transparent-focus);
|
||||
}
|
||||
|
||||
.form-field-button {
|
||||
margin-top: 1rem;
|
||||
margin-right: 1rem;
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
import {Component, EventEmitter, forwardRef, Input, OnInit, Output} from '@angular/core';
|
||||
import {AbstractControl, FormBuilder, FormControl, FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidationErrors} from '@angular/forms';
|
||||
import {
|
||||
AbstractControl,
|
||||
FormBuilder,
|
||||
FormControl,
|
||||
FormGroup,
|
||||
NG_VALIDATORS,
|
||||
NG_VALUE_ACCESSOR,
|
||||
ValidationErrors,
|
||||
Validators
|
||||
} from '@angular/forms';
|
||||
import {
|
||||
OldPasswordEmptyError,
|
||||
PasswordErrorStateMatcher
|
||||
|
@ -61,9 +70,9 @@ export class PasswordInputFromComponent implements OnInit {
|
|||
ngOnInit(): void {
|
||||
this.passwordFormGroup = this.fb.group(
|
||||
{
|
||||
oldPassword: ['', [PasswordInputFromComponent.containsBlankSpaceValidator]],
|
||||
newPassword: ['', [PasswordInputFromComponent.containsBlankSpaceValidator]],
|
||||
confirmNewPassword: ''
|
||||
oldPassword: [{value: '', disabled: true}, [Validators.required, PasswordInputFromComponent.containsBlankSpaceValidator]],
|
||||
newPassword: [{value: '', disabled: true}, [Validators.required, PasswordInputFromComponent.containsBlankSpaceValidator]],
|
||||
confirmNewPassword: [{value: '', disabled: true}, [Validators.required]]
|
||||
},
|
||||
{validators: [passwordValidator]}
|
||||
);
|
||||
|
|
|
@ -36,21 +36,15 @@
|
|||
type="text" required
|
||||
id="firstName" nbInput
|
||||
fullWidth
|
||||
class="form-field"
|
||||
class="form-field name"
|
||||
[status]="userFormGroup.get('firstName').dirty ? (userFormGroup.get('firstName').invalid ? 'danger' : 'basic') : 'basic'"
|
||||
placeholder="{{'profile.firstName.placeholder' | translate}} *">
|
||||
<!-- FIXME: when the bug (https://github.com/angular/components/issues/7739) is fixed -->
|
||||
<ng-template *ngIf="userFormGroup.get('firstName').dirty">
|
||||
<ng-container *ngIf="userFirstNameControl.dirty">
|
||||
<span class="error-text"
|
||||
*ngIf="userFormGroup.get('firstName')?.hasError('required')">
|
||||
{{'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW'}}
|
||||
*ngIf="userFirstNameControl.hasError('required')">
|
||||
{{'profile.validationMessage.firstNameRequired' | translate}}
|
||||
</span>
|
||||
<span class="error-text"
|
||||
*ngIf="userFormGroup.get('firstName').invalid">
|
||||
{{'Firstname is invalid' | translate}}
|
||||
</span>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</nb-form-field>
|
||||
<!--Lastname-->
|
||||
<nb-form-field class="user-form-field">
|
||||
|
@ -61,60 +55,66 @@
|
|||
type="text" required
|
||||
id="lastName" nbInput
|
||||
fullWidth
|
||||
class="form-field"
|
||||
class="form-field name"
|
||||
[status]="userFormGroup.get('lastName').dirty ? (userFormGroup.get('lastName').invalid ? 'danger' : 'basic') : 'basic'"
|
||||
placeholder="{{'profile.lastName.placeholder' | translate}} *">
|
||||
<!-- FIXME: when the bug (https://github.com/angular/components/issues/7739) is fixed -->
|
||||
<ng-template *ngIf="userFormGroup.get('lastName').dirty">
|
||||
<ng-container *ngIf="userLastNameControl.dirty">
|
||||
<span class="error-text"
|
||||
*ngIf="userFormGroup.get('lastName')?.hasError('required')">
|
||||
*ngIf="userLastNameControl.hasError('required')">
|
||||
{{'profile.validationMessage.lastNameRequired' | translate}}
|
||||
</span>
|
||||
<span class="error-text"
|
||||
*ngIf="userFormGroup.get('lastName').invalid">
|
||||
{{'Lastname is invalid' | translate}}
|
||||
</span>
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
</nb-form-field>
|
||||
</div>
|
||||
<!--ToDo: Email?-->
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="language-settings">
|
||||
<!--Language Radio Selection-->
|
||||
<label class="language-selection-label">
|
||||
{{ 'profile.languageLabel' | translate }}
|
||||
</label>
|
||||
<div fxLayout="row" fxLayoutGap="1rem" fxLayoutAlign="start center">
|
||||
<nb-radio-group name="language" [formControl]="profileLanguageControl"
|
||||
class="language-radio-buttons languageContainer" status="info">
|
||||
<nb-radio value="{{profileLanguages.ENGLISH}}" (click)="onClickLanguage(profileLanguages.ENGLISH)">
|
||||
<img src="../../assets/images/flags/{{profileLanguages.ENGLISH}}.svg" class="flag" width="25rem"
|
||||
height="16rem"
|
||||
alt="">
|
||||
</nb-radio>
|
||||
<nb-radio value="{{profileLanguages.GERMAN}}" (click)="onClickLanguage(profileLanguages.GERMAN)">
|
||||
<img src="../../assets/images/flags/{{profileLanguages.GERMAN}}.svg" class="flag" width="25rem"
|
||||
height="16rem"
|
||||
alt="">
|
||||
</nb-radio>
|
||||
</nb-radio-group>
|
||||
<div fxLayout="row" fxLayoutGap="2rem" fxLayoutAlign="start center">
|
||||
<div class="user-password-change">
|
||||
<!--User password change-->
|
||||
<label class="password-selection-label">
|
||||
{{'profile.password.title' | translate}}
|
||||
</label>
|
||||
<div class="password-form">
|
||||
<button nbButton size="small"
|
||||
class="password-btn"
|
||||
status="info"
|
||||
hero outline
|
||||
(click)="changePasswordInKeycloak()">
|
||||
<fa-icon [icon]="fa.faPassport" class="btn-icon"></fa-icon>
|
||||
{{'profile.password.button' | translate}}
|
||||
</button>
|
||||
<!--ToDo: Remove unused feature-->
|
||||
<!--<form class="password-form" [formGroup]="passwordFormGroup">
|
||||
<app-password-input-from
|
||||
formControlName="passwordInput"
|
||||
[userServiceError$]="userServiceError"
|
||||
(passwordStrong)="passwordStrong = $event">
|
||||
</app-password-input-from>
|
||||
</form>-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--ToDo: Add accordion for keycloak values-->
|
||||
<div class="user-password-change">
|
||||
<label class="password-selection-label">
|
||||
{{'profile.password.title' | translate}}
|
||||
</label>
|
||||
<div>
|
||||
<form class="password-form" [formGroup]="passwordFormGroup">
|
||||
<app-password-input-from
|
||||
formControlName="passwordInput"
|
||||
[userServiceError$]="userServiceError"
|
||||
(passwordStrong)="passwordStrong = $event">
|
||||
</app-password-input-from>
|
||||
</form>
|
||||
<div class="language-settings">
|
||||
<!--Language radio selection-->
|
||||
<label class="language-selection-label">
|
||||
{{ 'profile.languageLabel' | translate }}
|
||||
</label>
|
||||
<div fxLayout="row" fxLayoutGap="1rem" fxLayoutAlign="start center">
|
||||
<nb-radio-group name="language" [formControl]="profileLanguageControl"
|
||||
class="language-radio-buttons languageContainer" status="info">
|
||||
<nb-radio value="{{profileLanguages.ENGLISH}}" (click)="onClickLanguage(profileLanguages.ENGLISH)">
|
||||
<img src="../../assets/images/flags/{{profileLanguages.ENGLISH}}.svg" class="flag" width="25rem"
|
||||
height="16rem"
|
||||
alt="">
|
||||
</nb-radio>
|
||||
<nb-radio value="{{profileLanguages.GERMAN}}" (click)="onClickLanguage(profileLanguages.GERMAN)">
|
||||
<img src="../../assets/images/flags/{{profileLanguages.GERMAN}}.svg" class="flag" width="25rem"
|
||||
height="16rem"
|
||||
alt="">
|
||||
</nb-radio>
|
||||
</nb-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nb-card-body>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
.profile-setting-dialog {
|
||||
width: 45.25rem !important;
|
||||
height: 46rem;
|
||||
height: 32rem;
|
||||
|
||||
.dialog-header {
|
||||
height: 8vh;
|
||||
|
@ -54,6 +54,10 @@
|
|||
width: 30rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
width: 14.5rem !important;
|
||||
}
|
||||
|
||||
.error-text {
|
||||
float: left;
|
||||
color: nb-theme(color-danger-default);
|
||||
|
@ -62,7 +66,7 @@
|
|||
}
|
||||
|
||||
.language-settings{
|
||||
padding-top: 2rem;
|
||||
padding-top: 2.5rem;
|
||||
|
||||
.language-selection-label {
|
||||
font-weight: bold;
|
||||
|
@ -76,6 +80,7 @@
|
|||
}
|
||||
|
||||
.languageContainer {
|
||||
padding-top: 1rem;
|
||||
display: flex;
|
||||
max-width: 8rem;
|
||||
min-width: 8rem;
|
||||
|
@ -88,11 +93,22 @@
|
|||
}
|
||||
|
||||
.user-password-change{
|
||||
padding-top: 1rem;
|
||||
padding-top: 2rem;
|
||||
|
||||
.password-selection-label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.password-form {
|
||||
padding-top: 1rem;
|
||||
|
||||
.password-btn {
|
||||
.btn-icon {
|
||||
padding-bottom: 0.15rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,8 +92,8 @@ export class ProfileSettingsComponent implements OnInit {
|
|||
setupUserFormGroup(): void {
|
||||
this.userFormGroup = this.fb.group({
|
||||
username: [{value: '', disabled: true}, [Validators.required, Validators.pattern(Patterns.NO_WHITESPACES)]],
|
||||
firstName: [{value: '', disabled: false}, [Validators.required, Validators.pattern(Patterns.NO_WHITESPACES)]],
|
||||
lastName: [{value: '', disabled: false}, [Validators.required, Validators.pattern(Patterns.NO_WHITESPACES)]],
|
||||
firstName: [{value: '', disabled: true}, [Validators.required, Validators.pattern(Patterns.NO_WHITESPACES)]],
|
||||
lastName: [{value: '', disabled: true}, [Validators.required, Validators.pattern(Patterns.NO_WHITESPACES)]],
|
||||
eMail: [{value: '', disabled: true}, [Validators.required, Validators.email, Validators.pattern(Patterns.NO_WHITESPACES)]],
|
||||
avatarUploader: null
|
||||
});
|
||||
|
@ -112,6 +112,13 @@ export class ProfileSettingsComponent implements OnInit {
|
|||
this.userPasswordInputControl = this.passwordFormGroup.get('passwordInput');
|
||||
}
|
||||
|
||||
changePasswordInKeycloak(): void {
|
||||
this.userService.redirectToChangePasswordAction().then(r => {
|
||||
// tslint:disable-next-line:no-console
|
||||
console.info('Redirecting to Keycloak for password change...');
|
||||
});
|
||||
}
|
||||
|
||||
onClickLanguage(language: string): void {
|
||||
this.translateService.use(language);
|
||||
}
|
||||
|
@ -149,22 +156,20 @@ export class ProfileSettingsComponent implements OnInit {
|
|||
}
|
||||
|
||||
private handleUserUpdate(user: User): Observable<void> {
|
||||
/* return this.userService.updateUser(user, this.timeOfChange)
|
||||
.pipe(
|
||||
tap({
|
||||
next: resultingUser => {
|
||||
this.store.dispatch(new UpdateUserSettings(resultingUser));
|
||||
this.store.dispatch(new UpdateUser(resultingUser, true));
|
||||
},
|
||||
error: error => {
|
||||
console.error(error);
|
||||
this.onFailedUpdate(error);
|
||||
}
|
||||
}),
|
||||
mapTo(void 0),
|
||||
untilDestroyed(this)
|
||||
);*/
|
||||
return of();
|
||||
return this.userService.changeUserProperties(user)
|
||||
.pipe(
|
||||
tap({
|
||||
next: resultingUser => {
|
||||
this.store.dispatch(new UpdateUserSettings(resultingUser));
|
||||
this.store.dispatch(new UpdateUser(resultingUser, true));
|
||||
},
|
||||
error: error => {
|
||||
console.error(error);
|
||||
}
|
||||
}),
|
||||
mapTo(void 0),
|
||||
untilDestroyed(this)
|
||||
);
|
||||
}
|
||||
|
||||
private handlePasswordChange(): void {
|
||||
|
|
|
@ -61,7 +61,6 @@ export class PentestService {
|
|||
templatePentests[i]?.childEntries?.forEach((childEntry: Pentest) => {
|
||||
// ToDo: Add only child entrys that are not included in response aka available pentests
|
||||
if (!availablePentests.map(it => it.refNumber).includes(childEntry.refNumber)) {
|
||||
console.log('Child entry from template: ', childEntry);
|
||||
availablePentests[indexOfPentestWithChildEntries].childEntries.push(childEntry);
|
||||
} else {
|
||||
// Removes the pentest from availablePentests and add it as a child entry
|
||||
|
|
|
@ -7,12 +7,15 @@ import {KeycloakService} from 'keycloak-angular';
|
|||
import {map} from 'rxjs/operators';
|
||||
import {environment} from '../../../environments/environment';
|
||||
import {Route} from '@shared/models/route.enum';
|
||||
import {Project} from '@shared/models/project.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserService {
|
||||
|
||||
private keycloakBaseURL = `${environment.keycloakURL}/`;
|
||||
|
||||
constructor(private http: HttpClient,
|
||||
private keycloakService: KeycloakService,
|
||||
private store: Store) {
|
||||
|
@ -56,25 +59,22 @@ export class UserService {
|
|||
// https://stackoverflow.com/questions/33910615/is-there-an-api-call-for-changing-user-password-on-keycloak
|
||||
|
||||
// ToDo: https://www.keycloak.org/docs/latest/server_development/
|
||||
public changeUserProperties(): Observable<any> {
|
||||
public changeUserProperties(user: User): Observable<any> {
|
||||
// ToDo: There is a kc_action parameter available in keycloak to let application force required actions.
|
||||
console.warn(user);
|
||||
/*../realms/myrealm/protocol/openid-connect/auth
|
||||
?response_type=code
|
||||
&client_id=myclient
|
||||
&redirect_uri=https://myclient.com
|
||||
&kc_action=update_profile*/
|
||||
return of();
|
||||
return of(user);
|
||||
}
|
||||
|
||||
// ToDo: https://keycloak.discourse.group/t/integrate-change-password-from-account-console-into-own-webapp/12300
|
||||
public changePassword(): Observable<any> {
|
||||
// ToDo: To force (or allow) a password update, use kc_action=UPDATE_PASSWORD
|
||||
/*../realms/myrealm/protocol/openid-connect/auth
|
||||
?response_type=code
|
||||
&client_id=myclient
|
||||
&redirect_uri=https://myclient.com
|
||||
&kc_action=update_profile*/
|
||||
return of();
|
||||
public redirectToChangePasswordAction(): Promise<void> {
|
||||
// https://keycloak.discourse.group/t/integrate-change-password-from-account-console-into-own-webapp/12300
|
||||
return this.keycloakService.login({
|
||||
action: 'UPDATE_PASSWORD',
|
||||
});
|
||||
}
|
||||
|
||||
private getToken(): Observable<string> {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<span class="comments-count">{{numberOfComments}}</span>
|
||||
</ng-container>
|
||||
<ng-template #noComments>
|
||||
{{'-'}}
|
||||
<fa-icon [icon]="fa.faComment" size="lg" class="comment-icon"></fa-icon>
|
||||
<span class="comments-count">{{0}}</span>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<span class="findings-count">{{numberOfFindings}}</span>
|
||||
</ng-container>
|
||||
<ng-template #noFindings>
|
||||
{{'-'}}
|
||||
<fa-icon [icon]="fa.faExclamationCircle" size="lg" class="finding-icon"></fa-icon>
|
||||
<span class="findings-count">{{0}}</span>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
|
|
@ -37,8 +37,9 @@
|
|||
<div class="project-progress">
|
||||
<nb-progress-bar *ngIf="project.testingProgress > 0; else altProgressBar"
|
||||
status="warning"
|
||||
title="{{project.testingProgress + '%'}}"
|
||||
[value]="project.testingProgress"
|
||||
[displayValue]="true">
|
||||
[displayValue]="project.testingProgress > 25">
|
||||
</nb-progress-bar>
|
||||
<ng-template #altProgressBar>
|
||||
{{'popup.info' | translate}} {{'global.no.progress' | translate}}
|
||||
|
|
Loading…
Reference in New Issue