diff --git a/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.html b/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.html
index d4cec49..3c8a36c 100644
--- a/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.html
+++ b/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.html
@@ -9,6 +9,7 @@
+
diff --git a/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.spec.ts b/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.spec.ts
index 40cde6d..e3d01c1 100644
--- a/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.spec.ts
+++ b/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.spec.ts
@@ -24,6 +24,7 @@ import {Category} from '@shared/models/category.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
import {ExportReportDialogService} from '@shared/modules/export-report-dialog/service/export-report-dialog.service';
import {ExportReportDialogServiceMock} from '@shared/modules/export-report-dialog/service/export-report-dialog.service.mock';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -33,6 +34,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
diff --git a/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.ts b/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.ts
index b8ca420..973acd9 100644
--- a/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.ts
+++ b/security-c4po-angular/src/app/objective-overview/objective-header/objective-header.component.ts
@@ -75,21 +75,16 @@ export class ObjectiveHeaderComponent implements OnInit {
closeOnBackdropClick: false
}
).pipe(
- filter(value => !!value),
- mergeMap((value: ProjectDialogBody) => this.projectService.updateProject(this.selectedProject$.getValue().id, value)),
untilDestroyed(this)
).subscribe({
- next: (project: Project) => {
+ next: (project) => {
this.store.dispatch(new InitProjectState(
project,
[],
[]
- )).pipe(untilDestroyed(this)).subscribe();
- this.notificationService.showPopup('project.popup.update.success', PopupType.SUCCESS);
- },
- error: error => {
- console.error(error);
- this.notificationService.showPopup('project.popup.update.failed', PopupType.FAILURE);
+ )).pipe(
+ untilDestroyed(this)
+ ).subscribe();
}
});
}
diff --git a/security-c4po-angular/src/app/objective-overview/objective-overview.module.ts b/security-c4po-angular/src/app/objective-overview/objective-overview.module.ts
index 1528af1..817fc97 100644
--- a/security-c4po-angular/src/app/objective-overview/objective-overview.module.ts
+++ b/security-c4po-angular/src/app/objective-overview/objective-overview.module.ts
@@ -25,6 +25,7 @@ import {ObjectiveOverviewRoutingModule} from './objective-overview-routing.modul
import {ExportReportDialogModule} from '@shared/modules/export-report-dialog/export-report-dialog.module';
import {ProjectDialogModule} from '@shared/modules/project-dialog/project-dialog.module';
import {CommentWidgetModule} from '@shared/widgets/comment-widget/comment-widget.module';
+import {ReportStateTagModule} from '@shared/widgets/report-state-tag/report-state-tag.module';
@NgModule({
declarations: [
@@ -32,32 +33,33 @@ import {CommentWidgetModule} from '@shared/widgets/comment-widget/comment-widget
ObjectiveCategoriesComponent,
ObjectiveTableComponent,
],
- imports: [
- CommonModule,
- CommonAppModule,
- NbLayoutModule,
- NbCardModule,
- NbButtonModule,
- // nbTooltip crashes app right now if used in component,
- // workaround: use title in html for now
- NbTooltipModule,
- NbTreeGridModule,
- TranslateModule,
- StatusTagModule,
- RouterModule,
- FormsModule,
- NbListModule,
- FontAwesomeModule,
- FlexLayoutModule,
- NbActionsModule,
- ExportReportDialogModule,
- ProjectDialogModule,
- ObjectiveOverviewRoutingModule,
- // Table Widgets
- FindigWidgetModule,
- CommentWidgetModule,
- NbMenuModule
- ],
+ imports: [
+ CommonModule,
+ CommonAppModule,
+ NbLayoutModule,
+ NbCardModule,
+ NbButtonModule,
+ // nbTooltip crashes app right now if used in component,
+ // workaround: use title in html for now
+ NbTooltipModule,
+ NbTreeGridModule,
+ TranslateModule,
+ StatusTagModule,
+ RouterModule,
+ FormsModule,
+ NbListModule,
+ FontAwesomeModule,
+ FlexLayoutModule,
+ NbActionsModule,
+ ExportReportDialogModule,
+ ProjectDialogModule,
+ ObjectiveOverviewRoutingModule,
+ // Table Widgets
+ FindigWidgetModule,
+ CommentWidgetModule,
+ NbMenuModule,
+ ReportStateTagModule
+ ],
exports: [
ObjectiveHeaderComponent,
ObjectiveCategoriesComponent,
diff --git a/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.spec.ts b/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.spec.ts
index 25703f0..93011d3 100644
--- a/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.spec.ts
+++ b/security-c4po-angular/src/app/pentest/pentest-content/pentest-comments/pentest-comments.component.spec.ts
@@ -22,6 +22,7 @@ import {DialogService} from '@shared/services/dialog-service/dialog.service';
import {DialogServiceMock} from '@shared/services/dialog-service/dialog.service.mock';
import {CommentDialogService} from '@shared/modules/comment-dialog/service/comment-dialog.service';
import {CommentDialogServiceMock} from '@shared/modules/comment-dialog/service/comment-dialog.service.mock';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -31,6 +32,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
diff --git a/security-c4po-angular/src/app/pentest/pentest-content/pentest-content.component.spec.ts b/security-c4po-angular/src/app/pentest/pentest-content/pentest-content.component.spec.ts
index 399092e..1529afe 100644
--- a/security-c4po-angular/src/app/pentest/pentest-content/pentest-content.component.spec.ts
+++ b/security-c4po-angular/src/app/pentest/pentest-content/pentest-content.component.spec.ts
@@ -13,6 +13,7 @@ import {Category} from '@shared/models/category.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
import {NotificationService} from '@shared/services/toaster-service/notification.service';
import {NotificationServiceMock} from '@shared/services/toaster-service/notification.service.mock';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -22,6 +23,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
diff --git a/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.spec.ts b/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.spec.ts
index a923dd0..c5613b4 100644
--- a/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.spec.ts
+++ b/security-c4po-angular/src/app/pentest/pentest-content/pentest-findings/pentest-findings.component.spec.ts
@@ -22,6 +22,7 @@ import {FindingDialogService} from '@shared/modules/finding-dialog/service/findi
import {FindingDialogServiceMock} from '@shared/modules/finding-dialog/service/finding-dialog.service.mock';
import {DialogService} from '@shared/services/dialog-service/dialog.service';
import {DialogServiceMock} from '@shared/services/dialog-service/dialog.service.mock';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -31,6 +32,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
diff --git a/security-c4po-angular/src/app/pentest/pentest-content/pentest-info/pentest-info.component.spec.ts b/security-c4po-angular/src/app/pentest/pentest-content/pentest-info/pentest-info.component.spec.ts
index 68cf90f..0e8ccc0 100644
--- a/security-c4po-angular/src/app/pentest/pentest-content/pentest-info/pentest-info.component.spec.ts
+++ b/security-c4po-angular/src/app/pentest/pentest-content/pentest-info/pentest-info.component.spec.ts
@@ -13,6 +13,7 @@ import {NgxsModule, Store} from '@ngxs/store';
import {PROJECT_STATE_NAME, ProjectState, ProjectStateModel} from '@shared/stores/project-state/project-state';
import {Category} from '@shared/models/category.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -22,6 +23,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
diff --git a/security-c4po-angular/src/app/pentest/pentest-header/pentest-header.component.spec.ts b/security-c4po-angular/src/app/pentest/pentest-header/pentest-header.component.spec.ts
index 3bea60c..08162e3 100644
--- a/security-c4po-angular/src/app/pentest/pentest-header/pentest-header.component.spec.ts
+++ b/security-c4po-angular/src/app/pentest/pentest-header/pentest-header.component.spec.ts
@@ -13,6 +13,7 @@ import {Category} from '@shared/models/category.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
import {NotificationService} from '@shared/services/toaster-service/notification.service';
import {NotificationServiceMock} from '@shared/services/toaster-service/notification.service.mock';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -22,6 +23,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
diff --git a/security-c4po-angular/src/app/project-overview/project-overview.component.html b/security-c4po-angular/src/app/project-overview/project-overview.component.html
index be1d742..befa390 100644
--- a/security-c4po-angular/src/app/project-overview/project-overview.component.html
+++ b/security-c4po-angular/src/app/project-overview/project-overview.component.html
@@ -1,87 +1,131 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
{{project?.client}}
-
-
+
+
{{project?.tester}}
-
-
+
+
{{project?.createdAt | dateTimeFormat}}
-
-
-
-
- 0; else altProgressBar"
- status="warning"
- [value]="project.testingProgress"
- [displayValue]="true">
-
-
- {{'popup.info' | translate}} {{'global.no.progress' | translate}}
-
-
+
+
+
+
+ 0; else altProgressBar"
+ status="warning"
+ [value]="project.testingProgress"
+ [displayValue]="true">
+
+
+ {{'popup.info' | translate}} {{'global.no.progress' | translate}}
+
+
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
+ {{'project.overview.no.projects' | translate}}
+
+
+
+
-
-
- {{'project.overview.no.projects' | translate}}
-
+
+
-
-
-
-
-
-
diff --git a/security-c4po-angular/src/app/project-overview/project-overview.component.scss b/security-c4po-angular/src/app/project-overview/project-overview.component.scss
index 0fae7c5..7fa0d50 100644
--- a/security-c4po-angular/src/app/project-overview/project-overview.component.scss
+++ b/security-c4po-angular/src/app/project-overview/project-overview.component.scss
@@ -1,62 +1,118 @@
@import '../../assets/@theme/styles/themes';
+@import '../../assets/@theme/styles/variables';
-.project-card {
- max-width: 22rem;
- width: 22rem;
- min-width: 20rem;
- max-height: 100%;
- height: 100%;
- min-height: 100%;
+.pentest-overview {
+ width: 100vw;
+ height: 80vh;
+ // ToDo: Disable and fix scrolling
+ overflow: hidden;
- .project-header {
- max-height: 8rem;
- height: 8rem;
- min-height: 6rem;
+ .pentest-overview-header {
+ width: 100vw;
+
+ .header-filer {
+
+ .project-filter-input {
+ width: 24rem;
+
+ .search-prefix-icon {
+ color:nb-theme(color-info-default);
+ }
+ }
+
+ .state-dialog {
+ margin-left: auto;
+ margin-right: 0;
+
+ .states {
+ width: 14rem !important;
+ }
+ }
+
+ .reset-filter-btn {
+ .btn-icon {
+ padding-right: 0.5rem;
+ }
+ }
+ }
+
+ .header-project-button {
+ position: fixed;
+ right: 1.5rem;
+
+ .add-project-button {
+ // align-content: flex-end;
+ margin: 6rem 2rem 6rem 0;
+
+ .btn-icon {
+ padding-right: 0.5rem;
+ }
+ }
+ }
}
- .project-subheader {
- font-size: 1.25rem;
- font-weight: bold;
- }
+ .pentest-overview-column {
+ width: 100vw;
- .project-paragraph {
- font-size: 1.15rem;
- font-style: italic;
- }
+ .project-card {
+ max-width: 22rem;
+ width: 22rem;
+ min-width: 20rem;
+ max-height: 100%;
+ height: 100%;
+ min-height: 100%;
- .project-progress {
- max-width: 65%;
- width: 65%;
- min-width: 65%;
- }
+ .project-header {
+ max-height: 8rem;
+ height: 8rem;
+ min-height: 6rem;
- .project-button {
- height: 1.425rem;
+ .header-title {
+ width: 12.5rem;
+ }
+
+ .state-tag {
+ width: 1rem;
+ }
+ }
+
+ .project-subheader {
+ font-size: 1.25rem;
+ font-weight: bold;
+ }
+
+ .project-paragraph {
+ font-size: 1.15rem;
+ font-style: italic;
+ }
+
+ .project-progress {
+ max-width: 65%;
+ width: 65%;
+ min-width: 65%;
+ }
+
+ .project-button {
+ height: 1.425rem;
+ }
+ }
+
+ .project-card:hover {
+ background-color: nb-theme(color-basic-transparent-focus);
+ // Increases element size on hover
+ // Decreases usability which is why it is commented out
+ /*
+ margin-top: +0.625rem;
+ transform: scale(1.025);
+ */
+ }
+
+ .project-link:hover {
+ cursor: pointer !important;
+ }
+ .error-text {
+ font-size: 1.25rem;
+ font-weight: bold;
+ }
}
}
-
-.project-card:hover {
- background-color: nb-theme(color-basic-transparent-focus);
- // Increases element size on hover
- // Decreases usability which is why it is commented out
- /*
- margin-top: +0.625rem;
- transform: scale(1.025);
- */
-}
-
-.project-link:hover {
- cursor: pointer !important;
-}
-
-.add-project-button {
- margin: 6rem 2rem 6rem 0;
- .new-project-icon {
- padding-right: 0.5rem;
- }
-}
-
-.error-text {
- font-size: 1.25rem;
- font-weight: bold;
-}
diff --git a/security-c4po-angular/src/app/project-overview/project-overview.component.ts b/security-c4po-angular/src/app/project-overview/project-overview.component.ts
index c30b800..44c1834 100644
--- a/security-c4po-angular/src/app/project-overview/project-overview.component.ts
+++ b/security-c4po-angular/src/app/project-overview/project-overview.component.ts
@@ -5,7 +5,7 @@ import {BehaviorSubject, Observable} from 'rxjs';
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
import {ProjectService} from '@shared/services/api/project.service';
import {NotificationService, PopupType} from '@shared/services/toaster-service/notification.service';
-import {filter, tap} from 'rxjs/operators';
+import {filter, startWith, tap} from 'rxjs/operators';
import {DialogService} from '@shared/services/dialog-service/dialog.service';
import {ProjectDialogComponent} from '@shared/modules/project-dialog/project-dialog.component';
import {ProjectDialogService} from '@shared/modules/project-dialog/service/project-dialog.service';
@@ -13,6 +13,8 @@ import {Router} from '@angular/router';
import {Route} from '@shared/models/route.enum';
import {InitProjectState} from '@shared/stores/project-state/project-state.actions';
import {Store} from '@ngxs/store';
+import {ReportState} from '@shared/models/state.enum';
+import {FormControl} from '@angular/forms';
@UntilDestroy()
@Component({
@@ -26,6 +28,11 @@ export class ProjectOverviewComponent implements OnInit {
loading$: BehaviorSubject = new BehaviorSubject(true);
projects$: BehaviorSubject = new BehaviorSubject([]);
+ allProjects$: BehaviorSubject = new BehaviorSubject([]);
+
+ // Search
+ projectSearch: FormControl;
+ protected filter$: Observable;
constructor(
private readonly notificationService: NotificationService,
@@ -38,6 +45,9 @@ export class ProjectOverviewComponent implements OnInit {
ngOnInit(): void {
this.loadProjects();
+ // Setup Search
+ this.projectSearch = new FormControl({value: '', disabled: !this.allProjects$.getValue()});
+ this.setFilterObserverForProjects();
}
loadProjects(): void {
@@ -49,6 +59,7 @@ export class ProjectOverviewComponent implements OnInit {
.subscribe({
next: (projects: Project[]) => {
this.projects$.next(projects);
+ this.allProjects$.next(projects);
this.loading$.next(false);
},
error: err => {
@@ -156,6 +167,74 @@ export class ProjectOverviewComponent implements OnInit {
return this.loading$.asObservable();
}
+ /**
+ * HTML only
+ * @return the correct nb-accent for current report state of the project
+ */
+ getProjectAccentFillStatus(value: any): string {
+ let reportStateFillStatus;
+ const statusValue = typeof value !== 'number' ? ReportState[value] : value;
+ // Check for correct accent color of status
+ switch (statusValue) {
+ case 6:
+ case 7: {
+ reportStateFillStatus = 'success';
+ break;
+ }
+ case 0: {
+ reportStateFillStatus = 'info';
+ break;
+ }
+ case 8:
+ case 9:
+ case 11:
+ case 12: {
+ reportStateFillStatus = 'warning';
+ break;
+ }
+ case 1:
+ case 10: {
+ reportStateFillStatus = 'danger';
+ break;
+ }
+ default: {
+ reportStateFillStatus = 'control';
+ break;
+ }
+ }
+ return reportStateFillStatus;
+ }
+
+ onClickResetFilter(): void {
+ this.projectSearch.reset('');
+ this.projects$.next(this.allProjects$.getValue());
+ }
+
+ private setFilterObserverForProjects(): void {
+ this.filter$ = this.projectSearch.valueChanges.pipe(startWith(''));
+ this.filter$.subscribe(
+ (filterString: string) => {
+ if (filterString.length === 0) {
+ this.projects$.next(this.allProjects$.getValue());
+ } else {
+ const matchingProjects: Project[] = [];
+ this.allProjects$.getValue().forEach(project => {
+ // Project attributes that the user can filter through
+ if (
+ project.title.toLowerCase().includes(filterString.toLowerCase())
+ || project.client.toLowerCase().includes(filterString.toLowerCase())
+ || project.tester.toLowerCase().includes(filterString.toLowerCase())
+ || project.state.toString().toLowerCase().includes(filterString.toLowerCase())
+ ) {
+ matchingProjects.push(project);
+ }
+ });
+ this.projects$.next(matchingProjects);
+ }
+ }
+ );
+ }
+
private deleteProject(project: Project): void {
this.projectService.deleteProjectById(project.id).pipe(
untilDestroyed(this)
diff --git a/security-c4po-angular/src/app/project-overview/project-overview.module.ts b/security-c4po-angular/src/app/project-overview/project-overview.module.ts
index c30838a..5b0106d 100644
--- a/security-c4po-angular/src/app/project-overview/project-overview.module.ts
+++ b/security-c4po-angular/src/app/project-overview/project-overview.module.ts
@@ -2,7 +2,15 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ProjectOverviewComponent} from './project-overview.component';
import {ProjectOverviewRoutingModule} from './project-overview-routing.module';
-import {NbButtonModule, NbCardModule, NbProgressBarModule} from '@nebular/theme';
+import {
+ NbButtonModule,
+ NbCardModule,
+ NbFormFieldModule,
+ NbInputModule,
+ NbLayoutModule,
+ NbProgressBarModule,
+ NbSelectModule
+} from '@nebular/theme';
import {FlexLayoutModule} from '@angular/flex-layout';
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
import {TranslateModule} from '@ngx-translate/core';
@@ -12,6 +20,8 @@ import {CommonAppModule} from '../common-app.module';
import {ConfirmDialogModule} from '@shared/modules/confirm-dialog/confirm-dialog.module';
import {SecurityConfirmDialogModule} from '@shared/modules/security-confirm-dialog/security-confirm-dialog.module';
import {RouterModule} from '@angular/router';
+import {ReportStateTagModule} from '@shared/widgets/report-state-tag/report-state-tag.module';
+import {ReactiveFormsModule} from '@angular/forms';
@NgModule({
declarations: [
@@ -34,7 +44,13 @@ import {RouterModule} from '@angular/router';
TranslateModule,
ProjectDialogModule,
ConfirmDialogModule,
- SecurityConfirmDialogModule
+ ReportStateTagModule,
+ SecurityConfirmDialogModule,
+ NbLayoutModule,
+ NbInputModule,
+ NbFormFieldModule,
+ ReactiveFormsModule,
+ NbSelectModule
]
})
export class ProjectOverviewModule {
diff --git a/security-c4po-angular/src/app/project-overview/project/project.component.spec.ts b/security-c4po-angular/src/app/project-overview/project/project.component.spec.ts
index 081765b..6f237b5 100644
--- a/security-c4po-angular/src/app/project-overview/project/project.component.spec.ts
+++ b/security-c4po-angular/src/app/project-overview/project/project.component.spec.ts
@@ -8,7 +8,6 @@ import {HttpLoaderFactory} from '../../common-app.module';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {RouterTestingModule} from '@angular/router/testing';
import {NgxsModule, Store} from '@ngxs/store';
-import {SessionState} from '@shared/stores/session-state/session-state';
import {HttpClientTestingModule} from '@angular/common/http/testing';
import {NbCardModule, NbDialogRef, NbLayoutModule} from '@nebular/theme';
import {KeycloakService} from 'keycloak-angular';
@@ -27,6 +26,7 @@ import {PentestStatus} from '@shared/models/pentest-status.model';
import {createSpyObj} from '@shared/modules/finding-dialog/finding-dialog.component.spec';
import {ExportReportDialogService} from '@shared/modules/export-report-dialog/service/export-report-dialog.service';
import {ExportReportDialogServiceMock} from '@shared/modules/export-report-dialog/service/export-report-dialog.service.mock';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -36,6 +36,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
diff --git a/security-c4po-angular/src/assets/i18n/de-DE.json b/security-c4po-angular/src/assets/i18n/de-DE.json
index cd3dfeb..e887b71 100644
--- a/security-c4po-angular/src/assets/i18n/de-DE.json
+++ b/security-c4po-angular/src/assets/i18n/de-DE.json
@@ -52,6 +52,21 @@
"failed": "Benutzername oder Passwort falsch",
"unauthorized": "Benutzer nicht gefunden. Bitte registrieren und erneut versuchen"
},
+ "state": {
+ "new": "Neu",
+ "needs_more_info": "Benötigt mehr Informationen",
+ "pre_submission": "Voranmeldung",
+ "pending": "Pending",
+ "triaged": "Ausstehend",
+ "retesting": "Erneutes Testen",
+ "resolved": "Aufgeklärt",
+ "informative": "Informatif",
+ "duplicate": "Duplikat",
+ "not_applicable": "Unzutreffend",
+ "spam": "Spam",
+ "out_of_scope": "Außerhalb Anwendungsbereich",
+ "accepted_risk": "Akzeptiertes Risiko"
+ },
"report": {
"dialog": {
"header": "Penetrationstestbereicht exportieren",
@@ -69,17 +84,22 @@
"title.label": "Projekt Titel",
"client.label": "Name des Auftraggebers",
"tester.label": "Name des Pentester",
+ "state.label": "Penteststatus",
"summary.label": "Zusammenfassung",
"summary.placeholder": "Sollte eine Zusammenfassung, einen Ansatz, einen Umfang und eine Bewertungsübersicht sowie allgemeine Empfehlungen enthalten",
"title": "Titel",
"client": "Klient",
"tester": "Tester",
+ "state": "Penteststatus",
"summary": "Zusammenfassung",
"createdAt": "Erstellt am",
"overview": {
"add.project": "Projekt hinzufügen",
"no.projects": "Keine Projekte verfügbar"
},
+ "filter": {
+ "placeholder": "Projekt suchen"
+ },
"create": {
"header": "Neues Projekt erstellen"
},
@@ -96,6 +116,7 @@
"titleRequired": "Titel ist erforderlich.",
"clientRequired": "Klient ist erforderlich.",
"testerRequired": "Tester ist erforderlich.",
+ "stateRequired": "Status ist erforderlich.",
"summaryRequired": "Zusammenfassung ist erforderlich."
},
"popup": {
diff --git a/security-c4po-angular/src/assets/i18n/en-US.json b/security-c4po-angular/src/assets/i18n/en-US.json
index 5491102..c588327 100644
--- a/security-c4po-angular/src/assets/i18n/en-US.json
+++ b/security-c4po-angular/src/assets/i18n/en-US.json
@@ -52,6 +52,21 @@
"failed": "Wrong username or password",
"unauthorized": "User not found. Please register and try again"
},
+ "state": {
+ "new": "New",
+ "needs_more_info": "Needs More Info",
+ "pre_submission": "Pre-submission",
+ "pending": "Pending",
+ "triaged": "Triaged",
+ "retesting": "Retesting",
+ "resolved": "Resolved",
+ "informative": "Informative",
+ "duplicate": "Duplicate",
+ "not_applicable": "Not Applicable",
+ "spam": "Spam",
+ "out_of_scope": "Out Of Scope",
+ "accepted_risk": "Accepted Risk"
+ },
"report": {
"dialog": {
"header": "Export Penetrationtest Report",
@@ -69,17 +84,22 @@
"title.label": "Project Title",
"client.label": "Name of Client",
"tester.label": "Name of Pentester",
+ "state.label": "State of Pentest",
"summary.label": "Summary",
"summary.placeholder": "Should include Executive Summary, Approach, Scope and Assessment Overview as well as General Recommendations",
"title": "Title",
"client": "Client",
"tester": "Tester",
+ "state": "State of Pentest",
"summary": "Summary",
"createdAt": "Created at",
"overview": {
"add.project": "Add Project",
"no.projects": "No projects available"
},
+ "filter": {
+ "placeholder": "Search for project"
+ },
"create": {
"header": "Create New Project"
},
@@ -96,6 +116,7 @@
"titleRequired": "Title is required.",
"clientRequired": "Client is required.",
"testerRequired": "Tester is required.",
+ "stateRequired": "State is required.",
"summaryRequired": "Summary is required."
},
"popup": {
diff --git a/security-c4po-angular/src/shared/models/project.model.ts b/security-c4po-angular/src/shared/models/project.model.ts
index 80a865f..a05fec9 100644
--- a/security-c4po-angular/src/shared/models/project.model.ts
+++ b/security-c4po-angular/src/shared/models/project.model.ts
@@ -1,4 +1,5 @@
import {PentestStatus} from '@shared/models/pentest-status.model';
+import {ReportState} from '@shared/models/state.enum';
export class Project {
id: string;
@@ -7,6 +8,7 @@ export class Project {
createdAt: Date;
tester: string;
summary: string;
+ state: ReportState;
projectPentests?: Array;
testingProgress?: number;
createdBy: string;
@@ -16,6 +18,7 @@ export class Project {
title: string,
createdAt: Date,
tester: string,
+ state: ReportState,
projectPentests?: Array,
testingProgress?: number,
summary?: string,
@@ -28,14 +31,28 @@ export class Project {
this.projectPentests = projectPentests;
this.testingProgress = testingProgress;
this.summary = summary;
+ this.state = state;
this.createdBy = createdBy;
}
}
+export function transformProjectToRequestBody(project: ProjectDialogBody | Project): ProjectDialogBody {
+ const transformedProject = {
+ ...project,
+ title: project.title,
+ client: project.client,
+ tester: project.tester,
+ state: typeof project.state === 'number' ? ReportState[project.state] : project.state,
+ summary: project.summary,
+ } as unknown as ProjectDialogBody;
+ return transformedProject;
+}
+
export interface ProjectDialogBody {
title: string;
client: string;
tester: string;
+ state: ReportState;
summary: string;
}
diff --git a/security-c4po-angular/src/shared/models/state.enum.ts b/security-c4po-angular/src/shared/models/state.enum.ts
new file mode 100644
index 0000000..5c979e7
--- /dev/null
+++ b/security-c4po-angular/src/shared/models/state.enum.ts
@@ -0,0 +1,40 @@
+export enum ReportState {
+ NEW,
+ NEEDS_MORE_INFO,
+ // Report states depending on customer feedback
+ PRE_SUBMISSION,
+ PENDING,
+ TRIAGED,
+ RETESTING,
+ // Report states for closed submissions
+ RESOLVED,
+ INFORMATIVE,
+ DUPLICATE,
+ NOT_APPLICABLE,
+ SPAM,
+ OUT_OF_SCOPE,
+ ACCEPTED_RISK
+}
+
+export const reportStateTexts: Array = [
+ {value: ReportState.NEW, translationText: 'state.new'},
+ {value: ReportState.NEEDS_MORE_INFO, translationText: 'state.needs_more_info'},
+ // Report states depending on customer feedback
+ {value: ReportState.PRE_SUBMISSION, translationText: 'state.pre_submission'},
+ {value: ReportState.PENDING, translationText: 'state.pending'},
+ {value: ReportState.TRIAGED, translationText: 'state.triaged'},
+ {value: ReportState.RETESTING, translationText: 'state.retesting'},
+ // Report states for closed submissions
+ {value: ReportState.RESOLVED, translationText: 'state.resolved'},
+ {value: ReportState.INFORMATIVE, translationText: 'state.informative'},
+ {value: ReportState.DUPLICATE, translationText: 'state.duplicate'},
+ {value: ReportState.NOT_APPLICABLE, translationText: 'state.not_applicable'},
+ {value: ReportState.SPAM, translationText: 'state.spam'},
+ {value: ReportState.OUT_OF_SCOPE, translationText: 'state.out_of_scope'},
+ {value: ReportState.ACCEPTED_RISK, translationText: 'state.accepted_risk'}
+];
+
+export interface ReportStateText {
+ value: ReportState;
+ translationText: string;
+}
diff --git a/security-c4po-angular/src/shared/modules/comment-dialog/comment-dialog.component.spec.ts b/security-c4po-angular/src/shared/modules/comment-dialog/comment-dialog.component.spec.ts
index b185913..7bdbd98 100644
--- a/security-c4po-angular/src/shared/modules/comment-dialog/comment-dialog.component.spec.ts
+++ b/security-c4po-angular/src/shared/modules/comment-dialog/comment-dialog.component.spec.ts
@@ -32,6 +32,7 @@ import Mock = jest.Mock;
import {Finding} from '@shared/models/finding.model';
import {Severity} from '@shared/models/severity.enum';
import {Comment} from '@shared/models/comment.model';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -41,6 +42,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
diff --git a/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.spec.ts b/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.spec.ts
index aebeda0..424fee3 100644
--- a/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.spec.ts
+++ b/security-c4po-angular/src/shared/modules/export-report-dialog/export-report-dialog.component.spec.ts
@@ -28,6 +28,7 @@ import {Project, ProjectPentests} from '@shared/models/project.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
import {ObjectiveChartModule} from '@shared/modules/objective-chart/objective-chart.module';
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
+import {ReportState} from '@shared/models/state.enum';
describe('ExportReportDialogComponent', () => {
let component: ExportReportDialogComponent;
@@ -102,6 +103,7 @@ const mockProject: Project = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
projectPentests: mockedPentests,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
diff --git a/security-c4po-angular/src/shared/modules/finding-dialog/finding-dialog.component.spec.ts b/security-c4po-angular/src/shared/modules/finding-dialog/finding-dialog.component.spec.ts
index bd6c95e..df6bf2e 100644
--- a/security-c4po-angular/src/shared/modules/finding-dialog/finding-dialog.component.spec.ts
+++ b/security-c4po-angular/src/shared/modules/finding-dialog/finding-dialog.component.spec.ts
@@ -30,6 +30,7 @@ import {Category} from '@shared/models/category.model';
import {PentestStatus} from '@shared/models/pentest-status.model';
import {PROJECT_STATE_NAME, ProjectState, ProjectStateModel} from '@shared/stores/project-state/project-state';
import {NgxsModule, Store} from '@ngxs/store';
+import {ReportState} from '@shared/models/state.enum';
const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
selectedProject: {
@@ -39,6 +40,7 @@ const DESIRED_PROJECT_STATE_SESSION: ProjectStateModel = {
createdAt: new Date('2019-01-10T09:00:00'),
tester: 'Novatester',
summary: '',
+ state: ReportState.NEW,
testingProgress: 0,
createdBy: '11c47c56-3bcd-45f1-a05b-c197dbd33110'
},
@@ -97,13 +99,13 @@ describe('FindingDialogComponent', () => {
{provide: NotificationService, useValue: new NotificationServiceMock()},
{provide: DialogService, useClass: DialogServiceMock},
{provide: NbDialogRef, useValue: dialogSpy},
- {provide: NB_DIALOG_CONFIG, useValue: mockedCommentDialogData}
+ {provide: NB_DIALOG_CONFIG, useValue: mockedFindingDialogData}
]
}).compileComponents();
});
beforeEach(() => {
- TestBed.overrideProvider(NB_DIALOG_CONFIG, {useValue: mockedCommentDialogData});
+ TestBed.overrideProvider(NB_DIALOG_CONFIG, {useValue: mockedFindingDialogData});
fixture = TestBed.createComponent(FindingDialogComponent);
store = TestBed.inject(Store);
store.reset({
@@ -138,7 +140,7 @@ export const mockFinding: Finding = {
mitigation: 'Mitigation Test'
};
-export const mockedCommentDialogData = {
+export const mockedFindingDialogData = {
form: {
findingTitle: {
fieldName: 'findingTitle',
diff --git a/security-c4po-angular/src/shared/modules/project-dialog/project-dialog.component.html b/security-c4po-angular/src/shared/modules/project-dialog/project-dialog.component.html
index 818c189..45b7ab6 100644
--- a/security-c4po-angular/src/shared/modules/project-dialog/project-dialog.component.html
+++ b/security-c4po-angular/src/shared/modules/project-dialog/project-dialog.component.html
@@ -1,6 +1,18 @@