Compare commits
1 Commits
main
...
mhg_c4po_8
Author | SHA1 | Date |
---|---|---|
|
506af108ec |
|
@ -2305,27 +2305,48 @@
|
|||
"integrity": "sha512-a/7BiSgobHAgBWeN7N0w+lAhInrGxksn13uK7231n2m8EDPE3BMCl9NZLTGrj9ZXfCmC6LM0QLqXidIizVQ6yg=="
|
||||
},
|
||||
"@fortawesome/fontawesome-svg-core": {
|
||||
"version": "1.2.36",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.36.tgz",
|
||||
"integrity": "sha512-YUcsLQKYb6DmaJjIHdDWpBIGCcyE/W+p/LMGvjQem55Mm2XWVAP5kWTMKWLv9lwpCVjpLxPyOMOyUocP1GxrtA==",
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz",
|
||||
"integrity": "sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==",
|
||||
"requires": {
|
||||
"@fortawesome/fontawesome-common-types": "^0.2.36"
|
||||
"@fortawesome/fontawesome-common-types": "6.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz",
|
||||
"integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@fortawesome/free-regular-svg-icons": {
|
||||
"version": "5.15.4",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.15.4.tgz",
|
||||
"integrity": "sha512-9VNNnU3CXHy9XednJ3wzQp6SwNwT3XaM26oS4Rp391GsxVYA+0oDR2J194YCIWf7jNRCYKjUCOduxdceLrx+xw==",
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.3.0.tgz",
|
||||
"integrity": "sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg==",
|
||||
"requires": {
|
||||
"@fortawesome/fontawesome-common-types": "^0.2.36"
|
||||
"@fortawesome/fontawesome-common-types": "6.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz",
|
||||
"integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@fortawesome/free-solid-svg-icons": {
|
||||
"version": "5.15.4",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.4.tgz",
|
||||
"integrity": "sha512-JLmQfz6tdtwxoihXLg6lT78BorrFyCf59SAwBM6qV/0zXyVeDygJVb3fk+j5Qat+Yvcxp1buLTY5iDh1ZSAQ8w==",
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.3.0.tgz",
|
||||
"integrity": "sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA==",
|
||||
"requires": {
|
||||
"@fortawesome/fontawesome-common-types": "^0.2.36"
|
||||
"@fortawesome/fontawesome-common-types": "6.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-common-types": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz",
|
||||
"integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@istanbuljs/load-nyc-config": {
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
"@angular/router": "~12.2.16",
|
||||
"@fortawesome/angular-fontawesome": "^0.8.2",
|
||||
"@fortawesome/fontawesome-common-types": "^0.2.36",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.3.0",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.3.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.3.0",
|
||||
"@nebular/eva-icons": "^8.0.0",
|
||||
"@nebular/theme": "^8.0.0",
|
||||
"@ngneat/until-destroy": "~8.0.4",
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import {NbMenuItem, NbMenuService} from '@nebular/theme';
|
||||
import {Subject} from 'rxjs';
|
||||
import {of, Subject} from 'rxjs';
|
||||
import {Store} from '@ngxs/store';
|
||||
import {ChangeCategory} from '@shared/stores/project-state/project-state.actions';
|
||||
import {Category} from '@shared/models/category.model';
|
||||
import {untilDestroyed} from 'ngx-take-until-destroy';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
import {ProjectState} from '@shared/stores/project-state/project-state';
|
||||
import {catchError, switchMap, tap} from 'rxjs/operators';
|
||||
import {Pentest, transformPentestsToObjectiveEntries} from '@shared/models/pentest.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-objective-categories',
|
||||
|
@ -25,8 +28,22 @@ export class ObjectiveCategoriesComponent implements OnInit, OnDestroy {
|
|||
|
||||
ngOnInit(): void {
|
||||
this.initTranslation();
|
||||
// Set first item in list as selected
|
||||
this.categories[0].selected = true;
|
||||
this.store.select(ProjectState.selectedCategory).pipe(
|
||||
untilDestroyed(this)
|
||||
).subscribe({
|
||||
next: (categoryIndex) => {
|
||||
if (categoryIndex) {
|
||||
this.selectedCategory = categoryIndex;
|
||||
this.categories[categoryIndex].selected = true;
|
||||
} else {
|
||||
// Set first item in list as selected
|
||||
this.categories[0].selected = true;
|
||||
}
|
||||
},
|
||||
error: error => {
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
this.menuService.onItemClick()
|
||||
.pipe(
|
||||
untilDestroyed(this)
|
||||
|
|
|
@ -5,17 +5,8 @@
|
|||
class="comment-cell"
|
||||
fragment="{{comment.data['commentId']}}">
|
||||
</tr>
|
||||
<!-- Comment ID -->
|
||||
<ng-container [nbTreeGridColumnDef]="columns[0]">
|
||||
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef>
|
||||
{{ 'comment.commentId' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let comment">
|
||||
{{ comment.data['commentId'] || '-' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Title -->
|
||||
<ng-container [nbTreeGridColumnDef]="columns[1]">
|
||||
<ng-container [nbTreeGridColumnDef]="columns[0]">
|
||||
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef>
|
||||
{{ 'comment.title' | translate }}
|
||||
</th>
|
||||
|
@ -24,7 +15,7 @@
|
|||
</td>
|
||||
</ng-container>
|
||||
<!-- Description -->
|
||||
<ng-container [nbTreeGridColumnDef]="columns[2]">
|
||||
<ng-container [nbTreeGridColumnDef]="columns[1]">
|
||||
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef>
|
||||
{{ 'comment.description' | translate }}
|
||||
</th>
|
||||
|
@ -32,29 +23,15 @@
|
|||
{{ comment.data['description'] }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Related Findings -->
|
||||
<ng-container [nbTreeGridColumnDef]="columns[3]">
|
||||
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef>
|
||||
{{ 'comment.relatedFindings' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let comment" class="related-finding-cell">
|
||||
<ng-container *ngIf="comment.data['relatedFindings'].length > 0; else NoRelatedFindings">
|
||||
<app-findig-widget [numberOfFindings]="comment.data['relatedFindings'].length"></app-findig-widget>
|
||||
</ng-container>
|
||||
<ng-template #NoRelatedFindings>
|
||||
{{ 'comment.no.relatedFindings' | translate }}
|
||||
</ng-template>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Actions -->
|
||||
<ng-container [nbTreeGridColumnDef]="columns[4]">
|
||||
<ng-container [nbTreeGridColumnDef]="columns[2]">
|
||||
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef class="cell-actions">
|
||||
<button nbButton hero
|
||||
status="info"
|
||||
size="small"
|
||||
shape="round"
|
||||
class="add-comment-button"
|
||||
[disabled]="pentestInfo$.getValue().status === notStartedStatus"
|
||||
[disabled]="pentestInfo$.getValue().status !== inProgressStatus"
|
||||
(click)="onClickAddComment()">
|
||||
<fa-icon [icon]="fa.faPlus" class="new-comment-icon"></fa-icon>
|
||||
{{'comment.add' | translate}}
|
||||
|
|
|
@ -9,7 +9,7 @@ import {catchError, filter, mergeMap, switchMap, tap} from 'rxjs/operators';
|
|||
import {
|
||||
Comment,
|
||||
CommentDialogBody,
|
||||
CommentEntry, RelatedFindingOption,
|
||||
CommentEntry,
|
||||
transformCommentsToObjectiveEntries,
|
||||
transformCommentToRequestBody
|
||||
} from '@shared/models/comment.model';
|
||||
|
@ -35,15 +35,15 @@ export class PentestCommentsComponent implements OnInit {
|
|||
|
||||
// HTML only
|
||||
readonly fa = FA;
|
||||
notStartedStatus: PentestStatus = PentestStatus.NOT_STARTED;
|
||||
// HTML only for button enabling
|
||||
inProgressStatus: PentestStatus = PentestStatus.IN_PROGRESS;
|
||||
|
||||
pentestInfo$: BehaviorSubject<Pentest> = new BehaviorSubject<Pentest>(null);
|
||||
objectiveFindings: RelatedFindingOption[] = [];
|
||||
// comments$: BehaviorSubject<Comment[]> = new BehaviorSubject<Comment[]>(null);
|
||||
loading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
|
||||
|
||||
columns: Array<CommentColumns> = [
|
||||
CommentColumns.COMMENT_ID, CommentColumns.TITLE, CommentColumns.DESCRIPTION, CommentColumns.RELATED_FINDINGS, CommentColumns.ACTIONS
|
||||
CommentColumns.TITLE, CommentColumns.DESCRIPTION, CommentColumns.ACTIONS
|
||||
];
|
||||
dataSource: NbTreeGridDataSource<CommentEntry>;
|
||||
data: CommentEntry[] = [];
|
||||
|
@ -109,7 +109,6 @@ export class PentestCommentsComponent implements OnInit {
|
|||
this.commentDialogService.openCommentDialog(
|
||||
CommentDialogComponent,
|
||||
this.pentestInfo$.getValue().findingIds,
|
||||
this.objectiveFindings,
|
||||
null,
|
||||
{
|
||||
closeOnEsc: false,
|
||||
|
@ -149,7 +148,6 @@ export class PentestCommentsComponent implements OnInit {
|
|||
this.commentDialogService.openCommentDialog(
|
||||
CommentDialogComponent,
|
||||
this.pentestInfo$.getValue().findingIds,
|
||||
this.objectiveFindings,
|
||||
existingComment,
|
||||
{
|
||||
closeOnEsc: false,
|
||||
|
@ -187,12 +185,11 @@ export class PentestCommentsComponent implements OnInit {
|
|||
}
|
||||
|
||||
requestFindingsData(pentestId: string): void {
|
||||
this.objectiveFindings = [];
|
||||
this.findingService.getFindingsByPentestId(pentestId).pipe(
|
||||
untilDestroyed(this)
|
||||
).subscribe({
|
||||
next: (findings: Finding[]) => {
|
||||
findings.forEach(finding => this.objectiveFindings.push({id: finding.id, title: finding.title} as RelatedFindingOption));
|
||||
// findings.forEach(finding => this.objectiveFindings.push({id: finding.id, title: finding.title} as RelatedFindingOption));
|
||||
},
|
||||
error: err => {
|
||||
console.error(err);
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
class="finding-cell"
|
||||
fragment="{{finding.data['findingId']}}">
|
||||
</tr>
|
||||
<!-- Finding ID -->
|
||||
<!-- Title -->
|
||||
<ng-container [nbTreeGridColumnDef]="columns[0]">
|
||||
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef>
|
||||
{{ 'finding.findingId' | translate }}
|
||||
{{ 'finding.title' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let finding">
|
||||
{{ finding.data['findingId'] || '-' }}
|
||||
{{ finding.data['title'] }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Severity -->
|
||||
|
@ -25,13 +25,13 @@
|
|||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Title -->
|
||||
<!-- Description -->
|
||||
<ng-container [nbTreeGridColumnDef]="columns[2]">
|
||||
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef>
|
||||
{{ 'finding.title' | translate }}
|
||||
{{ 'finding.description' | translate }}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let finding">
|
||||
{{ finding.data['title'] }}
|
||||
{{ finding.data['description'] }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<!-- Impact -->
|
||||
|
@ -51,7 +51,7 @@
|
|||
size="small"
|
||||
shape="round"
|
||||
class="add-finding-button"
|
||||
[disabled]="pentestInfo$.getValue().status === notStartedStatus"
|
||||
[disabled]="pentestInfo$.getValue().status !== inProgressStatus"
|
||||
(click)="onClickAddFinding()">
|
||||
<fa-icon [icon]="fa.faPlus" class="new-finding-icon"></fa-icon>
|
||||
{{'finding.add' | translate}}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
import {PentestService} from '@shared/services/api/pentest.service';
|
||||
import {BehaviorSubject, Observable} from 'rxjs';
|
||||
import {Pentest} from '@shared/models/pentest.model';
|
||||
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
|
||||
|
@ -46,10 +45,11 @@ export class PentestFindingsComponent implements OnInit {
|
|||
|
||||
// HTML only
|
||||
readonly fa = FA;
|
||||
notStartedStatus: PentestStatus = PentestStatus.NOT_STARTED;
|
||||
// HTML only for button enabling
|
||||
inProgressStatus: PentestStatus = PentestStatus.IN_PROGRESS;
|
||||
|
||||
columns: Array<FindingColumns> = [
|
||||
FindingColumns.FINDING_ID, FindingColumns.SEVERITY, FindingColumns.TITLE, FindingColumns.IMPACT, FindingColumns.ACTIONS
|
||||
FindingColumns.TITLE, FindingColumns.SEVERITY, FindingColumns.DESCRIPTION, FindingColumns.IMPACT, FindingColumns.ACTIONS
|
||||
];
|
||||
dataSource: NbTreeGridDataSource<FindingEntry>;
|
||||
|
||||
|
@ -218,8 +218,9 @@ export class PentestFindingsComponent implements OnInit {
|
|||
|
||||
enum FindingColumns {
|
||||
FINDING_ID = 'findingId',
|
||||
SEVERITY = 'severity',
|
||||
TITLE = 'title',
|
||||
SEVERITY = 'severity',
|
||||
DESCRIPTION = 'description',
|
||||
IMPACT = 'impact',
|
||||
ACTIONS = 'actions'
|
||||
}
|
||||
|
|
|
@ -13,42 +13,23 @@
|
|||
|
||||
<h4>{{selectedProjectTitle$.getValue()}} / {{pentest$.getValue().refNumber}}</h4>
|
||||
|
||||
<div class="pentest-status-container">
|
||||
<!--ToDo: Add changing dialog here-->
|
||||
<!--<app-status-tag [currentStatus]="pentest$.getValue().status"></app-status-tag>-->
|
||||
|
||||
<!-- Pentest Status Selection -->
|
||||
<div class="pentest-status-dialog">
|
||||
<nb-select class="status"
|
||||
[(selected)]="currentStatus"
|
||||
shape="round" filled
|
||||
status="{{getPentestFillStatus(currentStatus)}}">
|
||||
<nb-option *ngFor="let status of statusTexts" [value]="status.value">
|
||||
{{ status.translationText | translate }}
|
||||
</nb-option>
|
||||
</nb-select>
|
||||
<div class="pentest-status-container" fxLayout="row" fxLayoutGap="2.5rem" fxLayoutAlign="end center">
|
||||
<!-- Pentest Timer-->
|
||||
<div class="timer-component">
|
||||
<app-timer></app-timer>
|
||||
</div>
|
||||
<div *ngIf="!pentest$.getValue().id; else updatePentest">
|
||||
<!-- Complete Pentest -->
|
||||
<div>
|
||||
<button nbButton
|
||||
class="save-pentest-button"
|
||||
status="primary"
|
||||
[disabled]="!pentestStatusChanged()"
|
||||
status="success"
|
||||
[disabled]="!pentestStatusChanged() || !pentestHasFindingsOrComments()"
|
||||
title="{{ 'global.action.save' | translate }}"
|
||||
(click)="onClickSavePentest()">
|
||||
<span class="exit-element-text"> {{ 'global.action.save' | translate }} </span>
|
||||
(click)="onClickCompletePentestAndRouteBack()">
|
||||
<fa-icon [icon]="fa.faSquare"></fa-icon>
|
||||
<span class="action-element-text"> {{ 'global.action.complete' | translate }} </span>
|
||||
</button>
|
||||
</div>
|
||||
<ng-template #updatePentest>
|
||||
<button nbButton
|
||||
class="save-pentest-button"
|
||||
status="primary"
|
||||
[disabled]="!pentestStatusChanged()"
|
||||
title="{{ 'global.action.update' | translate }}"
|
||||
(click)="onClickUpdatePentest()">
|
||||
<span class="exit-element-text"> {{ 'global.action.update' | translate }} </span>
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -11,10 +11,18 @@
|
|||
}
|
||||
|
||||
.pentest-status-container {
|
||||
display: flex;
|
||||
align-content: flex-end;
|
||||
// margin-right: 0.5rem;
|
||||
// height: 5%;
|
||||
// display: flex;
|
||||
// align-content: flex-end;
|
||||
|
||||
.timer-component {
|
||||
height: 2rem !important;
|
||||
max-height: 2rem !important;
|
||||
margin: 0.5rem 2.25rem 1rem 0;
|
||||
}
|
||||
|
||||
.action-element-text {
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
||||
.pentest-status-dialog {
|
||||
margin: 1rem 2.25rem 1rem 0;
|
||||
|
@ -41,6 +49,7 @@
|
|||
}
|
||||
|
||||
.save-pentest-button {
|
||||
// height: 1rem !important;
|
||||
margin: 1rem 0 1rem 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Component, OnInit} from '@angular/core';
|
||||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import * as FA from '@fortawesome/free-solid-svg-icons';
|
||||
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
|
||||
import {Route} from '@shared/models/route.enum';
|
||||
|
@ -20,7 +20,7 @@ import {StatusText} from '@shared/widgets/status-tag/status-tag.component';
|
|||
templateUrl: './pentest-header.component.html',
|
||||
styleUrls: ['./pentest-header.component.scss']
|
||||
})
|
||||
export class PentestHeaderComponent implements OnInit {
|
||||
export class PentestHeaderComponent implements OnInit, OnDestroy {
|
||||
// HTML only
|
||||
readonly fa = FA;
|
||||
|
||||
|
@ -28,16 +28,21 @@ export class PentestHeaderComponent implements OnInit {
|
|||
selectedProjectTitle$: BehaviorSubject<string> = new BehaviorSubject<string>('');
|
||||
pentestChanged$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
|
||||
// Pentest Timer Handler
|
||||
currentTimeSpent = 0;
|
||||
private initialTimeSpent: number;
|
||||
|
||||
// Pentest Status Handler
|
||||
status = PentestStatus;
|
||||
currentStatus: PentestStatus = PentestStatus.NOT_STARTED;
|
||||
private initialPentestStatus: PentestStatus;
|
||||
|
||||
// Status Text Translation Texts
|
||||
readonly statusTexts: Array<StatusText> = [
|
||||
{value: PentestStatus.NOT_STARTED, translationText: 'pentest.statusText.not_started'},
|
||||
/* ToDo: Disabled not needed inside pentest */
|
||||
/*{value: PentestStatus.DISABLED, translationText: 'pentest.statusText.disabled'},*/
|
||||
{value: PentestStatus.OPEN, translationText: 'pentest.statusText.open'},
|
||||
{value: PentestStatus.PAUSED, translationText: 'pentest.statusText.paused'},
|
||||
{value: PentestStatus.IN_PROGRESS, translationText: 'pentest.statusText.in_progress'},
|
||||
{value: PentestStatus.COMPLETED, translationText: 'pentest.statusText.completed'}
|
||||
];
|
||||
|
@ -51,7 +56,7 @@ export class PentestHeaderComponent implements OnInit {
|
|||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.store.select(ProjectState.project).pipe(
|
||||
this.store.selectOnce(ProjectState.project).pipe(
|
||||
untilDestroyed(this)
|
||||
).subscribe({
|
||||
next: (selectedProject: Project) => {
|
||||
|
@ -68,17 +73,20 @@ export class PentestHeaderComponent implements OnInit {
|
|||
).subscribe({
|
||||
next: (selectedPentest: Pentest) => {
|
||||
this.currentStatus = selectedPentest.status;
|
||||
this.initialPentestStatus = selectedPentest.status;
|
||||
this.currentTimeSpent = selectedPentest.timeSpent ? selectedPentest.timeSpent : 0;
|
||||
this.pentest$.next(selectedPentest);
|
||||
},
|
||||
error: err => {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
// Setup initial values for status and time outside of store subscription
|
||||
this.initialPentestStatus = this.currentStatus;
|
||||
this.initialTimeSpent = this.currentTimeSpent;
|
||||
}
|
||||
|
||||
onClickRouteBack(): void {
|
||||
// ToDo: Change to Objective Overview after routing is fixed
|
||||
// Route back to overview
|
||||
this.router.navigate([Route.OBJECTIVE_OVERVIEW])
|
||||
.then(
|
||||
() => {
|
||||
|
@ -87,27 +95,18 @@ export class PentestHeaderComponent implements OnInit {
|
|||
).finally();
|
||||
}
|
||||
|
||||
onClickSavePentest(): void {
|
||||
this.pentest$.next({...this.pentest$.getValue(), status: this.currentStatus});
|
||||
this.pentestService.savePentest(this.selectedProjectId$.getValue(), transformPentestToRequestBody(this.pentest$.getValue()))
|
||||
.subscribe({
|
||||
next: (pentest: Pentest) => {
|
||||
this.store.dispatch(new ChangePentest(pentest));
|
||||
this.notificationService.showPopup('pentest.popup.save.success', PopupType.SUCCESS);
|
||||
},
|
||||
error: err => {
|
||||
console.log(err);
|
||||
this.notificationService.showPopup('pentest.popup.save.failed', PopupType.FAILURE);
|
||||
}
|
||||
});
|
||||
onClickCompletePentestAndRouteBack(): void {
|
||||
// Update existing Pentest
|
||||
this.pentest$.next({...this.pentest$.getValue(), status: PentestStatus.COMPLETED, timeSpent: this.currentTimeSpent});
|
||||
this.updatePentest();
|
||||
}
|
||||
|
||||
onClickUpdatePentest(): void {
|
||||
this.pentest$.next({...this.pentest$.getValue(), status: this.currentStatus});
|
||||
private updatePentest(): void {
|
||||
this.pentestService.updatePentest(transformPentestToRequestBody(this.pentest$.getValue()))
|
||||
.subscribe({
|
||||
next: (pentest: Pentest) => {
|
||||
this.store.dispatch(new ChangePentest(pentest));
|
||||
this.initialTimeSpent = pentest.timeSpent;
|
||||
this.notificationService.showPopup('pentest.popup.update.success', PopupType.SUCCESS);
|
||||
},
|
||||
error: err => {
|
||||
|
@ -121,7 +120,7 @@ export class PentestHeaderComponent implements OnInit {
|
|||
* @return true if initial pentest Status is different from current pentest status
|
||||
*/
|
||||
pentestStatusChanged(): boolean {
|
||||
if (this.initialPentestStatus !== this.currentStatus) {
|
||||
if (this.initialTimeSpent !== this.currentTimeSpent && this.currentTimeSpent !== 0) {
|
||||
this.pentestChanged$.next(true);
|
||||
} else {
|
||||
this.pentestChanged$.next(false);
|
||||
|
@ -129,6 +128,15 @@ export class PentestHeaderComponent implements OnInit {
|
|||
return this.pentestChanged$.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if pentest includes at least one finding or comment
|
||||
*/
|
||||
pentestHasFindingsOrComments(): boolean {
|
||||
const pentest: Pentest = this.pentest$.getValue();
|
||||
// Check if pentest includes any findings or comments
|
||||
return pentest?.findingIds?.length > 0 || pentest?.commentIds?.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the correct nb-status for current pentest-status
|
||||
*/
|
||||
|
@ -139,7 +147,7 @@ export class PentestHeaderComponent implements OnInit {
|
|||
pentestFillStatus = 'basic';
|
||||
break;
|
||||
}
|
||||
case PentestStatus.OPEN: {
|
||||
case PentestStatus.PAUSED: {
|
||||
pentestFillStatus = 'info';
|
||||
break;
|
||||
}
|
||||
|
@ -158,4 +166,12 @@ export class PentestHeaderComponent implements OnInit {
|
|||
}
|
||||
return pentestFillStatus;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.pentestStatusChanged()) {
|
||||
// Save current Pentest before exiting
|
||||
this.pentest$.next({...this.pentest$.getValue(), status: PentestStatus.PAUSED, timeSpent: this.currentTimeSpent});
|
||||
this.updatePentest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import {SeverityTagModule} from '@shared/widgets/severity-tag/severity-tag.modul
|
|||
import {FindingDialogModule} from '@shared/modules/finding-dialog/finding-dialog.module';
|
||||
import {CommentDialogModule} from '@shared/modules/comment-dialog/comment-dialog.module';
|
||||
import {FindigWidgetModule} from '@shared/widgets/findig-widget/findig-widget.module';
|
||||
import {TimerModule} from '@shared/modules/timer/timer.module';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -49,6 +50,8 @@ import {FindigWidgetModule} from '@shared/widgets/findig-widget/findig-widget.mo
|
|||
FindingDialogModule,
|
||||
CommentDialogModule,
|
||||
FindigWidgetModule,
|
||||
// Modules
|
||||
TimerModule,
|
||||
]
|
||||
})
|
||||
export class PentestModule {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"action.download": "Herunterladen",
|
||||
"action.report": "Bericht",
|
||||
"action.reset": "Zurücksetzen",
|
||||
"action.complete": "Fertig",
|
||||
"action.yes": "Ja",
|
||||
"action.no": "Nein",
|
||||
"username": "Nutzername",
|
||||
|
@ -222,11 +223,14 @@
|
|||
"not_started": "Nicht angefangen",
|
||||
"disabled": "Deaktiviert",
|
||||
"open": "Offen",
|
||||
"paused": "Pausiert",
|
||||
"in_progress": "In Bearbeitung",
|
||||
"completed": "Fertig"
|
||||
},
|
||||
"popup": {
|
||||
"not.found": "Keine pentests gefunden",
|
||||
"initial.save.success": "Initialer Pentest erfolgreich aufgesetzt",
|
||||
"initial.save.failed": "Initialer Pentest konnte nicht aufgesetzt werden",
|
||||
"save.success": "Pentest erfolgreich gespeichert",
|
||||
"save.failed": "Pentest konnte nicht gespeichert werden",
|
||||
"update.success": "Pentest erfolgreich aktualisiert",
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"action.download": "Download",
|
||||
"action.report": "Report",
|
||||
"action.reset": "Reset",
|
||||
"action.complete": "Complete",
|
||||
"action.yes": "Yes",
|
||||
"action.no": "No",
|
||||
"username": "Username",
|
||||
|
@ -222,11 +223,14 @@
|
|||
"not_started": "Not Started",
|
||||
"disabled": "Disabled",
|
||||
"open": "Open",
|
||||
"paused": "Paused",
|
||||
"in_progress": "In progress",
|
||||
"completed": "Completed"
|
||||
},
|
||||
"popup": {
|
||||
"not.found": "No pentest found",
|
||||
"initial.save.success": "Initial Pentest successfully setup",
|
||||
"initial.save.failed": "Initial Pentest could not be setup",
|
||||
"save.success": "Pentest saved successfully",
|
||||
"save.failed": "Pentest could not be saved",
|
||||
"update.success": "Pentest updated successfully",
|
||||
|
|
|
@ -4,16 +4,17 @@ export class Comment {
|
|||
id?: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
relatedFindings?: Array<string>;
|
||||
// List of attachment id's for file upload
|
||||
attachments?: Array<string>;
|
||||
|
||||
constructor(title: string,
|
||||
description: string,
|
||||
id?: string,
|
||||
relatedFindings?: Array<string>) {
|
||||
attachments?: Array<string>) {
|
||||
this.id = id ? id : UUID();
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.relatedFindings = relatedFindings;
|
||||
this.attachments = attachments;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +22,7 @@ export interface CommentEntry {
|
|||
commentId: string;
|
||||
title: string;
|
||||
description: string;
|
||||
relatedFindings: Array<string>;
|
||||
attachments: Array<string>;
|
||||
kind?: string;
|
||||
childEntries?: [];
|
||||
expanded?: boolean;
|
||||
|
@ -34,7 +35,7 @@ export function transformCommentsToObjectiveEntries(findings: Comment[]): Commen
|
|||
commentId: value.id,
|
||||
title: value.title,
|
||||
description: value.description,
|
||||
relatedFindings: value.relatedFindings,
|
||||
attachments: value.attachments,
|
||||
kind: 'cell',
|
||||
childEntries: null,
|
||||
expanded: false
|
||||
|
@ -48,8 +49,7 @@ export function transformCommentToRequestBody(comment: CommentDialogBody | Comme
|
|||
...comment,
|
||||
title: comment.title,
|
||||
description: comment.description,
|
||||
// Transforms related findings from RelatedFindingOption to list of finding ids
|
||||
relatedFindings: comment.relatedFindings ? comment.relatedFindings.map(finding => finding.id) : [],
|
||||
attachments: comment.attachments,
|
||||
/* Remove Table Entry Object Properties */
|
||||
childEntries: undefined,
|
||||
kind: undefined,
|
||||
|
@ -62,10 +62,6 @@ export function transformCommentToRequestBody(comment: CommentDialogBody | Comme
|
|||
export interface CommentDialogBody {
|
||||
title: string;
|
||||
description: string;
|
||||
relatedFindings: Array<RelatedFindingOption>;
|
||||
attachments: Array<string>;
|
||||
}
|
||||
|
||||
export interface RelatedFindingOption {
|
||||
id: string;
|
||||
title: string;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ export class Finding {
|
|||
affectedUrls?: Array<string>;
|
||||
reproduction: string;
|
||||
mitigation?: string;
|
||||
// List of attachment id's for file upload
|
||||
attachments?: Array<string>;
|
||||
|
||||
constructor(title: string,
|
||||
severity: Severity,
|
||||
|
@ -18,7 +20,8 @@ export class Finding {
|
|||
reproduction: string,
|
||||
id?: string,
|
||||
affectedUrls?: Array<string>,
|
||||
mitigation?: string) {
|
||||
mitigation?: string,
|
||||
attachments?: Array<string>) {
|
||||
this.id = id ? id : UUID();
|
||||
this.severity = severity;
|
||||
this.title = title;
|
||||
|
@ -27,13 +30,15 @@ export class Finding {
|
|||
this.affectedUrls = affectedUrls ? affectedUrls : null;
|
||||
this.reproduction = reproduction;
|
||||
this.mitigation = mitigation ? mitigation : null;
|
||||
this.attachments = attachments ? attachments : null;
|
||||
}
|
||||
}
|
||||
|
||||
export interface FindingEntry {
|
||||
findingId: string;
|
||||
severity: Severity;
|
||||
title: string;
|
||||
severity: Severity;
|
||||
description: string;
|
||||
impact: string;
|
||||
kind?: string;
|
||||
childEntries?: [];
|
||||
|
@ -45,8 +50,9 @@ export function transformFindingsToObjectiveEntries(findings: Finding[]): Findin
|
|||
findings.forEach((value: Finding) => {
|
||||
findingEntries.push({
|
||||
findingId: value.id,
|
||||
severity: typeof value.severity !== 'number' ? Severity[value.severity] : value.severity,
|
||||
title: value.title,
|
||||
severity: typeof value.severity !== 'number' ? Severity[value.severity] : value.severity,
|
||||
description: value.description,
|
||||
impact: value.impact,
|
||||
kind: 'cell',
|
||||
childEntries: null,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export enum PentestStatus {
|
||||
NOT_STARTED = 'NOT_STARTED',
|
||||
DISABLED = 'DISABLED',
|
||||
OPEN = 'OPEN',
|
||||
PAUSED = 'PAUSED',
|
||||
IN_PROGRESS = 'IN_PROGRESS',
|
||||
COMPLETED = 'COMPLETED',
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ export class Pentest {
|
|||
status: PentestStatus;
|
||||
findingIds?: Array<string>;
|
||||
commentIds?: Array<string>;
|
||||
timeSpent?: number;
|
||||
|
||||
constructor(category: Category,
|
||||
refNumber: string,
|
||||
|
@ -18,7 +19,8 @@ export class Pentest {
|
|||
id?: string,
|
||||
projectId?: string,
|
||||
findingsIds?: Array<string>,
|
||||
commentsIds?: Array<string>) {
|
||||
commentsIds?: Array<string>,
|
||||
timeSpent?: number) {
|
||||
this.id = id ? id : UUID();
|
||||
this.projectId = projectId ? projectId : '';
|
||||
this.category = category;
|
||||
|
@ -26,6 +28,7 @@ export class Pentest {
|
|||
this.status = status;
|
||||
this.findingIds = findingsIds ? findingsIds : [];
|
||||
this.commentIds = commentsIds ? commentsIds : [];
|
||||
this.timeSpent = timeSpent ? timeSpent : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,25 +50,6 @@
|
|||
</nb-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Related Findings Layout -->
|
||||
<!-- Related Findings Form Field -->
|
||||
<nb-form-field class="comment-form-field">
|
||||
<label for="{{formArray[2].fieldName}}" class="label">
|
||||
{{formArray[2].labelKey | translate}}
|
||||
</label>
|
||||
<!--<fa-icon nbPrefix [icon]="fa.faExclamationCircle" size="lg" class="finding-icon"></fa-icon>-->
|
||||
<nb-select placeholder="{{formArray[2].placeholder | translate}}"
|
||||
id="{{formArray[2].fieldName}}"
|
||||
formControlName="{{formArray[2].fieldName}}"
|
||||
(selectedChange)="changeSelected($event)"
|
||||
multiple fullWidth shape="semi-round" filled status="info"
|
||||
[size]="'large'" class="form-field relatedFindings">
|
||||
<nb-option class="reset-option">{{'global.action.reset' | translate}}</nb-option>
|
||||
<nb-option class="finding-option" *ngFor="let finding of relatedFindings" [value]="finding">
|
||||
{{finding.title}}
|
||||
</nb-option>
|
||||
</nb-select>
|
||||
</nb-form-field>
|
||||
</form>
|
||||
</nb-card-body>
|
||||
<nb-card-footer fxLayout="row" fxLayoutGap="1.5rem" fxLayoutAlign="end end">
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
|
||||
.form-textarea {
|
||||
width: 42rem !important;
|
||||
height: 8rem;
|
||||
// Change back to 16rem after attachments can be uploaded
|
||||
height: 24rem;
|
||||
}
|
||||
|
||||
.comment-form-field {
|
||||
|
|
|
@ -5,7 +5,6 @@ import * as FA from '@fortawesome/free-solid-svg-icons';
|
|||
import deepEqual from 'deep-equal';
|
||||
import {NB_DIALOG_CONFIG, NbDialogRef} from '@nebular/theme';
|
||||
import {UntilDestroy} from '@ngneat/until-destroy';
|
||||
import {RelatedFindingOption} from '@shared/models/comment.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-comment-dialog',
|
||||
|
@ -24,11 +23,6 @@ export class CommentDialogComponent implements OnInit {
|
|||
// HTML only
|
||||
readonly fa = FA;
|
||||
|
||||
relatedFindings: RelatedFindingOption[] = [];
|
||||
// Includes the findings that got selected as an option
|
||||
selectedFindings: RelatedFindingOption[] = [];
|
||||
initialSelectedFindings: RelatedFindingOption[] = [];
|
||||
|
||||
constructor(
|
||||
@Inject(NB_DIALOG_CONFIG) private data: GenericDialogData,
|
||||
private fb: FormBuilder,
|
||||
|
@ -38,7 +32,6 @@ export class CommentDialogComponent implements OnInit {
|
|||
|
||||
ngOnInit(): void {
|
||||
this.dialogData = this.data;
|
||||
this.relatedFindings = this.dialogData.options[0].additionalData;
|
||||
this.commentFormGroup = this.generateFormCreationFieldArray();
|
||||
}
|
||||
|
||||
|
@ -48,29 +41,19 @@ export class CommentDialogComponent implements OnInit {
|
|||
...accumulator,
|
||||
[currentValue?.fieldName]: currentValue?.controlsConfig
|
||||
}), {});
|
||||
// tslint:disable-next-line:no-string-literal
|
||||
const preSelectedRelatedFindings = this.data.form['commentRelatedFindings'].controlsConfig[0].value;
|
||||
if (preSelectedRelatedFindings && preSelectedRelatedFindings.length > 0) {
|
||||
this.relatedFindings.forEach(finding => {
|
||||
if (preSelectedRelatedFindings.includes(finding)) {
|
||||
this.initialSelectedFindings.push(finding);
|
||||
this.selectedFindings.push(finding);
|
||||
}
|
||||
});
|
||||
}
|
||||
return this.fb.group(config);
|
||||
}
|
||||
|
||||
changeSelected($event): void {
|
||||
changeAttachments($event): void {
|
||||
// tslint:disable-next-line:no-string-literal
|
||||
this.selectedFindings = this.commentFormGroup.controls['commentRelatedFindings'].value;
|
||||
// this.commentFormGroup.controls['commentAttachments'].value;
|
||||
}
|
||||
|
||||
onClickSave(value: any): void {
|
||||
this.dialogRef.close({
|
||||
title: value.commentTitle,
|
||||
description: value.commentDescription,
|
||||
relatedFindings: this.selectedFindings ? this.selectedFindings : []
|
||||
// relatedFindings: this.selectedFindings ? this.selectedFindings : []
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -90,12 +73,8 @@ export class CommentDialogComponent implements OnInit {
|
|||
const newCommentData = this.commentFormGroup.getRawValue();
|
||||
Object.entries(newCommentData).forEach(entry => {
|
||||
const [key, value] = entry;
|
||||
// Related Findings form field can be ignored since changes here will be recognised inside commentRelatedFindings of tag-list
|
||||
if (value === null || key === 'commentRelatedFindings') {
|
||||
newCommentData[key] = '';
|
||||
}
|
||||
});
|
||||
const didChange = !deepEqual(oldCommentData, newCommentData) || !deepEqual(this.initialSelectedFindings, this.selectedFindings);
|
||||
const didChange = !deepEqual(oldCommentData, newCommentData);
|
||||
return didChange;
|
||||
}
|
||||
|
||||
|
@ -109,10 +88,6 @@ export class CommentDialogComponent implements OnInit {
|
|||
const [key, value] = entry;
|
||||
commentData[key] = value.controlsConfig[0] ?
|
||||
(value.controlsConfig[0].value ? value.controlsConfig[0].value : value.controlsConfig[0]) : '';
|
||||
// Related Findings form field can be ignored since changes here will be recognised inside commentRelatedFindings of tag-list
|
||||
if (key === 'commentRelatedFindings') {
|
||||
commentData[key] = '';
|
||||
}
|
||||
});
|
||||
return commentData;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import {ComponentType} from '@angular/cdk/overlay';
|
|||
import {Observable} from 'rxjs';
|
||||
import {Validators} from '@angular/forms';
|
||||
import {CommentDialogComponent} from '@shared/modules/comment-dialog/comment-dialog.component';
|
||||
import {Comment, RelatedFindingOption} from '@shared/models/comment.model';
|
||||
import {Comment} from '@shared/models/comment.model';
|
||||
|
||||
@Injectable()
|
||||
export class CommentDialogService {
|
||||
|
@ -30,18 +30,15 @@ export class CommentDialogService {
|
|||
|
||||
public openCommentDialog(componentOrTemplateRef: ComponentType<any>,
|
||||
findingIds: string[],
|
||||
relatedFindings: RelatedFindingOption[],
|
||||
comment?: Comment,
|
||||
config?: Partial<NbDialogConfig<Partial<any> | string>>): Observable<any> {
|
||||
let dialogOptions: Partial<NbDialogConfig<Partial<any> | string>>;
|
||||
let dialogData: GenericDialogData;
|
||||
// Preselect related findings
|
||||
const selectedRelatedFindings: RelatedFindingOption[] = [];
|
||||
if (comment && comment.relatedFindings.length > 0 && relatedFindings) {
|
||||
relatedFindings.forEach(finding => {
|
||||
if (comment.relatedFindings.includes(finding.id)) {
|
||||
selectedRelatedFindings.push(finding);
|
||||
}
|
||||
// Preselect attachments
|
||||
const attachments: string[] = [];
|
||||
if (comment && comment.attachments.length > 0) {
|
||||
comment.attachments.forEach(attachment => {
|
||||
// Load attachment to show
|
||||
});
|
||||
}
|
||||
// Setup CommentDialogBody
|
||||
|
@ -72,22 +69,6 @@ export class CommentDialogService {
|
|||
errors: [
|
||||
{errorCode: 'required', translationKey: 'comment.validationMessage.descriptionRequired'}
|
||||
]
|
||||
},
|
||||
commentRelatedFindings: {
|
||||
fieldName: 'commentRelatedFindings',
|
||||
type: 'text',
|
||||
labelKey: 'comment.relatedFindings.label',
|
||||
placeholder: findingIds.length === 0 ? 'comment.noFindingsInObjectivePlaceholder' : 'comment.relatedFindingsPlaceholder',
|
||||
controlsConfig: [
|
||||
{
|
||||
value: comment ? selectedRelatedFindings : [],
|
||||
disabled: findingIds.length === 0
|
||||
},
|
||||
[]
|
||||
],
|
||||
errors: [
|
||||
{errorCode: 'required', translationKey: 'finding.validationMessage.relatedFindings'}
|
||||
]
|
||||
}
|
||||
},
|
||||
options: []
|
||||
|
@ -97,8 +78,7 @@ export class CommentDialogService {
|
|||
{
|
||||
headerLabelKey: 'comment.edit.header',
|
||||
buttonKey: 'global.action.update',
|
||||
accentColor: 'warning',
|
||||
additionalData: relatedFindings
|
||||
accentColor: 'warning'
|
||||
},
|
||||
];
|
||||
} else {
|
||||
|
@ -106,8 +86,7 @@ export class CommentDialogService {
|
|||
{
|
||||
headerLabelKey: 'comment.create.header',
|
||||
buttonKey: 'global.action.save',
|
||||
accentColor: 'info',
|
||||
additionalData: relatedFindings
|
||||
accentColor: 'info'
|
||||
},
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {ExportReportDialogComponent} from './export-report-dialog.component';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {
|
||||
NB_DIALOG_CONFIG,
|
||||
NbButtonModule,
|
||||
|
@ -9,11 +8,10 @@ import {
|
|||
NbDialogRef,
|
||||
NbFormFieldModule,
|
||||
NbInputModule,
|
||||
NbLayoutModule, NbRadioModule,
|
||||
NbTagModule
|
||||
NbRadioModule
|
||||
} from '@nebular/theme';
|
||||
import {FlexLayoutModule} from '@angular/flex-layout';
|
||||
import {NG_VALUE_ACCESSOR, ReactiveFormsModule} from '@angular/forms';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {ThemeModule} from '@assets/@theme/theme.module';
|
||||
import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
|
||||
|
@ -29,7 +27,6 @@ import {createSpyObj} from '@shared/modules/finding-dialog/finding-dialog.compon
|
|||
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 {forwardRef} from '@angular/core';
|
||||
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
|
||||
|
||||
describe('ExportReportDialogComponent', () => {
|
||||
|
|
|
@ -41,7 +41,7 @@ export class ObjectiveChartComponent implements OnInit {
|
|||
readonly pentestStatusLabels: Array<string> = [
|
||||
'pentest.statusText.disabled',
|
||||
'pentest.statusText.not_started',
|
||||
'pentest.statusText.open',
|
||||
'pentest.statusText.paused',
|
||||
'pentest.statusText.in_progress',
|
||||
'pentest.statusText.completed'
|
||||
];
|
||||
|
@ -58,7 +58,7 @@ export class ObjectiveChartComponent implements OnInit {
|
|||
const disabledPentests: ProjectPentests[]
|
||||
= this.projectPentestData.filter(projectPentest => projectPentest.status === PentestStatus.DISABLED);
|
||||
const openPentests: ProjectPentests[]
|
||||
= this.projectPentestData.filter(projectPentest => projectPentest.status === PentestStatus.OPEN);
|
||||
= this.projectPentestData.filter(projectPentest => projectPentest.status === PentestStatus.PAUSED);
|
||||
const inProgressPentests: ProjectPentests[]
|
||||
= this.projectPentestData.filter(projectPentest => projectPentest.status === PentestStatus.IN_PROGRESS);
|
||||
const completedPentests: ProjectPentests[]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
.project-dialog {
|
||||
width: 34rem !important;
|
||||
height: 42.5rem;
|
||||
height: 43.5rem;
|
||||
|
||||
.project-dialog-header {
|
||||
height: 8vh;
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TimerService } from './timer.service';
|
||||
|
||||
describe('TimerService', () => {
|
||||
let service: TimerService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(TimerService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class TimerService {
|
||||
|
||||
constructor() { }
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<div class="timer-module" fxLayout="row" fxLayoutGap="0.5rem" fxLayoutAlign="end center">
|
||||
<div class="time">
|
||||
<fa-icon [icon]="fa.faStopwatch" class="stopwatch-icon fa-xl"></fa-icon>
|
||||
<span>{{ timer | timerDuration }}</span>
|
||||
</div>
|
||||
<!-- status="{{getStopwatchButtonStatus()}}" -->
|
||||
<button nbButton outline
|
||||
shape="semi-round"
|
||||
status="{{timerRunning$.getValue() === true ? 'warning' : 'info'}}"
|
||||
class="stopwatch-player-button"
|
||||
(click)="onClickTriggerTimer()">
|
||||
<fa-icon *ngIf="timerRunning$.getValue(), else changeTimerIcon" [icon]="fa.faPause"
|
||||
class="new-element-icon"></fa-icon>
|
||||
<ng-template #changeTimerIcon>
|
||||
<fa-icon [icon]="fa.faPlay" class="stopwatch-player-icon"></fa-icon>
|
||||
</ng-template>
|
||||
</button>
|
||||
</div>
|
|
@ -0,0 +1,28 @@
|
|||
@import '../../../assets/@theme/styles/themes';
|
||||
|
||||
.timer-module {
|
||||
width: 12rem;
|
||||
max-width: 12rem;
|
||||
|
||||
// height: 3rem;
|
||||
// max-height: 3rem;
|
||||
|
||||
// overflow: auto;
|
||||
|
||||
background-color: nb-theme(color-basic-transparent-focus);
|
||||
border-radius: 10px;
|
||||
|
||||
|
||||
.time {
|
||||
//font-family: Courier, serif;
|
||||
|
||||
.stopwatch-icon {
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.stopwatch-player-button {
|
||||
margin-left: 1rem;
|
||||
width: 3.25rem !important;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
|
||||
import {TimerComponent} from './timer.component';
|
||||
import {MockPipe} from 'ng-mocks';
|
||||
import {TimerDurationPipe} from '@shared/pipes/timer-duration.pipe';
|
||||
import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
|
||||
import {HttpLoaderFactory} from '../../../app/common-app.module';
|
||||
import {HttpClient, HttpClientModule} from '@angular/common/http';
|
||||
import {HttpClientTestingModule} from '@angular/common/http/testing';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {NotificationService} from '@shared/services/toaster-service/notification.service';
|
||||
import {NotificationServiceMock} from '@shared/services/toaster-service/notification.service.mock';
|
||||
import {NgxsModule} from '@ngxs/store';
|
||||
|
||||
describe('TimerComponent', () => {
|
||||
let component: TimerComponent;
|
||||
let fixture: ComponentFixture<TimerComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
TimerComponent,
|
||||
MockPipe(TimerDurationPipe)
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: HttpLoaderFactory,
|
||||
deps: [HttpClient]
|
||||
}
|
||||
}),
|
||||
NgxsModule.forRoot([]),
|
||||
HttpClientModule,
|
||||
HttpClientTestingModule
|
||||
],
|
||||
providers: [
|
||||
{provide: NotificationService, useValue: new NotificationServiceMock()}
|
||||
]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TimerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,142 @@
|
|||
import {ChangeDetectionStrategy, Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import * as FA from '@fortawesome/free-solid-svg-icons';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {PentestStatus} from '@shared/models/pentest-status.model';
|
||||
import {Store} from '@ngxs/store';
|
||||
import {ProjectState} from '@shared/stores/project-state/project-state';
|
||||
import {UntilDestroy, untilDestroyed} from '@ngneat/until-destroy';
|
||||
import {Pentest, transformPentestToRequestBody} from '@shared/models/pentest.model';
|
||||
import {ChangePentest, UpdatePentestStatus, UpdatePentestTime} from '@shared/stores/project-state/project-state.actions';
|
||||
import {NotificationService, PopupType} from '@shared/services/toaster-service/notification.service';
|
||||
import {PentestService} from '@shared/services/api/pentest.service';
|
||||
import {Project} from '@shared/models/project.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-timer',
|
||||
templateUrl: './timer.component.html',
|
||||
styleUrls: ['./timer.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.Default
|
||||
})
|
||||
@UntilDestroy()
|
||||
export class TimerComponent implements OnInit, OnDestroy {
|
||||
|
||||
readonly fa = FA;
|
||||
|
||||
timer = 0;
|
||||
interval;
|
||||
|
||||
pentestInfo$: BehaviorSubject<Pentest> = new BehaviorSubject<Pentest>(null);
|
||||
timerRunning$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||
// Needed for initial pentest creation
|
||||
selectedProjectId$: BehaviorSubject<string> = new BehaviorSubject<string>('');
|
||||
|
||||
constructor(private pentestService: PentestService,
|
||||
private notificationService: NotificationService,
|
||||
private readonly store: Store) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.store.selectOnce(ProjectState.project).pipe(
|
||||
untilDestroyed(this)
|
||||
).subscribe({
|
||||
next: (selectedProject: Project) => {
|
||||
this.selectedProjectId$.next(selectedProject.id);
|
||||
},
|
||||
error: err => {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
|
||||
this.store.selectOnce(ProjectState.pentest).pipe(
|
||||
untilDestroyed(this)
|
||||
).subscribe({
|
||||
next: (selectedPentest: Pentest) => {
|
||||
this.pentestInfo$.next(selectedPentest);
|
||||
// In case pentest time spent is undefined use 0
|
||||
this.timer = selectedPentest.timeSpent ? selectedPentest.timeSpent : 0;
|
||||
if (!selectedPentest.id) {
|
||||
this.createIntialPentestInBackend();
|
||||
}
|
||||
},
|
||||
error: err => {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private createIntialPentestInBackend(): void {
|
||||
// Save initial Pentest a new
|
||||
this.pentestInfo$.next({...this.pentestInfo$.getValue(), timeSpent: this.timer});
|
||||
this.pentestService.savePentest(this.selectedProjectId$.getValue(), transformPentestToRequestBody(this.pentestInfo$.getValue()))
|
||||
.subscribe({
|
||||
next: (pentest: Pentest) => {
|
||||
this.store.dispatch(new ChangePentest(pentest));
|
||||
this.notificationService.showPopup('pentest.popup.initial.save.success', PopupType.SUCCESS);
|
||||
},
|
||||
error: err => {
|
||||
console.log(err);
|
||||
this.notificationService.showPopup('pentest.popup.initial.save.failed', PopupType.FAILURE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onClickTriggerTimer(): void {
|
||||
this.timerRunning$.next(!this.timerRunning$.getValue());
|
||||
// Start or pause timer
|
||||
if (this.timerRunning$.getValue()) {
|
||||
this.startTimer();
|
||||
} else {
|
||||
this.pauseTimer();
|
||||
}
|
||||
}
|
||||
|
||||
// TIMER related functions below
|
||||
private startTimer(): boolean {
|
||||
this.interval = setInterval(() => this.timer++, 1000);
|
||||
this.store.dispatch(new UpdatePentestStatus(PentestStatus.IN_PROGRESS));
|
||||
return true;
|
||||
}
|
||||
|
||||
private pauseTimer(): boolean {
|
||||
clearInterval(this.interval);
|
||||
this.store.dispatch(new UpdatePentestTime(this.timer));
|
||||
this.store.dispatch(new UpdatePentestStatus(PentestStatus.PAUSED));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the correct nb-status for current pentest-status
|
||||
*/
|
||||
getStopwatchButtonStatus(): string {
|
||||
const value: PentestStatus = this.pentestInfo$.getValue().status;
|
||||
let stopwatchButtonStatus;
|
||||
switch (value) {
|
||||
case PentestStatus.NOT_STARTED: {
|
||||
stopwatchButtonStatus = 'basic';
|
||||
break;
|
||||
}
|
||||
case PentestStatus.PAUSED: {
|
||||
stopwatchButtonStatus = 'info';
|
||||
break;
|
||||
}
|
||||
case PentestStatus.IN_PROGRESS: {
|
||||
stopwatchButtonStatus = 'warning';
|
||||
break;
|
||||
}
|
||||
case PentestStatus.COMPLETED: {
|
||||
stopwatchButtonStatus = 'success';
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
stopwatchButtonStatus = 'basic';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return stopwatchButtonStatus;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
// Automatically push new time spent to store
|
||||
this.store.dispatch(new UpdatePentestTime(this.timer));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import {TimerComponent} from '@shared/modules/timer/timer.component';
|
||||
import {TimerService} from '@shared/modules/timer/service/timer.service';
|
||||
import {NbButtonModule, NbCardModule} from '@nebular/theme';
|
||||
import {FlexLayoutModule} from '@angular/flex-layout';
|
||||
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
|
||||
import {TimerDurationPipe} from '@shared/pipes/timer-duration.pipe';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
TimerComponent,
|
||||
TimerDurationPipe
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NbCardModule,
|
||||
FlexLayoutModule,
|
||||
FontAwesomeModule,
|
||||
NbButtonModule
|
||||
],
|
||||
providers: [
|
||||
TimerService
|
||||
],
|
||||
exports: [
|
||||
TimerComponent
|
||||
]
|
||||
})
|
||||
export class TimerModule { }
|
|
@ -0,0 +1,8 @@
|
|||
import { TimerDurationPipe } from './timer-duration.pipe';
|
||||
|
||||
describe('TimerDurationPipe', () => {
|
||||
it('create an instance', () => {
|
||||
const pipe = new TimerDurationPipe();
|
||||
expect(pipe).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
import {Pipe, PipeTransform} from '@angular/core';
|
||||
|
||||
@Pipe({
|
||||
name: 'timerDuration',
|
||||
pure: false
|
||||
})
|
||||
export class TimerDurationPipe implements PipeTransform {
|
||||
|
||||
/**
|
||||
* Transforms input time into readable time indication
|
||||
* @param time of type number
|
||||
* @param args The unit to be used for calculation
|
||||
* @returns string in the format `HH:mm:ss`
|
||||
*/
|
||||
transform(time: any, ...args: any[]): string {
|
||||
let hours: string | number = 0;
|
||||
let minutes: string | number = 0;
|
||||
let seconds: string | number = 0;
|
||||
if (time) {
|
||||
// tslint:disable-next-line:variable-name
|
||||
const sec_num = parseInt(time, 10); // don't forget the second param
|
||||
hours = Math.floor(sec_num / 3600);
|
||||
minutes = Math.floor((sec_num - (hours * 3600)) / 60);
|
||||
seconds = sec_num - (hours * 3600) - (minutes * 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the relevant `0` prefix if any of the numbers are less than 10
|
||||
* i.e. 5 -> 05
|
||||
*/
|
||||
seconds = (seconds < 10) ? '0' + seconds : seconds;
|
||||
minutes = (minutes < 10) ? '0' + minutes : minutes;
|
||||
hours = (hours < 10) ? '0' + hours : hours;
|
||||
// Return time in as string in `HH:mm:ss` format
|
||||
return `${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import {Project} from '@shared/models/project.model';
|
||||
import {Category} from '@shared/models/category.model';
|
||||
import {Pentest} from '@shared/models/pentest.model';
|
||||
import {PentestStatus} from '@shared/models/pentest-status.model';
|
||||
|
||||
|
||||
export class InitProjectState {
|
||||
|
@ -34,6 +35,20 @@ export class ChangePentest {
|
|||
}
|
||||
}
|
||||
|
||||
export class UpdatePentestStatus {
|
||||
static readonly type = '[ProjectState] UpdatePentestStatus';
|
||||
|
||||
constructor(public newPentestStatus: PentestStatus) {
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdatePentestTime {
|
||||
static readonly type = '[ProjectState] UpdatePentestTime';
|
||||
|
||||
constructor(public time: number) {
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdatePentestFindings {
|
||||
static readonly type = '[ProjectState] UpdatePentestFindings';
|
||||
|
||||
|
|
|
@ -5,11 +5,14 @@ import {
|
|||
ChangeCategory,
|
||||
ChangePentest,
|
||||
ChangeProject,
|
||||
InitProjectState, UpdatePentestComments,
|
||||
UpdatePentestFindings
|
||||
InitProjectState,
|
||||
UpdatePentestComments,
|
||||
UpdatePentestFindings, UpdatePentestStatus,
|
||||
UpdatePentestTime
|
||||
} from '@shared/stores/project-state/project-state.actions';
|
||||
import {Category} from '@shared/models/category.model';
|
||||
import {Pentest} from '@shared/models/pentest.model';
|
||||
import {PentestStatus} from '@shared/models/pentest-status.model';
|
||||
|
||||
export const PROJECT_STATE_NAME = 'project';
|
||||
|
||||
|
@ -91,6 +94,40 @@ export class ProjectState {
|
|||
});
|
||||
}
|
||||
|
||||
@Action(UpdatePentestStatus)
|
||||
updatePentestStatus(ctx: StateContext<ProjectStateModel>, {newPentestStatus}: UpdatePentestStatus): void {
|
||||
const state = ctx.getState();
|
||||
let stateSelectedPentest: Pentest = state.selectedPentest;
|
||||
// State object
|
||||
const statePentestStatus: PentestStatus = stateSelectedPentest.status || PentestStatus.NOT_STARTED;
|
||||
// overwrites only timeSpent
|
||||
stateSelectedPentest = {
|
||||
...stateSelectedPentest,
|
||||
status: newPentestStatus
|
||||
};
|
||||
// patch project state
|
||||
ctx.patchState({
|
||||
selectedPentest: stateSelectedPentest
|
||||
});
|
||||
}
|
||||
|
||||
@Action(UpdatePentestTime)
|
||||
updatePentestTime(ctx: StateContext<ProjectStateModel>, {time}: UpdatePentestTime): void {
|
||||
const state = ctx.getState();
|
||||
let stateSelectedPentest: Pentest = state.selectedPentest;
|
||||
// State object
|
||||
const statePentestTimeSpent: number = stateSelectedPentest.timeSpent || 0;
|
||||
// overwrites only timeSpent
|
||||
stateSelectedPentest = {
|
||||
...stateSelectedPentest,
|
||||
timeSpent: time
|
||||
};
|
||||
// patch project state
|
||||
ctx.patchState({
|
||||
selectedPentest: stateSelectedPentest
|
||||
});
|
||||
}
|
||||
|
||||
@Action(UpdatePentestFindings)
|
||||
updatePentestFindings(ctx: StateContext<ProjectStateModel>, {findingId}: UpdatePentestFindings): void {
|
||||
const state = ctx.getState();
|
||||
|
@ -109,7 +146,7 @@ export class ProjectState {
|
|||
...stateSelectedPentest,
|
||||
findingIds: updatedFindingIds
|
||||
};
|
||||
// path project state
|
||||
// patch project state
|
||||
ctx.patchState({
|
||||
selectedPentest: stateSelectedPentest
|
||||
});
|
||||
|
@ -133,7 +170,7 @@ export class ProjectState {
|
|||
...stateSelectedPentest,
|
||||
commentIds: updatedCommentIds
|
||||
};
|
||||
// path project state
|
||||
// patch project state
|
||||
ctx.patchState({
|
||||
selectedPentest: stateSelectedPentest
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<ng-container [ngSwitch]="currentStatus">
|
||||
<nb-tag-list>
|
||||
<nb-tag *ngSwitchCase="status.OPEN" status="info" appearance="filled"
|
||||
<nb-tag *ngSwitchCase="status.PAUSED" status="info" appearance="filled"
|
||||
text="{{getTranslationKey() | translate}}"></nb-tag>
|
||||
<nb-tag *ngSwitchCase="status.IN_PROGRESS" status="warning" appearance="filled"
|
||||
text=" {{getTranslationKey() | translate}}"></nb-tag>
|
||||
|
|
|
@ -14,7 +14,7 @@ export class StatusTagComponent implements OnInit {
|
|||
readonly statusTexts: Array<StatusText> = [
|
||||
{value: PentestStatus.NOT_STARTED, translationText: 'pentest.statusText.not_started'},
|
||||
{value: PentestStatus.DISABLED, translationText: 'pentest.statusText.disabled'},
|
||||
{value: PentestStatus.OPEN, translationText: 'pentest.statusText.open'},
|
||||
{value: PentestStatus.PAUSED, translationText: 'pentest.statusText.paused'},
|
||||
{value: PentestStatus.IN_PROGRESS, translationText: 'pentest.statusText.in_progress'},
|
||||
{value: PentestStatus.COMPLETED, translationText: 'pentest.statusText.completed'}
|
||||
];
|
||||
|
|
|
@ -550,7 +550,7 @@
|
|||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"title\": \"Test Comment\",\n \"description\": \"Test Comment Description\",\n \"relatedFindings\": []\n}",
|
||||
"raw": "{\n \"title\": \"Test Comment\",\n \"description\": \"Test Comment Description\"\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
|
@ -700,7 +700,7 @@
|
|||
"header": [],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"title\": \"Test Comment\",\n \"description\": \"Edited Test Comment Description\",\n \"relatedFindings\": []\n}",
|
||||
"raw": "{\n \"title\": \"Test Comment\",\n \"description\": \"Edited Test Comment Description\"\n}",
|
||||
"options": {
|
||||
"raw": {
|
||||
"language": "json"
|
||||
|
|
|
@ -14,7 +14,8 @@ data class Pentest(
|
|||
val refNumber: String,
|
||||
val status: PentestStatus,
|
||||
var findingIds: List<String> = emptyList(),
|
||||
var commentIds: List<String> = emptyList()
|
||||
var commentIds: List<String> = emptyList(),
|
||||
var timeSpent: Int
|
||||
)
|
||||
|
||||
fun buildPentest(body: PentestRequestBody, pentestEntity: PentestEntity): Pentest {
|
||||
|
@ -25,7 +26,8 @@ fun buildPentest(body: PentestRequestBody, pentestEntity: PentestEntity): Pentes
|
|||
refNumber = body.refNumber,
|
||||
status = PentestStatus.valueOf(body.status),
|
||||
findingIds = body.findingIds,
|
||||
commentIds = body.commentIds
|
||||
commentIds = body.commentIds,
|
||||
timeSpent = body.timeSpent
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -49,7 +51,8 @@ fun Pentest.toPentestResponseBody(): ResponseBody {
|
|||
"refNumber" to refNumber,
|
||||
"status" to status,
|
||||
"findingIds" to findingIds,
|
||||
"commentIds" to commentIds
|
||||
"commentIds" to commentIds,
|
||||
"timeSpent" to timeSpent
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -81,7 +84,8 @@ data class PentestRequestBody(
|
|||
val category: String,
|
||||
val status: String,
|
||||
val findingIds: List<String>,
|
||||
val commentIds: List<String>
|
||||
val commentIds: List<String>,
|
||||
val timeSpent: Int
|
||||
)
|
||||
|
||||
/**
|
||||
|
@ -107,6 +111,7 @@ fun PentestRequestBody.toPentest(): Pentest {
|
|||
refNumber = this.refNumber,
|
||||
status = PentestStatus.valueOf(this.status),
|
||||
findingIds = this.findingIds,
|
||||
commentIds = this.commentIds
|
||||
commentIds = this.commentIds,
|
||||
timeSpent = this.timeSpent
|
||||
)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,8 @@ fun PentestEntity.toPentest(): Pentest {
|
|||
this.data.refNumber,
|
||||
this.data.status,
|
||||
this.data.findingIds,
|
||||
this.data.commentIds
|
||||
this.data.commentIds,
|
||||
this.data.timeSpent
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.securityc4po.api.pentest
|
|||
enum class PentestStatus {
|
||||
NOT_STARTED,
|
||||
DISABLED,
|
||||
OPEN,
|
||||
PAUSED,
|
||||
IN_PROGRESS,
|
||||
COMPLETED
|
||||
}
|
|
@ -10,30 +10,28 @@ data class Comment (
|
|||
val id: String = UUID.randomUUID().toString(),
|
||||
val title: String,
|
||||
val description: String,
|
||||
val relatedFindings: List<String>? = emptyList()
|
||||
// List of attachment id's for file upload
|
||||
val attachments: List<String>? = emptyList()
|
||||
)
|
||||
|
||||
fun buildComment(body: CommentRequestBody, commentEntity: CommentEntity): Comment {
|
||||
return Comment(
|
||||
id = commentEntity.data.id,
|
||||
title = body.title,
|
||||
description = body.description,
|
||||
relatedFindings = body.relatedFindings
|
||||
description = body.description
|
||||
)
|
||||
}
|
||||
|
||||
data class CommentRequestBody(
|
||||
val title: String,
|
||||
val description: String,
|
||||
val relatedFindings: List<String>? = emptyList()
|
||||
val description: String
|
||||
)
|
||||
|
||||
fun Comment.toCommentResponseBody(): ResponseBody {
|
||||
return mapOf(
|
||||
"id" to id,
|
||||
"title" to title,
|
||||
"description" to description,
|
||||
"relatedFindings" to relatedFindings
|
||||
"description" to description
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -60,7 +58,6 @@ fun CommentRequestBody.toComment(): Comment {
|
|||
return Comment(
|
||||
id = UUID.randomUUID().toString(),
|
||||
title = this.title,
|
||||
description = this.description,
|
||||
relatedFindings = this.relatedFindings
|
||||
description = this.description
|
||||
)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,6 @@ fun CommentEntity.toComment(): Comment {
|
|||
this.data.id,
|
||||
this.data.title,
|
||||
this.data.description,
|
||||
this.data.relatedFindings
|
||||
this.data.attachments
|
||||
)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ data class Finding (
|
|||
val impact: String,
|
||||
val affectedUrls: List<String>? = emptyList(),
|
||||
val reproduction: String,
|
||||
val mitigation: String?
|
||||
val mitigation: String?,
|
||||
// List of attachment id's for file upload
|
||||
val attachments: List<String>? = emptyList()
|
||||
)
|
||||
|
||||
fun buildFinding(body: FindingRequestBody, findingEntity: FindingEntity): Finding {
|
||||
|
|
|
@ -17,6 +17,7 @@ fun FindingEntity.toFinding(): Finding {
|
|||
this.data.impact,
|
||||
this.data.affectedUrls,
|
||||
this.data.reproduction,
|
||||
this.data.mitigation
|
||||
this.data.mitigation,
|
||||
this.data.attachments
|
||||
)
|
||||
}
|
||||
|
|
|
@ -70,8 +70,10 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
Preprocessors.prettyPrint()
|
||||
),
|
||||
RequestDocumentation.relaxedRequestParameters(
|
||||
RequestDocumentation.parameterWithName("projectId").description("The id of the project you want to get the pentests for"),
|
||||
RequestDocumentation.parameterWithName("category").description("The category you want to get the pentests for")
|
||||
RequestDocumentation.parameterWithName("projectId")
|
||||
.description("The id of the project you want to get the pentests for"),
|
||||
RequestDocumentation.parameterWithName("category")
|
||||
.description("The category you want to get the pentests for")
|
||||
),
|
||||
PayloadDocumentation.relaxedResponseFields(
|
||||
PayloadDocumentation.fieldWithPath("[].id").type(JsonFieldType.STRING)
|
||||
|
@ -87,7 +89,9 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
PayloadDocumentation.fieldWithPath("[].findingIds").type(JsonFieldType.ARRAY)
|
||||
.description("List of ids of the findings in the requested pentest"),
|
||||
PayloadDocumentation.fieldWithPath("[].commentIds").type(JsonFieldType.ARRAY)
|
||||
.description("List of ids of the comments of the requested pentest")
|
||||
.description("List of ids of the comments of the requested pentest"),
|
||||
PayloadDocumentation.fieldWithPath("[].timeSpent").type(JsonFieldType.NUMBER)
|
||||
.description("Time spent on the pentest")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -100,7 +104,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-INFO-001",
|
||||
status = PentestStatus.NOT_STARTED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
private val pentestTwo = Pentest(
|
||||
id = "43fbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -109,7 +114,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-INFO-002",
|
||||
status = PentestStatus.IN_PROGRESS,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
|
||||
private fun getProjectsResponse() = listOf(
|
||||
|
@ -143,7 +149,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
Preprocessors.prettyPrint()
|
||||
),
|
||||
RequestDocumentation.relaxedPathParameters(
|
||||
RequestDocumentation.parameterWithName("projectId").description("The id of the project you want to save the pentest for")
|
||||
RequestDocumentation.parameterWithName("projectId")
|
||||
.description("The id of the project you want to save the pentest for")
|
||||
),
|
||||
PayloadDocumentation.relaxedResponseFields(
|
||||
PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
|
||||
|
@ -159,7 +166,9 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
PayloadDocumentation.fieldWithPath("findingIds").type(JsonFieldType.ARRAY)
|
||||
.description("List of ids of the findings in the created pentest"),
|
||||
PayloadDocumentation.fieldWithPath("commentIds").type(JsonFieldType.ARRAY)
|
||||
.description("List of ids of the comments of the created pentest")
|
||||
.description("List of ids of the comments of the created pentest"),
|
||||
PayloadDocumentation.fieldWithPath("timeSpent").type(JsonFieldType.NUMBER)
|
||||
.description("Time spent on the pentest")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -171,7 +180,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-CLIENT-001",
|
||||
status = "IN_PROGRESS",
|
||||
findingIds = emptyList<String>(),
|
||||
commentIds = emptyList<String>()
|
||||
commentIds = emptyList<String>(),
|
||||
timeSpent = 0
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -200,7 +210,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
Preprocessors.prettyPrint()
|
||||
),
|
||||
RequestDocumentation.relaxedPathParameters(
|
||||
RequestDocumentation.parameterWithName("pentestId").description("The id of the pentest you want to update")
|
||||
RequestDocumentation.parameterWithName("pentestId")
|
||||
.description("The id of the pentest you want to update")
|
||||
),
|
||||
PayloadDocumentation.relaxedResponseFields(
|
||||
PayloadDocumentation.fieldWithPath("id").type(JsonFieldType.STRING)
|
||||
|
@ -216,7 +227,9 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
PayloadDocumentation.fieldWithPath("findingIds").type(JsonFieldType.ARRAY)
|
||||
.description("List of ids of the findings in the updated pentest"),
|
||||
PayloadDocumentation.fieldWithPath("commentIds").type(JsonFieldType.ARRAY)
|
||||
.description("List of ids of the comments of the updated pentest")
|
||||
.description("List of ids of the comments of the updated pentest"),
|
||||
PayloadDocumentation.fieldWithPath("timeSpent").type(JsonFieldType.NUMBER)
|
||||
.description("Time spent on the pentest")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -226,9 +239,10 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
projectId = "d2e126ba-f608-11ec-b939-0242ac120025",
|
||||
category = "INFORMATION_GATHERING",
|
||||
refNumber = "OTG-INFO-001",
|
||||
status = "OPEN",
|
||||
status = "PAUSED",
|
||||
findingIds = emptyList<String>(),
|
||||
commentIds = emptyList<String>()
|
||||
commentIds = emptyList<String>(),
|
||||
timeSpent = 0
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -252,7 +266,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-INFO-001",
|
||||
status = PentestStatus.NOT_STARTED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
val pentestTwo = Pentest(
|
||||
id = "43fbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -261,7 +276,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-INFO-002",
|
||||
status = PentestStatus.IN_PROGRESS,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
val pentestThree = Pentest(
|
||||
id = "74eae112-f62c-11ec-b939-0242ac120002",
|
||||
|
@ -270,7 +286,8 @@ class PentestControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-AUTHN-001",
|
||||
status = PentestStatus.COMPLETED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
// persist test data in database
|
||||
mongoTemplate.save(ProjectEntity(projectOne))
|
||||
|
|
|
@ -77,7 +77,8 @@ class PentestControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-INFO-001",
|
||||
status = PentestStatus.NOT_STARTED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
private val pentestTwo = Pentest(
|
||||
id = "43fbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -86,7 +87,8 @@ class PentestControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-INFO-002",
|
||||
status = PentestStatus.IN_PROGRESS,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
|
||||
private fun getPentests() = listOf(
|
||||
|
@ -122,7 +124,8 @@ class PentestControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-CLIENT-001",
|
||||
status = "IN_PROGRESS",
|
||||
findingIds = emptyList<String>(),
|
||||
commentIds = emptyList<String>()
|
||||
commentIds = emptyList<String>(),
|
||||
timeSpent = 0
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -143,7 +146,7 @@ class PentestControllerIntTest : BaseIntTest() {
|
|||
.jsonPath("$.projectId").isEqualTo("d2e126ba-f608-11ec-b939-0242ac120025")
|
||||
.jsonPath("$.category").isEqualTo("INFORMATION_GATHERING")
|
||||
.jsonPath("$.refNumber").isEqualTo("OTG-INFO-001")
|
||||
.jsonPath("$.status").isEqualTo("OPEN")
|
||||
.jsonPath("$.status").isEqualTo("PAUSED")
|
||||
.jsonPath("$.findingIds").isEmpty
|
||||
.jsonPath("$.commentIds").isEmpty
|
||||
}
|
||||
|
@ -152,9 +155,10 @@ class PentestControllerIntTest : BaseIntTest() {
|
|||
projectId = "d2e126ba-f608-11ec-b939-0242ac120025",
|
||||
category = "INFORMATION_GATHERING",
|
||||
refNumber = "OTG-INFO-001",
|
||||
status = "OPEN",
|
||||
status = "PAUSED",
|
||||
findingIds = emptyList<String>(),
|
||||
commentIds = emptyList<String>()
|
||||
commentIds = emptyList<String>(),
|
||||
timeSpent = 24
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -177,7 +181,8 @@ class PentestControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-INFO-001",
|
||||
status = PentestStatus.NOT_STARTED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
val pentestTwo = Pentest(
|
||||
id = "43fbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -186,7 +191,8 @@ class PentestControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-INFO-002",
|
||||
status = PentestStatus.IN_PROGRESS,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
val pentestThree = Pentest(
|
||||
id = "16vbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -195,7 +201,8 @@ class PentestControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-AUTHN-001",
|
||||
status = PentestStatus.COMPLETED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
// persist test data in database
|
||||
mongoTemplate.save(ProjectEntity(projectOne))
|
||||
|
|
|
@ -302,7 +302,8 @@ class CommentControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-INFO-001",
|
||||
status = PentestStatus.NOT_STARTED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
val pentestTwo = Pentest(
|
||||
id = "43fbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -311,7 +312,8 @@ class CommentControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-INFO-002",
|
||||
status = PentestStatus.IN_PROGRESS,
|
||||
findingIds = emptyList(),
|
||||
commentIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f")
|
||||
commentIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
|
||||
timeSpent = 56
|
||||
)
|
||||
val pentestThree = Pentest(
|
||||
id = "74eae112-f62c-11ec-b939-0242ac120002",
|
||||
|
@ -320,7 +322,8 @@ class CommentControllerDocumentationTest : BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-AUTHN-001",
|
||||
status = PentestStatus.COMPLETED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 124
|
||||
)
|
||||
// Comment
|
||||
val commentOne = Comment(
|
||||
|
|
|
@ -193,7 +193,8 @@ class CommentControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-INFO-001",
|
||||
status = PentestStatus.NOT_STARTED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
val pentestTwo = Pentest(
|
||||
id = "43fbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -202,7 +203,8 @@ class CommentControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-INFO-002",
|
||||
status = PentestStatus.IN_PROGRESS,
|
||||
findingIds = emptyList(),
|
||||
commentIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f")
|
||||
commentIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
|
||||
timeSpent = 56
|
||||
)
|
||||
val pentestThree = Pentest(
|
||||
id = "16vbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -211,7 +213,8 @@ class CommentControllerIntTest : BaseIntTest() {
|
|||
refNumber = "OTG-AUTHN-001",
|
||||
status = PentestStatus.COMPLETED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 124
|
||||
)
|
||||
// Comment
|
||||
val commentOne = Comment(
|
||||
|
|
|
@ -350,7 +350,8 @@ class FindingControllerDocumentationTest: BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-INFO-001",
|
||||
status = PentestStatus.NOT_STARTED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
val pentestTwo = Pentest(
|
||||
id = "43fbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -359,7 +360,8 @@ class FindingControllerDocumentationTest: BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-INFO-002",
|
||||
status = PentestStatus.IN_PROGRESS,
|
||||
findingIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 56
|
||||
)
|
||||
val pentestThree = Pentest(
|
||||
id = "74eae112-f62c-11ec-b939-0242ac120002",
|
||||
|
@ -368,7 +370,8 @@ class FindingControllerDocumentationTest: BaseDocumentationIntTest() {
|
|||
refNumber = "OTG-AUTHN-001",
|
||||
status = PentestStatus.COMPLETED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 124
|
||||
)
|
||||
// Finding
|
||||
val findingOne = Finding(
|
||||
|
|
|
@ -217,7 +217,8 @@ class FindingControllerIntTest: BaseIntTest() {
|
|||
refNumber = "OTG-INFO-001",
|
||||
status = PentestStatus.NOT_STARTED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 0
|
||||
)
|
||||
val pentestTwo = Pentest(
|
||||
id = "43fbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -226,7 +227,8 @@ class FindingControllerIntTest: BaseIntTest() {
|
|||
refNumber = "OTG-INFO-002",
|
||||
status = PentestStatus.IN_PROGRESS,
|
||||
findingIds = listOf("ab62d365-1b1d-4da1-89bc-5496616e220f"),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 56
|
||||
)
|
||||
val pentestThree = Pentest(
|
||||
id = "16vbc63c-f624-11ec-b939-0242ac120002",
|
||||
|
@ -235,7 +237,8 @@ class FindingControllerIntTest: BaseIntTest() {
|
|||
refNumber = "OTG-AUTHN-001",
|
||||
status = PentestStatus.COMPLETED,
|
||||
findingIds = emptyList(),
|
||||
commentIds = emptyList()
|
||||
commentIds = emptyList(),
|
||||
timeSpent = 124
|
||||
)
|
||||
// Finding
|
||||
val findingOne = Finding(
|
||||
|
|
|
@ -1,54 +1,33 @@
|
|||
[{
|
||||
"_id": {
|
||||
"$oid": "63a4530b9bb2aa2c3bc77b52"
|
||||
"$oid": "6405dbf113ae975803a09901"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1671713547508"
|
||||
"$numberLong": "1678105585081"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "89703b19-16c7-49e5-8e33-0c706313e5fe",
|
||||
"title": "Test Comment",
|
||||
"description": "No related findings",
|
||||
"relatedFindings": []
|
||||
"_id": "85935303-e5b7-48ca-a504-910c1a94fb1f",
|
||||
"title": "Uninteresting comment",
|
||||
"description": "Nothing",
|
||||
"attachments": []
|
||||
},
|
||||
"_class": "com.securityc4po.api.comment.CommentEntity"
|
||||
"_class": "com.securityc4po.api.pentest.comment.CommentEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "63a453e4377c3f53f86d27d8"
|
||||
"$oid": "6405dc0513ae975803a09902"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1671713764781"
|
||||
"$numberLong": "1678105605811"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "df516de6-ca5e-44a6-ac50-db89bb17aac3",
|
||||
"title": "New Test Comment",
|
||||
"description": "Two related findings",
|
||||
"relatedFindings": [
|
||||
"0bda8950-94fa-4ec6-8fa7-e09f5a8cd3e8",
|
||||
"4ddb84f6-068c-4319-a8ee-1000008bb75a"
|
||||
]
|
||||
"_id": "a785aaf0-1feb-429e-beb1-31bfcf70c404",
|
||||
"title": "Interesting comment",
|
||||
"description": "I know where your house lives",
|
||||
"attachments": []
|
||||
},
|
||||
"_class": "com.securityc4po.api.comment.CommentEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "63a454b5377c3f53f86d27d9"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1671713973541"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "e55e943b-6a48-4d84-8d72-b48d7d9de5b7",
|
||||
"title": "Another Test Comment",
|
||||
"description": "One related findings",
|
||||
"relatedFindings": [
|
||||
"5e22d38f-a4f6-4809-84ea-a803b5f1f9fc"
|
||||
]
|
||||
},
|
||||
"_class": "com.securityc4po.api.comment.CommentEntity"
|
||||
"_class": "com.securityc4po.api.pentest.comment.CommentEntity"
|
||||
}]
|
|
@ -1,357 +1,106 @@
|
|||
[{
|
||||
"_id": {
|
||||
"$oid": "6372223efea5724fd22bae8a"
|
||||
"$oid": "6405d88b13ae975803a098fb"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668424254533"
|
||||
"$numberLong": "1678104715816"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "ef31449d-71ec-4736-952f-8b20e53117d5",
|
||||
"_id": "a343150a-91c9-4564-9638-d0377eecc7c9",
|
||||
"severity": "LOW",
|
||||
"title": "Test Title",
|
||||
"description": "Test Description",
|
||||
"impact": "Test Impact",
|
||||
"affectedUrls": [
|
||||
"https://akveo.github.io/nebular/docs/components/progress-bar/examples#nbprogressbarcomponent"
|
||||
],
|
||||
"reproduction": "Step 1: Test",
|
||||
"mitigation": "Test Mitigatin"
|
||||
"title": "Low Prio Finding",
|
||||
"description": "This is Low Prio.",
|
||||
"impact": "Impacts nothing.",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Open App.",
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
"_class": "com.securityc4po.api.pentest.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "63725fa6e612626e2c6956ee"
|
||||
"$oid": "6405db8a13ae975803a098fe"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668439974730"
|
||||
"$numberLong": "1678105482494"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "0bda8950-94fa-4ec6-8fa7-e09f5a8cd3e8",
|
||||
"_id": "5bf1b2e1-69b7-463b-a1ca-4ac6ac66b10f",
|
||||
"severity": "MEDIUM",
|
||||
"title": "Medium Prio Finding",
|
||||
"description": "Medium Description",
|
||||
"impact": "Medium Impact",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "1. Open App",
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
},
|
||||
"_class": "com.securityc4po.api.pentest.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6405dba513ae975803a098ff"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1678105509645"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "f6e6c632-ab34-479e-9584-565f61c5862a",
|
||||
"severity": "HIGH",
|
||||
"title": "High Title",
|
||||
"description": "High Description",
|
||||
"title": "High Prio Finding",
|
||||
"description": "High Prio Description",
|
||||
"impact": "High Impact",
|
||||
"affectedUrls": [
|
||||
"https://angular.io/guide/routing-overview"
|
||||
],
|
||||
"reproduction": "Step 1: Not be High",
|
||||
"mitigation": ""
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374c3c4e0136563b96187b8"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668596676210"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "58f63b4e-97fb-4fe8-8527-7996896089d2",
|
||||
"severity": "MEDIUM",
|
||||
"title": "Medium Finding",
|
||||
"description": "Medium",
|
||||
"impact": "Medium",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Medium",
|
||||
"mitigation": ""
|
||||
"reproduction": "1. Open App\n2. Hack",
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
"_class": "com.securityc4po.api.pentest.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374c43be0136563b96187b9"
|
||||
"$oid": "6405dbcc13ae975803a09900"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668596795003"
|
||||
"$numberLong": "1678105548815"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "72886128-b2d9-4a92-bbfe-b54373441321",
|
||||
"_id": "176f5d93-0fe3-40b1-8a25-f11a6f760148",
|
||||
"severity": "CRITICAL",
|
||||
"title": "Critical Issue",
|
||||
"description": "Critical",
|
||||
"impact": "Critical",
|
||||
"title": "Critical Prio Finding",
|
||||
"description": "Critical Description",
|
||||
"impact": "Critical Impact",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Critical",
|
||||
"mitigation": ""
|
||||
"reproduction": "1. Open App\n2. Hack\n3. Break everything",
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
"_class": "com.securityc4po.api.pentest.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374c488e0136563b96187ba"
|
||||
"$oid": "640854a01d5b385d85c60ba7"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668596872152"
|
||||
"$numberLong": "1678267552968"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "4ddb84f6-068c-4319-a8ee-1000008bb75a",
|
||||
"severity": "HIGH",
|
||||
"title": "Anothe High Issues",
|
||||
"description": "High",
|
||||
"impact": "High",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "High",
|
||||
"mitigation": ""
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374c624e0136563b96187bb"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668597284983"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "42831151-51fd-4348-b829-6b18ddd14fe1",
|
||||
"severity": "MEDIUM",
|
||||
"title": "Another Medium FInding",
|
||||
"description": "Medium",
|
||||
"impact": "Medium",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Medium",
|
||||
"mitigation": ""
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374cb33e0136563b96187bc"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668598579443"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "559cd0ac-9e64-41f9-892a-4c8a9dd30357",
|
||||
"_id": "1ffc2215-b8ae-43b7-bbb7-bfcfb414d534",
|
||||
"severity": "LOW",
|
||||
"title": "Another Low One",
|
||||
"description": "Low",
|
||||
"impact": "Low",
|
||||
"title": "Low Prio Title",
|
||||
"description": "Low Prio Description",
|
||||
"impact": "Low Prio Impact",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Low",
|
||||
"mitigation": ""
|
||||
"reproduction": "Do Nothing",
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374cb98e0136563b96187bd"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668598680140"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "5e22d38f-a4f6-4809-84ea-a803b5f1f9fc",
|
||||
"severity": "LOW",
|
||||
"title": "common",
|
||||
"description": "common",
|
||||
"impact": "common",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "common",
|
||||
"mitigation": ""
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374cc51e0136563b96187be"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668598865728"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "0bfa7511-fe33-4ab5-9af2-d4ed70c1b350",
|
||||
"severity": "HIGH",
|
||||
"title": "Highihihi",
|
||||
"description": "High",
|
||||
"impact": "High",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "High",
|
||||
"mitigation": ""
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374cd00e0136563b96187bf"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668599040593"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "70e413b9-d736-40d2-b7d6-236768b1230c",
|
||||
"severity": "MEDIUM",
|
||||
"title": "Medium Rare",
|
||||
"description": "Medium",
|
||||
"impact": "Medium",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Medium",
|
||||
"mitigation": ""
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6374ec35e0136563b96187c8"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668607029072"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "672d9f87-fb3d-4fc5-8c6f-cadf97661ca5",
|
||||
"severity": "HIGH",
|
||||
"title": "Test",
|
||||
"description": "Test",
|
||||
"impact": "Test",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Test",
|
||||
"mitigation": ""
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "637606830687d905ca60af1d"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668679299814"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "bddf810b-f20e-473e-a63d-34fcba7e48ef",
|
||||
"severity": "CRITICAL",
|
||||
"title": "Login SQL Injection ",
|
||||
"description": "Inside Login Form using the ' or TRUE-- Syntax will enable the user to login as the Admin.",
|
||||
"impact": "Active User Session with Admin priviledges can affect the whole application.",
|
||||
"affectedUrls": [
|
||||
"http://localhost:3000/#/login"
|
||||
],
|
||||
"reproduction": "Step 1:\nGo to login page.\n\nStep 2:\nEnter ' or TRUE-- in the username field and enter a random password.",
|
||||
"mitigation": ""
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "637612280687d905ca60af20"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668682280551"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "d7c95af7-5434-4768-b62c-5b11f9396276",
|
||||
"severity": "MEDIUM",
|
||||
"title": "Searchbar XSS",
|
||||
"description": "Adding <iframe> in the search bar of the header results in XSS Vuln.",
|
||||
"impact": "This impacts the Webapplication",
|
||||
"affectedUrls": [
|
||||
"http://localhost:3000/#/search?q=%3Ciframe%20src%3D%22javascript:alert(%60xss%60)%22%3E"
|
||||
],
|
||||
"reproduction": "Step 1: \nClick on search bar of header.\n\nStep 2: \nEnter <iframe src=\"javascript:alert(`xss`)\">\n\nStep3: Press ENTER\n\nYou will now get a PopUp because the javascript code was executed inside the browser.",
|
||||
"mitigation": "Sanitse Input Field."
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "63776860fcdda12bf2e51eb2"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1670489874240"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "cb33fad4-7965-4654-a9f9-f007edaca35c",
|
||||
"severity": "HIGH",
|
||||
"title": "Searchbar XSS",
|
||||
"description": "Adding <iframe src=\"javascript:alert('xss')\"> in the search bar of the header results in XSS Vuln.",
|
||||
"impact": "This impacts the Webbapp.",
|
||||
"affectedUrls": [
|
||||
"http://localhost:3000/#/search?q=%3Ciframe%20src%3D%22javascript:alert('xss')%22%3E"
|
||||
],
|
||||
"reproduction": "Step1: \nClick on search field of the header\n\nStep 2: \nEnter <iframe src=\"javascript:alert('xss')\">\n\nStep 3: \nPress ENTER\n\nYou will now get a PopUp",
|
||||
"mitigation": "Sanitise Input Fields."
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6391a364aceddd4dd1b32322"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1670488932489"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "b6dfddde-9bc2-4658-8c18-668190053105",
|
||||
"severity": "CRITICAL",
|
||||
"title": "Searchbar XSS",
|
||||
"description": "Adding <iframe src=\"javascript:alert('xss')\"> in the search bar of the header results in XSS Vuln.",
|
||||
"impact": "This impacts the Webbapp.",
|
||||
"affectedUrls": [
|
||||
"http://localhost:3000/#/search?q=%3Ciframe%20src%3D%22javascript:alert('xss')%22%3E"
|
||||
],
|
||||
"reproduction": "Step1: \nClick on search field of the header\n\nStep 2: \nEnter <iframe src=\"javascript:alert('xss')\">\n\nStep 3: \nPress ENTER\n\nYou will now get a PopUp",
|
||||
"mitigation": "Sanitise Input Fields."
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6391a39baceddd4dd1b32323"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1670488987700"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "e9a50c5d-e9ea-4596-b1a9-8ad67eddef04",
|
||||
"severity": "CRITICAL",
|
||||
"title": "Searchbar XSS",
|
||||
"description": "Adding <iframe src=\"javascript:alert('xss')\"> in the search bar of the header results in XSS Vuln.",
|
||||
"impact": "This impacts the Webbapp.",
|
||||
"affectedUrls": [
|
||||
"http://localhost:3000/#/search?q=%3Ciframe%20src%3D%22javascript:alert('xss')%22%3E"
|
||||
],
|
||||
"reproduction": "Step1: \nClick on search field of the header\n\nStep 2: \nEnter <iframe src=\"javascript:alert('xss')\">\n\nStep 3: \nPress ENTER\n\nYou will now get a PopUp",
|
||||
"mitigation": "Sanitise Input Fields."
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "6391a3cbaceddd4dd1b32324"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1670489035954"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "7f51e615-230f-4f90-a671-13e66e82370f",
|
||||
"severity": "CRITICAL",
|
||||
"title": "Searchbar XSS",
|
||||
"description": "Adding <iframe src=\"javascript:alert('xss')\"> in the search bar of the header results in XSS Vuln.",
|
||||
"impact": "This impacts the Webbapp.",
|
||||
"affectedUrls": [
|
||||
"http://localhost:3000/#/search?q=%3Ciframe%20src%3D%22javascript:alert('xss')%22%3E"
|
||||
],
|
||||
"reproduction": "Step1: \nClick on search field of the header\n\nStep 2: \nEnter <iframe src=\"javascript:alert('xss')\">\n\nStep 3: \nPress ENTER\n\nYou will now get a PopUp",
|
||||
"mitigation": "Sanitise Input Fields."
|
||||
},
|
||||
"_class": "com.securityc4po.api.finding.FindingEntity"
|
||||
}]
|
||||
"_class": "com.securityc4po.api.pentest.finding.FindingEntity"
|
||||
}]
|
File diff suppressed because it is too large
Load Diff
|
@ -1,351 +1,269 @@
|
|||
[{
|
||||
"_id": {
|
||||
"$oid": "62f3c50c7acde34f740ba737"
|
||||
"$oid": "6405d84a13ae975803a098fa"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1668425376081"
|
||||
"$numberLong": "1678109612474"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "5a4f126c-9471-43b8-80b9-6eb02b7c35d0",
|
||||
"_id": "575dd9d4-cb3c-4df3-981e-8a18bf8dc1d2",
|
||||
"client": "Dio Stonemask Inc.",
|
||||
"title": "log4jj bizarre adventure",
|
||||
"createdAt": "2022-08-10T14:47:40.140406Z",
|
||||
"createdAt": "2023-03-06T12:10:50.835664Z",
|
||||
"tester": "Jojo",
|
||||
"summary": "This report includes an Executeive Summary, the rules in regards to the scope of the pentest and the choosen approach of the pentester.\nDio Stonemask Inc. contracted Jojo to perform a Penetration Test to identify security weaknesses,\ndetermine the impact to Dio Stonemask Inc., document all findings in a clear and repeatable manner,\nand provide remediation recommendations",
|
||||
"projectPentests": [
|
||||
{
|
||||
"pentestId": "11601f51-bc17-47fd-847d-0c53df5405b5",
|
||||
"status": "IN_PROGRESS"
|
||||
"pentestId": "54f3ce12-784a-4e44-b9b3-0a986119ec50",
|
||||
"status": "COMPLETED"
|
||||
},
|
||||
{
|
||||
"pentestId": "9a073a08-e4fc-4450-8202-c902455b66ec",
|
||||
"status": "OPEN"
|
||||
"pentestId": "d724df75-e85a-4124-a5be-bccadc78beaf",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "981c5e24-7276-47f8-a821-ff5976292ad4",
|
||||
"status": "OPEN"
|
||||
"pentestId": "c9c1c2f4-14dd-43f4-bc0d-bac03755f798",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "2d46a183-8f11-4fbc-bbf1-e439f7282bb9",
|
||||
"status": "OPEN"
|
||||
"pentestId": "288599c2-c295-4825-b1ff-db20e99f45ba",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "eb4f80f3-caac-4fef-a5dd-53616701f171",
|
||||
"status": "OPEN"
|
||||
"pentestId": "7c1c1d64-000d-461b-b60f-50bfc70868e6",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "0ab8de31-9d5e-4b6b-a43c-12207c160863",
|
||||
"status": "IN_PROGRESS"
|
||||
"pentestId": "415528d1-a92c-4e14-adf1-2846b2ce0f70",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "3ed9e894-58e8-46b9-9859-cde675fec17c",
|
||||
"status": "OPEN"
|
||||
"pentestId": "8d91e25f-eaeb-42f6-800c-4e7113656321",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "53fdab75-ea52-4cea-85ed-df8b67f41b72",
|
||||
"status": "OPEN"
|
||||
"pentestId": "ed9595bb-cc80-4daa-873e-e7470fc0b7d1",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "6270d4bc-5f39-4358-ad0a-fd5791191f28",
|
||||
"status": "IN_PROGRESS"
|
||||
"pentestId": "35481ca5-5672-4a11-a2b8-38ece069ca70",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "1a90f468-470a-4b1e-9783-cc761b1770ee",
|
||||
"status": "OPEN"
|
||||
"pentestId": "538f8e15-8d0e-43ac-b7a6-d6b5959581eb",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "6eb37869-baef-4a5b-9ac0-bf202a49874f",
|
||||
"status": "OPEN"
|
||||
"pentestId": "3bff597e-d680-4b87-8352-be32f40db074",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "da89c933-1413-4186-ad2c-f1967cb8dbb4",
|
||||
"status": "OPEN"
|
||||
"pentestId": "27ca5852-aa9f-44ed-b2fe-c46c31b415f4",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "b3682591-f6c3-4969-bf15-69f4d495ef18",
|
||||
"status": "OPEN"
|
||||
"pentestId": "60cf0cf9-f62a-4669-87a7-f519e7be0613",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "9e8e2736-afc9-4f63-b29f-567f9f316c83",
|
||||
"status": "OPEN"
|
||||
"pentestId": "05251dfd-a382-47af-85d5-798dd1a6171a",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "3405bdd6-1ae2-4876-9c18-443a791cec9c",
|
||||
"status": "OPEN"
|
||||
"pentestId": "be6780a2-b66e-42a6-a725-805633589921",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "2fd387b3-b7a5-4297-9790-5d7845214c05",
|
||||
"status": "OPEN"
|
||||
"pentestId": "192b9fed-596b-4345-b33d-ca3882ba9bdd",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "a61116c5-1859-4df3-8252-7788c31472d8",
|
||||
"status": "OPEN"
|
||||
"pentestId": "6d3f0b58-b311-465e-9f01-e3e45d165902",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "47d8b39d-9fa7-4772-8605-84aa0531f49e",
|
||||
"status": "OPEN"
|
||||
"pentestId": "058dd5c7-63a5-40cb-a4ed-46e5cdcb87ff",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "bd2b8899-0cd9-41fd-a975-257aac48b81f",
|
||||
"status": "OPEN"
|
||||
"pentestId": "36e1c198-d425-4a38-ad0b-2f9d6759931e",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "b9bde632-c275-4566-b693-c57a3dad47f3",
|
||||
"status": "OPEN"
|
||||
"pentestId": "b3063d09-237f-493e-b0db-603a11829d88",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "32cc5c4e-7234-42b7-8031-c2e231bc0404",
|
||||
"status": "OPEN"
|
||||
"pentestId": "6ae89321-678f-4191-b008-8abfc42401c3",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "07e34e95-7dda-499a-8be8-0e8378f0e0d0",
|
||||
"status": "OPEN"
|
||||
"pentestId": "3334d254-87bf-4115-8d88-e2fed022ad06",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "b70f6720-ee17-49d6-8838-bd776cd18d0a",
|
||||
"status": "OPEN"
|
||||
"pentestId": "8e97f1e0-b02c-4be2-b30e-372d09614038",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "9fb260ea-333f-44c6-884b-e46352564e2a",
|
||||
"status": "OPEN"
|
||||
"pentestId": "e9c9eecb-116b-4a8c-ac8c-4a279f77e1f4",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "87f492f7-991b-4e04-9531-5dba0bc34b1b",
|
||||
"status": "OPEN"
|
||||
"pentestId": "f0531d71-18d3-41a7-a37a-2c15f6b26dcb",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "6d846445-d470-447a-96b3-8f4b57df3221",
|
||||
"status": "OPEN"
|
||||
"pentestId": "d73543ef-a66f-4878-9ecb-ab5207ed734f",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "123c43ae-6870-4883-a1c5-2f99946e2c2d",
|
||||
"status": "OPEN"
|
||||
"pentestId": "22130f1e-53c2-404b-8f77-750e82d12768",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "8be5b377-3eb0-4b54-81d2-8cfd5ea1f0f1",
|
||||
"status": "OPEN"
|
||||
"pentestId": "54db12f1-1fdc-48f9-9b1d-b6b1fb39bc07",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "6b1d2b71-9e31-4e78-a82e-5325c699658c",
|
||||
"status": "OPEN"
|
||||
"pentestId": "7853a95c-7ee3-4b31-af18-401c104efc7e",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "77e765ef-40fb-4b6e-9d80-1e06cae7d4a3",
|
||||
"status": "OPEN"
|
||||
"pentestId": "7ca78e39-7d4c-46c5-a9c3-ba58c7fba844",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "5821cd2c-aa17-4339-b697-1b4089d3bf93",
|
||||
"status": "OPEN"
|
||||
"pentestId": "dca5b8b3-e994-4d5c-8740-b21ee806a4e5",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "bb57b94f-c8bc-4dd9-b4bf-e14d0a97cc31",
|
||||
"status": "OPEN"
|
||||
"pentestId": "5e7b999c-e878-4d48-9ce8-9b65ef578dae",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "a5e3aaba-268e-4a40-92f9-05c0dae4cc0f",
|
||||
"status": "OPEN"
|
||||
"pentestId": "8bc131f4-b9c8-4dd5-927b-0675dff6344e",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "18ed1ddb-524a-4333-af90-7716bd51dc7b",
|
||||
"status": "OPEN"
|
||||
"pentestId": "ed134842-6578-4d22-af57-282161c5306b",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "c2d19d1e-39e5-4862-82c9-d88c5d91f630",
|
||||
"status": "OPEN"
|
||||
"pentestId": "f35f30fb-f246-4a1f-ae26-ce864647a341",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "728e294f-e27d-4bef-903b-d9eeb54cf086",
|
||||
"status": "OPEN"
|
||||
"pentestId": "47021e69-95ab-4d93-ac13-aac0379ca809",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "91cd7aee-acda-4c95-ba35-16932448f29f",
|
||||
"status": "OPEN"
|
||||
"pentestId": "f19a5176-64bc-452b-aa63-8861aab75059",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "e496d9ba-7775-479e-8904-864c04fec3f9",
|
||||
"status": "OPEN"
|
||||
"pentestId": "c60ac6e5-39e8-4fae-8d65-d71ea69a2404",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "ee87e923-63d7-40bc-b41e-049fe087e1dd",
|
||||
"status": "OPEN"
|
||||
"pentestId": "2764e64b-0a7e-456c-9999-cdd05c5ef50b",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "cbe94eaf-c734-4d6f-96ec-7d84a4a5b5cc",
|
||||
"status": "IN_PROGRESS"
|
||||
"pentestId": "1247dd20-2986-4887-9c17-74806ce56eef",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "c9ecfc9f-23f1-4744-a578-54b0c96a9e87",
|
||||
"status": "IN_PROGRESS"
|
||||
"pentestId": "e01d1a34-15fa-4f29-8054-8209a422e505",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "ca0c10a1-8fcc-4b0b-98c0-2403709d7e50",
|
||||
"status": "OPEN"
|
||||
"pentestId": "c55343b0-c99c-4bfd-8f30-b8464b442dad",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "bce6f266-2c70-4e45-a1db-d767e4bcc1f8",
|
||||
"status": "OPEN"
|
||||
"pentestId": "47ff61bb-2e4f-45e3-9630-136f9d704882",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "be0b07a3-64e4-4122-a362-dd657b8b6b0a",
|
||||
"status": "OPEN"
|
||||
"pentestId": "0b353e67-3092-4586-9558-172354beaf8b",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "8f2230fb-bd5c-4047-9db6-74bc49be9cc1",
|
||||
"status": "OPEN"
|
||||
"pentestId": "5804e2ce-8c5b-4f3d-8674-433042e61a7f",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "a1b00a90-cb14-475f-ba3a-5807a21df704",
|
||||
"status": "OPEN"
|
||||
"pentestId": "4fc1260b-8b5b-47a7-bdee-61261e23919d",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "af2e7766-ecd1-4015-b4e1-c0b978643a0f",
|
||||
"status": "OPEN"
|
||||
"pentestId": "39dfbf25-e97d-4bd8-9943-a9eec183bfcf",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "27b64044-b3ff-48bf-9220-837b420f3904",
|
||||
"status": "OPEN"
|
||||
"pentestId": "53668fb6-471d-4363-9e47-8f73e4f1a7d4",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "b5eb1683-700a-4522-8b53-45809e665643",
|
||||
"status": "OPEN"
|
||||
"pentestId": "86637ffd-8e6e-4e00-9179-42f52780427a",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "86b4d382-e433-4bac-ab6e-530a0dce299d",
|
||||
"status": "OPEN"
|
||||
"pentestId": "04f9532e-3c05-4eff-9e9f-b2d733a14a77",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "7a118a29-f983-4219-834c-f01554231910",
|
||||
"status": "OPEN"
|
||||
"pentestId": "1e58f29e-81fb-48d2-94bf-7b89e227f590",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "ac9bc697-a53f-4278-98b9-05d8ba19a50d",
|
||||
"status": "OPEN"
|
||||
"pentestId": "2c78589b-558e-4b99-a182-df4df3c1439b",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "13cecebb-321a-4ef8-8116-f6814652f7d7",
|
||||
"status": "OPEN"
|
||||
"pentestId": "9383b9c1-6c2e-422b-b16f-31a9640d1647",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "048287bc-c41b-49a1-aeb5-2cc98a5bad06",
|
||||
"status": "OPEN"
|
||||
"pentestId": "2f87faf9-611f-40ae-9c0e-412d0bfd0481",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "4d1b424e-05ea-468c-9902-3626a79ccfe6",
|
||||
"status": "OPEN"
|
||||
"pentestId": "0f47fcbc-f567-4009-ae56-a894cf17cc46",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "377d73b8-f8da-461e-909b-524a38a37ed6",
|
||||
"status": "OPEN"
|
||||
"pentestId": "ba0fa19c-5533-4be8-8169-9ffa7d449ab0",
|
||||
"status": "PAUSED"
|
||||
},
|
||||
{
|
||||
"pentestId": "16e10ad9-f49d-4a74-9de7-10a49e2401e2",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "4c68c22e-6073-4ec8-aebb-45ad2a3cc848",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "276e5823-b517-445c-b182-e6eda6478d44",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "84c661c0-2775-440a-97c5-ff35f345cabb",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "fb6d909c-8d16-48e3-b0e5-aba9bf3e8eae",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "0b211e22-dd63-46cc-a12f-be7ac73d7a64",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "63310549-e2a8-4dd0-a91a-9cfa06e2dc41",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "ac8d52d0-f0c8-47ec-ab13-24f40dc4f9e6",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "3ddc4950-f662-4ec1-9a04-b9c3591d8b06",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "4c11d176-2ec5-4ed9-9c8a-c1edd33b262c",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "b9a6f4ba-62e6-442b-a274-b3ffe209d248",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "705e28a2-b0a4-4b8c-9922-10c5c67faf65",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "4c59259d-4a24-43ef-8738-fe214e0b0673",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "a7ab3344-db7d-495a-8e55-dd572ea7c5e0",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "195e7f58-a7b2-4571-9c66-1e91a0dfca28",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "543a9768-4e5c-4c70-9aae-977afa542afa",
|
||||
"status": "OPEN"
|
||||
},
|
||||
{
|
||||
"pentestId": "a17516de-e92a-43b9-a415-203dce48fb0e",
|
||||
"status": "OPEN"
|
||||
"pentestId": "0f47ac3b-d19a-4115-9ddf-dc9b2f11abae",
|
||||
"status": "PAUSED"
|
||||
}
|
||||
],
|
||||
"createdBy": "3c4ae87f-0d56-4634-a824-b4883c403c8a"
|
||||
"createdBy": "ce650edd-aebc-4478-9e17-40545ff66280"
|
||||
},
|
||||
"_class": "com.securityc4po.api.project.ProjectEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "62f3c5317acde34f740ba738"
|
||||
"$oid": "6405e92813ae975803a09905"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1660142897912"
|
||||
"$numberLong": "1678108968564"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "42b8c0df-b70e-4526-8ed0-7c022195fe85",
|
||||
"_id": "d6e83738-4251-44ac-ad40-21b360780c98",
|
||||
"client": "Allsafe",
|
||||
"title": "CashMyData (iOS)",
|
||||
"createdAt": "2022-08-10T14:48:17.912592Z",
|
||||
"createdAt": "2023-03-06T13:22:48.564351Z",
|
||||
"tester": "Elliot",
|
||||
"projectPentests": [],
|
||||
"createdBy": "6740ad72-8f42-486a-bcf3-e057e6afb0de"
|
||||
},
|
||||
"_class": "com.securityc4po.api.project.ProjectEntity"
|
||||
},{
|
||||
"_id": {
|
||||
"$oid": "62ff7534ac2b4d14d86215c4"
|
||||
},
|
||||
"lastModified": {
|
||||
"$date": {
|
||||
"$numberLong": "1660908852340"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"_id": "195809ed-9722-4ad5-a84b-0099a9a01652",
|
||||
"client": "Novatec",
|
||||
"title": "log4j pentest",
|
||||
"createdAt": "2022-08-19T11:34:12.339990Z",
|
||||
"tester": "Stipe",
|
||||
"projectPentests": [],
|
||||
"createdBy": "7fe49c8d-fee3-47e0-9224-94e0ac7436c6"
|
||||
"createdBy": "5f104d76-bd8d-4258-852a-d000c7f0666d"
|
||||
},
|
||||
"_class": "com.securityc4po.api.project.ProjectEntity"
|
||||
}]
|
|
@ -106,7 +106,7 @@
|
|||
"bearer": [
|
||||
{
|
||||
"key": "token",
|
||||
"value": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItdG1lbEV0ZHhGTnRSMW9aNXlRdE5jaFFpX0RVN2VNeV9YcU44aXY0S3hzIn0.eyJleHAiOjE2NzY5ODY0NTgsImlhdCI6MTY3Njk4NjE1OCwianRpIjoiMzk2NjcwM2UtMTk4My00MWU4LTkyNjAtYjhmNDExOWRmYzYwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2M0cG9fcmVhbG1fbG9jYWwiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMTBlMDZkN2EtOGRkMC00ZWNkLTg5NjMtMDU2YjQ1MDc5YzRmIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYzRwb19sb2NhbCIsInNlc3Npb25fc3RhdGUiOiIxZDBmMTk4YS03MTg5LTQ4ZmItYWQ0Ny00NTllNjVkOWU3ZjciLCJhbGxvd2VkLW9yaWdpbnMiOlsiKiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiYzRwb191c2VyIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImM0cG9fbG9jYWwiOnsicm9sZXMiOlsidXNlciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiMWQwZjE5OGEtNzE4OS00OGZiLWFkNDctNDU5ZTY1ZDllN2Y3IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoidGVzdCB1c2VyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidHR0IiwiZ2l2ZW5fbmFtZSI6InRlc3QiLCJmYW1pbHlfbmFtZSI6InVzZXIifQ.m1aOgFK_8ADYS6EdPLWT_wQNTsptSM9XipQQcttSd1lZKdZu6FgFVRSsW39fdgVLGurKxaglGoNgsywGDeomPS7hJuowzmYIEoDZr13MXCBqX9-YAsEDbwvrGcUI4jVXwKl8E-rTLpl3c5Ckj4tbDeUD3EuLk7yTYbkUnijqwsFlZpwJ_gbjZAfNiZCZpJlvh95cQKvFBbyzP7sfxkYikzpxY-1UHSUpoHBxJaOcJ6hoh-PIQVUw-8mvuoOyd5dMmavl5njvijr716_2loj6B6YHLueHIGlenI5Aob9DEOcL17SXivvcEyM5xTKyfqx3Jt1XY7jQ8mOIT4_iqxTc_w",
|
||||
"value": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItdG1lbEV0ZHhGTnRSMW9aNXlRdE5jaFFpX0RVN2VNeV9YcU44aXY0S3hzIn0.eyJleHAiOjE2NzgyNjg2NTksImlhdCI6MTY3ODI2ODM1OSwianRpIjoiNTkzODgzZWYtZDZkZS00MGJjLWE3MGQtMTU5MDE3YzBlY2Q4IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL2M0cG9fcmVhbG1fbG9jYWwiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiMTBlMDZkN2EtOGRkMC00ZWNkLTg5NjMtMDU2YjQ1MDc5YzRmIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYzRwb19sb2NhbCIsInNlc3Npb25fc3RhdGUiOiIxNGUwNzYwNy02YTUyLTRmZTItODA0MC00Zjc4NDc4ZjI3ZGQiLCJhbGxvd2VkLW9yaWdpbnMiOlsiKiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiYzRwb191c2VyIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImM0cG9fbG9jYWwiOnsicm9sZXMiOlsidXNlciJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiMTRlMDc2MDctNmE1Mi00ZmUyLTgwNDAtNGY3ODQ3OGYyN2RkIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoidGVzdCB1c2VyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidHR0IiwiZ2l2ZW5fbmFtZSI6InRlc3QiLCJmYW1pbHlfbmFtZSI6InVzZXIifQ.gHG1z-amLiv4mv6DujwEMPIjfn8ojROSmypOG4_A2GvF6ekmSi36WQO8I2IjPJZ4XB1amKgeG5pAI6I4AYU8DwYIOsDrqKgPSitDEyY9lCjUtxFHZpmemkQljdJw3UNjDKgDuyYpu-lPcapcEwN75BeSxmnkNVQ7ri3dLHf5AhLlQExlVD0ts4ux4kQ4X82cn_iPGRa869jZEWbVHKnhZaHufsA0444qgw45mBJu1ycG7_4VzKmoeprSV5RSH_DxMMZaDCUb0_Xf1QZ58VVEpjW1WRNvvAip5uVNnyduQe2SJ7TlZqNy5DzDyzBko8d4LnWjE_-qdo4JmwztApkOww",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
|
@ -124,7 +124,7 @@
|
|||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "http://localhost:8444/reports/5a4f126c-9471-43b8-80b9-6eb02b7c35d0/pdf",
|
||||
"raw": "http://localhost:8444/reports/575dd9d4-cb3c-4df3-981e-8a18bf8dc1d2/pdf",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
|
@ -132,7 +132,7 @@
|
|||
"port": "8444",
|
||||
"path": [
|
||||
"reports",
|
||||
"5a4f126c-9471-43b8-80b9-6eb02b7c35d0",
|
||||
"575dd9d4-cb3c-4df3-981e-8a18bf8dc1d2",
|
||||
"pdf"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -4,5 +4,7 @@ data class Comment (
|
|||
val id: String,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val relatedFindings: List<String>? = emptyList()
|
||||
val relatedFindings: List<String>? = emptyList(),
|
||||
// List of attachment id's for file upload
|
||||
val attachments: List<String>? = emptyList()
|
||||
)
|
||||
|
|
|
@ -8,7 +8,9 @@ data class Finding (
|
|||
val impact: String,
|
||||
val affectedUrls: List<String>? = emptyList(),
|
||||
val reproduction: String,
|
||||
val mitigation: String?
|
||||
val mitigation: String?,
|
||||
// List of attachment id's for file upload
|
||||
val attachments: List<String>? = emptyList()
|
||||
)
|
||||
|
||||
enum class Severity {
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.securityc4po.reporting.remote.model.api
|
|||
enum class PentestStatus {
|
||||
NOT_STARTED,
|
||||
DISABLED,
|
||||
OPEN,
|
||||
PAUSED,
|
||||
IN_PROGRESS,
|
||||
COMPLETED
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ data class Project(
|
|||
val title: String,
|
||||
val createdAt: String,
|
||||
val tester: String,
|
||||
val summary: String? = null,
|
||||
val summary: String? = "",
|
||||
var projectPentests: List<ProjectPentest>? = emptyList(),
|
||||
val createdBy: String
|
||||
)
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad -->
|
||||
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="CommentsSubreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="2d64b016-bc6c-4109-8b3a-f9f818c7397d">
|
||||
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectReportJasperData Template JSON Adapter"/>
|
||||
<queryString language="json">
|
||||
<![CDATA[projectReportData.projectPentestReport.comments]]>
|
||||
</queryString>
|
||||
<field name="id" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="id"/>
|
||||
<fieldDescription><![CDATA[id]]></fieldDescription>
|
||||
</field>
|
||||
<field name="title" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="title"/>
|
||||
<fieldDescription><![CDATA[title]]></fieldDescription>
|
||||
</field>
|
||||
<field name="description" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="description"/>
|
||||
<fieldDescription><![CDATA[description]]></fieldDescription>
|
||||
</field>
|
||||
<field name="attachments" class="java.util.ArrayList"/>
|
||||
<group name="id">
|
||||
<groupExpression><![CDATA[$F{id}]]></groupExpression>
|
||||
</group>
|
||||
<group name="title">
|
||||
<groupExpression><![CDATA[$F{title}]]></groupExpression>
|
||||
</group>
|
||||
<group name="description">
|
||||
<groupExpression><![CDATA[$F{description}]]></groupExpression>
|
||||
</group>
|
||||
<group name="relatedFindings">
|
||||
<groupExpression><![CDATA[$F{attachments}]]></groupExpression>
|
||||
</group>
|
||||
<background>
|
||||
<band splitType="Stretch"/>
|
||||
</background>
|
||||
<detail>
|
||||
<band height="280" splitType="Stretch">
|
||||
<staticText>
|
||||
<reportElement x="0" y="50" width="100" height="19" forecolor="#232B44" uuid="27e653a4-f25c-4e14-a2dd-98639beaa958"/>
|
||||
<textElement>
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Title:]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement positionType="Float" x="0" y="120" width="100" height="20" forecolor="#232B44" uuid="4f0f0eaf-177b-4af7-99d8-a46b0faa9357"/>
|
||||
<textElement>
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Description:]]></text>
|
||||
</staticText>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement x="0" y="70" width="530" height="30" uuid="62ff1e8e-7987-4cd0-a79e-536859418d32"/>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement positionType="Float" x="0" y="140" width="530" height="40" uuid="7e9aa6ea-d9f7-4879-bbca-753e3d654996"/>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{description}]]></textFieldExpression>
|
||||
</textField>
|
||||
<rectangle>
|
||||
<reportElement x="0" y="-12" width="575" height="33" forecolor="#35A4FE" backcolor="#35A4FE" uuid="6b56d210-7a17-4ac9-bab8-b27008e039e4"/>
|
||||
<graphicElement>
|
||||
<pen lineWidth="0.0"/>
|
||||
</graphicElement>
|
||||
</rectangle>
|
||||
<ellipse>
|
||||
<reportElement x="-19" y="-12" width="40" height="33" forecolor="#35A4FE" backcolor="#35A4FE" uuid="fa27cf34-9e98-4d59-9cd2-9f436f0b6c25"/>
|
||||
<graphicElement>
|
||||
<pen lineWidth="0.0"/>
|
||||
</graphicElement>
|
||||
</ellipse>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement x="80" y="-12" width="480" height="32" forecolor="#FFFFFF" uuid="f3b19575-bca9-450c-93bf-f9abbfe15bde"/>
|
||||
<textElement verticalAlignment="Middle">
|
||||
<font size="14" isBold="true"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement x="0" y="-12" width="80" height="32" forecolor="#FFFFFF" uuid="06c9b872-ccec-44a6-854f-ef7b5dcedec9"/>
|
||||
<textElement verticalAlignment="Middle">
|
||||
<font size="14" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Comment:]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</detail>
|
||||
</jasperReport>
|
Binary file not shown.
|
@ -0,0 +1,213 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad -->
|
||||
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="FindingsSubreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="e998075b-1539-4178-93ab-d58a24d7a1a1">
|
||||
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="ProjectReportJasperData Template JSON Adapter"/>
|
||||
<style name="SeverityStyles">
|
||||
<conditionalStyle>
|
||||
<conditionExpression><![CDATA[$F{severity}.equals("LOW")]]></conditionExpression>
|
||||
<style forecolor="#01D68F" backcolor="#01D68F"/>
|
||||
</conditionalStyle>
|
||||
<conditionalStyle>
|
||||
<conditionExpression><![CDATA[$F{severity}.equals("MEDIUM")]]></conditionExpression>
|
||||
<style forecolor="#35A4FE" backcolor="#35A4FE"/>
|
||||
</conditionalStyle>
|
||||
<conditionalStyle>
|
||||
<conditionExpression><![CDATA[$F{severity}.equals("HIGH")]]></conditionExpression>
|
||||
<style forecolor="#FFAB00" backcolor="#FFAB00"/>
|
||||
</conditionalStyle>
|
||||
<conditionalStyle>
|
||||
<conditionExpression><![CDATA[$F{severity}.equals("CRITICAL")]]></conditionExpression>
|
||||
<style forecolor="#FF3D70" backcolor="#FF3D70"/>
|
||||
</conditionalStyle>
|
||||
</style>
|
||||
<style name="URL">
|
||||
<conditionalStyle>
|
||||
<conditionExpression><![CDATA[$F{affectedUrls}.size() > 0]]></conditionExpression>
|
||||
<style forecolor="#3267FE" backcolor="#3267FE" isUnderline="true"/>
|
||||
</conditionalStyle>
|
||||
</style>
|
||||
<subDataset name="AffectedUrlsList" uuid="847d946c-60fb-4c27-bfef-875d197d89f9">
|
||||
<queryString>
|
||||
<![CDATA[]]>
|
||||
</queryString>
|
||||
<field name="_THIS" class="java.lang.String"/>
|
||||
</subDataset>
|
||||
<queryString language="json">
|
||||
<![CDATA[projectReportData.projectPentestReport.findings]]>
|
||||
</queryString>
|
||||
<field name="id" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="id"/>
|
||||
<fieldDescription><![CDATA[id]]></fieldDescription>
|
||||
</field>
|
||||
<field name="severity" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="severity"/>
|
||||
<fieldDescription><![CDATA[severity]]></fieldDescription>
|
||||
</field>
|
||||
<field name="title" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="title"/>
|
||||
<fieldDescription><![CDATA[title]]></fieldDescription>
|
||||
</field>
|
||||
<field name="description" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="description"/>
|
||||
<fieldDescription><![CDATA[description]]></fieldDescription>
|
||||
</field>
|
||||
<field name="impact" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="impact"/>
|
||||
<fieldDescription><![CDATA[impact]]></fieldDescription>
|
||||
</field>
|
||||
<field name="affectedUrls" class="java.util.ArrayList">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="affectedUrls"/>
|
||||
<fieldDescription><![CDATA[affectedUrls]]></fieldDescription>
|
||||
</field>
|
||||
<field name="reproduction" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="reproduction"/>
|
||||
<fieldDescription><![CDATA[reproduction]]></fieldDescription>
|
||||
</field>
|
||||
<field name="mitigation" class="java.lang.String">
|
||||
<property name="net.sf.jasperreports.json.field.expression" value="mitigation"/>
|
||||
<fieldDescription><![CDATA[mitigation]]></fieldDescription>
|
||||
</field>
|
||||
<field name="attachments" class="java.util.ArrayList"/>
|
||||
<background>
|
||||
<band splitType="Stretch"/>
|
||||
</background>
|
||||
<detail>
|
||||
<band height="600" splitType="Stretch">
|
||||
<ellipse>
|
||||
<reportElement key="" style="SeverityStyles" mode="Opaque" x="445" y="45" width="30" height="30" uuid="5dfe3093-6943-446e-8126-d7230d895b0c"/>
|
||||
<graphicElement>
|
||||
<pen lineWidth="0.0"/>
|
||||
</graphicElement>
|
||||
</ellipse>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement positionType="Float" x="0" y="140" width="530" height="40" uuid="2882cfe1-475e-4ac3-a987-38cb01a462f4"/>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{description}]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement positionType="Float" x="0" y="120" width="100" height="20" forecolor="#232B44" uuid="cb620215-7d9a-422e-a286-d1374c29469a"/>
|
||||
<textElement>
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Description:]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement x="0" y="50" width="100" height="20" forecolor="#232B44" uuid="a8c19344-4ce8-4d15-919b-4cbb004aba79"/>
|
||||
<textElement>
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Title:]]></text>
|
||||
</staticText>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement x="0" y="70" width="430" height="30" uuid="1ac22e9e-2fe9-4fc7-94ca-5e30db7aa74f"/>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement positionType="Float" x="0" y="200" width="100" height="20" forecolor="#232B44" uuid="3d056116-a999-4c17-b3b0-94b26e69c9c6"/>
|
||||
<textElement>
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Impact:]]></text>
|
||||
</staticText>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement positionType="Float" x="0" y="220" width="530" height="40" uuid="d026c3e2-1431-4010-b0d7-bf07cb339ed7"/>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{impact}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement positionType="Float" x="0" y="300" width="530" height="40" uuid="8d1f42e3-a821-475e-b862-126018ae2e95"/>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{reproduction}]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement positionType="Float" x="0" y="280" width="180" height="20" forecolor="#232B44" uuid="5d0ab6e7-dd18-4da2-848b-95abc47936e8"/>
|
||||
<textElement>
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Reproduction Steps:]]></text>
|
||||
</staticText>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement positionType="Float" x="0" y="380" width="530" height="40" uuid="09dea210-c47a-486e-b461-c6fb7c27bb39"/>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[(($F{mitigation}.length() == 0) ? "No mitigation to avoid, minimize or compensate the finding found or needed." : $F{mitigation})]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement positionType="Float" x="0" y="360" width="180" height="20" forecolor="#232B44" uuid="0aaec1e4-9ac0-48de-96ef-0ac5ad1e9be0"/>
|
||||
<textElement>
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Mitigation:]]></text>
|
||||
</staticText>
|
||||
<rectangle>
|
||||
<reportElement x="0" y="-12" width="575" height="33" forecolor="#FF3D70" backcolor="#FF3D70" uuid="cb580eb9-9492-4fb6-8eb7-304e50612c9f"/>
|
||||
<graphicElement>
|
||||
<pen lineWidth="0.0"/>
|
||||
</graphicElement>
|
||||
</rectangle>
|
||||
<ellipse>
|
||||
<reportElement x="-19" y="-12" width="40" height="33" forecolor="#FF3D70" backcolor="#FF3D70" uuid="b7284920-9281-446c-a04f-0e5c1b433cd5"/>
|
||||
<graphicElement>
|
||||
<pen lineWidth="0.0"/>
|
||||
</graphicElement>
|
||||
</ellipse>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement x="80" y="-12" width="480" height="32" forecolor="#FFFFFF" uuid="fd9a8e55-90df-468c-920e-f4154c0c0476"/>
|
||||
<textElement verticalAlignment="Middle">
|
||||
<font size="14" isBold="true"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
|
||||
</textField>
|
||||
<rectangle>
|
||||
<reportElement style="SeverityStyles" mode="Opaque" x="460" y="45" width="70" height="30" uuid="6b40b4f8-4f4a-4e2e-9eb8-dcb32646353d"/>
|
||||
<graphicElement>
|
||||
<pen lineWidth="0.0"/>
|
||||
</graphicElement>
|
||||
</rectangle>
|
||||
<ellipse>
|
||||
<reportElement style="SeverityStyles" mode="Opaque" x="515" y="45" width="30" height="30" uuid="a9c34649-525e-40e7-b9c6-4132773009d3"/>
|
||||
<graphicElement>
|
||||
<pen lineWidth="0.0"/>
|
||||
</graphicElement>
|
||||
</ellipse>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement x="460" y="50" width="70" height="20" forecolor="#FEFEFF" uuid="c2c6ef50-1470-41aa-80a1-44db4bbc1b64"/>
|
||||
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[$F{severity}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField textAdjust="StretchHeight">
|
||||
<reportElement style="URL" positionType="Float" x="0" y="460" width="530" height="40" uuid="9d6be22b-6f8c-41bf-ab85-3d5901979a06"/>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
</textElement>
|
||||
<textFieldExpression><![CDATA[(($F{affectedUrls}.size() == 0) ? "No specific URL's affected." : $F{affectedUrls}.toString().substring(1, $F{affectedUrls}.toString().length() - 1))]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement positionType="Float" x="0" y="440" width="180" height="20" forecolor="#232B44" uuid="003646c0-fc53-4add-84d2-b3816d52789d"/>
|
||||
<textElement>
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Affected URL's:]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement x="0" y="-12" width="80" height="32" forecolor="#FFFFFF" uuid="c6ec29f3-3687-4098-80b5-30fd33a7989a"/>
|
||||
<textElement verticalAlignment="Middle">
|
||||
<font size="14" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Finding:]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</detail>
|
||||
</jasperReport>
|
|
@ -0,0 +1,190 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad -->
|
||||
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="SeverityRatingTableSubreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="6a3399a9-b8f7-4c58-a21d-8578e392dc84">
|
||||
<style name="Table_TH" mode="Opaque" backcolor="#232B44">
|
||||
<box>
|
||||
<pen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<topPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<leftPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<bottomPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<rightPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
</box>
|
||||
</style>
|
||||
<style name="Table_CH" mode="Opaque" backcolor="#FEFEFF">
|
||||
<box>
|
||||
<pen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<topPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<leftPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<bottomPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<rightPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
</box>
|
||||
</style>
|
||||
<style name="Table_TD" mode="Opaque" backcolor="#FFFFFF">
|
||||
<box>
|
||||
<pen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<topPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<leftPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<bottomPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
<rightPen lineWidth="0.5" lineColor="#232B44"/>
|
||||
</box>
|
||||
</style>
|
||||
<subDataset name="SeverityRatingDefinition" uuid="adea3afd-3a9c-4386-b540-562fde7a2419">
|
||||
<queryString>
|
||||
<![CDATA[]]>
|
||||
</queryString>
|
||||
</subDataset>
|
||||
<queryString>
|
||||
<![CDATA[]]>
|
||||
</queryString>
|
||||
<background>
|
||||
<band splitType="Stretch"/>
|
||||
</background>
|
||||
<detail>
|
||||
<band height="620" splitType="Stretch">
|
||||
<componentElement>
|
||||
<reportElement positionType="Float" x="-20" y="-20" width="560" height="620" uuid="10d88177-713d-4c60-9266-5afb31684f19">
|
||||
<property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.VerticalRowLayout"/>
|
||||
<property name="com.jaspersoft.studio.table.style.table_header" value="Table_TH"/>
|
||||
<property name="com.jaspersoft.studio.table.style.column_header" value="Table_CH"/>
|
||||
<property name="com.jaspersoft.studio.table.style.detail" value="Table_TD"/>
|
||||
<property name="com.jaspersoft.studio.components.autoresize.proportional" value="true"/>
|
||||
</reportElement>
|
||||
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" whenNoDataType="AllSectionsNoDetail">
|
||||
<datasetRun subDataset="SeverityRatingDefinition" uuid="297fe663-872d-43d4-a947-9106a126a556">
|
||||
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JREmptyDataSource()]]></dataSourceExpression>
|
||||
</datasetRun>
|
||||
<jr:column width="112" uuid="dd4a463a-7807-42ae-9419-7a17135a2a58">
|
||||
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column1"/>
|
||||
<jr:tableHeader style="Table_TH" height="30" rowSpan="1">
|
||||
<staticText>
|
||||
<reportElement x="0" y="0" width="112" height="30" forecolor="#FFFFFF" uuid="140fe665-f028-4805-a55f-4b4190be3140"/>
|
||||
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||
<font size="12" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Rating]]></text>
|
||||
</staticText>
|
||||
</jr:tableHeader>
|
||||
<jr:tableFooter style="Table_CH" height="200" rowSpan="1">
|
||||
<staticText>
|
||||
<reportElement positionType="Float" stretchType="ContainerHeight" x="0" y="0" width="112" height="200" forecolor="#03C886" uuid="bb091668-8003-45fc-a4aa-e54a96f7fa87"/>
|
||||
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||
<font size="16" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Low]]></text>
|
||||
</staticText>
|
||||
</jr:tableFooter>
|
||||
<jr:columnHeader style="Table_CH" height="90" rowSpan="1">
|
||||
<staticText>
|
||||
<reportElement positionType="Float" stretchType="ContainerHeight" x="0" y="0" width="112" height="90" forecolor="#FF3D70" uuid="d742063f-e537-400f-bb31-bb55fa9f20fd"/>
|
||||
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||
<font size="16" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Critical]]></text>
|
||||
</staticText>
|
||||
</jr:columnHeader>
|
||||
<jr:columnFooter style="Table_CH" height="200" rowSpan="1">
|
||||
<staticText>
|
||||
<reportElement positionType="Float" stretchType="ContainerHeight" x="0" y="0" width="112" height="200" forecolor="#35A4FE" uuid="a8b12a40-8144-4226-870f-0e0a1e5ea752"/>
|
||||
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||
<font size="16" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Medium]]></text>
|
||||
</staticText>
|
||||
</jr:columnFooter>
|
||||
<jr:detailCell style="Table_TD" height="100">
|
||||
<staticText>
|
||||
<reportElement positionType="Float" stretchType="ContainerHeight" x="0" y="0" width="112" height="100" forecolor="#FFAB00" uuid="4a1dd484-384f-45ca-a41a-8d1d2b5fb1e6"/>
|
||||
<textElement textAlignment="Center" verticalAlignment="Middle">
|
||||
<font size="16" isBold="true"/>
|
||||
</textElement>
|
||||
<text><![CDATA[High]]></text>
|
||||
</staticText>
|
||||
</jr:detailCell>
|
||||
</jr:column>
|
||||
<jr:column width="448" uuid="ab851b91-c506-48d4-a4e6-77292e4c42ef">
|
||||
<property name="com.jaspersoft.studio.components.table.model.column.name" value="Column2"/>
|
||||
<jr:tableHeader style="Table_TH" height="30" rowSpan="1">
|
||||
<staticText>
|
||||
<reportElement x="0" y="0" width="448" height="30" forecolor="#FFFFFF" uuid="7c3f036d-ed06-4aa2-bba2-f45c7eb91316">
|
||||
<property name="com.jaspersoft.studio.unit.leftIndent" value="px"/>
|
||||
</reportElement>
|
||||
<textElement textAlignment="Left" verticalAlignment="Middle">
|
||||
<font size="12" isBold="true"/>
|
||||
<paragraph leftIndent="2"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Severity Rating Definition]]></text>
|
||||
</staticText>
|
||||
</jr:tableHeader>
|
||||
<jr:tableFooter style="Table_CH" height="200" rowSpan="1">
|
||||
<staticText>
|
||||
<reportElement positionType="Float" stretchType="ContainerHeight" x="0" y="0" width="448" height="200" uuid="9e066b11-0381-46ce-a05b-99b2293ce66c">
|
||||
<property name="com.jaspersoft.studio.unit.leftIndent" value="px"/>
|
||||
</reportElement>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
<paragraph leftIndent="2"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Exploitation of the technical or procedural vulnerability will cause minimal impact to operations. The
|
||||
Confidentiality, Integrity and Availability (CIA) of sensitive information are not at risk of compromise.
|
||||
Exploitation of the vulnerability may cause slight financial loss or public embarrassment. The threat exposure is
|
||||
moderate-to-low. Security controls are in place to contain the severity of impact if the vulnerability were
|
||||
exploited, such that further political, financial, or legal damage will not occur.
|
||||
- OR -
|
||||
The vulnerability is such that it would otherwise be considered Medium Risk, but the threat exposure is so limited
|
||||
that the likelihood of occurrence is minimal.]]></text>
|
||||
</staticText>
|
||||
</jr:tableFooter>
|
||||
<jr:columnHeader style="Table_CH" height="90" rowSpan="1">
|
||||
<staticText>
|
||||
<reportElement positionType="Float" stretchType="ContainerHeight" x="0" y="0" width="448" height="90" uuid="628591b9-4f90-45cf-896c-e38355ed9de8">
|
||||
<property name="com.jaspersoft.studio.unit.firstLineIndent" value="pixel"/>
|
||||
<property name="com.jaspersoft.studio.unit.leftIndent" value="px"/>
|
||||
</reportElement>
|
||||
<textElement textAlignment="Left">
|
||||
<font size="12"/>
|
||||
<paragraph lineSpacingSize="1.0" leftIndent="2"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Exploitation of the technical or procedural vulnerability will cause substantial harm. Significant political,
|
||||
financial, and/or legal damage is likely to result. The threat exposure is critical, and a publicly available mechanism exists to exploit the vulnerability. Security controls are not effectively implemented to reduce the severity of impact if the vulnerability were exploited.]]></text>
|
||||
</staticText>
|
||||
</jr:columnHeader>
|
||||
<jr:columnFooter style="Table_CH" height="200" rowSpan="1">
|
||||
<staticText>
|
||||
<reportElement positionType="Float" stretchType="ContainerHeight" x="0" y="0" width="448" height="200" uuid="b9e7a6f9-946f-4824-8a9e-24bc3279589a">
|
||||
<property name="com.jaspersoft.studio.unit.leftIndent" value="px"/>
|
||||
</reportElement>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
<paragraph leftIndent="2"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Exploitation of the technical or procedural vulnerability will significantly impact the confidentiality, integrity,
|
||||
and/or availability of the system, application, or data. Exploitation of the vulnerability may cause moderate
|
||||
financial loss or public embarrassment. The threat exposure is moderate-to-high, thereby increasing the
|
||||
likelihood of occurrence. Security controls are in place to contain the severity of impact if the vulnerability were
|
||||
exploited, such that further political, financial, or legal damage will not occur.
|
||||
- OR -
|
||||
The vulnerability is such that it would otherwise be considered High Risk, but the threat exposure is so limited
|
||||
that the likelihood of occurrence is minimal.]]></text>
|
||||
</staticText>
|
||||
</jr:columnFooter>
|
||||
<jr:detailCell style="Table_TD" height="100">
|
||||
<staticText>
|
||||
<reportElement positionType="Float" stretchType="ContainerHeight" x="0" y="0" width="448" height="100" uuid="8a292592-81b2-49a1-bfda-e9540ecb3aa9">
|
||||
<property name="com.jaspersoft.studio.unit.leftIndent" value="px"/>
|
||||
</reportElement>
|
||||
<textElement>
|
||||
<font size="12"/>
|
||||
<paragraph leftIndent="2"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Exploitation of the technical or procedural vulnerability will cause substantial harm. Significant political,
|
||||
financial, and/or legal damage is likely to result. The threat exposure is high, thereby increasing the likelihood of
|
||||
occurrence. Security controls are not effectively implemented to reduce the severity of impact if the vulnerability
|
||||
were exploited.]]></text>
|
||||
</staticText>
|
||||
</jr:detailCell>
|
||||
</jr:column>
|
||||
</jr:table>
|
||||
</componentElement>
|
||||
</band>
|
||||
</detail>
|
||||
</jasperReport>
|
|
@ -14,7 +14,8 @@
|
|||
"https://akveo.github.io/nebular/docs/components/progress-bar/examples#nbprogressbarcomponent"
|
||||
],
|
||||
"reproduction": "Step 1: Test",
|
||||
"mitigation": "Test Mitigation"
|
||||
"mitigation": "Test Mitigation",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"id": "58f63b4e-97fb-4fe8-8527-7996896089d2",
|
||||
|
@ -24,7 +25,8 @@
|
|||
"impact": "Medium",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Medium",
|
||||
"mitigation": ""
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"comments": [
|
||||
|
@ -32,7 +34,7 @@
|
|||
"id": "89703b19-16c7-49e5-8e33-0c706313e5fe",
|
||||
"title": "Test Comment",
|
||||
"description": "No related findings",
|
||||
"relatedFindings": []
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"status": "COMPLETED"
|
||||
|
@ -50,7 +52,8 @@
|
|||
"impact": "High",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "High",
|
||||
"mitigation": ""
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"comments": [],
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
"https://www.google.de/"
|
||||
],
|
||||
"reproduction": "Step 1: Test",
|
||||
"mitigation": ""
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"id": "58f63b4e-97fb-4fe8-8527-7996896089d2",
|
||||
|
@ -32,7 +33,8 @@
|
|||
"impact": "Medium Impact",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Step 1: Medium",
|
||||
"mitigation": "Fusce sit amet massa efficitur, egestas neque vitae, elementum orci. Nullam accumsan nunc id risus volutpat, quis sagittis lorem sollicitudin. Nam finibus justo non arcu vulputate dignissim. Etiam libero felis, dignissim non feugiat at, ornare non elit. Sed hendrerit risus id magna porttitor interdum."
|
||||
"mitigation": "Fusce sit amet massa efficitur, egestas neque vitae, elementum orci. Nullam accumsan nunc id risus volutpat, quis sagittis lorem sollicitudin. Nam finibus justo non arcu vulputate dignissim. Etiam libero felis, dignissim non feugiat at, ornare non elit. Sed hendrerit risus id magna porttitor interdum.",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"id": "58f63b4e-97fb-4fe8-8527-7996896089d2",
|
||||
|
@ -42,7 +44,8 @@
|
|||
"impact": "High Impact",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Step 1: High",
|
||||
"mitigation": ""
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"id": "58f63b4e-97fb-4fe8-8527-7996896089d2",
|
||||
|
@ -54,7 +57,8 @@
|
|||
"https://community.jaspersoft.com/system/files/restricted-docs/jaspersoft-studio-user-guide.pdf"
|
||||
],
|
||||
"reproduction": "Step 1: Critical",
|
||||
"mitigation": "Fusce sit amet massa efficitur, egestas neque vitae, elementum orci. Nullam accumsan nunc id risus volutpat, quis sagittis lorem sollicitudin. Nam finibus justo non arcu vulputate dignissim. Etiam libero felis, dignissim non feugiat at, ornare non elit. Sed hendrerit risus id magna porttitor interdum."
|
||||
"mitigation": "Fusce sit amet massa efficitur, egestas neque vitae, elementum orci. Nullam accumsan nunc id risus volutpat, quis sagittis lorem sollicitudin. Nam finibus justo non arcu vulputate dignissim. Etiam libero felis, dignissim non feugiat at, ornare non elit. Sed hendrerit risus id magna porttitor interdum.",
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"comments": [
|
||||
|
@ -62,15 +66,13 @@
|
|||
"id": "89703b19-16c7-49e5-8e33-0c706313e5fe",
|
||||
"title": "Test Comment",
|
||||
"description": "Not related to findings",
|
||||
"relatedFindings": [
|
||||
"58f63b4e-97fb-4fe8-8527-7996896089d2"
|
||||
]
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"id": "89703b19-16c7-49e5-8e33-0c706313e5fe",
|
||||
"title": "Test Comment",
|
||||
"description": "Test Decription",
|
||||
"relatedFindings": []
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"status": "COMPLETED"
|
||||
|
@ -88,7 +90,8 @@
|
|||
"impact": "High",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "High",
|
||||
"mitigation": ""
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"comments": [],
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
"https://akveo.github.io/nebular/docs/components/progress-bar/examples#nbprogressbarcomponent"
|
||||
],
|
||||
"reproduction": "Step 1: Test",
|
||||
"mitigation": "Test Mitigation"
|
||||
"mitigation": "Test Mitigation",
|
||||
"attachments": []
|
||||
},
|
||||
{
|
||||
"id": "58f63b4e-97fb-4fe8-8527-7996896089d2",
|
||||
|
@ -33,7 +34,8 @@
|
|||
"impact": "Medium",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "Medium",
|
||||
"mitigation": ""
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"comments": [
|
||||
|
@ -41,7 +43,7 @@
|
|||
"id": "89703b19-16c7-49e5-8e33-0c706313e5fe",
|
||||
"title": "Test Comment",
|
||||
"description": "No related findings",
|
||||
"relatedFindings": []
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"status": "COMPLETED"
|
||||
|
@ -59,7 +61,8 @@
|
|||
"impact": "High",
|
||||
"affectedUrls": [],
|
||||
"reproduction": "High",
|
||||
"mitigation": ""
|
||||
"mitigation": "",
|
||||
"attachments": []
|
||||
}
|
||||
],
|
||||
"comments": [],
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 220 KiB After Width: | Height: | Size: 224 KiB |
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue