From 47596f0ce2e86f2cd2b5f68ff722479c69f6692a Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Wed, 27 Sep 2023 11:21:36 -0400 Subject: [PATCH 01/22] Fix/textarea autosize firefox (#505) * formatting * ngx-autosize * line-height * set min-height on firefox to fix tab jumping * markdown preview height * update css --- app/package-lock.json | 13 ++++++++++++ app/package.json | 1 + app/src/app/app.module.ts | 4 +++- .../descriptive-edit.component.html | 4 ++-- .../descriptive-edit.component.scss | 15 +++++++++++++ .../descriptive-edit.component.ts | 21 +++++++++---------- 6 files changed, 44 insertions(+), 14 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index edbdde5f..558592db 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -22,6 +22,7 @@ "@angular/router": "^14.3.0", "jdenticon": "^3.2.0", "moment": "^2.29.4", + "ngx-autosize": "^2.0.4", "ngx-jdenticon": "^2.0.0", "ngx-logger": "^5.0.12", "ngx-markdown": "^14.0.1", @@ -9810,6 +9811,18 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/ngx-autosize": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/ngx-autosize/-/ngx-autosize-2.0.4.tgz", + "integrity": "sha512-+MgkvrJs5k/CdTXpkGnwFq/zhNurT1npuQYgCN/e3oDn3LV7xRJaRJQtYY6j+BwqnN4Tkujr4+6kUQtAMp55mA==", + "dependencies": { + "tslib": ">2.0.0" + }, + "peerDependencies": { + "@angular/common": ">12.0.0", + "@angular/core": ">12.0.0" + } + }, "node_modules/ngx-jdenticon": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ngx-jdenticon/-/ngx-jdenticon-2.0.0.tgz", diff --git a/app/package.json b/app/package.json index d6c9e3d9..2f19b148 100644 --- a/app/package.json +++ b/app/package.json @@ -44,6 +44,7 @@ "@angular/router": "^14.3.0", "jdenticon": "^3.2.0", "moment": "^2.29.4", + "ngx-autosize": "^2.0.4", "ngx-jdenticon": "^2.0.0", "ngx-logger": "^5.0.12", "ngx-markdown": "^14.0.1", diff --git a/app/src/app/app.module.ts b/app/src/app/app.module.ts index 1f133e19..4b0d2a1e 100644 --- a/app/src/app/app.module.ts +++ b/app/src/app/app.module.ts @@ -1,7 +1,7 @@ import { environment } from 'src/environments/environment'; import { LoggerModule } from 'ngx-logger'; -//angular imports +// angular imports import { BrowserModule } from '@angular/platform-browser'; import { APP_INITIALIZER, NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; @@ -52,6 +52,7 @@ import { MaterialFileInputModule } from 'ngx-material-file-input'; import { MarkdownModule } from "ngx-markdown"; import { PopoverModule } from "ngx-smart-popover"; import { NgxJdenticonModule, JDENTICON_CONFIG } from 'ngx-jdenticon'; +import { AutosizeModule } from 'ngx-autosize'; // custom components import { HeaderComponent } from './components/header/header.component'; @@ -359,6 +360,7 @@ export function initConfig(appConfigService: AppConfigService) { }), PopoverModule, NgxJdenticonModule, + AutosizeModule, BrowserModule, diff --git a/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.html b/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.html index e2916caa..05f8df12 100644 --- a/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.html +++ b/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.html @@ -6,7 +6,7 @@

{{config.label}}

info_outline - + @@ -14,7 +14,7 @@

{{config.label}}

{{config.label}}

- +
diff --git a/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.scss b/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.scss index 11fe22f5..d43883a8 100644 --- a/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.scss +++ b/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.scss @@ -1,6 +1,21 @@ @import "../../../../../style/globals"; .descriptive-edit { + @-moz-document url-prefix() { + min-height: 40vh; + .moz-height { + min-height: 40vh !important; + max-height: 60vh; + overflow-y: auto !important; + } + .markdown-view { + min-height: 40vh !important; + display: flex; + } + } + .mat-input-element { + line-height: 1.5; + } .mat-tab-header { border: 0px; } diff --git a/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.ts b/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.ts index 2abc4d6f..44a3492a 100644 --- a/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.ts +++ b/app/src/app/components/stix/descriptive-property/descriptive-edit/descriptive-edit.component.ts @@ -11,7 +11,6 @@ import { EditorService } from 'src/app/services/editor/editor.service'; styleUrls: ['./descriptive-edit.component.scss'], encapsulation: ViewEncapsulation.None }) - export class DescriptiveEditComponent implements OnDestroy, OnInit { @Input() public config: DescriptivePropertyConfig; @ViewChild('description') public description: DescriptiveViewComponent; @@ -22,9 +21,9 @@ export class DescriptiveEditComponent implements OnDestroy, OnInit { constructor(public restApiConnector: RestApiConnectorService, public editorService: EditorService) { } ngOnInit(): void { - if (this.config && 'parseReferences' in this.config) { - this.parseReferences = this.config.parseReferences; - } + if (this.config && 'parseReferences' in this.config) { + this.parseReferences = this.config.parseReferences; + } } ngOnDestroy(): void { @@ -46,13 +45,13 @@ export class DescriptiveEditComponent implements OnDestroy, OnInit { */ public parseCitations(): void { if (this.parseReferences) { - this.parsingCitations = true; - this.sub = this.config.object['external_references'].parseObjectCitations(this.config.object, this.restApiConnector).subscribe({ - next: (result) => { - this.parsingCitations = false; - this.editorService.onReloadReferences.emit(); - } - }) + this.parsingCitations = true; + this.sub = this.config.object['external_references'].parseObjectCitations(this.config.object, this.restApiConnector).subscribe({ + next: (result) => { + this.parsingCitations = false; + this.editorService.onReloadReferences.emit(); + } + }) } } } From 6498aa9a8ed731e3f4fe62592f0d412958799108 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Wed, 27 Sep 2023 11:56:15 -0400 Subject: [PATCH 02/22] Feature/#265 assets (#498) * add asset endpoints to api connector service * add asset class * index stix objects * add valid source/target types for asset relationships * remove unused components * asset support for collections * namespacing & validation for assets * workflow status & history support * stix-list support for assets * update stix page & stix dialog components * init asset components * asset routes * asset list page * intial asset view/edit page * update indentation * update comments * add select edit type to string property * remove padding from version field * add sector property to asset view * minor alias updates * subtype property config * fix async issue * add custom tooltip config * rename spec file * prevent memory leaks * edit related assets * initi related assets view component * update sectors type * add domain property * load allowed values for sector property * update asset view for consistency with other objects * add external references & relationships * update relationship labels * configure relationship source/target type * edit related assets * parse related asset citations * bug fix for related asset citation validation * view related assets * subtype table styles * add sectors to list page * rearrange asset fields * fix technique targets relationships * bug fixes * code smells * more code smells * reduce cognitive complexities * adjust column width * update changelog * make related_asset_sector an optional field * related_asset_sectors multi-select * update related assets table formatting --- app/src/app/app-routing-stix.module.ts | 7 + app/src/app/app.module.ts | 20 ++- app/src/app/classes/external-references.ts | 34 +++- app/src/app/classes/stix/asset.ts | 140 +++++++++++++++++ app/src/app/classes/stix/collection.ts | 24 ++- app/src/app/classes/stix/index.ts | 15 ++ app/src/app/classes/stix/relationship.ts | 2 + app/src/app/classes/stix/stix-object.ts | 26 +-- .../add-relationship-button.component.html | 2 +- .../add-relationship-button.component.ts | 6 + .../collection-import-summary.component.html | 2 +- .../collection-import-summary.component.ts | 14 +- .../object-status/object-status.component.ts | 1 + .../history-timeline.component.ts | 3 +- .../alias-edit-dialog.component.html | 3 +- ...t.spec.ts => alias-edit.component.spec.ts} | 0 .../alias-edit/alias-edit.component.ts | 4 +- .../alias-property.component.ts | 2 +- .../alias-view/alias-view.component.html | 2 - .../alias-view/alias-view.component.ts | 2 +- .../descriptive-diff.component.html | 1 - .../descriptive-diff.component.scss | 0 .../descriptive-diff.component.spec.ts | 25 --- .../descriptive-diff.component.ts | 17 -- .../external-references-diff.component.html | 1 - .../external-references-diff.component.scss | 0 ...external-references-diff.component.spec.ts | 25 --- .../external-references-diff.component.ts | 17 -- .../list-edit/list-edit.component.html | 6 +- .../list-edit/list-edit.component.scss | 1 + .../list-edit/list-edit.component.ts | 31 ++-- .../stix/stix-list/stix-list.component.ts | 19 ++- .../string-property.component.html | 5 +- .../subtype-dialog.component.html | 37 +++++ .../subtype-dialog.component.scss | 13 ++ .../subtype-dialog.component.spec.ts | 25 +++ .../subtype-dialog.component.ts | 128 +++++++++++++++ .../subtype-edit/subtype-edit.component.html | 13 ++ .../subtype-edit/subtype-edit.component.scss | 5 + .../subtype-edit.component.spec.ts | 25 +++ .../subtype-edit/subtype-edit.component.ts | 52 ++++++ .../subtype-property.component.html | 4 + .../subtype-property.component.spec.ts | 25 +++ .../subtype-property.component.ts | 34 ++++ .../subtype-view/subtype-view.component.html | 17 ++ .../subtype-view/subtype-view.component.scss | 29 ++++ .../subtype-view.component.spec.ts | 25 +++ .../subtype-view/subtype-view.component.ts | 79 ++++++++++ .../stix/timestamp-property/README.md | 2 - .../timestamp-diff.component.html | 1 - .../timestamp-diff.component.scss | 0 .../timestamp-diff.component.spec.ts | 25 --- .../timestamp-diff.component.ts | 19 --- .../version-edit/version-edit.component.scss | 3 + .../version-edit/version-edit.component.ts | 5 +- .../rest-api/rest-api-connector.service.ts | 45 +++++- .../asset-list/asset-list.component.html | 11 ++ .../asset-list/asset-list.component.scss | 4 + .../asset-list/asset-list.component.spec.ts | 25 +++ .../asset/asset-list/asset-list.component.ts | 15 ++ .../asset-view/asset-view.component.html | 148 ++++++++++++++++++ .../asset-view/asset-view.component.spec.ts | 25 +++ .../asset/asset-view/asset-view.component.ts | 24 +++ .../campaign-list/campaign-list.component.ts | 4 +- .../campaign-view.component.html | 9 +- .../collection-import-review.component.ts | 17 +- .../collection-import.component.ts | 20 +-- .../collection-imported-list.component.html | 1 - .../collection-imported-list.component.scss | 0 ...collection-imported-list.component.spec.ts | 25 --- .../collection-imported-list.component.ts | 17 -- .../collection-view.component.html | 2 +- .../collection-view.component.ts | 23 +-- .../data-component-view.component.html | 3 +- .../group-view/group-view.component.html | 8 +- .../mitigation-view.component.html | 3 +- .../relationship-view.component.ts | 7 +- .../software-view.component.html | 9 +- .../stix-dialog/stix-dialog.component.html | 5 + .../stix/stix-dialog/stix-dialog.component.ts | 19 +-- .../stix/stix-page/stix-page.component.html | 1 + .../stix/stix-page/stix-page.component.ts | 14 +- app/src/app/views/stix/stix-view-page.ts | 4 +- .../technique-view.component.html | 38 ++++- docs/changelog.md | 3 + 85 files changed, 1214 insertions(+), 338 deletions(-) create mode 100644 app/src/app/classes/stix/asset.ts create mode 100644 app/src/app/classes/stix/index.ts rename app/src/app/components/stix/alias-property/alias-edit/{aliias-edit.component.spec.ts => alias-edit.component.spec.ts} (100%) delete mode 100644 app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.html delete mode 100644 app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.scss delete mode 100644 app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.spec.ts delete mode 100644 app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.ts delete mode 100644 app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.html delete mode 100644 app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.scss delete mode 100644 app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.spec.ts delete mode 100644 app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.ts create mode 100644 app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.html create mode 100644 app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.scss create mode 100644 app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.spec.ts create mode 100644 app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.ts create mode 100644 app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.html create mode 100644 app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.scss create mode 100644 app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.spec.ts create mode 100644 app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.ts create mode 100644 app/src/app/components/stix/subtype-property/subtype-property.component.html create mode 100644 app/src/app/components/stix/subtype-property/subtype-property.component.spec.ts create mode 100644 app/src/app/components/stix/subtype-property/subtype-property.component.ts create mode 100644 app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.html create mode 100644 app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.scss create mode 100644 app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.spec.ts create mode 100644 app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.ts delete mode 100644 app/src/app/components/stix/timestamp-property/README.md delete mode 100644 app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.html delete mode 100644 app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.scss delete mode 100644 app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.spec.ts delete mode 100644 app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.ts create mode 100644 app/src/app/views/stix/asset/asset-list/asset-list.component.html create mode 100644 app/src/app/views/stix/asset/asset-list/asset-list.component.scss create mode 100644 app/src/app/views/stix/asset/asset-list/asset-list.component.spec.ts create mode 100644 app/src/app/views/stix/asset/asset-list/asset-list.component.ts create mode 100644 app/src/app/views/stix/asset/asset-view/asset-view.component.html create mode 100644 app/src/app/views/stix/asset/asset-view/asset-view.component.spec.ts create mode 100644 app/src/app/views/stix/asset/asset-view/asset-view.component.ts delete mode 100644 app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.html delete mode 100644 app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.scss delete mode 100644 app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.spec.ts delete mode 100644 app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.ts diff --git a/app/src/app/app-routing-stix.module.ts b/app/src/app/app-routing-stix.module.ts index c179b0e1..51b681aa 100644 --- a/app/src/app/app-routing-stix.module.ts +++ b/app/src/app/app-routing-stix.module.ts @@ -11,6 +11,7 @@ import { MarkingDefinitionListComponent } from './views/stix/marking-definition/ import { DataSourceListComponent } from './views/stix/data-source/data-source-list/data-source-list.component'; import { ReferenceManagerComponent } from './views/reference-manager/reference-manager.component'; import { CampaignListComponent } from './views/stix/campaign/campaign-list/campaign-list.component'; +import { AssetListComponent } from './views/stix/asset/asset-list/asset-list.component'; import { NotesPageComponent } from './views/notes-page/notes-page.component'; import { StixPageComponent } from './views/stix/stix-page/stix-page.component'; @@ -31,6 +32,7 @@ const attackTypeToPlural = { 'mitigation': 'mitigations', 'matrix': 'matrices', 'data-source': 'data-sources', + 'asset': 'assets', } const stixRouteData = [ { @@ -73,6 +75,11 @@ const stixRouteData = [ editable: true, component: CampaignListComponent }, + { + attackType: 'asset', + editable: true, + component: AssetListComponent + }, ] const stixRoutes: Routes = []; diff --git a/app/src/app/app.module.ts b/app/src/app/app.module.ts index 4b0d2a1e..6340a4da 100644 --- a/app/src/app/app.module.ts +++ b/app/src/app/app.module.ts @@ -83,16 +83,13 @@ import { UsersListComponent } from './components/users-list/users-list.component import { ExternalReferencesPropertyComponent } from "./components/stix/external-references-property/external-references-property.component"; import { ExternalReferencesViewComponent } from './components/stix/external-references-property/external-references-view/external-references-view.component'; -import { ExternalReferencesDiffComponent } from './components/stix/external-references-property/external-references-diff/external-references-diff.component'; import { DescriptivePropertyComponent } from './components/stix/descriptive-property/descriptive-property.component'; import { DescriptiveViewComponent } from './components/stix/descriptive-property/descriptive-view/descriptive-view.component'; import { DescriptiveEditComponent } from './components/stix/descriptive-property/descriptive-edit/descriptive-edit.component'; -import { DescriptiveDiffComponent } from './components/stix/descriptive-property/descriptive-diff/descriptive-diff.component'; import { TimestampPropertyComponent } from "./components/stix/timestamp-property/timestamp-property.component"; import { TimestampViewComponent } from "./components/stix/timestamp-property/timestamp-view/timestamp-view.component"; -import { TimestampDiffComponent } from "./components/stix/timestamp-property/timestamp-diff/timestamp-diff.component"; import { StatementPropertyComponent } from "./components/stix/statement-property/statement-property.component"; import { StatementViewComponent } from './components/stix/statement-property/statement-view/statement-view.component'; @@ -125,6 +122,11 @@ import { AliasViewComponent } from './components/stix/alias-property/alias-view/ import { AliasEditComponent } from './components/stix/alias-property/alias-edit/alias-edit.component'; import { AliasEditDialogComponent } from './components/stix/alias-property/alias-edit/alias-edit-dialog/alias-edit-dialog.component'; +import { SubtypePropertyComponent } from './components/stix/subtype-property/subtype-property.component'; +import { SubtypeViewComponent } from './components/stix/subtype-property/subtype-view/subtype-view.component'; +import { SubtypeEditComponent } from './components/stix/subtype-property/subtype-edit/subtype-edit.component'; +import { SubtypeDialogComponent } from './components/stix/subtype-property/subtype-dialog/subtype-dialog.component'; + import { OrderedListPropertyComponent } from './components/stix/ordered-list-property/ordered-list-property.component'; import { OrderedListViewComponent } from './components/stix/ordered-list-property/ordered-list-view/ordered-list-view.component'; import { OrderedListEditComponent } from './components/stix/ordered-list-property/ordered-list-edit/ordered-list-edit.component'; @@ -200,6 +202,9 @@ import { TacticCellComponent } from './components/matrix/tactic-cell/tactic-cell import { TechniqueCellComponent } from './components/matrix/technique-cell/technique-cell.component'; import { MatrixFlatComponent } from './views/stix/matrix/matrix-flat/matrix-flat.component'; +import { AssetListComponent } from './views/stix/asset/asset-list/asset-list.component'; +import { AssetViewComponent } from './views/stix/asset/asset-view/asset-view.component'; + import { TeamsListPageComponent } from './views/admin-page/teams/teams-list-page/teams-list-page.component'; import { TeamsViewPageComponent } from './views/admin-page/teams/teams-view-page/teams-view-page.component'; import { CreateNewDialogComponent } from './components/create-new-dialog/create-new-dialog.component'; @@ -240,13 +245,10 @@ export function initConfig(appConfigService: AppConfigService) { DescriptivePropertyComponent, DescriptiveViewComponent, DescriptiveEditComponent, - DescriptiveDiffComponent, ExternalReferencesPropertyComponent, ExternalReferencesViewComponent, - ExternalReferencesDiffComponent, TimestampPropertyComponent, TimestampViewComponent, - TimestampDiffComponent, StatementPropertyComponent, StatementViewComponent, StatementEditComponent, @@ -340,6 +342,12 @@ export function initConfig(appConfigService: AppConfigService) { TeamsViewPageComponent, CreateNewDialogComponent, UsersListComponent, + AssetListComponent, + AssetViewComponent, + SubtypePropertyComponent, + SubtypeViewComponent, + SubtypeEditComponent, + SubtypeDialogComponent, BreadcrumbComponent ], imports: [ diff --git a/app/src/app/classes/external-references.ts b/app/src/app/classes/external-references.ts index e4420740..291feb5c 100644 --- a/app/src/app/classes/external-references.ts +++ b/app/src/app/classes/external-references.ts @@ -4,6 +4,7 @@ import { RestApiConnectorService } from "../services/connectors/rest-api/rest-ap import { Serializable, ValidationData } from "./serializable"; import { StixObject } from "./stix/stix-object"; import { logger } from "../util/logger"; +import { RelatedAsset } from "./stix/asset"; export class ExternalReferences extends Serializable { private _externalReferences : Map = new Map(); @@ -146,12 +147,15 @@ export class ExternalReferences extends Serializable { // get list of descriptive fields that support citations let refs_fields = ['description']; if (['software', 'group', 'campaign'].includes(object.attackType)) refs_fields.push('aliases'); + if (object.attackType == 'asset') refs_fields.push('relatedAssets'); if (object.attackType == 'technique') refs_fields.push('detection'); if (object.attackType == 'campaign') refs_fields.push('first_seen_citation', 'last_seen_citation'); + // parse citations for each descriptive field on the object let parse_apis = []; for (let field of refs_fields) { if (field == 'aliases') parse_apis.push(this.parseCitationsFromAliases(object[field], restAPIConnector)); + if (field == 'relatedAssets') parse_apis.push(this.parseCitationsFromRelatedAssets(object[field], restAPIConnector)); else parse_apis.push(this.parseCitations(object[field], restAPIConnector)); } @@ -252,6 +256,33 @@ export class ExternalReferences extends Serializable { ) } + /** + * Parse citations from related assets which stores descriptions in the related asset object + * Add missing references to object if found in global external reference list + * @param relatedAssets list of related asset objects + * @param restApiConnector to connect to the REST API + */ + public parseCitationsFromRelatedAssets(relatedAssets : RelatedAsset[], restApiConnector : RestApiConnectorService): Observable { + // Parse citations from the related asset descriptions + let api_calls = []; + let result = new CitationParseResult(); + for (let relatedAsset of relatedAssets) { + if ('description' in relatedAsset && relatedAsset.description) { + api_calls.push(this.parseCitations(relatedAsset.description, restApiConnector)); + } + } + if (api_calls.length == 0) return of(result); + else return forkJoin(api_calls).pipe( // get citation errors + map((api_results) => { + let citation_results = api_results as any; + for (let citation_result of citation_results) { // merge into master list + result.merge(citation_result); + } + return result; // return master list + }) + ) + } + /** * Update external references map with given reference list * @param references list of references @@ -354,7 +385,8 @@ export class ExternalReferences extends Serializable { let parse_apis = []; for (let field of options.fields) { if (!Object.keys(options.object)) continue; //object does not implement the field - if (field == "aliases") parse_apis.push(this.parseCitationsFromAliases(options.object[field], restAPIService)) + if (field == "aliases") parse_apis.push(this.parseCitationsFromAliases(options.object[field], restAPIService)); + else if (field == 'relatedAssets') parse_apis.push(this.parseCitationsFromRelatedAssets(options.object[field], restAPIService)); else parse_apis.push(this.parseCitations(options.object[field], restAPIService)); } return forkJoin(parse_apis).pipe( diff --git a/app/src/app/classes/stix/asset.ts b/app/src/app/classes/stix/asset.ts new file mode 100644 index 00000000..9a1243d7 --- /dev/null +++ b/app/src/app/classes/stix/asset.ts @@ -0,0 +1,140 @@ +import { StixObject } from "./stix-object"; +import { logger } from "../../util/logger"; +import { Observable } from "rxjs"; +import { RestApiConnectorService } from "src/app/services/connectors/rest-api/rest-api-connector.service"; +import { ValidationData } from "../serializable"; + +export class Asset extends StixObject { + public name: string = ""; + public contributors: string[] = []; + public sectors: string[] = []; + public relatedAssets: RelatedAsset[] = []; + public platforms: string[] = []; + + // assets are ICS-only + public domains: string[] = ['ics-attack']; + + public readonly supportsAttackID = true; + public readonly supportsNamespace = true; + protected get attackIDValidator() { + return { + regex: "A\\d{4}", + format: "A####" + } + } + + constructor(sdo?: any) { + super(sdo, "x-mitre-asset"); + if (sdo) { + this.deserialize(sdo); + } + } + + /** + * Transform the current object into a raw object for sending to the back-end, stripping any unnecessary fields + * @abstract + * @returns {*} the raw object to send + */ + public serialize(): any { + let rep = super.base_serialize(); + + rep.stix.name = this.name.trim(); + rep.stix.x_mitre_domains = this.domains; + rep.stix.x_mitre_sectors = this.sectors; + rep.stix.x_mitre_related_assets = this.relatedAssets.map((asset: RelatedAsset) => { + return { + name: asset.name.trim(), + related_asset_sectors: asset.related_asset_sectors ? asset.related_asset_sectors : [], + description: asset.description ? asset.description : "" + } + }); + rep.stix.x_mitre_platforms = this.platforms; + rep.stix.x_mitre_contributors = this.contributors.map(x => x.trim()); + + return rep; + } + + public isRelatedAssetArray(arr: any[]): boolean { + return arr.every(a => this.instanceOfRelatedAsset(a)); + } + + public instanceOfRelatedAsset(object: any): boolean { + return 'name' in object && 'related_asset_sectors' in object; + } + + /** + * Parse the object from the record returned from the back-end + * @abstract + * @param {*} raw the raw object to parse + */ + public deserialize(raw: any) { + if (!("stix" in raw)) return; + + let sdo = raw.stix; + + if (!("name" in sdo)) this.name = ""; + else if (typeof(sdo.name) === "string") this.name = sdo.name; + else logger.error(`TypeError: name field is not a string: ${sdo.name} (${typeof(sdo.name)})`); + + if (!("x_mitre_sectors" in sdo)) this.sectors = []; + else if (this.isStringArray(sdo.x_mitre_sectors)) this.sectors = sdo.x_mitre_sectors; + else logger.error(`TypeError: x_mitre_sectors field is not a string array.`); + + if (!("x_mitre_related_assets" in sdo)) this.relatedAssets = []; + else if (this.isRelatedAssetArray(sdo.x_mitre_related_assets)) this.relatedAssets = sdo.x_mitre_related_assets; + else logger.error(`TypeError: x_mitre_related_assets field is not an array of related assets.`); + + if (!("x_mitre_platforms" in sdo)) this.platforms = []; + else if (this.isStringArray(sdo.x_mitre_platforms)) this.platforms = sdo.x_mitre_platforms; + else logger.error(`TypeError: platforms field is not a string array.`); + + if (!("x_mitre_domains" in sdo)) this.domains = ["ics-attack"]; + else if(this.isStringArray(sdo.x_mitre_domains)) this.domains = sdo.x_mitre_domains; + else logger.error(`TypeError: domains field is not a string array.`); + + if (!("x_mitre_contributors" in sdo)) this.contributors = []; + else if (this.isStringArray(sdo.x_mitre_contributors)) this.contributors = sdo.x_mitre_contributors; + else logger.error(`TypeError: x_mitre_contributors is not a string array.`); + } + + /** + * Validate the current object state and return information on the result of the validation + * @param {RestApiConnectorService} restAPIService: the REST API connector through which asynchronous validation can be completed + * @returns {Observable} the validation warnings and errors once validation is complete. + */ + public validate(restAPIService: RestApiConnectorService): Observable { + return this.base_validate(restAPIService); + } + + /** + * Save the current state of the STIX object in the database. Update the current object from the response + * @param restAPIService [RestApiConnectorService] the service to perform the POST/PUT through + * @returns {Observable} of the post + */ + public save(restAPIService: RestApiConnectorService): Observable { + let postObservable = restAPIService.postAsset(this); + let subscription = postObservable.subscribe({ + next: (result) => { this.deserialize(result.serialize()); }, + complete: () => { subscription.unsubscribe(); } + }); + return postObservable; + } + + /** + * Delete this STIX object from the database. + * @param restAPIService [RestApiConnectorService] the service to perform the DELETE through + */ + public delete(restAPIService: RestApiConnectorService) : Observable<{}> { + let deleteObservable = restAPIService.deleteAsset(this.stixID); + let subscription = deleteObservable.subscribe({ + complete: () => { subscription.unsubscribe(); } + }); + return deleteObservable; + } +} + +export interface RelatedAsset { + name: string; + related_asset_sectors: string; + description: string; +} \ No newline at end of file diff --git a/app/src/app/classes/stix/collection.ts b/app/src/app/classes/stix/collection.ts index 60a50476..3b56711a 100644 --- a/app/src/app/classes/stix/collection.ts +++ b/app/src/app/classes/stix/collection.ts @@ -1,19 +1,8 @@ import { Observable, of } from 'rxjs'; import { RestApiConnectorService } from 'src/app/services/connectors/rest-api/rest-api-connector.service'; import { ValidationData } from '../serializable'; -import { Group } from './group'; -import { Matrix } from './matrix'; -import { Mitigation } from './mitigation'; -import { Relationship } from './relationship'; -import { Software } from './software'; -import { StixObject } from './stix-object'; -import { Tactic } from './tactic'; -import { Technique } from './technique'; -import { DataSource } from './data-source'; -import { DataComponent } from './data-component'; +import { Asset, Campaign, DataComponent, DataSource, Group, MarkingDefinition, Matrix, Mitigation, Relationship, Software, StixObject, Tactic, Technique } from '../stix'; import { logger } from "../../util/logger"; -import { MarkingDefinition } from './marking-definition'; -import { Campaign } from './campaign'; /** * auto-generated changelog/report about an import @@ -296,6 +285,9 @@ export class Collection extends StixObject { case "marking-definition": // marking definition this.stix_contents.push(new MarkingDefinition(obj)) break; + case "asset": // asset + this.stix_contents.push(new Asset(obj)) + break; } } } @@ -315,8 +307,9 @@ export class Collection extends StixObject { matrix: CollectionDiffCategories, group: CollectionDiffCategories, data_source: CollectionDiffCategories, - data_component: CollectionDiffCategories - marking_definition: CollectionDiffCategories + data_component: CollectionDiffCategories, + marking_definition: CollectionDiffCategories, + asset: CollectionDiffCategories } { let results = { technique: new CollectionDiffCategories(), @@ -329,7 +322,8 @@ export class Collection extends StixObject { group: new CollectionDiffCategories(), data_source: new CollectionDiffCategories(), data_component: new CollectionDiffCategories(), - marking_definition: new CollectionDiffCategories() + marking_definition: new CollectionDiffCategories(), + asset: new CollectionDiffCategories(), } // build helper lookups to reduce complexity from n^2 to n. let thisStixLookup = new Map(this.stix_contents.map(sdo => [sdo.stixID, sdo])) diff --git a/app/src/app/classes/stix/index.ts b/app/src/app/classes/stix/index.ts new file mode 100644 index 00000000..7ca4c5be --- /dev/null +++ b/app/src/app/classes/stix/index.ts @@ -0,0 +1,15 @@ +export { Asset } from "./asset"; +export { Campaign } from "./campaign"; +export { DataComponent } from "./data-component"; +export { DataSource } from "./data-source"; +export { Group } from "./group"; +export { Identity } from "./identity"; +export { MarkingDefinition } from "./marking-definition"; +export { Matrix } from "./matrix"; +export { Mitigation } from "./mitigation"; +export { Note } from "./note"; +export { Relationship } from "./relationship"; +export { Software } from "./software"; +export { StixObject } from "./stix-object"; +export { Tactic } from "./tactic"; +export { Technique } from "./technique"; \ No newline at end of file diff --git a/app/src/app/classes/stix/relationship.ts b/app/src/app/classes/stix/relationship.ts index 388ef244..4c02bc74 100644 --- a/app/src/app/classes/stix/relationship.ts +++ b/app/src/app/classes/stix/relationship.ts @@ -43,6 +43,7 @@ export class Relationship extends StixObject { if (this.relationship_type == "subtechnique-of") return ["technique"]; if (this.relationship_type == "detects") return ["data-component"]; if (this.relationship_type == "attributed-to") return ["campaign"]; + if (this.relationship_type == "targets") return ["technique"]; else return null; } /** @@ -58,6 +59,7 @@ export class Relationship extends StixObject { if (this.relationship_type == "subtechnique-of") return ["technique"]; if (this.relationship_type == "detects") return ["technique"]; if (this.relationship_type == "attributed-to") return ["group"]; + if (this.relationship_type == "targets") return ["asset"]; else return null; } diff --git a/app/src/app/classes/stix/stix-object.ts b/app/src/app/classes/stix/stix-object.ts index 1b57ca5e..9247feb2 100644 --- a/app/src/app/classes/stix/stix-object.ts +++ b/app/src/app/classes/stix/stix-object.ts @@ -22,6 +22,7 @@ let stixTypeToAttackType = { "marking-definition": "marking-definition", "x-mitre-data-source": "data-source", "x-mitre-data-component": "data-component", + "x-mitre-asset": "asset", "note": "note" } export { stixTypeToAttackType }; @@ -59,7 +60,8 @@ export abstract class StixObject extends Serializable { "note": "notes", "marking-definition": "marking-definitions", "data-source": "datasources", - "data-component": "datacomponents" + "data-component": "datacomponents", + "asset": "assets" } private defaultMarkingDefinitionsLoaded = false; // avoid overloading of default marking definitions @@ -305,6 +307,7 @@ export abstract class StixObject extends Serializable { else if (this.attackType == "technique") accessor = restAPIService.getAllTechniques(options); else if (this.attackType == "data-source") accessor = restAPIService.getAllDataSources(options); else if (this.attackType == "data-component") accessor = restAPIService.getAllDataComponents(options); + else if (this.attackType == "asset") accessor = restAPIService.getAllAssets(); else accessor = restAPIService.getAllTactics(options); return accessor.pipe( @@ -404,6 +407,7 @@ export abstract class StixObject extends Serializable { // build list of fields to validate external references on according to ATT&CK type let refs_fields = ['description']; if (['software', 'group', 'campaign'].includes(this.attackType)) refs_fields.push('aliases'); + if (this.attackType == 'asset') refs_fields.push('relatedAssets'); if (this.attackType == 'technique') refs_fields.push('detection'); if (this.attackType == 'campaign') refs_fields.push('first_seen_citation', 'last_seen_citation'); @@ -587,17 +591,19 @@ export abstract class StixObject extends Serializable { public getNamespaceID(restAPIConnector, orgNamespace): Observable { let prefix = ''; // i.e. 'TA', if StixObject type is tactic let count = '' as any; // i.e. 1234 - let copyID = this.attackID.slice(); // Deep copy of attack id this.attackID = '(generating ID)'; - let accessor = this.attackType == "group" ? restAPIConnector.getAllGroups() : - this.attackType == "campaign" ? restAPIConnector.getAllCampaigns() : - this.attackType == "mitigation" ? restAPIConnector.getAllMitigations() : - this.attackType == "software" ? restAPIConnector.getAllSoftware() : - this.attackType == "tactic" ? restAPIConnector.getAllTactics() : - this.attackType == "technique" ? restAPIConnector.getAllTechniques() : - this.attackType == "data-source" ? restAPIConnector.getAllDataSources() : - this.attackType == "matrix" ? restAPIConnector.getAllMatrices() : null; + let accessor: Observable>; + if (this.attackType == "group") accessor = restAPIConnector.getAllGroups(); + else if (this.attackType == "campaign") accessor = restAPIConnector.getAllCampaigns(); + else if (this.attackType == "mitigation") accessor = restAPIConnector.getAllMitigations(); + else if (this.attackType == "software") accessor = restAPIConnector.getAllSoftware(); + else if (this.attackType == "tactic") accessor = restAPIConnector.getAllTactics(); + else if (this.attackType == "technique") accessor = restAPIConnector.getAllTechniques(); + else if (this.attackType == "data-source") accessor = restAPIConnector.getAllDataSources(); + else if (this.attackType == "asset") accessor = restAPIConnector.getAllAssets(); + else if (this.attackType == "matrix") accessor = restAPIConnector.getAllMatrices(); + else accessor = null; // Find all other objects that have this prefix and range, and set ID to the most recent & unique ID available if (accessor) { diff --git a/app/src/app/components/add-relationship-button/add-relationship-button.component.html b/app/src/app/components/add-relationship-button/add-relationship-button.component.html index 24b722e3..8bcbdabd 100644 --- a/app/src/app/components/add-relationship-button/add-relationship-button.component.html +++ b/app/src/app/components/add-relationship-button/add-relationship-button.component.html @@ -1,6 +1,6 @@
diff --git a/app/src/app/components/add-relationship-button/add-relationship-button.component.ts b/app/src/app/components/add-relationship-button/add-relationship-button.component.ts index ca371fdb..11347461 100644 --- a/app/src/app/components/add-relationship-button/add-relationship-button.component.ts +++ b/app/src/app/components/add-relationship-button/add-relationship-button.component.ts @@ -25,6 +25,8 @@ export class AddRelationshipButtonComponent implements OnInit { public createRelationship() { let relationship = new Relationship(); relationship.relationship_type = this.config.relationship_type; + let sourceType = this.config.sourceType ? this.config.sourceType : null; + let targetType = this.config.targetType ? this.config.targetType : null; let initializer = null; if (this.config.source_object) initializer = relationship.set_source_object(this.config.source_object, this.restApiService); else if (this.config.source_ref) initializer = relationship.set_source_ref(this.config.source_ref, this.restApiService); @@ -37,6 +39,8 @@ export class AddRelationshipButtonComponent implements OnInit { this.loading = false; let config: StixViewConfig = { object: relationship, + sourceType: sourceType, + targetType: targetType, editable: true, is_new: true, mode: "edit", @@ -74,8 +78,10 @@ export interface AddRelationshipButtonConfig { relationship_type: string; //relationship type to create source_ref?: string; //initial relationship source ref. source_object?: StixObject; //initial relationship source object. Takes precedence over source_ref if both are specified, and is much faster to execute + sourceType?: string; // the source type of the relationship target_ref?: string; //initial relationship target ref target_object?: StixObject; //initial relationship target object. Takes precedence over target_ref if both are specified, and is much faster to execute + targetType?: string; // the target type of the relationship /** * reference to the current working dialog. This is relevant when adding a new relationship from within the dialog. * If provided, the 'create relationship' interface will replace the dialog content. diff --git a/app/src/app/components/collection-import-summary/collection-import-summary.component.html b/app/src/app/components/collection-import-summary/collection-import-summary.component.html index d41de28a..4f71f22d 100644 --- a/app/src/app/components/collection-import-summary/collection-import-summary.component.html +++ b/app/src/app/components/collection-import-summary/collection-import-summary.component.html @@ -1,6 +1,6 @@
- + {{format(attackType)}} ({{config.object_import_categories[attackType].object_count}}) diff --git a/app/src/app/components/collection-import-summary/collection-import-summary.component.ts b/app/src/app/components/collection-import-summary/collection-import-summary.component.ts index 0e908556..3dd900c3 100644 --- a/app/src/app/components/collection-import-summary/collection-import-summary.component.ts +++ b/app/src/app/components/collection-import-summary/collection-import-summary.component.ts @@ -1,16 +1,7 @@ import { SelectionModel } from '@angular/cdk/collections'; import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; -import { Campaign } from 'src/app/classes/stix/campaign'; +import { Asset, Campaign, DataComponent, DataSource, Group, Matrix, Mitigation, Relationship, Software, Tactic, Technique } from 'src/app/classes/stix'; import { CollectionDiffCategories } from 'src/app/classes/stix/collection'; -import { DataComponent } from 'src/app/classes/stix/data-component'; -import { DataSource } from 'src/app/classes/stix/data-source'; -import { Group } from 'src/app/classes/stix/group'; -import { Matrix } from 'src/app/classes/stix/matrix'; -import { Mitigation } from 'src/app/classes/stix/mitigation'; -import { Relationship } from 'src/app/classes/stix/relationship'; -import { Software } from 'src/app/classes/stix/software'; -import { Tactic } from 'src/app/classes/stix/tactic'; -import { Technique } from 'src/app/classes/stix/technique'; @Component({ selector: 'app-collection-import-summary', @@ -45,7 +36,8 @@ export interface CollectionImportSummaryConfig { matrix: CollectionDiffCategories, group: CollectionDiffCategories, data_source: CollectionDiffCategories, - data_component: CollectionDiffCategories + data_component: CollectionDiffCategories, + asset: CollectionDiffCategories }; select?: SelectionModel; } diff --git a/app/src/app/components/object-status/object-status.component.ts b/app/src/app/components/object-status/object-status.component.ts index a4c47302..5d5b3dde 100644 --- a/app/src/app/components/object-status/object-status.component.ts +++ b/app/src/app/components/object-status/object-status.component.ts @@ -57,6 +57,7 @@ export class ObjectStatusComponent implements OnInit { else if (this.editorService.type == "collection") data$ = this.restAPIService.getAllCollections(options); else if (this.editorService.type == "data-source") data$ = this.restAPIService.getAllDataSources(options); else if (this.editorService.type == "data-component") data$ = this.restAPIService.getAllDataComponents(options); + else if (this.editorService.type == "asset") data$ = this.restAPIService.getAllAssets(options); let objSubscription = data$.subscribe({ next: (data) => { this.objects = data.data; diff --git a/app/src/app/components/resources-drawer/history-timeline/history-timeline.component.ts b/app/src/app/components/resources-drawer/history-timeline/history-timeline.component.ts index 4abcafe7..3bd01678 100644 --- a/app/src/app/components/resources-drawer/history-timeline/history-timeline.component.ts +++ b/app/src/app/components/resources-drawer/history-timeline/history-timeline.component.ts @@ -40,8 +40,6 @@ export class HistoryTimelineComponent implements OnInit, OnDestroy { public showObjectHistory: boolean = true; public showRelationshipHistory: boolean = true; public onEditStopSubscription: Subscription; - - constructor(private route: ActivatedRoute, private router: Router, @@ -155,6 +153,7 @@ export class HistoryTimelineComponent implements OnInit, OnDestroy { else if (objectType == "collection") objects$ = this.restAPIConnectorService.getCollection(objectStixID, null, "all"); else if (objectType == "data-source") objects$ = this.restAPIConnectorService.getDataSource(objectStixID, null, "all"); else if (objectType == "data-component") objects$ = this.restAPIConnectorService.getDataComponent(objectStixID, null, "all"); + else if (objectType == "asset") objects$ = this.restAPIConnectorService.getAsset(objectStixID, null, "all"); // set up subscribers to get relationships let relationships$ = this.restAPIConnectorService.getRelatedTo({sourceOrTargetRef: objectStixID, versions: "all"}); // join subscribers diff --git a/app/src/app/components/stix/alias-property/alias-edit/alias-edit-dialog/alias-edit-dialog.component.html b/app/src/app/components/stix/alias-property/alias-edit/alias-edit-dialog/alias-edit-dialog.component.html index b55a5db1..5a598bd1 100644 --- a/app/src/app/components/stix/alias-property/alias-edit/alias-edit-dialog/alias-edit-dialog.component.html +++ b/app/src/app/components/stix/alias-property/alias-edit/alias-edit-dialog/alias-edit-dialog.component.html @@ -1,6 +1,5 @@
-

Add an associated {{config.object.attackType}}

-

Edit an associated {{config.object.attackType}}

+

{{is_new ? 'Add' : 'Edit'}} an associated {{config.object.attackType}}

associated {{config.object.attackType}} name diff --git a/app/src/app/components/stix/alias-property/alias-edit/aliias-edit.component.spec.ts b/app/src/app/components/stix/alias-property/alias-edit/alias-edit.component.spec.ts similarity index 100% rename from app/src/app/components/stix/alias-property/alias-edit/aliias-edit.component.spec.ts rename to app/src/app/components/stix/alias-property/alias-edit/alias-edit.component.spec.ts diff --git a/app/src/app/components/stix/alias-property/alias-edit/alias-edit.component.ts b/app/src/app/components/stix/alias-property/alias-edit/alias-edit.component.ts index 83b34b33..da2229a8 100644 --- a/app/src/app/components/stix/alias-property/alias-edit/alias-edit.component.ts +++ b/app/src/app/components/stix/alias-property/alias-edit/alias-edit.component.ts @@ -14,7 +14,9 @@ export class AliasEditComponent implements OnInit { @Input() public config: AliasPropertyConfig; public attackType: string; - constructor(public dialog: MatDialog) { } + constructor(public dialog: MatDialog) { + // intentionally left blank + } ngOnInit(): void { let object = Array.isArray(this.config.object)? this.config.object[0] : this.config.object; diff --git a/app/src/app/components/stix/alias-property/alias-property.component.ts b/app/src/app/components/stix/alias-property/alias-property.component.ts index 71ec1677..02f4914f 100644 --- a/app/src/app/components/stix/alias-property/alias-property.component.ts +++ b/app/src/app/components/stix/alias-property/alias-property.component.ts @@ -19,7 +19,7 @@ export class AliasPropertyComponent implements OnInit { } export interface AliasPropertyConfig { - /* What is the current mode? Default: 'view + /* What is the current mode? Default: 'view' * view: viewing the alias property * edit: editing the alias property * diff: displaying the diff between two STIX objects. If this mode is selected, two StixObjects must be specified in the objects field diff --git a/app/src/app/components/stix/alias-property/alias-view/alias-view.component.html b/app/src/app/components/stix/alias-property/alias-view/alias-view.component.html index df3f7e23..21716e2e 100644 --- a/app/src/app/components/stix/alias-property/alias-view/alias-view.component.html +++ b/app/src/app/components/stix/alias-property/alias-view/alias-view.component.html @@ -29,5 +29,3 @@
- - diff --git a/app/src/app/components/stix/alias-property/alias-view/alias-view.component.ts b/app/src/app/components/stix/alias-property/alias-view/alias-view.component.ts index 0055a571..ed2ea7ba 100644 --- a/app/src/app/components/stix/alias-property/alias-view/alias-view.component.ts +++ b/app/src/app/components/stix/alias-property/alias-view/alias-view.component.ts @@ -76,7 +76,7 @@ export class AliasViewComponent implements OnInit { } /** - * return list of aliass with descriptive text + * return list of aliases with descriptive text */ public get description(): Array<[string, string]> { if (this.config.referencesField) { diff --git a/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.html b/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.html deleted file mode 100644 index 9426a6a0..00000000 --- a/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.html +++ /dev/null @@ -1 +0,0 @@ -

descriptive-diff works!

diff --git a/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.scss b/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.spec.ts b/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.spec.ts deleted file mode 100644 index 966f7bcd..00000000 --- a/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { DescriptiveDiffComponent } from './descriptive-diff.component'; - -describe('DescriptiveDiffComponent', () => { - let component: DescriptiveDiffComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ DescriptiveDiffComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(DescriptiveDiffComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.ts b/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.ts deleted file mode 100644 index f16db1cf..00000000 --- a/app/src/app/components/stix/descriptive-property/descriptive-diff/descriptive-diff.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-descriptive-diff', - templateUrl: './descriptive-diff.component.html', - styleUrls: ['./descriptive-diff.component.scss'] -}) -export class DescriptiveDiffComponent implements OnInit { - - constructor() { - // intentionally left blank - } - - ngOnInit(): void { - // intentionally left blank - } -} diff --git a/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.html b/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.html deleted file mode 100644 index 4870eda4..00000000 --- a/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.html +++ /dev/null @@ -1 +0,0 @@ -

external-references-diff works!

diff --git a/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.scss b/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.spec.ts b/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.spec.ts deleted file mode 100644 index 8e29d9de..00000000 --- a/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ExternalReferencesDiffComponent } from './external-references-diff.component'; - -describe('ExternalReferencesDiffComponent', () => { - let component: ExternalReferencesDiffComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ ExternalReferencesDiffComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(ExternalReferencesDiffComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.ts b/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.ts deleted file mode 100644 index 1631360c..00000000 --- a/app/src/app/components/stix/external-references-property/external-references-diff/external-references-diff.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-external-references-diff', - templateUrl: './external-references-diff.component.html', - styleUrls: ['./external-references-diff.component.scss'] -}) -export class ExternalReferencesDiffComponent implements OnInit { - - constructor() { - // intentionally left blank - } - - ngOnInit(): void { - // intentionally left blank - } -} diff --git a/app/src/app/components/stix/list-property/list-edit/list-edit.component.html b/app/src/app/components/stix/list-property/list-edit/list-edit.component.html index 66faeb28..b588873b 100644 --- a/app/src/app/components/stix/list-property/list-edit/list-edit.component.html +++ b/app/src/app/components/stix/list-property/list-edit/list-edit.component.html @@ -1,5 +1,5 @@
- + {{config.label? config.label : config.field}} @@ -12,7 +12,7 @@ (matChipInputTokenEnd)="add($event)" /> - + @@ -31,7 +31,7 @@ {{item}} - + {{config.label? config.label : config.field}} diff --git a/app/src/app/components/stix/list-property/list-edit/list-edit.component.scss b/app/src/app/components/stix/list-property/list-edit/list-edit.component.scss index b22c86a3..a94e0c86 100644 --- a/app/src/app/components/stix/list-property/list-edit/list-edit.component.scss +++ b/app/src/app/components/stix/list-property/list-edit/list-edit.component.scss @@ -15,6 +15,7 @@ flex-direction: column; margin: 0.25em 0 0 0 !important; :active, :focus { outline: none; } + padding-bottom: 0px !important; } .mat-form-field-flex { flex: 1 0; diff --git a/app/src/app/components/stix/list-property/list-edit/list-edit.component.ts b/app/src/app/components/stix/list-property/list-edit/list-edit.component.ts index 0c6dce51..eb952da9 100644 --- a/app/src/app/components/stix/list-property/list-edit/list-edit.component.ts +++ b/app/src/app/components/stix/list-property/list-edit/list-edit.component.ts @@ -50,7 +50,8 @@ export class ListEditComponent implements OnInit, AfterContentChecked { "effective_permissions": "x_mitre_effective_permissions", "permissions_required": "x_mitre_permissions_required", "collection_layers": "x_mitre_collection_layers", - "data_sources": "x_mitre_data_sources" + "data_sources": "x_mitre_data_sources", + "sectors": "x_mitre_sectors" } public domains = [ "enterprise-attack", @@ -77,7 +78,8 @@ export class ListEditComponent implements OnInit, AfterContentChecked { || this.config.field == 'impact_type' || this.config.field == 'domains' || this.config.field == 'collection_layers' - || this.config.field == 'data_sources') { + || this.config.field == 'data_sources' + || this.config.field == 'sectors') { if (!this.dataLoaded) { let data$ = this.restAPIConnectorService.getAllAllowedValues(); this.sub = data$.subscribe({ @@ -117,19 +119,18 @@ export class ListEditComponent implements OnInit, AfterContentChecked { complete: () => { subscription.unsubscribe(); } }) } else if (this.config.field == 'parentTechnique') { - this.type = 'technique'; - const subscription = this.restAPIConnectorService.getAllTechniques().subscribe({ - next: (r: Paginated) => { - this.allObjects = r.data.filter((t) => !t.is_subtechnique); - const selectableTechniqueIDs = r.data.map(t => t.stixID); - this.select = new SelectionModel(false, selectableTechniqueIDs); - this.dataLoaded = true; - }, - complete: () => { - subscription.unsubscribe(); - } - }); - + this.type = 'technique'; + const subscription = this.restAPIConnectorService.getAllTechniques().subscribe({ + next: (r: Paginated) => { + this.allObjects = r.data.filter((t) => !t.is_subtechnique); + const selectableTechniqueIDs = r.data.map(t => t.stixID); + this.select = new SelectionModel(false, selectableTechniqueIDs); + this.dataLoaded = true; + }, + complete: () => { + subscription.unsubscribe(); + } + }); } } diff --git a/app/src/app/components/stix/stix-list/stix-list.component.ts b/app/src/app/components/stix/stix-list/stix-list.component.ts index 96eff0a3..a270f584 100644 --- a/app/src/app/components/stix/stix-list/stix-list.component.ts +++ b/app/src/app/components/stix/stix-list/stix-list.component.ts @@ -100,7 +100,8 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { "identity": "identity", "marking-definition": "marking-definition", "x-mitre-data-source": "data-source", - "x-mitre-data-component": "data-component" + "x-mitre-data-component": "data-component", + "x-mitre-asset": "asset" } // all possible each type of filter/groupBy @@ -306,6 +307,19 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { "display": "descriptive" }] break; + case "asset": + this.addColumn("", "workflow", "icon"); + this.addColumn("", "state", "icon"); + this.addColumn("ID", "attackID", "plain", false); + this.addColumn("name", "name", "plain", sticky_allowed, ["name"]); + this.addColumn("platforms", "platforms", "list"); + this.addColumn("sectors", "sectors", "list"); + this.addVersionsAndDatesColumns(); + this.tableDetail = [{ + "field": "description", + "display": "descriptive" + }] + break; case "relationship": this.addColumn("", "state", "icon"); if (this.config.relationshipType && this.config.relationshipType !== "detects") { @@ -786,6 +800,7 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { else if (this.config.type == "relationship") this.data$ = this.restAPIConnectorService.getRelatedTo({ sourceRef: this.config.sourceRef, targetRef: this.config.targetRef, sourceType: this.config.sourceType, targetType: this.config.targetType, relationshipType: this.config.relationshipType, excludeSourceRefs: this.config.excludeSourceRefs, excludeTargetRefs: this.config.excludeTargetRefs, limit: limit, offset: offset, includeDeprecated: deprecated }); else if (this.config.type == "data-source") this.data$ = this.restAPIConnectorService.getAllDataSources(options); else if (this.config.type == "data-component") this.data$ = this.restAPIConnectorService.getAllDataComponents(options); + else if (this.config.type == "asset") this.data$ = this.restAPIConnectorService.getAllAssets(options); else if (this.config.type == "marking-definition") this.data$ = this.restAPIConnectorService.getAllMarkingDefinitions(options); else if (this.config.type == "note") this.data$ = this.restAPIConnectorService.getAllNotes(options); let subscription = this.data$.subscribe({ @@ -886,7 +901,7 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { } //allowed types for StixListConfig -type type_attacktype = "collection" | "campaign" | "group" | "matrix" | "mitigation" | "software" | "tactic" | "technique" | "relationship" | "data-source" | "data-component" | "marking-definition" | "note"; +type type_attacktype = "collection" | "campaign" | "group" | "matrix" | "mitigation" | "software" | "tactic" | "technique" | "relationship" | "data-source" | "data-component" | "asset" | "marking-definition" | "note"; type selection_types = "one" | "many" | "disabled"; type filter_types = "state" | "workflow_status"; export interface StixListConfig { diff --git a/app/src/app/components/stix/string-property/string-property.component.html b/app/src/app/components/stix/string-property/string-property.component.html index fbcbb0db..6c5c59b3 100644 --- a/app/src/app/components/stix/string-property/string-property.component.html +++ b/app/src/app/components/stix/string-property/string-property.component.html @@ -5,11 +5,10 @@
-
+
{{config.label? config.label : config.field}}
- -
\ No newline at end of file + diff --git a/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.html b/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.html new file mode 100644 index 00000000..1e9bb13c --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.html @@ -0,0 +1,37 @@ +
+

{{isNew ? 'Add' : 'Edit'}} {{config.tooltip}}

+ + + + + {{field.name}} + + + + + + +   + Loading {{field.label? field.label : field.name}}... + + {{field.label ? field.label : field.name}} + + + + + + {{value}} cancel + + + + {{item}} + + + + + +
+ + +
+
\ No newline at end of file diff --git a/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.scss b/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.scss new file mode 100644 index 00000000..b05b2f22 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.scss @@ -0,0 +1,13 @@ +.subtype-edit-dialog { + min-width: 75vw; + .mat-form-field { + width: 100%; + } + .buttons { + button + button { + margin-left: 10px; + } + margin-top: 24px; + margin-bottom: 24px; + } +} \ No newline at end of file diff --git a/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.spec.ts b/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.spec.ts new file mode 100644 index 00000000..e74e312a --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SubtypeDialogComponent } from './subtype-dialog.component'; + +describe('SubtypeDialogComponent', () => { + let component: SubtypeDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SubtypeDialogComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SubtypeDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.ts b/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.ts new file mode 100644 index 00000000..0e977f9d --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-dialog/subtype-dialog.component.ts @@ -0,0 +1,128 @@ +import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { MatOptionSelectionChange } from '@angular/material/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { Subscription } from 'rxjs'; +import { StixObject } from 'src/app/classes/stix'; +import { RestApiConnectorService } from 'src/app/services/connectors/rest-api/rest-api-connector.service'; +import { EditorService } from 'src/app/services/editor/editor.service'; + +@Component({ + selector: 'app-subtype-dialog', + templateUrl: './subtype-dialog.component.html', + styleUrls: ['./subtype-dialog.component.scss'] +}) +export class SubtypeDialogComponent implements OnInit, OnDestroy { + public isNew: boolean = false; + public data: any = {}; + + public allowedValues: any = {}; + public selectControls: {[index: string] : FormControl} = {} ; + public dataLoaded: boolean = false; + private allowedValuesSub: Subscription = new Subscription(); + private saveSubscription: Subscription = new Subscription(); + + public get isValid(): boolean { + let required = this.config.subtypeFields.filter(field => field.required); + return required.every(field => field.name in this.data && this.data[field.name].length) + } + + constructor(public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public config: SubtypeDialogConfig, + public restApiService: RestApiConnectorService, + public editorService: EditorService) { + this.isNew = config.index == undefined; + if (!this.isNew) this.data = config.object[config.field][config.index]; + } + + ngOnInit(): void { + // retrieve 'select' fields + let selections = this.config.subtypeFields.filter(field => field.editType == 'select').map(field => field.name); + if (!selections.length) return; + + // create a form control for each 'select' field + selections.forEach(fieldName => { + if (!this.data[fieldName]) this.data[fieldName] = []; + this.selectControls[fieldName] = new FormControl(this.data[fieldName]); + }); + + // load allowed values for 'select' fields + this.allowedValuesSub = this.restApiService.getAllAllowedValues().subscribe({ + next: (data) => { + let allAllowedValues = data.find(obj => obj.objectType == this.config.object.attackType); + selections.forEach(field => { + let values: Set = new Set(); + let property = allAllowedValues.properties.find(p => p.propertyName == field); + if ("domains" in this.config.object) { + let obj = this.config.object as any; + property.domains.forEach(domain => { + if (obj.domains.includes(domain.domainName)) { + domain.allowedValues.forEach(values.add, values); + } + }) + } else { // domains not specified on object + property.domains.forEach(domain => { + domain.allowedValues.forEach(values.add, values); + }); + } + this.allowedValues[field] = Array.from(values); + }); + this.dataLoaded = true; + } + }); + } + + ngOnDestroy(): void { + if (this.allowedValuesSub) this.allowedValuesSub.unsubscribe(); + if (this.saveSubscription) this.saveSubscription.unsubscribe(); + } + + /** Add value to subtype field */ + public add(): void { + if (this.config.index || this.config.index === 0) { + // update the existing value + this.config.object[this.config.field][this.config.index] = this.data; + } else { + // add the value to the field + this.config.object[this.config.field].push(this.data); + } + + // parse citations + this.saveSubscription = this.config.object['external_references'].parseObjectCitations(this.config.object, this.restApiService).subscribe({ + next: (result) => { + this.editorService.onReloadReferences.emit(); + } + }) + this.dialogRef.close(); + } + + /** Handles onSelectionChange event to add or remove the + * user's selection from a multi-select field */ + public change(event: MatOptionSelectionChange, fieldName: string): void { + if (!event.isUserInput) return; + if (event.source.selected) this.data[fieldName].push(event.source.value); + else this.remove(fieldName, event.source.value); + } + + /** Remove value from multi-select field */ + public remove(fieldName: string, value: string): void { + let values = this.selectControls[fieldName].value as string[]; + let i = values.indexOf(value); + if (i >= 0) values.splice(i, 1); + this.selectControls[fieldName].setValue(values); + } +} + +export interface SubtypeDialogConfig { + object: StixObject; + field: string; + index?: number; + tooltip: string; + subtypeFields: { + name: string; + editType: string; + label: string; + required?: boolean; + key?: boolean; /** Specifies which subtypeField is used as an indexing key, there must be at least one */ + }[]; +} \ No newline at end of file diff --git a/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.html b/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.html new file mode 100644 index 00000000..3ccf4198 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.html @@ -0,0 +1,13 @@ +
+
+ + + {{value}} cancel + + + +
+ +
\ No newline at end of file diff --git a/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.scss b/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.scss new file mode 100644 index 00000000..fb5897d4 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.scss @@ -0,0 +1,5 @@ +.subtype-edit { + .mat-chip { + cursor: pointer; + } +} \ No newline at end of file diff --git a/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.spec.ts b/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.spec.ts new file mode 100644 index 00000000..f26afb64 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SubtypeEditComponent } from './subtype-edit.component'; + +describe('SubtypeEditComponent', () => { + let component: SubtypeEditComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SubtypeEditComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SubtypeEditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.ts b/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.ts new file mode 100644 index 00000000..b2a85067 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-edit/subtype-edit.component.ts @@ -0,0 +1,52 @@ +import { Component, Input, ViewEncapsulation } from '@angular/core'; +import { SubtypePropertyConfig } from '../subtype-property.component'; +import { MatDialog } from '@angular/material/dialog'; +import { SubtypeDialogComponent } from '../subtype-dialog/subtype-dialog.component'; + +@Component({ + selector: 'app-subtype-edit', + templateUrl: './subtype-edit.component.html', + styleUrls: ['./subtype-edit.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class SubtypeEditComponent { + @Input() public config: SubtypePropertyConfig; + + /** + * Get list of key values from subtype list + */ + public get keyValues(): any[] { + let key = this.config.subtypeFields.find(subtype => subtype.key).name; + return this.config.object[this.config.field].map(value => value[key]); + } + + constructor(public dialog: MatDialog) { + // intentionally left blank + } + + public removeValue(i: number): void { + // remove subtype from field + this.config.object[this.config.field].splice(i, 1); + } + + /** + * Open the edit dialog to create/edit the item + * @param i the index of the selected item to edit; or, if none is + * provided, create a new item + */ + public editValue(i?: number): void { + let ref = this.dialog.open(SubtypeDialogComponent, { + maxHeight: "75vh", + data: { + object: this.config.object, + field: this.config.field, + index: i, + subtypeFields: this.config.subtypeFields, + tooltip: this.config.tooltip + } + }); + let subscription = ref.afterClosed().subscribe({ + complete: () => { subscription.unsubscribe(); } + }); + } +} diff --git a/app/src/app/components/stix/subtype-property/subtype-property.component.html b/app/src/app/components/stix/subtype-property/subtype-property.component.html new file mode 100644 index 00000000..4197ad94 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-property.component.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/app/src/app/components/stix/subtype-property/subtype-property.component.spec.ts b/app/src/app/components/stix/subtype-property/subtype-property.component.spec.ts new file mode 100644 index 00000000..acb40655 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-property.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SubtypePropertyComponent } from './subtype-property.component'; + +describe('SubtypePropertyComponent', () => { + let component: SubtypePropertyComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SubtypePropertyComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SubtypePropertyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/app/src/app/components/stix/subtype-property/subtype-property.component.ts b/app/src/app/components/stix/subtype-property/subtype-property.component.ts new file mode 100644 index 00000000..28055e87 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-property.component.ts @@ -0,0 +1,34 @@ +import { Component, Input } from '@angular/core'; +import { StixObject } from 'src/app/classes/stix'; + +@Component({ + selector: 'app-subtype-property', + templateUrl: './subtype-property.component.html' +}) +export class SubtypePropertyComponent { + @Input() public config: SubtypePropertyConfig +} + +export interface SubtypePropertyConfig { + /* What is the current mode? Default: 'view' */ + mode?: "view" | "edit"; + /* The object to show the field of */ + object: StixObject; + /* The field of the object to visualize */ + field: string; + /* The label for labelled box */ + label: string; + /* The object's references field. References will be removed if not included */ + referencesField?: string; + /* The fields & types of the subtype property */ + subtypeFields: { + name: string; + type: "string" | "select"; + required?: boolean; // default false + label?: string; + supportsReferences?: boolean; // whether this field supports references, default false + key?: boolean; /** The key field, must have at least one */ + }[]; + /* The tooltip for the add button/edit dialog */ + tooltip: string; +} \ No newline at end of file diff --git a/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.html b/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.html new file mode 100644 index 00000000..37fba22a --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.html @@ -0,0 +1,17 @@ +
+
+ + + + + + + + +
{{ (column.label ? column.label : column.name) | titlecase }} + {{format(element[column.name])}} + +
+
+ +
diff --git a/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.scss b/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.scss new file mode 100644 index 00000000..9574a4b0 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.scss @@ -0,0 +1,29 @@ +@import "../../../../../style/globals"; + +.subtype-view { + @extend .labelled-box; + + .subtype-table{ + width: 100%; + padding: 8px; + tr.mat-header-row { height: 25px; } + .mat-cell, .mat-header-cell { + padding: 0 10px; + .light & { border-color: border-color(light); } + .dark & { border-color: border-color(dark); } + } + .ref-column { + // width: 65%; + } + } + .subtype-markdown { + p { + padding: 0; + margin: 0; + } + sup { + vertical-align: top; + position: relative; + } + } +} \ No newline at end of file diff --git a/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.spec.ts b/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.spec.ts new file mode 100644 index 00000000..24d96de4 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SubtypeViewComponent } from './subtype-view.component'; + +describe('SubtypeViewComponent', () => { + let component: SubtypeViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SubtypeViewComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SubtypeViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.ts b/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.ts new file mode 100644 index 00000000..a2814632 --- /dev/null +++ b/app/src/app/components/stix/subtype-property/subtype-view/subtype-view.component.ts @@ -0,0 +1,79 @@ +import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { SubtypePropertyConfig } from '../subtype-property.component'; + +@Component({ + selector: 'app-subtype-view', + templateUrl: './subtype-view.component.html', + styleUrls: ['./subtype-view.component.scss'], + encapsulation: ViewEncapsulation.None +}) +export class SubtypeViewComponent implements OnInit { + @Input() public config: SubtypePropertyConfig; + + private citationRegex = /\(Citation: (.*?)\)/gmu; + public showMore: boolean = false; + public detailTable: any[] = []; + + public get subtypeFields() { return this.config.subtypeFields; } + public get fieldLabels(): string[] { return this.config.subtypeFields.map(f => f.label ? f.label : f.name); } + + public get valueCopy() { + return JSON.parse(JSON.stringify(this.config.object[this.config.field])); //deep copy + } + + ngOnInit(): void { + this.detailTable = this.valueCopy; + this.buildTable(); + } + + /** + * Get list of references in string + * @param value string that may contains references + */ + private getReferences(value: string): Array { + return value.match(this.citationRegex); + } + + /** + * Get HTML string for reference + * @param sourceName source name of the reference + */ + private referenceToHTML(sourceName: string): string { + let reference = this.config.object[this.config.referencesField].getReference(sourceName); + let referenceNumber = this.config.object[this.config.referencesField].getIndexOfReference(sourceName); + + if (reference && referenceNumber) { + if (reference.url) { + return "[" + referenceNumber + "]"; + } + return "[" + referenceNumber + "]" + } + return ""; + } + + // Build table of values including any inline citations + public buildTable(): void { + // get subtype field that supports references + let referenceField = this.config.subtypeFields.find(f => f.supportsReferences); + if (!referenceField || !this.config.referencesField) return; + for (let row of this.detailTable) { + if (referenceField.name in row) { + // field supporting references found in row, parse citations + let references = this.getReferences(row[referenceField.name]); + if (references) { + for (let reference of references) { + let sourceName = reference.split("(Citation: ")[1].slice(0, -1); + let referenceHTML = this.referenceToHTML(sourceName); + row[referenceField.name] = row[referenceField.name].replace(reference, referenceHTML); + } + } + } + } + } + + /** Format table column */ + public format(value): string { + if (Array.isArray(value)) return value.join("; "); + return value; + } +} diff --git a/app/src/app/components/stix/timestamp-property/README.md b/app/src/app/components/stix/timestamp-property/README.md deleted file mode 100644 index 7f7d2820..00000000 --- a/app/src/app/components/stix/timestamp-property/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# timestamp-property -`timestamp-property.component` is used to display timestamp properties of STIX objects such as `created` and `modified` dates. \ No newline at end of file diff --git a/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.html b/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.html deleted file mode 100644 index 2fe189a5..00000000 --- a/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.html +++ /dev/null @@ -1 +0,0 @@ -

timestamp-diff works!

diff --git a/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.scss b/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.spec.ts b/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.spec.ts deleted file mode 100644 index ae7e91cf..00000000 --- a/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { TimestampDiffComponent } from './timestamp-diff.component'; - -describe('TimestampDiffComponent', () => { - let component: TimestampDiffComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ TimestampDiffComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(TimestampDiffComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.ts b/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.ts deleted file mode 100644 index 379efed3..00000000 --- a/app/src/app/components/stix/timestamp-property/timestamp-diff/timestamp-diff.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { TimestampPropertyConfig } from '../timestamp-property.component'; - -@Component({ - selector: 'app-timestamp-diff', - templateUrl: './timestamp-diff.component.html', - styleUrls: ['./timestamp-diff.component.scss'] -}) -export class TimestampDiffComponent implements OnInit { - @Input() public config: TimestampPropertyConfig; - - constructor() { - // intentionally left blank - } - - ngOnInit(): void { - // intentionally left blank - } -} diff --git a/app/src/app/components/stix/version-property/version-edit/version-edit.component.scss b/app/src/app/components/stix/version-property/version-edit/version-edit.component.scss index bb9951de..7e6532e8 100644 --- a/app/src/app/components/stix/version-property/version-edit/version-edit.component.scss +++ b/app/src/app/components/stix/version-property/version-edit/version-edit.component.scss @@ -2,4 +2,7 @@ mat-form-field { width: 100%; } + .mat-form-field-wrapper { + padding-bottom: 0 !important; + } } \ No newline at end of file diff --git a/app/src/app/components/stix/version-property/version-edit/version-edit.component.ts b/app/src/app/components/stix/version-property/version-edit/version-edit.component.ts index 790e1639..fd20c434 100644 --- a/app/src/app/components/stix/version-property/version-edit/version-edit.component.ts +++ b/app/src/app/components/stix/version-property/version-edit/version-edit.component.ts @@ -1,10 +1,11 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core'; import { VersionPropertyConfig } from '../version-property.component'; @Component({ selector: 'app-version-edit', templateUrl: './version-edit.component.html', - styleUrls: ['./version-edit.component.scss'] + styleUrls: ['./version-edit.component.scss'], + encapsulation: ViewEncapsulation.None }) export class VersionEditComponent implements OnInit { @Input() public config: VersionPropertyConfig; diff --git a/app/src/app/services/connectors/rest-api/rest-api-connector.service.ts b/app/src/app/services/connectors/rest-api/rest-api-connector.service.ts index 2320e6d2..28c3702e 100644 --- a/app/src/app/services/connectors/rest-api/rest-api-connector.service.ts +++ b/app/src/app/services/connectors/rest-api/rest-api-connector.service.ts @@ -25,15 +25,17 @@ import { DataComponent } from 'src/app/classes/stix/data-component'; import { UserAccount } from 'src/app/classes/authn/user-account'; import { Campaign } from 'src/app/classes/stix/campaign'; import { Team } from 'src/app/classes/authn/team'; +import { Asset } from 'src/app/classes/stix/asset'; //attack types -type AttackType = "campaign" | "collection" | "group" | "matrix" | "mitigation" | "software" | "tactic" | "technique" | "relationship" | "note" | "identity" | "marking-definition" | "data-source" | "data-component"; +type AttackType = "asset" | "campaign" | "collection" | "group" | "matrix" | "mitigation" | "software" | "tactic" | "technique" | "relationship" | "note" | "identity" | "marking-definition" | "data-source" | "data-component"; // pluralize AttackType const attackTypeToPlural = { "technique": "techniques", "tactic": "tactics", "group": "groups", "campaign": "campaigns", + "asset": "assets", "software": "software", "mitigation": "mitigations", "matrix": "matrices", @@ -51,6 +53,7 @@ const attackTypeToClass = { "tactic": Tactic, "group": Group, "campaign": Campaign, + "asset": Asset, "software": Software, "mitigation": Mitigation, "matrix": Matrix, @@ -69,6 +72,7 @@ const stixTypeToClass = { "x-mitre-tactic": Tactic, "intrusion-set": Group, "campaign": Campaign, + "x-mitre-asset": Asset, "tool": Software, "malware": Software, "course-of-action": Mitigation, @@ -275,6 +279,18 @@ export class RestApiConnectorService extends ApiConnector { * @returns {Observable} observable of retrieved objects */ public get getAllCampaigns() { return this.getStixObjectsFactory("campaign"); } + /** + * Get all assets + * @param {number} [limit] the number of assets to retrieve + * @param {number} [offset] the number of assets to skip + * @param {string} [state] if specified, only get objects with this state + * @param {string} [lastUpdatedBy] if specified, only get objects which were last updated by these users + * @param {boolean} [revoked] if true, get revoked objects + * @param {boolean} [deprecated] if true, get deprecated objects + * @param {string[]} [excludeIDs] if specified, excludes these STIX IDs from the result + * @returns {Observable} observable of retrieved objects + */ + public get getAllAssets() { return this.getStixObjectsFactory("asset"); } /** * Get all software * @param {number} [limit] the number of software to retrieve @@ -632,6 +648,14 @@ export class RestApiConnectorService extends ApiConnector { * @returns {Observable} the object with the given ID and modified date */ public get getCampaign() { return this.getStixObjectFactory("campaign"); } + /** + * Get a single asset by STIX ID + * @param {string} id the object STIX ID + * @param {Date} [modified] if specified, get the version modified at the given date + * * @param {versions} [string] default "latest", if "all" returns all versions of the object instead of just the latest version. + * @returns {Observable} the object with the given ID and modified date + */ + public get getAsset() { return this.getStixObjectFactory("asset"); } /** * Get a single software by STIX ID * @param {string} id the object STIX ID @@ -752,6 +776,12 @@ export class RestApiConnectorService extends ApiConnector { * @returns {Observable} the created object */ public get postCampaign() { return this.postStixObjectFactory("campaign"); } + /** + * POST (create) a new asset + * @param {Asset} object the object to create + * @returns {Observable} the created object + */ + public get postAsset() { return this.postStixObjectFactory("asset"); } /** * POST (create) a new software * @param {Software} object the object to create @@ -866,6 +896,13 @@ export class RestApiConnectorService extends ApiConnector { * @returns {Observable} the updated object */ public get putCampaign() { return this.putStixObjectFactory("campaign"); } + /** + * PUT (update) an asset + * @param {Asset} object the object to update + * @param {Date} [modified] optional, the modified date to overwrite. If omitted, uses the modified field of the object + * @returns {Observable} the updated object + */ + public get putAsset() { return this.putStixObjectFactory("asset"); } /** * PUT (update) a software * @param {Software} object the object to update @@ -960,6 +997,12 @@ export class RestApiConnectorService extends ApiConnector { * @returns {Observable<{}>} observable of the response body */ public get deleteCampaign() { return this.deleteStixObjectFactory("campaign"); } + /** + * DELETE an asset + * @param {string} id the STIX ID of the object to delete + * @returns {Observable<{}>} observable of the response body + */ + public get deleteAsset() { return this.deleteStixObjectFactory("asset"); } /** * DELETE a software * @param {string} id the STIX ID of the object to delete diff --git a/app/src/app/views/stix/asset/asset-list/asset-list.component.html b/app/src/app/views/stix/asset/asset-list/asset-list.component.html new file mode 100644 index 00000000..30c9ab18 --- /dev/null +++ b/app/src/app/views/stix/asset/asset-list/asset-list.component.html @@ -0,0 +1,11 @@ +
+
+

assets

+
+ +
+
+ +
\ No newline at end of file diff --git a/app/src/app/views/stix/asset/asset-list/asset-list.component.scss b/app/src/app/views/stix/asset/asset-list/asset-list.component.scss new file mode 100644 index 00000000..414f1001 --- /dev/null +++ b/app/src/app/views/stix/asset/asset-list/asset-list.component.scss @@ -0,0 +1,4 @@ +.add-button { + text-align: center; + margin-bottom: 20px; +} \ No newline at end of file diff --git a/app/src/app/views/stix/asset/asset-list/asset-list.component.spec.ts b/app/src/app/views/stix/asset/asset-list/asset-list.component.spec.ts new file mode 100644 index 00000000..83bb183e --- /dev/null +++ b/app/src/app/views/stix/asset/asset-list/asset-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AssetListComponent } from './asset-list.component'; + +describe('AssetListComponent', () => { + let component: AssetListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [AssetListComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AssetListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/app/src/app/views/stix/asset/asset-list/asset-list.component.ts b/app/src/app/views/stix/asset/asset-list/asset-list.component.ts new file mode 100644 index 00000000..071a11b7 --- /dev/null +++ b/app/src/app/views/stix/asset/asset-list/asset-list.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { AuthenticationService } from 'src/app/services/connectors/authentication/authentication.service'; + +@Component({ + selector: 'app-asset-list', + templateUrl: './asset-list.component.html', + styleUrls: ['./asset-list.component.scss'] +}) +export class AssetListComponent { + public get canEdit(): boolean { return this.authenticationService.canEdit(); } + + constructor(private authenticationService: AuthenticationService) { + // intentionally left blank + } +} diff --git a/app/src/app/views/stix/asset/asset-view/asset-view.component.html b/app/src/app/views/stix/asset/asset-view/asset-view.component.html new file mode 100644 index 00000000..7afb01ac --- /dev/null +++ b/app/src/app/views/stix/asset/asset-view/asset-view.component.html @@ -0,0 +1,148 @@ +
+
+
+ + + +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+ +
+ +
+
+

Techniques Used

+
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+

References

+
+
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/app/src/app/views/stix/asset/asset-view/asset-view.component.spec.ts b/app/src/app/views/stix/asset/asset-view/asset-view.component.spec.ts new file mode 100644 index 00000000..bcb6e948 --- /dev/null +++ b/app/src/app/views/stix/asset/asset-view/asset-view.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AssetViewComponent } from './asset-view.component'; + +describe('AssetViewComponent', () => { + let component: AssetViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [AssetViewComponent] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AssetViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/app/src/app/views/stix/asset/asset-view/asset-view.component.ts b/app/src/app/views/stix/asset/asset-view/asset-view.component.ts new file mode 100644 index 00000000..9313e843 --- /dev/null +++ b/app/src/app/views/stix/asset/asset-view/asset-view.component.ts @@ -0,0 +1,24 @@ +import { Component, EventEmitter, OnInit, Output } from '@angular/core'; +import { Asset } from 'src/app/classes/stix'; +import { AuthenticationService } from 'src/app/services/connectors/authentication/authentication.service'; +import { RestApiConnectorService } from 'src/app/services/connectors/rest-api/rest-api-connector.service'; +import { StixViewPage } from '../../stix-view-page'; + +@Component({ + selector: 'app-asset-view', + templateUrl: './asset-view.component.html' +}) +export class AssetViewComponent extends StixViewPage implements OnInit { + @Output() public onReload = new EventEmitter(); + public get asset(): Asset { return this.config.object as Asset; } + + constructor(authenticationService: AuthenticationService, private restApiConnector: RestApiConnectorService) { + super(authenticationService) + } + + ngOnInit(): void { + if (this.asset.firstInitialized) { + this.asset.initializeWithDefaultMarkingDefinitions(this.restApiConnector); + } + } +} diff --git a/app/src/app/views/stix/campaign/campaign-list/campaign-list.component.ts b/app/src/app/views/stix/campaign/campaign-list/campaign-list.component.ts index c9df16cf..4bcf113e 100644 --- a/app/src/app/views/stix/campaign/campaign-list/campaign-list.component.ts +++ b/app/src/app/views/stix/campaign/campaign-list/campaign-list.component.ts @@ -9,7 +9,9 @@ import { AuthenticationService } from 'src/app/services/connectors/authenticatio export class CampaignListComponent implements OnInit { public get canEdit(): boolean { return this.authenticationService.canEdit(); } - constructor(private authenticationService: AuthenticationService) { } + constructor(private authenticationService: AuthenticationService) { + // intentionally left blank + } ngOnInit(): void { // intentionally left blank diff --git a/app/src/app/views/stix/campaign/campaign-view/campaign-view.component.html b/app/src/app/views/stix/campaign/campaign-view/campaign-view.component.html index db222734..c7ce5f09 100644 --- a/app/src/app/views/stix/campaign/campaign-view/campaign-view.component.html +++ b/app/src/app/views/stix/campaign/campaign-view/campaign-view.component.html @@ -116,8 +116,9 @@

Groups

@@ -144,8 +145,9 @@

Techniques Used

@@ -172,8 +174,9 @@

Software Used

diff --git a/app/src/app/views/stix/collection/collection-import/collection-import-review/collection-import-review.component.ts b/app/src/app/views/stix/collection/collection-import/collection-import-review/collection-import-review.component.ts index b30a0a66..e74dcfc3 100644 --- a/app/src/app/views/stix/collection/collection-import/collection-import-review/collection-import-review.component.ts +++ b/app/src/app/views/stix/collection/collection-import/collection-import-review/collection-import-review.component.ts @@ -1,19 +1,10 @@ import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Collection, CollectionDiffCategories } from 'src/app/classes/stix/collection'; -import { Group } from 'src/app/classes/stix/group'; -import { Matrix } from 'src/app/classes/stix/matrix'; -import { Mitigation } from 'src/app/classes/stix/mitigation'; -import { Relationship } from 'src/app/classes/stix/relationship'; -import { Software } from 'src/app/classes/stix/software'; -import { Tactic } from 'src/app/classes/stix/tactic'; -import { Technique } from 'src/app/classes/stix/technique'; -import { DataSource } from 'src/app/classes/stix/data-source'; -import { DataComponent } from 'src/app/classes/stix/data-component'; +import { Asset, Campaign, DataComponent, DataSource, Group, Matrix, Mitigation, Relationship, Software, Tactic, Technique } from 'src/app/classes/stix'; import { EditorService } from 'src/app/services/editor/editor.service'; import { StixViewPage } from '../../../stix-view-page'; import { AuthenticationService } from 'src/app/services/connectors/authentication/authentication.service'; -import { Campaign } from 'src/app/classes/stix/campaign'; @Component({ selector: 'app-collection-import-review', @@ -37,7 +28,8 @@ export class CollectionImportReviewComponent extends StixViewPage implements OnI matrix: new CollectionDiffCategories(), group: new CollectionDiffCategories(), data_source: new CollectionDiffCategories(), - data_component: new CollectionDiffCategories() + data_component: new CollectionDiffCategories(), + asset: new CollectionDiffCategories() } constructor(private route: ActivatedRoute, public editor: EditorService, authenticationService: AuthenticationService) { @@ -119,6 +111,9 @@ export class CollectionImportReviewComponent extends StixViewPage implements OnI case "campaign": // campaign this.collection_import_categories.campaign[category].push(object); break; + case "asset": // asset + this.collection_import_categories.asset[category].push(object); + break; } } } diff --git a/app/src/app/views/stix/collection/collection-import/collection-import-workflow/collection-import.component.ts b/app/src/app/views/stix/collection/collection-import/collection-import-workflow/collection-import.component.ts index 14459e09..49d47b15 100644 --- a/app/src/app/views/stix/collection/collection-import/collection-import-workflow/collection-import.component.ts +++ b/app/src/app/views/stix/collection/collection-import/collection-import-workflow/collection-import.component.ts @@ -6,17 +6,8 @@ import { MatSnackBar } from '@angular/material/snack-bar'; import { MatStepper } from '@angular/material/stepper'; import { ActivatedRoute } from '@angular/router'; import { FileInputComponent } from 'ngx-material-file-input'; -import { Campaign } from 'src/app/classes/stix/campaign'; +import { Asset, Campaign, DataComponent, DataSource, Group, Matrix, Mitigation, Relationship, Software, Tactic, Technique } from 'src/app/classes/stix'; import { Collection, CollectionDiffCategories } from 'src/app/classes/stix/collection'; -import { DataComponent } from 'src/app/classes/stix/data-component'; -import { DataSource } from 'src/app/classes/stix/data-source'; -import { Group } from 'src/app/classes/stix/group'; -import { Matrix } from 'src/app/classes/stix/matrix'; -import { Mitigation } from 'src/app/classes/stix/mitigation'; -import { Relationship } from 'src/app/classes/stix/relationship'; -import { Software } from 'src/app/classes/stix/software'; -import { Tactic } from 'src/app/classes/stix/tactic'; -import { Technique } from 'src/app/classes/stix/technique'; import { ConfirmationDialogComponent } from 'src/app/components/confirmation-dialog/confirmation-dialog.component'; import { RestApiConnectorService } from 'src/app/services/connectors/rest-api/rest-api-connector.service'; import { AuthenticationService } from 'src/app/services/connectors/authentication/authentication.service'; @@ -66,6 +57,7 @@ export class CollectionImportComponent implements OnInit { group: new CollectionDiffCategories(), data_source: new CollectionDiffCategories(), data_component: new CollectionDiffCategories(), + asset: new CollectionDiffCategories() }; // list of headers that comes from mitre-generated excel files and the mapping to support collection objects @@ -596,6 +588,11 @@ export class CollectionImportComponent implements OnInit { new Campaign(raw) ); break; + case 'asset': // asset + this.object_import_categories.asset[category].push( + new Asset(raw) + ); + break; } } // set up selection @@ -653,6 +650,9 @@ export class CollectionImportComponent implements OnInit { case 'c': // campaign object.id = 'campaign--' + uuid(); return; + case 'a': // asset + object.id = 'x-mitre-asset--' + uuid(); + return; } } // relationships don't have attack ids, so check for target and source fields here diff --git a/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.html b/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.html deleted file mode 100644 index 0b5c20ee..00000000 --- a/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.html +++ /dev/null @@ -1 +0,0 @@ -

collection-imported-list works!

diff --git a/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.scss b/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.spec.ts b/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.spec.ts deleted file mode 100644 index dfa897dc..00000000 --- a/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { CollectionImportedListComponent } from './collection-imported-list.component'; - -describe('CollectionImportedListComponent', () => { - let component: CollectionImportedListComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ CollectionImportedListComponent ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(CollectionImportedListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.ts b/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.ts deleted file mode 100644 index 3b59f5fe..00000000 --- a/app/src/app/views/stix/collection/collection-import/collection-imported-list/collection-imported-list.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-collection-imported-list', - templateUrl: './collection-imported-list.component.html', - styleUrls: ['./collection-imported-list.component.scss'] -}) -export class CollectionImportedListComponent implements OnInit { - - constructor() { - // intentionally left blank - } - - ngOnInit(): void { - // intentionally left blank - } -} diff --git a/app/src/app/views/stix/collection/collection-view/collection-view.component.html b/app/src/app/views/stix/collection/collection-view/collection-view.component.html index 4c15cb7d..09e60466 100644 --- a/app/src/app/views/stix/collection/collection-view/collection-view.component.html +++ b/app/src/app/views/stix/collection/collection-view/collection-view.component.html @@ -103,7 +103,7 @@

Changes in this release

diff --git a/app/src/app/views/stix/collection/collection-view/collection-view.component.ts b/app/src/app/views/stix/collection/collection-view/collection-view.component.ts index 55e2325f..d0d6f14f 100644 --- a/app/src/app/views/stix/collection/collection-view/collection-view.component.ts +++ b/app/src/app/views/stix/collection/collection-view/collection-view.component.ts @@ -4,16 +4,7 @@ import { forkJoin, of } from 'rxjs'; import { delay, map, switchMap, tap } from 'rxjs/operators'; import { ValidationData } from 'src/app/classes/serializable'; import { Collection, CollectionDiffCategories, VersionReference } from 'src/app/classes/stix/collection'; -import { Group } from 'src/app/classes/stix/group'; -import { Matrix } from 'src/app/classes/stix/matrix'; -import { Mitigation } from 'src/app/classes/stix/mitigation'; -import { Relationship } from 'src/app/classes/stix/relationship'; -import { Software } from 'src/app/classes/stix/software'; -import { StixObject } from 'src/app/classes/stix/stix-object'; -import { Tactic } from 'src/app/classes/stix/tactic'; -import { Technique } from 'src/app/classes/stix/technique'; -import { DataSource } from 'src/app/classes/stix/data-source'; -import { DataComponent } from 'src/app/classes/stix/data-component'; +import { Asset, Campaign, DataComponent, DataSource, Group, Matrix, Mitigation, Relationship, Software, StixObject, Tactic, Technique } from 'src/app/classes/stix'; import { StixListComponent } from 'src/app/components/stix/stix-list/stix-list.component'; import { RestApiConnectorService } from 'src/app/services/connectors/rest-api/rest-api-connector.service'; import { EditorService } from 'src/app/services/editor/editor.service'; @@ -24,7 +15,6 @@ import { logger } from "../../../../util/logger"; import { AuthenticationService } from 'src/app/services/connectors/authentication/authentication.service'; import { MatDialog } from '@angular/material/dialog'; import { CollectionUpdateDialogComponent } from 'src/app/components/collection-update-dialog/collection-update-dialog.component'; -import { Campaign } from 'src/app/classes/stix/campaign'; import { AddDialogComponent } from 'src/app/components/add-dialog/add-dialog.component'; import { SelectionModel } from '@angular/cdk/collections'; @@ -62,6 +52,7 @@ export class CollectionViewComponent extends StixViewPage implements OnInit { 'Intrusion-Set': 'group', 'Data-Source': 'data_source', 'Data-Component': 'data_component', + 'Asset': 'asset' }; // pluralize attackType for text display @@ -73,7 +64,8 @@ export class CollectionViewComponent extends StixViewPage implements OnInit { "mitigation": "mitigations", "matrix": "matrices", "data-source": "data sources", - "data-component": "data components" + "data-component": "data components", + "asset": "assets" } public get collectionDownloadURL() { @@ -96,7 +88,8 @@ export class CollectionViewComponent extends StixViewPage implements OnInit { matrix: new CollectionDiffCategories(), group: new CollectionDiffCategories(), data_source: new CollectionDiffCategories(), - data_component: new CollectionDiffCategories() + data_component: new CollectionDiffCategories(), + asset: new CollectionDiffCategories() } public collectionChanges = { @@ -109,12 +102,12 @@ export class CollectionViewComponent extends StixViewPage implements OnInit { matrix: new CollectionDiffCategories(), group: new CollectionDiffCategories(), data_source: new CollectionDiffCategories(), - data_component: new CollectionDiffCategories() + data_component: new CollectionDiffCategories(), + asset: new CollectionDiffCategories() } public collection_import_categories = []; - constructor(private route: ActivatedRoute, private router: Router, private restApiConnector: RestApiConnectorService, diff --git a/app/src/app/views/stix/data-component/data-component-view/data-component-view.component.html b/app/src/app/views/stix/data-component/data-component-view/data-component-view.component.html index 294c315e..d831db62 100644 --- a/app/src/app/views/stix/data-component/data-component-view/data-component-view.component.html +++ b/app/src/app/views/stix/data-component/data-component-view/data-component-view.component.html @@ -55,8 +55,9 @@

Techniques Detected

diff --git a/app/src/app/views/stix/group/group-view/group-view.component.html b/app/src/app/views/stix/group/group-view/group-view.component.html index b99bf180..065a99b7 100644 --- a/app/src/app/views/stix/group/group-view/group-view.component.html +++ b/app/src/app/views/stix/group/group-view/group-view.component.html @@ -69,7 +69,7 @@

Campaigns

@@ -96,8 +96,9 @@

Techniques Used

@@ -124,8 +125,9 @@

Software Used

diff --git a/app/src/app/views/stix/mitigation/mitigation-view/mitigation-view.component.html b/app/src/app/views/stix/mitigation/mitigation-view/mitigation-view.component.html index 1b98aa6e..526bf812 100644 --- a/app/src/app/views/stix/mitigation/mitigation-view/mitigation-view.component.html +++ b/app/src/app/views/stix/mitigation/mitigation-view/mitigation-view.component.html @@ -70,8 +70,9 @@

Techniques Addressed by Mitigation

diff --git a/app/src/app/views/stix/relationship/relationship-view/relationship-view.component.ts b/app/src/app/views/stix/relationship/relationship-view/relationship-view.component.ts index 97184dda..e5d453be 100644 --- a/app/src/app/views/stix/relationship/relationship-view/relationship-view.component.ts +++ b/app/src/app/views/stix/relationship/relationship-view/relationship-view.component.ts @@ -46,9 +46,12 @@ export class RelationshipViewComponent extends StixViewPage implements OnInit { ngOnInit(): void { // initialize source/target types if there is a source/target object, or if there is only one possible value - if (this.relationship.source_object) this.source_type = stixTypeToAttackType[this.relationship.source_object.stix.type] + if (this.relationship.source_object) this.source_type = stixTypeToAttackType[this.relationship.source_object.stix.type]; + else if (this.config.sourceType) this.source_type = this.config.sourceType; else if (this.relationship.valid_source_types.length == 1) this.source_type = this.relationship.valid_source_types[0]; - if (this.relationship.target_object) this.target_type = stixTypeToAttackType[this.relationship.target_object.stix.type] + + if (this.relationship.target_object) this.target_type = stixTypeToAttackType[this.relationship.target_object.stix.type]; + else if (this.config.targetType) this.target_type = this.config.targetType; else if (this.relationship.valid_target_types.length == 1) this.target_type = this.relationship.valid_target_types[0]; // fetch parent of source and/or target objects diff --git a/app/src/app/views/stix/software/software-view/software-view.component.html b/app/src/app/views/stix/software/software-view/software-view.component.html index 1b2af2ac..0b8c3606 100644 --- a/app/src/app/views/stix/software/software-view/software-view.component.html +++ b/app/src/app/views/stix/software/software-view/software-view.component.html @@ -100,8 +100,9 @@

Techniques Used

@@ -128,8 +129,9 @@

Associated Groups

@@ -156,8 +158,9 @@

Campaigns

diff --git a/app/src/app/views/stix/stix-dialog/stix-dialog.component.html b/app/src/app/views/stix/stix-dialog/stix-dialog.component.html index 0c7f5d02..04a4af27 100644 --- a/app/src/app/views/stix/stix-dialog/stix-dialog.component.html +++ b/app/src/app/views/stix/stix-dialog/stix-dialog.component.html @@ -74,6 +74,11 @@ (onOpenNotes)="openNotes()" (onClickRelationship)="changeDialogObject($event)"> + + ¯\_(ツ)_/¯ Nothing her + diff --git a/app/src/app/views/stix/stix-page/stix-page.component.ts b/app/src/app/views/stix/stix-page/stix-page.component.ts index eee18566..c12f4ba2 100644 --- a/app/src/app/views/stix/stix-page/stix-page.component.ts +++ b/app/src/app/views/stix/stix-page/stix-page.component.ts @@ -3,19 +3,9 @@ import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router, NavigationEnd } from '@angular/router'; import { Observable, forkJoin } from 'rxjs'; -import { Campaign } from 'src/app/classes/stix/campaign'; +import { Asset, Campaign, DataSource, Group, MarkingDefinition, Matrix, Mitigation, Note, Software, StixObject, Tactic, Technique } from 'src/app/classes/stix'; import { concatMap } from "rxjs/operators"; import { Collection } from 'src/app/classes/stix/collection'; -import { DataSource } from 'src/app/classes/stix/data-source'; -import { Group } from 'src/app/classes/stix/group'; -import { MarkingDefinition } from 'src/app/classes/stix/marking-definition'; -import { Matrix } from 'src/app/classes/stix/matrix'; -import { Mitigation } from 'src/app/classes/stix/mitigation'; -import { Note } from 'src/app/classes/stix/note'; -import { Software } from 'src/app/classes/stix/software'; -import { StixObject } from 'src/app/classes/stix/stix-object'; -import { Tactic } from 'src/app/classes/stix/tactic'; -import { Technique } from 'src/app/classes/stix/technique'; import { VersionNumber } from 'src/app/classes/version-number'; import { DeleteDialogComponent } from 'src/app/components/delete-dialog/delete-dialog.component'; import { MultipleChoiceDialogComponent } from 'src/app/components/multiple-choice-dialog/multiple-choice-dialog.component'; @@ -196,6 +186,7 @@ export class StixPageComponent implements OnInit, OnDestroy { else if (this.objectType == "collection") objects$ = this.restApiService.getCollection(objectStixID, objectModified, "latest", false, true); else if (this.objectType == "data-source") objects$ = this.restApiService.getDataSource(objectStixID, null, "latest", false, false, true); else if (this.objectType == "data-component") objects$ = this.restApiService.getDataComponent(objectStixID); + else if (this.objectType == "asset") objects$ = this.restApiService.getAsset(objectStixID); else if (this.objectType == "marking-definition") objects$ = this.restApiService.getMarkingDefinition(objectStixID); let subscription = objects$.subscribe({ next: result => { @@ -244,6 +235,7 @@ export class StixPageComponent implements OnInit, OnDestroy { case 'group': return new Group(); case 'collection': return new Collection(); case 'data-source': return new DataSource(); + case 'asset': return new Asset(); case 'marking-definition': return new MarkingDefinition(); default: return null; } diff --git a/app/src/app/views/stix/stix-view-page.ts b/app/src/app/views/stix/stix-view-page.ts index 671d927f..e857abef 100644 --- a/app/src/app/views/stix/stix-view-page.ts +++ b/app/src/app/views/stix/stix-view-page.ts @@ -30,7 +30,9 @@ export interface StixViewConfig { /* The object to show on the page * Note: if mode is diff, pass an array of two objects to diff */ - object: StixObject | StixObject[] + object: StixObject | StixObject[]; + sourceType?: string; // the relationship source type (only relevant when creating a new relationship) + targetType?: string; // the relationship target type (only relevant when creating a new relationship) /* if true or omitted, show relationships with the object on the page. If false, omit the relationships */ showRelationships?: boolean; /* is the current page editable? diff --git a/app/src/app/views/stix/technique/technique-view/technique-view.component.html b/app/src/app/views/stix/technique/technique-view/technique-view.component.html index d691f642..10da17d0 100644 --- a/app/src/app/views/stix/technique/technique-view/technique-view.component.html +++ b/app/src/app/views/stix/technique/technique-view/technique-view.component.html @@ -252,7 +252,7 @@

Sub-techniques

@@ -300,8 +300,9 @@

Campaigns

@@ -327,7 +328,7 @@

Mitigations

@@ -353,7 +354,7 @@

Procedure Examples

@@ -379,7 +380,7 @@

Data Sources

@@ -396,6 +397,33 @@

Data Sources

}">
+ +
+
+

Assets

+
+
+
+
+ +
+
+
+
+ +
+
diff --git a/docs/changelog.md b/docs/changelog.md index 2d3990a0..3808ea4c 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -36,6 +36,9 @@ ### ATT&CK Workbench version 2.0.1 +#### New Features in x.x.x +- Added ability to create and edit Asset objects. + #### Fixes in 2.0.1 - Fixed a crash that would occur when retrieving recent activity for large teams. - Fixed the incorrect path to the REST API Docker image documented in [`docker-compose.md`](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/docker-compose.md). From 1250600aee3c4a0afea28cd99375ed5a63c4bdb4 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:02:50 -0400 Subject: [PATCH 03/22] update changelog --- docs/changelog.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 3808ea4c..e25fe3fe 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -34,11 +34,13 @@ ## Changes Staged on Develop -### ATT&CK Workbench version 2.0.1 - #### New Features in x.x.x - Added ability to create and edit Asset objects. +## 21 September 2023 + +### ATT&CK Workbench version 2.0.1 + #### Fixes in 2.0.1 - Fixed a crash that would occur when retrieving recent activity for large teams. - Fixed the incorrect path to the REST API Docker image documented in [`docker-compose.md`](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/docker-compose.md). From 8f80b4cf6c5aa0982253bcee92794bec77c4754a Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Thu, 28 Sep 2023 14:40:58 -0400 Subject: [PATCH 04/22] fix parsing of object citations --- app/src/app/classes/external-references.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/app/classes/external-references.ts b/app/src/app/classes/external-references.ts index 291feb5c..29bb5254 100644 --- a/app/src/app/classes/external-references.ts +++ b/app/src/app/classes/external-references.ts @@ -155,7 +155,7 @@ export class ExternalReferences extends Serializable { let parse_apis = []; for (let field of refs_fields) { if (field == 'aliases') parse_apis.push(this.parseCitationsFromAliases(object[field], restAPIConnector)); - if (field == 'relatedAssets') parse_apis.push(this.parseCitationsFromRelatedAssets(object[field], restAPIConnector)); + else if (field == 'relatedAssets') parse_apis.push(this.parseCitationsFromRelatedAssets(object[field], restAPIConnector)); else parse_apis.push(this.parseCitations(object[field], restAPIConnector)); } From 264a93efd78a6e7eacc9108202da6767241aa34d Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Tue, 3 Oct 2023 12:26:55 -0400 Subject: [PATCH 05/22] Fix/467 (#506) * update revoke/deprecate logic * code smell * update changelog * minor update --- .../object-status/object-status.component.ts | 31 ++++++------------- docs/changelog.md | 7 +++-- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/app/src/app/components/object-status/object-status.component.ts b/app/src/app/components/object-status/object-status.component.ts index 5d5b3dde..de99c64e 100644 --- a/app/src/app/components/object-status/object-status.component.ts +++ b/app/src/app/components/object-status/object-status.component.ts @@ -63,7 +63,7 @@ export class ObjectStatusComponent implements OnInit { this.objects = data.data; this.object = this.objects.find(object => object.stixID === this.editorService.stixId); if (this.object) { - if (this.object.workflow && this.object.workflow.state) { + if (this.object.workflow?.state) { this.statusControl.setValue(this.object.workflow.state); } this.revoked = this.object.revoked; @@ -155,32 +155,18 @@ export class ObjectStatusComponent implements OnInit { complete: () => { revokedSubscription.unsubscribe(); } }); } else { - // deprecate the 'revoked-by' relationship - let revokedRelationships = this.relationships.filter(relationship => relationship.relationship_type == 'revoked-by'); - for (let relationship of revokedRelationships) { - let other_obj: any; - if (relationship.source_object.stix.id == this.object.stixID) other_obj = relationship.target_object.stix; - else other_obj = relationship.source_object.stix; - - if (!this.isDeprecatedOrRevoked(other_obj)) { - relationship.deprecated = true; - relationship.save(this.restAPIService); - } + // unrevoke object, deprecate the 'revoked-by' relationship + // this is the only case in which a 'revoked-by' relationship is deprecated + let revokedRelationship = this.relationships.find(r => r.relationship_type == 'revoked-by' && r.source_ref == this.object.stixID); + if (revokedRelationship) { + revokedRelationship.deprecated = true; + revokedRelationship.save(this.restAPIService); } - // un-revoke object this.object.revoked = false; this.save(); } } - /** - * Check if the given object is deprecated or revoked - * @param object source or target object of a relationship - */ - private isDeprecatedOrRevoked(object: any) { - return ('x_mitre_deprecated' in object && object.x_mitre_deprecated) || ('revoked' in object && object.revoked); - } - /** * Handle the selection for deprecating or un-deprecating an object * @param event deprecate selection @@ -225,7 +211,8 @@ export class ObjectStatusComponent implements OnInit { // update relationships with the object for (let relationship of this.relationships) { - if (!relationship.deprecated && relationship.relationship_type != 'subtechnique-of') { + // do not deprecate 'subtechnique-of' or 'revoked-by' relationships + if (!relationship.deprecated && !['subtechnique-of', 'revoked-by'].includes(relationship.relationship_type)) { relationship.deprecated = true; saves.push(relationship.save(this.restAPIService)); } diff --git a/docs/changelog.md b/docs/changelog.md index e25fe3fe..30cdb7c4 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -34,8 +34,11 @@ ## Changes Staged on Develop -#### New Features in x.x.x -- Added ability to create and edit Asset objects. +#### New Features in 2.1.0 +- Added the ability to create, view, and edit Asset objects. + +#### Fixes in 2.1.0 +- Fixed an issue where revoking or deprecating an object would deprecate all `revoked-by` relationships with the object. See [frontend#467](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/467). ## 21 September 2023 From 14daa11ef9ef08a5cfab24125841d0bcda05a183 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Wed, 11 Oct 2023 13:16:04 -0400 Subject: [PATCH 06/22] Fix first seen/last seen date parsing (#508) * same date output for all timezones * update changelog --- .../stix/datepicker-property/datepicker-property.component.ts | 2 +- docs/changelog.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/app/components/stix/datepicker-property/datepicker-property.component.ts b/app/src/app/components/stix/datepicker-property/datepicker-property.component.ts index fe6a92ef..deadf087 100644 --- a/app/src/app/components/stix/datepicker-property/datepicker-property.component.ts +++ b/app/src/app/components/stix/datepicker-property/datepicker-property.component.ts @@ -47,7 +47,7 @@ export class DatepickerPropertyComponent { public get formatHint() { return DATE_FORMATS.parse.dateInput; } public get date() { // get date in view display format (i.e. January 2022) if (this.config.object[this.config.field]) { - return moment(this.config.object[this.config.field]).format('MMMM YYYY'); + return moment.utc(this.config.object[this.config.field]).format('MMMM YYYY'); } return null; } diff --git a/docs/changelog.md b/docs/changelog.md index 30cdb7c4..27a77108 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -39,6 +39,7 @@ #### Fixes in 2.1.0 - Fixed an issue where revoking or deprecating an object would deprecate all `revoked-by` relationships with the object. See [frontend#467](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/467). +- Fixed an issue where first/last seen Campaign dates were parsed in local time, causing the dates to be displayed incorrectly in certain timezones. See [frontend#508](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/508). ## 21 September 2023 From 5b743be437479e3348673d510803fed65653b146 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:11:59 -0400 Subject: [PATCH 07/22] Bump postcss and @angular-devkit/build-angular in /app (#507) * Update docker-compose.md (#501) fix path error for restAPI image * Update changelog.md * Bump postcss and @angular-devkit/build-angular in /app Bumps [postcss](https://github.com/postcss/postcss) to 8.4.31 and updates ancestor dependency [@angular-devkit/build-angular](https://github.com/angular/angular-cli). These dependencies need to be updated together. Updates `postcss` from 8.4.16 to 8.4.31 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.16...8.4.31) Updates `@angular-devkit/build-angular` from 14.2.12 to 14.2.13 - [Release notes](https://github.com/angular/angular-cli/releases) - [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md) - [Commits](https://github.com/angular/angular-cli/compare/14.2.12...14.2.13) --- updated-dependencies: - dependency-name: postcss dependency-type: indirect - dependency-name: "@angular-devkit/build-angular" dependency-type: direct:development ... Signed-off-by: dependabot[bot] --------- Signed-off-by: dependabot[bot] Co-authored-by: Mike Cunningham Co-authored-by: Charissa Miller <48832936+clemiller@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- app/package-lock.json | 269 ++++++++++++++++++++++++++++++++---------- app/package.json | 2 +- docs/changelog.md | 2 +- 3 files changed, 206 insertions(+), 67 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index 558592db..f48501a7 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -35,7 +35,7 @@ "zone.js": "~0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "^14.2.12", + "@angular-devkit/build-angular": "^14.2.13", "@angular/cli": "^14.2.12", "@angular/compiler-cli": "^14.3.0", "@types/jasmine": "^4.3.5", @@ -89,15 +89,15 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.12.tgz", - "integrity": "sha512-ei8/FaL80Q6si/aF6FLZgtT4Kr2rudlyGMqQM4Rd2Zvt8mCh3TgM7QdLhoI11t9A0LWz6RIdROlDimMyyOEF6Q==", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-14.2.13.tgz", + "integrity": "sha512-FJZKQ3xYFvEJ807sxVy4bCVyGU2NMl3UUPNfLIdIdzwwDEP9tx/cc+c4VtVPEZZfU8jVenu8XOvL6L0vpjt3yg==", "dev": true, "dependencies": { "@ampproject/remapping": "2.2.0", - "@angular-devkit/architect": "0.1402.12", - "@angular-devkit/build-webpack": "0.1402.12", - "@angular-devkit/core": "14.2.12", + "@angular-devkit/architect": "0.1402.13", + "@angular-devkit/build-webpack": "0.1402.13", + "@angular-devkit/core": "14.2.13", "@babel/core": "7.18.10", "@babel/generator": "7.18.12", "@babel/helper-annotate-as-pure": "7.18.6", @@ -108,7 +108,7 @@ "@babel/runtime": "7.18.9", "@babel/template": "7.18.10", "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "14.2.12", + "@ngtools/webpack": "14.2.13", "ansi-colors": "4.1.3", "babel-loader": "8.2.5", "babel-plugin-istanbul": "6.1.1", @@ -133,7 +133,7 @@ "ora": "5.4.1", "parse5-html-rewriting-stream": "6.0.1", "piscina": "3.2.0", - "postcss": "8.4.16", + "postcss": "8.4.31", "postcss-import": "15.0.0", "postcss-loader": "7.0.1", "postcss-preset-env": "7.8.0", @@ -196,6 +196,72 @@ } } }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { + "version": "0.1402.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.13.tgz", + "integrity": "sha512-n0ISBuvkZHoOpAzuAZql1TU9VLHUE9e/a9g4VNOPHewjMzpN02VqeGKvJfOCKtzkCs6gVssIlILm2/SXxkIFxQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "14.2.13", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.13.tgz", + "integrity": "sha512-aIefeZcbjghQg/V6U9CTLtyB5fXDJ63KwYqVYkWP+i0XriS5A9puFgq2u/OVsWxAfYvqpDqp5AdQ0g0bi3CAsA==", + "dev": true, + "dependencies": { + "ajv": "8.11.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.1.0", + "rxjs": "6.6.7", + "source-map": "0.7.4" + }, + "engines": { + "node": "^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -224,6 +290,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/@angular-devkit/build-angular/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -295,12 +367,12 @@ "dev": true }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1402.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.12.tgz", - "integrity": "sha512-xBkbSwOhHgUsJk1tTtITqbHHiA0OdjwdrYZYceyfDASAglyRX6rT4Q9/Ppf7TSck6M1tUR76efYOn3D3ial29w==", + "version": "0.1402.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.13.tgz", + "integrity": "sha512-K27aJmuw86ZOdiu5PoGeGDJ2v7g2ZCK0bGwc8jzkjTLRfvd4FRKIIZumGv3hbQ3vQRLikiU6WMDRTFyCZky/EA==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1402.12", + "@angular-devkit/architect": "0.1402.13", "rxjs": "6.6.7" }, "engines": { @@ -313,6 +385,69 @@ "webpack-dev-server": "^4.0.0" } }, + "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { + "version": "0.1402.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.13.tgz", + "integrity": "sha512-n0ISBuvkZHoOpAzuAZql1TU9VLHUE9e/a9g4VNOPHewjMzpN02VqeGKvJfOCKtzkCs6gVssIlILm2/SXxkIFxQ==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "14.2.13", + "rxjs": "6.6.7" + }, + "engines": { + "node": "^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.13.tgz", + "integrity": "sha512-aIefeZcbjghQg/V6U9CTLtyB5fXDJ63KwYqVYkWP+i0XriS5A9puFgq2u/OVsWxAfYvqpDqp5AdQ0g0bi3CAsA==", + "dev": true, + "dependencies": { + "ajv": "8.11.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.1.0", + "rxjs": "6.6.7", + "source-map": "0.7.4" + }, + "engines": { + "node": "^14.15.0 || >=16.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/@angular-devkit/core": { "version": "14.2.12", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.12.tgz", @@ -3052,9 +3187,9 @@ "dev": true }, "node_modules/@ngtools/webpack": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.12.tgz", - "integrity": "sha512-d/NRQAjS3BsMDUpLrhza+bvI7HKIV+lyRAvD3LYj5FE9kMoEGw4zRo9JG8ookCzvT2FjNiXQ7DWDZSAeMOy+WQ==", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-14.2.13.tgz", + "integrity": "sha512-RQx/rGX7K/+R55x1R6Ax1JzyeHi8cW11dEXpzHWipyuSpusQLUN53F02eMB4VTakXsL3mFNWWy4bX3/LSq8/9w==", "dev": true, "engines": { "node": "^14.15.0 || >=16.10.0", @@ -3331,9 +3466,9 @@ "dev": true }, "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", + "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", "dev": true, "dependencies": { "@types/connect": "*", @@ -3341,9 +3476,9 @@ } }, "node_modules/@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "version": "3.5.11", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.11.tgz", + "integrity": "sha512-isGhjmBtLIxdHBDl2xGwUzEM8AOyOvWsADWq7rqirdi/ZQoHnLWErHvsThcEzTX8juDRiZtzp2Qkv5bgNh6mAg==", "dev": true, "dependencies": { "@types/node": "*" @@ -3410,9 +3545,9 @@ "dev": true }, "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "version": "4.17.18", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", + "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", "dev": true, "dependencies": { "@types/body-parser": "*", @@ -3422,9 +3557,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.36", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.36.tgz", - "integrity": "sha512-zbivROJ0ZqLAtMzgzIUC4oNqDG9iF0lSsAqpOD9kbs5xcIM3dTiyuHvBc7R8MtWBp3AAWGaovJa+wzWPjLYW7Q==", + "version": "4.17.37", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", + "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", "dev": true, "dependencies": { "@types/node": "*", @@ -3434,15 +3569,15 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", + "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==", "dev": true }, "node_modules/@types/http-proxy": { - "version": "1.17.11", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", - "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", + "version": "1.17.12", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.12.tgz", + "integrity": "sha512-kQtujO08dVtQ2wXAuSFfk9ASy3sug4+ogFR8Kd8UgP8PEuc1/G/8yjYRmp//PcDNJEUKOza/MrQu15bouEUCiw==", "dev": true, "dependencies": { "@types/node": "*" @@ -3475,9 +3610,9 @@ "integrity": "sha512-vSSbKZFbNktrQ15v7o1EaH78EbWV+sPQbPjHG+Cp8CaNcPFUEfjZ0Iml/V0bFDwsTlYe8o6XC5Hfdp91cqPV2g==" }, "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz", + "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==", "dev": true }, "node_modules/@types/node": { @@ -3498,9 +3633,9 @@ "dev": true }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.5.tgz", + "integrity": "sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==", "dev": true }, "node_modules/@types/retry": { @@ -3510,9 +3645,9 @@ "dev": true }, "node_modules/@types/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", - "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", + "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", "dev": true, "dependencies": { "@types/mime": "^1", @@ -3520,18 +3655,18 @@ } }, "node_modules/@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.2.tgz", + "integrity": "sha512-asaEIoc6J+DbBKXtO7p2shWUpKacZOoMBEGBgPG91P8xhO53ohzHWGCs4ScZo5pQMf5ukQzVT9fhX1WzpHihig==", "dev": true, "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", - "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", + "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", "dev": true, "dependencies": { "@types/http-errors": "*", @@ -3540,18 +3675,18 @@ } }, "node_modules/@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "version": "0.3.34", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.34.tgz", + "integrity": "sha512-R+n7qBFnm/6jinlteC9DBL5dGiDGjWAvjo4viUanpnc/dG1y7uDoacXPIQ/PQEg1fI912SMHIa014ZjRpvDw4g==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.6.tgz", + "integrity": "sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg==", "dev": true, "dependencies": { "@types/node": "*" @@ -7320,9 +7455,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", - "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, "node_modules/fs.realpath": { @@ -10833,9 +10968,9 @@ } }, "node_modules/postcss": { - "version": "8.4.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "dev": true, "funding": [ { @@ -10845,10 +10980,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -14108,9 +14247,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", "dev": true, "engines": { "node": ">=10.0.0" diff --git a/app/package.json b/app/package.json index 2f19b148..c279c7cb 100644 --- a/app/package.json +++ b/app/package.json @@ -57,7 +57,7 @@ "zone.js": "~0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "^14.2.12", + "@angular-devkit/build-angular": "^14.2.13", "@angular/cli": "^14.2.12", "@angular/compiler-cli": "^14.3.0", "@types/jasmine": "^4.3.5", diff --git a/docs/changelog.md b/docs/changelog.md index 27a77108..db8cf1de 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -32,7 +32,7 @@ # Changelog -## Changes Staged on Develop +## 21 September 2023 #### New Features in 2.1.0 - Added the ability to create, view, and edit Asset objects. From 7fda1c0b08e3ddb43fb9ef84ef124c9e62882843 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:14:34 -0400 Subject: [PATCH 08/22] update changelog --- docs/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index db8cf1de..27a77108 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -32,7 +32,7 @@ # Changelog -## 21 September 2023 +## Changes Staged on Develop #### New Features in 2.1.0 - Added the ability to create, view, and edit Asset objects. From ab7e0ef36443a7469df086d0ad7237e2f7acd3af Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Thu, 19 Oct 2023 09:19:38 -0400 Subject: [PATCH 09/22] package updates --- app/package-lock.json | 2465 +++++++++++++++++++---------------------- 1 file changed, 1113 insertions(+), 1352 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index f48501a7..78d90770 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -74,12 +74,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1402.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.12.tgz", - "integrity": "sha512-LuK26pyaqyClEbY0n4/WIh3irUuA8wwmMmEj8uW4boziuJWv7U42lJJRF3VwkchiyOIp8qiKg995K6IoeXkWgA==", + "version": "0.1402.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.13.tgz", + "integrity": "sha512-n0ISBuvkZHoOpAzuAZql1TU9VLHUE9e/a9g4VNOPHewjMzpN02VqeGKvJfOCKtzkCs6gVssIlILm2/SXxkIFxQ==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.2.12", + "@angular-devkit/core": "14.2.13", "rxjs": "6.6.7" }, "engines": { @@ -196,176 +196,12 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { - "version": "0.1402.13", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.13.tgz", - "integrity": "sha512-n0ISBuvkZHoOpAzuAZql1TU9VLHUE9e/a9g4VNOPHewjMzpN02VqeGKvJfOCKtzkCs6gVssIlILm2/SXxkIFxQ==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "14.2.13", - "rxjs": "6.6.7" - }, - "engines": { - "node": "^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "14.2.13", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.13.tgz", - "integrity": "sha512-aIefeZcbjghQg/V6U9CTLtyB5fXDJ63KwYqVYkWP+i0XriS5A9puFgq2u/OVsWxAfYvqpDqp5AdQ0g0bi3CAsA==", - "dev": true, - "dependencies": { - "ajv": "8.11.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.1.0", - "rxjs": "6.6.7", - "source-map": "0.7.4" - }, - "engines": { - "node": "^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/glob": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/@angular-devkit/build-angular/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", "dev": true }, - "node_modules/@angular-devkit/build-angular/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@angular-devkit/build-webpack": { "version": "0.1402.13", "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1402.13.tgz", @@ -385,22 +221,7 @@ "webpack-dev-server": "^4.0.0" } }, - "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/architect": { - "version": "0.1402.13", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.13.tgz", - "integrity": "sha512-n0ISBuvkZHoOpAzuAZql1TU9VLHUE9e/a9g4VNOPHewjMzpN02VqeGKvJfOCKtzkCs6gVssIlILm2/SXxkIFxQ==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "14.2.13", - "rxjs": "6.6.7" - }, - "engines": { - "node": "^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/@angular-devkit/core": { + "node_modules/@angular-devkit/core": { "version": "14.2.13", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.13.tgz", "integrity": "sha512-aIefeZcbjghQg/V6U9CTLtyB5fXDJ63KwYqVYkWP+i0XriS5A9puFgq2u/OVsWxAfYvqpDqp5AdQ0g0bi3CAsA==", @@ -426,83 +247,13 @@ } } }, - "node_modules/@angular-devkit/build-webpack/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/build-webpack/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/@angular-devkit/core": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.12.tgz", - "integrity": "sha512-tg1+deEZdm3fgk2BQ6y7tujciL6qhtN5Ums266lX//kAZeZ4nNNXTBT+oY5xgfjvmLbW+xKg0XZrAS0oIRKY5g==", - "dev": true, - "dependencies": { - "ajv": "8.11.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.1.0", - "rxjs": "6.6.7", - "source-map": "0.7.4" - }, - "engines": { - "node": "^14.15.0 || >=16.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/core/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/core/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/@angular-devkit/schematics": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.12.tgz", - "integrity": "sha512-MN5yGR+SSSPPBBVMf4cifDJn9u0IYvxiHst+HWokH2AkBYy+vB1x8jYES2l1wkiISD7nvjTixfqX+Y95oMBoLg==", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-14.2.13.tgz", + "integrity": "sha512-2zczyeNzeBcrT2HOysv52X9SH3tZoHfWJvVf6H0SIa74rfDKEl7hFpKNXnh3x8sIMLj5mZn05n5RCqGxCczcIg==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.2.12", + "@angular-devkit/core": "14.2.13", "jsonc-parser": "3.1.0", "magic-string": "0.26.2", "ora": "5.4.1", @@ -544,22 +295,16 @@ "rxjs": "^6.5.3 || ^7.4.0" } }, - "node_modules/@angular/cdk/node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "optional": true - }, "node_modules/@angular/cli": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.12.tgz", - "integrity": "sha512-G/785b6jIIX7J+zS8RHaCT1OYzqANw5hJlnLf8tLgmaadLMVNQvIrvHTYtmD86pbqCYyVDLoMxefxRIwMHJuqw==", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-14.2.13.tgz", + "integrity": "sha512-I5EepRem2CCyS3GDzQxZ2ZrqQwVqoGoLY+ZQhsK1QGWUnUyFOjbv3OlUGxRUYwcedu19V1EBAKjmQ96HzMIcVQ==", "dev": true, "dependencies": { - "@angular-devkit/architect": "0.1402.12", - "@angular-devkit/core": "14.2.12", - "@angular-devkit/schematics": "14.2.12", - "@schematics/angular": "14.2.12", + "@angular-devkit/architect": "0.1402.13", + "@angular-devkit/core": "14.2.13", + "@angular-devkit/schematics": "14.2.13", + "@schematics/angular": "14.2.13", "@yarnpkg/lockfile": "1.1.0", "ansi-colors": "4.1.3", "debug": "4.3.4", @@ -586,33 +331,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular/cli/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@angular/cli/node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@angular/cli/node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -622,12 +340,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/@angular/cli/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/@angular/common": { "version": "14.3.0", "resolved": "https://registry.npmjs.org/@angular/common/-/common-14.3.0.tgz", @@ -829,9 +541,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.2.tgz", + "integrity": "sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1062,22 +774,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -1110,12 +822,12 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz", - "integrity": "sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.15" + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -1134,16 +846,16 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.15.tgz", - "integrity": "sha512-l1UiX4UyHSFsYt17iQ3Se5pQQZZHa22zyIXURmvkmLCD4t/aU+dvNWHatKac/D9Vm9UES7nvIqHs4jZqKviUmQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.15" + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -1174,14 +886,14 @@ } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz", - "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.9" + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -1203,13 +915,13 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", - "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", "dev": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", "@babel/helper-optimise-call-expression": "^7.22.5" }, "engines": { @@ -1265,9 +977,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -1283,14 +995,14 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.10.tgz", - "integrity": "sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", "dev": true, "dependencies": { "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.10" + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" }, "engines": { "node": ">=6.9.0" @@ -1311,14 +1023,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz", - "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz", + "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==", "dev": true, "dependencies": { "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.23.2", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -1339,12 +1051,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", - "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, @@ -1353,9 +1065,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.15.tgz", - "integrity": "sha512-RWmQ/sklUN9BvGGpCDgSubhHWfAx24XDTDObup4ffvxaYsptOg2P3KG0j+1eWKLxpkX0j0uHxmpq2Z1SP/VhxA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1900,9 +1612,9 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.15.tgz", - "integrity": "sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz", + "integrity": "sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -1980,9 +1692,9 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.15.tgz", - "integrity": "sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz", + "integrity": "sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" @@ -2104,12 +1816,12 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", - "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz", + "integrity": "sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5" }, "engines": { @@ -2120,12 +1832,12 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz", - "integrity": "sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", + "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-simple-access": "^7.22.5" }, @@ -2137,15 +1849,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz", - "integrity": "sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz", + "integrity": "sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==", "dev": true, "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.9", + "@babel/helper-module-transforms": "^7.23.0", "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-validator-identifier": "^7.22.20" }, "engines": { "node": ">=6.9.0" @@ -2218,9 +1930,9 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.15.tgz", - "integrity": "sha512-ngQ2tBhq5vvSJw2Q2Z9i7ealNkpDMU0rGWnHPKqRZO0tzZ5tlaoz4hDvhXioOoaE0X2vfNss1djwg0DXlfu30A==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz", + "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==", "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", @@ -2578,19 +2290,19 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.15.tgz", - "integrity": "sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2599,12 +2311,12 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.22.15", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -2628,13 +2340,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.15.tgz", - "integrity": "sha512-X+NLXr0N8XXmN5ZsaQdm9U2SSC3UbIYq/doL++sueHOTisgZHoKaQtZxGuV2cUPQHMfjKEfg/g6oy7Hm6SKFtA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -3171,9 +2883,9 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -3279,18 +2991,6 @@ "node": ">=12" } }, - "node_modules/@npmcli/git/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@npmcli/git/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3336,18 +3036,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/@npmcli/move-file/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@npmcli/node-gyp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz", @@ -3411,13 +3099,13 @@ } }, "node_modules/@schematics/angular": { - "version": "14.2.12", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.12.tgz", - "integrity": "sha512-nCxoFzH/uh5vqhaAjAfQIBgGuCdV3RMjdSwD0VQ+GFiFvTe8rqFyDl+qpNCgETz4LwmGHb5HNjDH9+VyVLgfZQ==", + "version": "14.2.13", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-14.2.13.tgz", + "integrity": "sha512-MLxTpTU3E8QACQ/5c0sENMR2gRiMXpGaKeD5IHY+3wyU2fUSJVB0QPU/l1WhoyZbX8N9ospBgf5UEG7taVF9rg==", "dev": true, "dependencies": { - "@angular-devkit/core": "14.2.12", - "@angular-devkit/schematics": "14.2.12", + "@angular-devkit/core": "14.2.13", + "@angular-devkit/schematics": "14.2.13", "jsonc-parser": "3.1.0" }, "engines": { @@ -3466,9 +3154,9 @@ "dev": true }, "node_modules/@types/body-parser": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.3.tgz", - "integrity": "sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ==", + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.4.tgz", + "integrity": "sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==", "dev": true, "dependencies": { "@types/connect": "*", @@ -3476,27 +3164,27 @@ } }, "node_modules/@types/bonjour": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.11.tgz", - "integrity": "sha512-isGhjmBtLIxdHBDl2xGwUzEM8AOyOvWsADWq7rqirdi/ZQoHnLWErHvsThcEzTX8juDRiZtzp2Qkv5bgNh6mAg==", + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.12.tgz", + "integrity": "sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.36", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.36.tgz", - "integrity": "sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w==", + "version": "3.4.37", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.37.tgz", + "integrity": "sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.1.tgz", - "integrity": "sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.2.tgz", + "integrity": "sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q==", "dev": true, "dependencies": { "@types/express-serve-static-core": "*", @@ -3510,18 +3198,18 @@ "dev": true }, "node_modules/@types/cors": { - "version": "2.8.14", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.14.tgz", - "integrity": "sha512-RXHUvNWYICtbP6s18PnOCaqToK8y14DnLd75c6HfyKf228dxy7pHNOQkxPtvXKp/hINFMDjbYzsj63nnpPMSRQ==", + "version": "2.8.15", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.15.tgz", + "integrity": "sha512-n91JxbNLD8eQIuXDIChAN1tCKNWCEgpceU9b7ZMbFA+P+Q4yIeh80jizFLEvolRPc1ES0VdwFlGv+kJTSirogw==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/eslint": { - "version": "8.44.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", - "integrity": "sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==", + "version": "8.44.6", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.6.tgz", + "integrity": "sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw==", "dev": true, "dependencies": { "@types/estree": "*", @@ -3529,9 +3217,9 @@ } }, "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "version": "3.7.6", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.6.tgz", + "integrity": "sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ==", "dev": true, "dependencies": { "@types/eslint": "*", @@ -3545,9 +3233,9 @@ "dev": true }, "node_modules/@types/express": { - "version": "4.17.18", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.18.tgz", - "integrity": "sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ==", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.20.tgz", + "integrity": "sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==", "dev": true, "dependencies": { "@types/body-parser": "*", @@ -3557,9 +3245,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.37", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz", - "integrity": "sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg==", + "version": "4.17.38", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.38.tgz", + "integrity": "sha512-hXOtc0tuDHZPFwwhuBJXPbjemWtXnJjbvuuyNH2Y5Z6in+iXc63c4eXYDc7GGGqHy+iwYqAJMdaItqdnbcBKmg==", "dev": true, "dependencies": { "@types/node": "*", @@ -3569,50 +3257,50 @@ } }, "node_modules/@types/http-errors": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.2.tgz", - "integrity": "sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.3.tgz", + "integrity": "sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA==", "dev": true }, "node_modules/@types/http-proxy": { - "version": "1.17.12", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.12.tgz", - "integrity": "sha512-kQtujO08dVtQ2wXAuSFfk9ASy3sug4+ogFR8Kd8UgP8PEuc1/G/8yjYRmp//PcDNJEUKOza/MrQu15bouEUCiw==", + "version": "1.17.13", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.13.tgz", + "integrity": "sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/jasmine": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.3.5.tgz", - "integrity": "sha512-9YHUdvuNDDRJYXZwHqSsO72Ok0vmqoJbNn73ttyITQp/VA60SarnZ+MPLD37rJAhVoKp+9BWOvJP5tHIRfZylQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-4.6.1.tgz", + "integrity": "sha512-Q00+pqd3WGt3xLmbIV6w9cP2uncjzIld+NOE4dl1ETQEut7RACj3QdAE8nD+n2ubPHneeGYsqXK//ORvH2m6eQ==", "dev": true }, "node_modules/@types/jasminewd2": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.10.tgz", - "integrity": "sha512-J7mDz7ovjwjc+Y9rR9rY53hFWKATcIkrr9DwQWmOas4/pnIPJTXawnzjwpHm3RSxz/e3ZVUvQ7cRbd5UQLo10g==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.12.tgz", + "integrity": "sha512-C4rXKMnGqLqTw4mgfiT0fL91g5oFAUhreR8jeeYk4xYcgh1/CImqgn5pWcErnpJJS43XFUfHGit0sSPQ39G1Pg==", "dev": true, "dependencies": { "@types/jasmine": "*" } }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", "dev": true }, "node_modules/@types/marked": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.1.tgz", - "integrity": "sha512-vSSbKZFbNktrQ15v7o1EaH78EbWV+sPQbPjHG+Cp8CaNcPFUEfjZ0Iml/V0bFDwsTlYe8o6XC5Hfdp91cqPV2g==" + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-4.3.2.tgz", + "integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==" }, "node_modules/@types/mime": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.3.tgz", - "integrity": "sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.4.tgz", + "integrity": "sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw==", "dev": true }, "node_modules/@types/node": { @@ -3621,21 +3309,21 @@ "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" }, "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.1.tgz", + "integrity": "sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng==", "dev": true }, "node_modules/@types/qs": { - "version": "6.9.8", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz", - "integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg==", + "version": "6.9.9", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.9.tgz", + "integrity": "sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==", "dev": true }, "node_modules/@types/range-parser": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.5.tgz", - "integrity": "sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.6.tgz", + "integrity": "sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA==", "dev": true }, "node_modules/@types/retry": { @@ -3645,9 +3333,9 @@ "dev": true }, "node_modules/@types/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.2.tgz", - "integrity": "sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.3.tgz", + "integrity": "sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==", "dev": true, "dependencies": { "@types/mime": "^1", @@ -3655,18 +3343,18 @@ } }, "node_modules/@types/serve-index": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.2.tgz", - "integrity": "sha512-asaEIoc6J+DbBKXtO7p2shWUpKacZOoMBEGBgPG91P8xhO53ohzHWGCs4ScZo5pQMf5ukQzVT9fhX1WzpHihig==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.3.tgz", + "integrity": "sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg==", "dev": true, "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.3.tgz", - "integrity": "sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg==", + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.4.tgz", + "integrity": "sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw==", "dev": true, "dependencies": { "@types/http-errors": "*", @@ -3675,18 +3363,18 @@ } }, "node_modules/@types/sockjs": { - "version": "0.3.34", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.34.tgz", - "integrity": "sha512-R+n7qBFnm/6jinlteC9DBL5dGiDGjWAvjo4viUanpnc/dG1y7uDoacXPIQ/PQEg1fI912SMHIa014ZjRpvDw4g==", + "version": "0.3.35", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.35.tgz", + "integrity": "sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw==", "dev": true, "dependencies": { "@types/node": "*" } }, "node_modules/@types/ws": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.6.tgz", - "integrity": "sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.8.tgz", + "integrity": "sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg==", "dev": true, "dependencies": { "@types/node": "*" @@ -3984,14 +3672,14 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" }, "funding": { @@ -4016,35 +3704,16 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, "peerDependencies": { - "ajv": "^6.9.1" + "ajv": "^8.8.2" } }, "node_modules/ansi-colors": { @@ -4160,6 +3829,12 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, "node_modules/aria-query": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", @@ -4183,9 +3858,9 @@ "dev": true }, "node_modules/autoprefixer": { - "version": "10.4.15", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz", - "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==", + "version": "10.4.16", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", + "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", "dev": true, "funding": [ { @@ -4203,8 +3878,8 @@ ], "dependencies": { "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001520", - "fraction.js": "^4.2.0", + "caniuse-lite": "^1.0.30001538", + "fraction.js": "^4.3.6", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" @@ -4261,30 +3936,6 @@ "node": ">=8.9.0" } }, - "node_modules/babel-loader/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/babel-loader/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", @@ -4420,13 +4071,13 @@ } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -4434,22 +4085,13 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, + "unpipe": "1.0.0" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/body-parser/node_modules/debug": { @@ -4506,13 +4148,12 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { @@ -4528,9 +4169,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", "dev": true, "funding": [ { @@ -4547,10 +4188,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -4584,15 +4225,15 @@ } }, "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -4608,9 +4249,9 @@ } }, "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { "node": ">= 0.8" @@ -4645,34 +4286,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/cacache/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -4682,30 +4295,6 @@ "node": ">=12" } }, - "node_modules/cacache/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -4738,9 +4327,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001527", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001527.tgz", - "integrity": "sha512-YkJi7RwPgWtXVSgK4lG9AHH57nSzvvOp9MesgXmw4Q7n0C3H04L0foHqfxcmSAm5AcWb8dW9AYj2tR7/5GnddQ==", + "version": "1.0.30001551", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001551.tgz", + "integrity": "sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==", "dev": true, "funding": [ { @@ -4864,9 +4453,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", "dev": true, "engines": { "node": ">=6" @@ -4984,12 +4573,6 @@ "node": ">=0.10.0" } }, - "node_modules/codelyzer/node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "node_modules/codelyzer/node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -5022,7 +4605,7 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/color-support": { @@ -5091,6 +4674,15 @@ "node": ">= 0.8.0" } }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5151,51 +4743,12 @@ "ms": "2.0.0" } }, - "node_modules/connect/node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/connect/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/connect/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/connect/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -5230,9 +4783,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", "dev": true, "engines": { "node": ">= 0.6" @@ -5280,34 +4833,6 @@ "webpack": "^5.1.0" } }, - "node_modules/copy-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, "node_modules/copy-webpack-plugin/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5320,12 +4845,6 @@ "node": ">=10.13.0" } }, - "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/copy-webpack-plugin/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", @@ -5346,12 +4865,12 @@ } }, "node_modules/core-js-compat": { - "version": "3.32.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.1.tgz", - "integrity": "sha512-GSvKDv4wE0bPnQtjklV101juQ85g6H3rm5PDP20mqlS5j0kXF3pP97YvAu5hl+uFHqMictp3b2VxOHljWMAtuA==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", + "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", "dev": true, "dependencies": { - "browserslist": "^4.21.10" + "browserslist": "^4.22.1" }, "funding": { "type": "opencollective", @@ -5490,6 +5009,12 @@ "node": ">=8" } }, + "node_modules/critters/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "node_modules/critters/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5656,9 +5181,9 @@ } }, "node_modules/cssdb": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.7.2.tgz", - "integrity": "sha512-pQPYP7/kch4QlkTcLuUNiNL2v/E+O+VIdotT+ug62/+2B2/jkzs5fMM6RHCzGCZ9C82pODEMSIzRRUzJOrl78g==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.8.0.tgz", + "integrity": "sha512-SkeezZOQr5AHt9MgJgSFNyiuJwg1p8AwoVln6JwaQJsyxduRW9QJ+HP/gAQzbsz8SIqINtYvpJKjxTRI67zxLg==", "dev": true, "funding": [ { @@ -6150,9 +5675,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", - "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" }, "node_modules/debug": { "version": "4.3.4", @@ -6387,9 +5912,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.508", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.508.tgz", - "integrity": "sha512-FFa8QKjQK/A5QuFr2167myhMesGrhlOBD+3cYNxO9/S4XzHEXesyTD/1/xF644gC8buFPz3ca6G1LOQD0tZrrg==", + "version": "1.4.559", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.559.tgz", + "integrity": "sha512-iS7KhLYCSJbdo3rUSkhDTVuFNCV34RKs2UaB9Ecr7VlqzjjWW//0nfsFF5dtDmyXlZQaDYYtID5fjtC/6lpRug==", "dev": true }, "node_modules/elkjs": { @@ -6450,9 +5975,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.2.tgz", - "integrity": "sha512-IXsMcGpw/xRfjra46sVZVHiSWo/nJ/3g1337q9KNXtS6YRzbW5yIzTCb9DjhrBe7r3GZQR0I4+nq+4ODk5g/cA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.3.tgz", + "integrity": "sha512-IML/R4eG/pUS5w7OfcDE0jKrljWS9nwnEfsxWCIJF5eO6AHo6+Hlv+lQbdlAYsiJPHzUthLm1RUjnBzWOs45cw==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -6479,36 +6004,6 @@ "node": ">=10.0.0" } }, - "node_modules/engine.io/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/engine.io/node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -6967,7 +6462,7 @@ "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -7145,6 +6640,39 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, + "node_modules/express/node_modules/body-parser": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -7154,12 +6682,54 @@ "ms": "2.0.0" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/express/node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -7263,17 +6833,17 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.3.0", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "engines": { @@ -7295,6 +6865,18 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -7312,30 +6894,6 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, - "node_modules/find-cache-dir/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-cache-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -7350,15 +6908,15 @@ } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true, "funding": [ { @@ -7421,9 +6979,9 @@ } }, "node_modules/fraction.js": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", - "integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "dev": true, "engines": { "node": "*" @@ -7442,6 +7000,20 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -7463,7 +7035,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "node_modules/fsevents": { @@ -7481,10 +7053,13 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gauge": { "version": "4.0.4", @@ -7560,20 +7135,19 @@ } }, "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", + "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": "*" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -7646,13 +7220,10 @@ "dev": true }, "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, "engines": { "node": ">= 0.4.0" } @@ -7660,7 +7231,7 @@ "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -7831,6 +7402,15 @@ "node": ">= 0.8" } }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", @@ -7985,27 +7565,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/ignore-walk/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/ignore-walk/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", @@ -8077,7 +7636,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { "once": "^1.3.0", @@ -8426,9 +7985,9 @@ } }, "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, "engines": { "node": ">=8" @@ -8450,15 +8009,6 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-instrument/node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -8469,17 +8019,17 @@ } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-report/node_modules/has-flag": { @@ -8492,29 +8042,20 @@ } }, "node_modules/istanbul-lib-report/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-report/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/istanbul-lib-report/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -8543,6 +8084,36 @@ "node": ">=6" } }, + "node_modules/istanbul-lib-source-maps/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/istanbul-lib-source-maps/node_modules/istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", @@ -8552,6 +8123,40 @@ "node": ">=6" } }, + "node_modules/istanbul-lib-source-maps/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/istanbul-lib-source-maps/node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -8564,6 +8169,15 @@ "rimraf": "bin.js" } }, + "node_modules/istanbul-lib-source-maps/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8574,9 +8188,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -8587,9 +8201,9 @@ } }, "node_modules/jackspeak": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.3.tgz", - "integrity": "sha512-R2bUw+kVZFS/h1AZqBKrSgDmdmjApzgY0AlCPumopFiAlbUxE2gf+SCuBzQ0cP5hHmUmFYF5yw55T97Th5Kstg==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -8684,9 +8298,9 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { "argparse": "^1.0.7", @@ -8715,9 +8329,9 @@ "dev": true }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "node_modules/json5": { @@ -8819,6 +8433,28 @@ "url": "https://github.com/sponsors/mattlewis92" } }, + "node_modules/karma-coverage-istanbul-reporter/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/karma-coverage-istanbul-reporter/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/karma-jasmine": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", @@ -8860,6 +8496,16 @@ "source-map-support": "^0.5.5" } }, + "node_modules/karma/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/karma/node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -8880,16 +8526,28 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/karma/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "node_modules/karma/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, - "bin": { - "mime": "cli.js" + "dependencies": { + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=4.0.0" + "node": "*" + } + }, + "node_modules/karma/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, "node_modules/karma/node_modules/source-map": { @@ -8941,9 +8599,9 @@ } }, "node_modules/katex": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.8.tgz", - "integrity": "sha512-ftuDnJbcbOckGY11OO+zg3OofESlbR5DRl2cmN8HeWeeFIV7wTXvAOx8kEjZjobhA+9wh2fbKeO6cdcA9Mnovg==", + "version": "0.16.9", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.9.tgz", + "integrity": "sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" @@ -8964,9 +8622,9 @@ } }, "node_modules/khroma": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.0.0.tgz", - "integrity": "sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" }, "node_modules/kind-of": { "version": "6.0.3", @@ -9037,6 +8695,53 @@ "webpack": "^5.0.0" } }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, "node_modules/less/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -9240,25 +8945,27 @@ } }, "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/make-dir/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/make-error": { @@ -9305,15 +9012,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/make-fetch-happen/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/make-fetch-happen/node_modules/cacache": { "version": "17.1.4", "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", @@ -9338,9 +9036,9 @@ } }, "node_modules/make-fetch-happen/node_modules/cacache/node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -9359,28 +9057,28 @@ } }, "node_modules/make-fetch-happen/node_modules/fs-minipass/node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/make-fetch-happen/node_modules/glob": { - "version": "10.3.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", - "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", + "jackspeak": "^2.3.5", "minimatch": "^9.0.1", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", "path-scurry": "^1.10.1" }, "bin": { - "glob": "dist/cjs/src/bin.js" + "glob": "dist/esm/bin.mjs" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -9435,9 +9133,9 @@ } }, "node_modules/make-fetch-happen/node_modules/ssri/node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -9566,15 +9264,15 @@ } }, "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, "bin": { "mime": "cli.js" }, "engines": { - "node": ">=4" + "node": ">=4.0.0" } }, "node_modules/mime-db": { @@ -9626,40 +9324,6 @@ "webpack": "^5.0.0" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", @@ -9686,15 +9350,15 @@ "dev": true }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=10" } }, "node_modules/minimist": { @@ -9748,9 +9412,9 @@ } }, "node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -9828,15 +9492,15 @@ "dev": true }, "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/moment": { @@ -10105,6 +9769,48 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/node-gyp/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -10239,46 +9945,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/npm-packlist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/npm-packlist/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm-packlist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/npm-packlist/node_modules/npm-bundled": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-2.0.1.tgz", @@ -10435,9 +10101,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.0.tgz", + "integrity": "sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10473,7 +10139,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { "wrappy": "1" @@ -10721,18 +10387,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/pacote/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -10779,10 +10433,10 @@ } }, "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "optional": true }, "node_modules/parse5-html-rewriting-stream": { "version": "6.0.1", @@ -10794,6 +10448,12 @@ "parse5-sax-parser": "^6.0.1" } }, + "node_modules/parse5-html-rewriting-stream/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", @@ -10803,6 +10463,12 @@ "parse5": "^6.0.1" } }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "node_modules/parse5-sax-parser": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz", @@ -10812,6 +10478,12 @@ "parse5": "^6.0.1" } }, + "node_modules/parse5-sax-parser/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -10833,7 +10505,7 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -10880,9 +10552,9 @@ } }, "node_modules/path-scurry/node_modules/minipass": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.3.tgz", - "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -10922,12 +10594,12 @@ } }, "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, "node_modules/piscina": { @@ -11797,11 +11469,11 @@ "engines": { "node": ">= 0.6" } - }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -11813,15 +11485,6 @@ "node": ">= 0.8" } }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -11831,15 +11494,6 @@ "pify": "^2.3.0" } }, - "node_modules/read-cache/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/read-package-json": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-5.0.2.tgz", @@ -11868,46 +11522,6 @@ "node": ">=10" } }, - "node_modules/read-package-json/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/read-package-json/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/read-package-json/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/read-package-json/node_modules/npm-normalize-package-bin": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz", @@ -11956,9 +11570,9 @@ "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dev": true, "dependencies": { "regenerate": "^1.4.2" @@ -12168,6 +11782,48 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/robust-predicates": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", @@ -12307,10 +11963,11 @@ } }, "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", + "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==", + "dev": true, + "optional": true }, "node_modules/schema-utils": { "version": "2.7.1", @@ -12330,6 +11987,37 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -12354,9 +12042,9 @@ } }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -12378,9 +12066,9 @@ } }, "node_modules/semver-dsl/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -12443,12 +12131,33 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/serialize-javascript": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", @@ -12527,15 +12236,6 @@ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "dev": true }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -12665,27 +12365,6 @@ "ws": "~8.11.0" } }, - "node_modules/socket.io-adapter/node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/socket.io-parser": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", @@ -12799,9 +12478,9 @@ } }, "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -12851,9 +12530,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", + "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", "dev": true }, "node_modules/spdy": { @@ -12887,9 +12566,9 @@ } }, "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", "dev": true }, "node_modules/ssf": { @@ -12916,12 +12595,12 @@ } }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, "node_modules/streamroller": { @@ -12938,20 +12617,6 @@ "node": ">=8.0" } }, - "node_modules/streamroller/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -13073,6 +12738,54 @@ "webpack": "^5.0.0" } }, + "node_modules/stylus/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/stylus/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/stylus/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/stylus/node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -13135,22 +12848,10 @@ "node_modules/tar/node_modules/minipass": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, "engines": { - "node": ">=10" + "node": ">=8" } }, "node_modules/tar/node_modules/yallist": { @@ -13211,6 +12912,37 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -13229,29 +12961,10 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/terser-webpack-plugin/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser-webpack-plugin/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/terser-webpack-plugin/node_modules/terser": { - "version": "5.19.4", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz", - "integrity": "sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==", + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.22.0.tgz", + "integrity": "sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==", "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -13266,25 +12979,6 @@ "node": ">=10" } }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/terser/node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -13299,6 +12993,48 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -13460,19 +13196,73 @@ "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" } }, + "node_modules/tslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/tslint/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tslint/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/tslint/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" } }, "node_modules/tslint/node_modules/tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "node_modules/tsutils": { @@ -13488,9 +13278,9 @@ } }, "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "node_modules/type-fest": { @@ -13538,9 +13328,9 @@ } }, "node_modules/ua-parser-js": { - "version": "0.7.35", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz", - "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==", + "version": "0.7.36", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.36.tgz", + "integrity": "sha512-CPPLoCts2p7D8VbybttE3P2ylv0OBZEAy7a12DsulIEcAiMtWJy+PBgMXgWDI80D5UwqE8oQPHYnk13tm38M2Q==", "dev": true, "funding": [ { @@ -13550,6 +13340,10 @@ { "type": "paypal", "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" } ], "engines": { @@ -13633,9 +13427,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -13687,9 +13481,13 @@ } }, "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -13851,40 +13649,6 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/webpack-dev-middleware/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", @@ -13959,40 +13723,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/webpack-dev-server/node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", @@ -14055,6 +13785,37 @@ } } }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -14243,20 +14004,20 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { "bufferutil": { From e9328c95f5a33e460e5ccfee2c0866f76b23e779 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Thu, 19 Oct 2023 09:20:48 -0400 Subject: [PATCH 10/22] update version number --- app/package-lock.json | 4 ++-- app/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index 78d90770..36de17ad 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -1,12 +1,12 @@ { "name": "attack-workbench-frontend", - "version": "2.0.1", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "attack-workbench-frontend", - "version": "2.0.1", + "version": "2.1.0", "license": "Apache-2.0", "dependencies": { "@angular/animations": "^14.3.0", diff --git a/app/package.json b/app/package.json index c279c7cb..851f82aa 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "attack-workbench-frontend", - "version": "2.0.1", + "version": "2.1.0", "description": "An application allowing users to explore, create, annotate, and share extensions of the MITRE ATT&CK® knowledge base. This repository contains an Angular-based web application providing the user interface for the ATT&CK Workbench application.", "repository": { "type": "git", From 6c9a026fc74065323c8a786831a38963e9b0aa6b Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 11:13:18 -0400 Subject: [PATCH 11/22] Fix #494 Navigation Menu (#510) * collapse nav menu into hamburger * fix hamburger pos * update changelog --- .../components/header/header.component.html | 36 ++++++++++--------- .../components/header/header.component.scss | 1 + .../app/components/header/header.component.ts | 2 +- docs/changelog.md | 3 ++ 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/app/src/app/components/header/header.component.html b/app/src/app/components/header/header.component.html index 9d7c0c67..803a8066 100644 --- a/app/src/app/components/header/header.component.html +++ b/app/src/app/components/header/header.component.html @@ -23,22 +23,9 @@

ATT&CK Workbench v

- - - - - - - - - + + + + + + + + + + + diff --git a/app/src/app/components/header/header.component.scss b/app/src/app/components/header/header.component.scss index 2f5c22f1..d5fcd94d 100644 --- a/app/src/app/components/header/header.component.scss +++ b/app/src/app/components/header/header.component.scss @@ -33,6 +33,7 @@ overflow: hidden; &.pad-right { padding-right: 12px; } } + .account.pad-left { margin-left: 12px; } .hamburger { position: relative; width: 0; diff --git a/app/src/app/components/header/header.component.ts b/app/src/app/components/header/header.component.ts index 6e3988fe..75ec17d0 100644 --- a/app/src/app/components/header/header.component.ts +++ b/app/src/app/components/header/header.component.ts @@ -35,7 +35,7 @@ export class HeaderComponent implements AfterViewInit { this.allRoutes = stixRoutes; this.filteredRoutes = stixRoutes.filter( x => x.data.more != true ); this.moreRoutes = stixRoutes.filter( x => x.data.more == true ); - + this.authnTypeSubscription = this.authenticationService.getAuthType().subscribe({ next: (v) => { this.authnType = v }, complete: () => { this.authnTypeSubscription.unsubscribe(); } diff --git a/docs/changelog.md b/docs/changelog.md index 27a77108..f5f071c6 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -37,6 +37,9 @@ #### New Features in 2.1.0 - Added the ability to create, view, and edit Asset objects. +#### Improvements in 2.1.0 +- Navigation menu collapses under a separate hamburger menu rather than the identity icon. See [frontend#494](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/494). + #### Fixes in 2.1.0 - Fixed an issue where revoking or deprecating an object would deprecate all `revoked-by` relationships with the object. See [frontend#467](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/467). - Fixed an issue where first/last seen Campaign dates were parsed in local time, causing the dates to be displayed incorrectly in certain timezones. See [frontend#508](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/508). From 99c5f536ef6c3d7ab563e52b48adfa944c129133 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 12:39:17 -0400 Subject: [PATCH 12/22] Feature/#263 reference object list (#511) * add list of objects that cite a reference to reference dialog * update headers * clean up css * remove stix-list filters * minor changes * update var name * add option to route to citing object page * update changelog --- .../reference-edit-dialog.component.html | 28 +++++++++++++- .../reference-edit-dialog.component.scss | 11 +++++- .../reference-edit-dialog.component.ts | 11 +++++- .../stix/stix-list/stix-list.component.html | 2 +- .../stix/stix-list/stix-list.component.ts | 11 ++++-- .../reference-manager.component.ts | 38 +++++++++++++------ docs/changelog.md | 1 + 7 files changed, 81 insertions(+), 21 deletions(-) diff --git a/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.html b/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.html index bd01d5e5..cf98dc1b 100644 --- a/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.html +++ b/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.html @@ -11,7 +11,7 @@ - + @@ -193,6 +193,32 @@

{{reference.source_name}}

+ + +

Objects citing this reference

+
+ No objects in the knowledge base cite this reference. +
+
+ + +

Objects citing this reference

+ +
+ +

Relationships citing this reference

+ +
+
\ No newline at end of file diff --git a/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.scss b/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.scss index c9aafd61..142bb59c 100644 --- a/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.scss +++ b/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.scss @@ -8,6 +8,11 @@ } h1 { margin-top: 0; + } + h3 { + margin-top: 20px; + } + h1, h3, .center-align { margin-bottom: 20px; text-align: center; } @@ -48,8 +53,7 @@ } .reference-view { padding: 25px; - max-width: 50vw; - min-width: 35vw; + width: 60vw; .clickable { cursor: pointer; } @@ -67,4 +71,7 @@ margin-top: 24px; margin-bottom: 24px; } + .section-header { + padding-top: 10px; + } } \ No newline at end of file diff --git a/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.ts b/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.ts index f6b4286e..e0ffd17f 100644 --- a/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.ts +++ b/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.ts @@ -14,7 +14,7 @@ import { DeleteDialogComponent } from '../delete-dialog/delete-dialog.component' export class CustomErrorStateMatcher implements ErrorStateMatcher { isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { - return !!(control && control.invalid && (control.dirty || control.touched)); + return !!(control?.invalid && (control.dirty || control.touched)); } } @@ -26,6 +26,9 @@ export class CustomErrorStateMatcher implements ErrorStateMatcher { }) export class ReferenceEditDialogComponent implements OnInit, OnDestroy { public reference: ExternalReference; + public stixObjects: StixObject[] = []; + public relationships: StixObject[] = []; + public isNew: boolean; public stage: number = 0; public patchObjects: StixObject[]; @@ -45,6 +48,7 @@ export class ReferenceEditDialogComponent implements OnInit, OnDestroy { public get editing(): boolean { return this.config.mode == 'edit'; } public get editable(): boolean { return this.authenticationService.canEdit(); } public get deletable(): boolean { return this.authenticationService.canDelete(); } + public get numCitingObjects(): number { return this.stixObjects.length + this.relationships.length; } constructor(@Inject(MAT_DIALOG_DATA) public config: ReferenceEditConfig, public dialogRef: MatDialogRef, @@ -55,6 +59,8 @@ export class ReferenceEditDialogComponent implements OnInit, OnDestroy { if (this.config.reference) { this.isNew = false; this.reference = this.referenceCopy; + this.stixObjects = this.config.objects?.filter(sdo => sdo.attackType != 'relationship'); + this.relationships = this.config.objects?.filter(sdo => sdo.attackType == 'relationship'); } else { this.isNew = true; @@ -171,7 +177,7 @@ export class ReferenceEditDialogComponent implements OnInit, OnDestroy { this.stage = 1; //enter patching stage let subscription = this.restApiConnectorService.getAllObjects(null, null, null, null, true, true, true).subscribe({ next: (results) => { - // build ID to [name, attackID] lookup + // build ID to SDO lookup let idToObject = {} results.data.forEach(x => { idToObject[x.stixID] = x }); // find objects with given reference @@ -325,4 +331,5 @@ export interface ReferenceEditConfig { */ mode?: "view" | "edit"; reference?: ExternalReference + objects?: StixObject[] } \ No newline at end of file diff --git a/app/src/app/components/stix/stix-list/stix-list.component.html b/app/src/app/components/stix/stix-list/stix-list.component.html index 58468923..f3929589 100644 --- a/app/src/app/components/stix/stix-list/stix-list.component.html +++ b/app/src/app/components/stix/stix-list/stix-list.component.html @@ -112,7 +112,7 @@ - + diff --git a/app/src/app/components/stix/stix-list/stix-list.component.ts b/app/src/app/components/stix/stix-list/stix-list.component.ts index a270f584..d4e2c341 100644 --- a/app/src/app/components/stix/stix-list/stix-list.component.ts +++ b/app/src/app/components/stix/stix-list/stix-list.component.ts @@ -386,7 +386,7 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { } // open-link icon setup - if (this.config.clickBehavior && this.config.clickBehavior == "linkToObjectRef") { + if (this.config.clickBehavior && ["linkToObjectPage", "linkToObjectRef"].includes(this.config.clickBehavior)) { controls_after.push("open-link") } @@ -528,6 +528,10 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { complete: () => { subscription.unsubscribe(); } }); } + else if (this.config.clickBehavior && this.config.clickBehavior == "linkToObjectPage") { + this.onRowAction.emit(); // close any open dialogs + this.router.navigateByUrl('/' + element.attackType + '/' + element.stixID); + } else if (this.config.clickBehavior && this.config.clickBehavior == "linkToSourceRef") { let source_ref = element['source_ref']; // Get type to navigate from source_ref @@ -950,12 +954,13 @@ export interface StixListConfig { * How should the table act when the row is clicked? default "expand" * "expand": expand the row to show additional detail * "dialog": open a dialog with the full object definition + * "linkToObjectPage": clicking redirects to the object's page * "linkToSourceRef": clicking redirects to the source ref object * "linkToTargetRef": clicking redirects user to target ref object - * "linkToObjectRef": clicking redirects user to first object in the object ref array + * "linkToObjectRef": clicking redirects user to first object in a Note's object ref array * "none": row is not clickable */ - clickBehavior?: "expand" | "dialog" | "linkToSourceRef" | "linkToTargetRef" | "linkToObjectRef" | "none"; + clickBehavior?: "expand" | "dialog" | "linkToObjectPage" | "linkToSourceRef" | "linkToTargetRef" | "linkToObjectRef" | "none"; /** * Default false. If true, allows for edits of the objects in the table * when in dialog mode diff --git a/app/src/app/views/reference-manager/reference-manager.component.ts b/app/src/app/views/reference-manager/reference-manager.component.ts index 385d21d8..141aa6ce 100644 --- a/app/src/app/views/reference-manager/reference-manager.component.ts +++ b/app/src/app/views/reference-manager/reference-manager.component.ts @@ -5,6 +5,7 @@ import { MatSnackBar } from '@angular/material/snack-bar'; import { fromEvent, Observable, Subscription } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, tap } from 'rxjs/operators'; import { ExternalReference } from 'src/app/classes/external-references'; +import { Relationship } from 'src/app/classes/stix/relationship'; import { StixObject } from 'src/app/classes/stix/stix-object'; import { ReferenceEditDialogComponent } from 'src/app/components/reference-edit-dialog/reference-edit-dialog.component'; import { AuthenticationService } from 'src/app/services/connectors/authentication/authentication.service'; @@ -19,11 +20,11 @@ import { Paginated, RestApiConnectorService } from 'src/app/services/connectors/ export class ReferenceManagerComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChild('search') search: ElementRef; @ViewChild(MatPaginator) paginator: MatPaginator; - public attackObjects: StixObject[]; // all objects in the knowledge base + public attackObjects: StixObject[] = []; // all objects in the knowledge base public references$: Observable>; public totalReferences: number = 0; public columnDefs: string[] = ['citation', 'reference', 'count', 'open']; - public referenceMap: Map = new Map(); // reference.source_name => number of objects that use the reference + public referenceMap: Map = new Map(); // reference.source_name => list of STIX objects citing the reference public loading: boolean = false; private searchSubscription: Subscription; public searchQuery: string = ""; @@ -36,9 +37,25 @@ export class ReferenceManagerComponent implements OnInit, AfterViewInit, OnDestr public snackbar: MatSnackBar) { } ngOnInit(): void { - let subscription = this.restApiConnector.getAllObjects().subscribe({ + let subscription = this.restApiConnector.getAllObjects(null, null, null, null, true, true, true).subscribe({ next: (results) => { - this.attackObjects = results as StixObject[]; + // build ID to SDO lookup + let idToObject = {}; + results.data.forEach(x => idToObject[x.stixID] = x); + + results.data.forEach(sdo => { + if (sdo.attackType == 'relationship') { + // serialize relationship source/target objects + let rel = sdo as Relationship; + if (idToObject[rel.source_ref] && idToObject[rel.target_ref]) { + let serialized = rel.serialize(); + serialized.source_object = idToObject[rel.source_ref].serialize(); + serialized.target_object = idToObject[rel.target_ref].serialize(); + rel.deserialize(serialized); + this.attackObjects.push(rel); + } + } else this.attackObjects.push(sdo); + }); }, complete: () => { this.applyControls(); @@ -85,7 +102,7 @@ export class ReferenceManagerComponent implements OnInit, AfterViewInit, OnDestr data: { mode: reference ? 'view' : 'edit', reference: reference, - count: reference ? this.referenceCount(reference.source_name): 0 + objects: reference ? this.referenceMap[reference.source_name] : [] } }); let subscription = prompt.afterClosed().subscribe({ @@ -116,13 +133,10 @@ export class ReferenceManagerComponent implements OnInit, AfterViewInit, OnDestr let uses = function(reference: ExternalReference) { // count number of objects that have this reference in its external_references list let usesReference: StixObject[] = self.attackObjects.filter(o => { - let ext_refs: any[] = o['stix'] && o['stix']['external_references'] && o['stix']['external_references'].length > 0 ? o['stix']['external_references'] : undefined; - if (!ext_refs) return false; // object does not have external references - let sources = ext_refs.map(ref => ref.source_name); - if (sources.includes(reference.source_name)) return true; - return false; + let ext_refs = o.external_references && o.external_references.list().length > 0 ? o.external_references : undefined; + return ext_refs?.hasValue(reference.source_name); }); - return usesReference.length; + return usesReference; } for (let ref of data.data) { if (!this.referenceMap.has(ref.source_name)) { @@ -140,6 +154,6 @@ export class ReferenceManagerComponent implements OnInit, AfterViewInit, OnDestr */ public referenceCount(source: string): number { if (!source) return 0; - return this.referenceMap[source]; + return this.referenceMap[source]?.length; } } diff --git a/docs/changelog.md b/docs/changelog.md index f5f071c6..68d07e74 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -36,6 +36,7 @@ #### New Features in 2.1.0 - Added the ability to create, view, and edit Asset objects. +- Added the ability to view and route to objects that cite a given reference from the reference dialog. See [frontend#263](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/263). #### Improvements in 2.1.0 - Navigation menu collapses under a separate hamburger menu rather than the identity icon. See [frontend#494](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/494). From 0fd3519916f4befcb76ffcd498f7b3fff36596b2 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 12:45:49 -0400 Subject: [PATCH 13/22] group button bug fix --- app/src/app/services/editor/editor.service.ts | 4 ++-- docs/changelog.md | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/app/services/editor/editor.service.ts b/app/src/app/services/editor/editor.service.ts index 120ea04d..89eb4c62 100644 --- a/app/src/app/services/editor/editor.service.ts +++ b/app/src/app/services/editor/editor.service.ts @@ -43,13 +43,13 @@ export class EditorService { let editable = this.getEditableFromRoute(this.router.routerState, this.router.routerState.root); let attackType = this.route.root.firstChild.snapshot.data.breadcrumb; this.editable = editable.length > 0 && editable.every(x => x) && this.authenticationService.canEdit(attackType); - // if we have a group type and it is NOT new we can create a collection from all of the objects in the group - this.isGroup = this.type === 'group' && !this.router.url.includes("/new"); this.hasWorkflow = attackType !== 'home'; if (!(this.editable && this.hasWorkflow)) this.sidebarService.currentTab = "references"; this.sidebarService.setEnabled("history", this.editable && this.hasWorkflow); this.sidebarService.setEnabled("notes", this.editable && this.hasWorkflow); if (this.editable) { + // if we have a group type and it is NOT new we can create a collection from all of the objects in the group + this.isGroup = this.type === 'group' && !this.router.url.includes("/new"); if (!this.hasWorkflow) { this.hasRelationships = false; if (this.type.includes('profile')) this.deletable = false; diff --git a/docs/changelog.md b/docs/changelog.md index 68d07e74..7d69a5f5 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -44,6 +44,7 @@ #### Fixes in 2.1.0 - Fixed an issue where revoking or deprecating an object would deprecate all `revoked-by` relationships with the object. See [frontend#467](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/467). - Fixed an issue where first/last seen Campaign dates were parsed in local time, causing the dates to be displayed incorrectly in certain timezones. See [frontend#508](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/508). +- Fixed a bug where the "create a collection from group" button was being displayed on the group list page. ## 21 September 2023 From 5375c8039af88d5b3731a3eceb89261c88da0518 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 12:47:45 -0400 Subject: [PATCH 14/22] minor changes --- app/src/app/services/editor/editor.service.ts | 1 + docs/changelog.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/src/app/services/editor/editor.service.ts b/app/src/app/services/editor/editor.service.ts index 89eb4c62..8d1c0e26 100644 --- a/app/src/app/services/editor/editor.service.ts +++ b/app/src/app/services/editor/editor.service.ts @@ -47,6 +47,7 @@ export class EditorService { if (!(this.editable && this.hasWorkflow)) this.sidebarService.currentTab = "references"; this.sidebarService.setEnabled("history", this.editable && this.hasWorkflow); this.sidebarService.setEnabled("notes", this.editable && this.hasWorkflow); + this.isGroup = false; if (this.editable) { // if we have a group type and it is NOT new we can create a collection from all of the objects in the group this.isGroup = this.type === 'group' && !this.router.url.includes("/new"); diff --git a/docs/changelog.md b/docs/changelog.md index 7d69a5f5..c4e82225 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -34,6 +34,8 @@ ## Changes Staged on Develop +### ATT&CK Workbench version 2.1.0 + #### New Features in 2.1.0 - Added the ability to create, view, and edit Asset objects. - Added the ability to view and route to objects that cite a given reference from the reference dialog. See [frontend#263](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/263). From 2497c9725548afcae7a372bf83ff7bcded025f31 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:04:06 -0400 Subject: [PATCH 15/22] format changelog --- docs/changelog.md | 429 ++++++++++++++++++++++++---------------------- 1 file changed, 221 insertions(+), 208 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index c4e82225..85e57a35 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -36,29 +36,33 @@ ### ATT&CK Workbench version 2.1.0 -#### New Features in 2.1.0 -- Added the ability to create, view, and edit Asset objects. -- Added the ability to view and route to objects that cite a given reference from the reference dialog. See [frontend#263](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/263). +#### New Features -#### Improvements in 2.1.0 -- Navigation menu collapses under a separate hamburger menu rather than the identity icon. See [frontend#494](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/494). +- Added the ability to create, view, and edit Asset objects. +- Added the ability to view and route to objects that cite a given reference from the reference dialog. See [frontend#263](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/263). -#### Fixes in 2.1.0 -- Fixed an issue where revoking or deprecating an object would deprecate all `revoked-by` relationships with the object. See [frontend#467](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/467). -- Fixed an issue where first/last seen Campaign dates were parsed in local time, causing the dates to be displayed incorrectly in certain timezones. See [frontend#508](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/508). -- Fixed a bug where the "create a collection from group" button was being displayed on the group list page. +#### Improvements + +- Navigation menu collapses under a separate hamburger menu rather than the identity icon. See [frontend#494](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/494). + +#### Fixes + +- Fixed an issue where revoking or deprecating an object would deprecate all `revoked-by` relationships with the object. See [frontend#467](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/467). +- Fixed an issue where first/last seen Campaign dates were parsed in local time, causing the dates to be displayed incorrectly in certain timezones. See [frontend#508](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/508). +- Fixed a bug where the "create a collection from group" button was being displayed on the group list page. ## 21 September 2023 ### ATT&CK Workbench version 2.0.1 -#### Fixes in 2.0.1 -- Fixed a crash that would occur when retrieving recent activity for large teams. -- Fixed the incorrect path to the REST API Docker image documented in [`docker-compose.md`](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/docker-compose.md). -- Fixed an issue where the version number of an object could be saved in an invalid format. -- Fixed object name and ATT&CK ID validation to check against revoked and deprecated objects. -- Fixed an issue where the `retrieveAll()` query for Relationships and ATT&CK objects would cause a "Sort exceeded memory limit" error. See [rest-api#285](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/285). -- Updated Angular to v14. +#### Fixes + +- Fixed a crash that would occur when retrieving recent activity for large teams. +- Fixed the incorrect path to the REST API Docker image documented in [`docker-compose.md`](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/docker-compose.md). +- Fixed an issue where the version number of an object could be saved in an invalid format. +- Fixed object name and ATT&CK ID validation to check against revoked and deprecated objects. +- Fixed an issue where the `retrieveAll()` query for Relationships and ATT&CK objects would cause a "Sort exceeded memory limit" error. See [rest-api#285](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/285). +- Updated Angular to v14. ## 16 August 2023 @@ -68,45 +72,51 @@ As of v2.0.0, the [ATT&CK Workbench Collection Manager](https://github.com/cente The ATT&CK Workbench now features a persistent database for Docker installs with the use of a named volume. **This change may result in data on the current anonymous volume being lost.** The [Docker Install Update Guide](/docs/update.md) describes how to backup your existing ATT&CK Workbench data, update to v2.0.0, and restore your data after the update. -#### New Features in 2.0.0 -- Added an Admin interface for creating and managing teams. -- Added the ability to search objects by one or more users. -- Added a new user profile page where logged in users can view their recent activity across the Workbench and view/edit their display name. -- Added an option to configure an external ATT&CK Website in which to view Workbench objects, if a relevant object page exists. -- Added functionality to create a collection from a group and its related objects. -- Added button to import groups and their related objects into new or existing collections. -- Added an option to deprecate Data Component objects. See [frontend#429](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/429). -- Added Matrix view to Matrix pages similar to the full matrix on the [ATT&CK website](https://attack.mitre.org/). See [frontend#20](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/20). -- Added ability to upload csv and excel files in collection imports. -- Added support for configuring a default landing page. The desired landing page can be specified in `assets/config.json`, which Workbench will route to upon login. - -#### Improvements in 2.0.0 -- Improved error handling during collection import. -- Lists of objects can now be filtered when viewing or editing collections. See [frontend#393](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/393). -- Added a persistent database to Docker installs. -- Published pre-built Docker images to the Github Container Registry. See [frontend#250](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/250). -- Improved the collection view to display versions in the drop down rather than in the main list. - -#### Fixes in 2.0.0 -- Fixed an issue where duplicate entries would be displayed in some dropdown lists for objects in multiple domains. See [frontend#454](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/454). +#### New Features + +- Added an Admin interface for creating and managing teams. +- Added the ability to search objects by one or more users. +- Added a new user profile page where logged in users can view their recent activity across the Workbench and view/edit their display name. +- Added an option to configure an external ATT&CK Website in which to view Workbench objects, if a relevant object page exists. +- Added functionality to create a collection from a group and its related objects. +- Added button to import groups and their related objects into new or existing collections. +- Added an option to deprecate Data Component objects. See [frontend#429](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/429). +- Added Matrix view to Matrix pages similar to the full matrix on the [ATT&CK website](https://attack.mitre.org/). See [frontend#20](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/20). +- Added ability to upload csv and excel files in collection imports. +- Added support for configuring a default landing page. The desired landing page can be specified in `assets/config.json`, which Workbench will route to upon login. + +#### Improvements + +- Improved error handling during collection import. +- Lists of objects can now be filtered when viewing or editing collections. See [frontend#393](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/393). +- Added a persistent database to Docker installs. +- Published pre-built Docker images to the Github Container Registry. See [frontend#250](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/250). +- Improved the collection view to display versions in the drop down rather than in the main list. + +#### Fixes + +- Fixed an issue where duplicate entries would be displayed in some dropdown lists for objects in multiple domains. See [frontend#454](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/454). ## 21 April 2023 ### ATT&CK Workbench version 1.3.1 -#### New Features in 1.3.1 -- Added universal Notes page where users can search for notes based on title or content. Selecting a note in the table will redirect the user to the object the note was created on. See [frontend#176](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/175). +#### New Features + +- Added universal Notes page where users can search for notes based on title or content. Selecting a note in the table will redirect the user to the object the note was created on. See [frontend#176](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/175). + +#### Improvements -#### Improvements in 1.3.1 -- Added individual attribution to edits made on Note objects. -- Added the ICS Security Control mapping field to Mitigation objects. See [frontend#419](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/419). -- Updated the documentation for installing Workbench with additional certs. See [frontend#225](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/225). +- Added individual attribution to edits made on Note objects. +- Added the ICS Security Control mapping field to Mitigation objects. See [frontend#419](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/419). +- Updated the documentation for installing Workbench with additional certs. See [frontend#225](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/225). -#### Fixes in 1.3.1 -- Fixed an issue where assigning an existing technique as a sub-technique would not create a `subtechnique-of` relationship. See [frontend#446](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/446). -- Fixed an issue causing a user's `displayName` to be removed when updating a user account on the admin page. See [frontend#449](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/449). -- Fixed an issue where updates to a user account role or status would not be reflected until the page was refreshed. See [frontend#450](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/450). -- Fixed a bug with the validation of the `source_name` field on Reference objects. +#### Fixes + +- Fixed an issue where assigning an existing technique as a sub-technique would not create a `subtechnique-of` relationship. See [frontend#446](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/446). +- Fixed an issue causing a user's `displayName` to be removed when updating a user account on the admin page. See [frontend#449](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/449). +- Fixed an issue where updates to a user account role or status would not be reflected until the page was refreshed. See [frontend#450](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/450). +- Fixed a bug with the validation of the `source_name` field on Reference objects. ## 8 March 2023 @@ -114,22 +124,24 @@ The ATT&CK Workbench now features a persistent database for Docker installs with ATT&CK Workbench version 1.3.0 supports the deletion of objects. -#### New Features in 1.3.0 +#### New Features + +- Added a Reference Manager page to the Workbench to increase usability. The ability to view and edit a reference has been moved from the sidebar to the Reference Manager page. See [frontend#349](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/349). +- Added functionality to delete Relationship objects, with the exception of `subtechnique_of` relationships. See [frontend#341](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/341). +- Added functionality to delete References which are not cited by any objects. See [frontend#350](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/350). +- Added functionality to delete Mitigation, Group, Software, Data Source, Data Component, and Technique objects. Objects can only be deleted by users with `admin` roles if the object does not have any existing relationships. See [frontend#342](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/342), [frontend#346](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/346), [frontend#347](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/347), and [frontend#343](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/343). + +#### Improvements -- Added a Reference Manager page to the Workbench to increase usability. The ability to view and edit a reference has been moved from the sidebar to the Reference Manager page. See [frontend#349](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/349). -- Added functionality to delete Relationship objects, with the exception of `subtechnique_of` relationships. See [frontend#341](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/341). -- Added functionality to delete References which are not cited by any objects. See [frontend#350](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/350). -- Added functionality to delete Mitigation, Group, Software, Data Source, Data Component, and Technique objects. Objects can only be deleted by users with `admin` roles if the object does not have any existing relationships. See [frontend#342](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/342), [frontend#346](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/346), [frontend#347](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/347), and [frontend#343](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/343). +- Improved validation for the `source_name` field on Reference objects to prevent duplicated source names and issues caused by invalid characters during citation parsing. See [frontend#352](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/352). +- Enabled editing of the `domains` field for Data Sources and Data Components. See [frontend#428](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/428). -#### Improvements in 1.3.0 -- Improved validation for the `source_name` field on Reference objects to prevent duplicated source names and issues caused by invalid characters during citation parsing. See [frontend#352](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/352). -- Enabled editing of the `domains` field for Data Sources and Data Components. See [frontend#428](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/428). +#### Fixes -#### Fixes in 1.3.0 -- Fixed an issue where the "apply patches and save" button would be unavailable when updating a reference used only by Relationship objects. See [frontend#356](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/356). -- Fixed an issue where the external reference for a Data Source's ATT&CK ID pointed to an incorrect URL. See [frontend#422](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/422). -- Fixed an issue where updating a reference used by a revoked or deprecated object would throw an error and prevent the user from saving the changes to the reference. See [frontend#355](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/355). -- Fixed a bug where citations would break if the reference source name contained special characters because the query was not correctly encoded in the request. See [frontend#371](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/371). +- Fixed an issue where the "apply patches and save" button would be unavailable when updating a reference used only by Relationship objects. See [frontend#356](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/356). +- Fixed an issue where the external reference for a Data Source's ATT&CK ID pointed to an incorrect URL. See [frontend#422](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/422). +- Fixed an issue where updating a reference used by a revoked or deprecated object would throw an error and prevent the user from saving the changes to the reference. See [frontend#355](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/355). +- Fixed a bug where citations would break if the reference source name contained special characters because the query was not correctly encoded in the request. See [frontend#371](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/371). ## 25 October 2022 @@ -139,55 +151,56 @@ ATT&CK Workbench v1.2.0 supports authentication and authorization for users. The Additionally, Workbench v1.2.0 introduces the ability to create, edit, and view Campaign objects and coincides with the ATT&CK v12.0 release. Users who do not upgrade to Workbench v1.2.0 may encounter issues with the new ATT&CK data. -#### New Features in 1.2.0 - -- Added functionality to generate object ATT&CK IDs. See [frontend#114](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/114) and [frontend#300](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/300). -- Added optional namespace settings for ATT&CK IDs, so object IDs don't conflict with ATT&CK or other organizations' object IDs. These settings are automatically applied when creating a new object. See [frontend#113](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/113). -- Added parent technique field when creating a sub-technique, this will automatically create a relationship between the parent and sub-technique. See [frontend#308](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/308). -- Added support for LinkById tags, which allow users to add links from one object to another in Workbench. LinkById tags are formatted as `(LinkById: ATT&CK ID)` and are supported in `description` and `x_mitre_detection` fields. When previewing or viewing these fields, LinkById tags are detected and replaced with a link to the corresponding object's page on the Workbench. See [frontend#279](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/279). - - LinkById tags are automatically checked and updated when a referenced object's ATT&CK ID is changed. See [frontend#281](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/281). -- Added a button to object ATT&CK ID fields to copy the object's LinkById tag. See [frontend#327](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/327). -- Added `contributors` field to Technique and Tactic objects. See [frontend#325](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/325). -- Added ability to search for objects by ATT&CK ID. See [rest-api#162](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/162). -- Added a view page for References in the Reference Manager. See [frontend#304](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/304). -- Added a link to the parent technique page from the sub-technique page. See [frontend#309](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/309). -- Added a link to tactic pages from the matrix page. See [frontend#391](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/391). -- Added support for viewing techniques associated with a tactic on the tactic view page. See [frontend#390](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/390). -- Added ability to create and edit Campaign objects. See [frontend#376](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/376), [frontend#377](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/377), and [frontend#384](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/384). -- Added the ability to automatically find and add tactics related to techniques when creating or editing a collection. See [frontend#388](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/388). -- Added the option to include associated Note objects in the Collection bundle export. See [frontend#389](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/389). - -#### Improvements in 1.2.0 - -- Added authentication and authorization to the Workbench. Only authorized users can access the data of the Workbench instance. Documentation pages may be viewed by unauthenticated users. See [frontend#192](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/192). -- Added user registration and approval. Administrators can approve registrants and set their permission levels on the administrator user accounts page. See [frontend#193](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/193). -- Added user login and logout functionality. Pending users cannot log in until the Adminstrator has approved their account. See [frontend#266](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/266). -- Added support for individual attribution. If a user is logged in, the application will display the individual user who has edited an object in place of the organization-level identity. Individual attribution is not supported when the Workbench instance is set up with anonymous authentication. See [frontend#191](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/191). -- Added support for marking definitions. See [frontend#188](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/188). -- Relationships which have been deprecated are hidden in the list of relationships without requiring a page refresh. See [frontend#321](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/321). -- Changing a user's role to `admin`, `editor` or `visitor` automatically sets the user's status to `active`. A user's status is automatically set to `inactive` if their role is changed to `none`. See [frontend#318](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/318). -- Added options to the relationship edit dialog to increment the source and/or target object versions when creating a new relationship. See [frontend#307](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/307). -- The source and target objects' version numbers and last modified dates are shown alongside their names when creating a new relationship to provide more context. See [frontend#313](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/313). -- When creating a new Reference object, the `retrieved` field will default to the current date. See [frontend#305](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/305). -- The external references field at the bottom of object pages are automatically updated to reflect citation changes to the `description` and `x_mitre_detection` fields before the object is saved. See [frontend#329](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/329). -- Added validation to ensure a technique has been assigned at least one tactic. See [frontend#273](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/273). -- Removed the comma key as a keycode separator for list input fields (i.e. `contributors`, `system requirements`, `CAPEC IDs`, etc.). See [frontend#335](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/335). -- Whitespace is trimmed during the serialization of string fields for all STIX objects and external references. See [frontend#187](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/187). -- Lists of objects can now be filtered by domains and platforms. See [frontend#392](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/392). -- Added validation for Reference URLs. See [frontend#407](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/407). - - -#### Fixes in 1.2.0 -- Added missing fields from User Account objects: `created`, `modified`, and `displayName`. See [frontend#319](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/319). -- Fixed a bug where spaces would break the search in object tables and show no results. See [frontend#303](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/303). -- Fixed an issue where other external references (such as MTC IDs or CAPEC IDs) were being identified as the object's ATT&CK ID, when the object had not yet been assigned an ATT&CK ID. See [frontend#322](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/322). -- Fixed an issue where Matrix ATT&CK IDs (a.k.a. domain identifiers) were being validated and preventing users from saving. This caused issues for domains which have multiple matrices with the same domain identifier. See [frontend#315](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/315). -- Fixed the unexpected calls being made to the REST API before the user is authenticated. See [frontend#314](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/314). -- Fixed a bug where the external reference links at the bottom of object pages did not redirect to the reference's associated URL. See [frontend#306](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/306). -- Fixed a bug where the search functionality would break with special characters because the query was not correctly encoded in the request. See [frontend#332](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/332). -- Fixed an issue where Note objects were not registered as a valid class, resulting in errors when trying to retrieve all objects from the REST API. See [frontend#338](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/338). -- Fixed an issue where the Software/Group `aliases` field expected the object name as the first array entry, causing display issues in downstream applications. See [frontend#370](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/370). -- Increased request timeout in nginx. See [frontend#387](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/387). +#### New Features + +- Added functionality to generate object ATT&CK IDs. See [frontend#114](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/114) and [frontend#300](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/300). +- Added optional namespace settings for ATT&CK IDs, so object IDs don't conflict with ATT&CK or other organizations' object IDs. These settings are automatically applied when creating a new object. See [frontend#113](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/113). +- Added parent technique field when creating a sub-technique, this will automatically create a relationship between the parent and sub-technique. See [frontend#308](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/308). +- Added support for LinkById tags, which allow users to add links from one object to another in Workbench. LinkById tags are formatted as `(LinkById: ATT&CK ID)` and are supported in `description` and `x_mitre_detection` fields. When previewing or viewing these fields, LinkById tags are detected and replaced with a link to the corresponding object's page on the Workbench. See [frontend#279](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/279). + - LinkById tags are automatically checked and updated when a referenced object's ATT&CK ID is changed. See [frontend#281](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/281). +- Added a button to object ATT&CK ID fields to copy the object's LinkById tag. See [frontend#327](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/327). +- Added `contributors` field to Technique and Tactic objects. See [frontend#325](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/325). +- Added ability to search for objects by ATT&CK ID. See [rest-api#162](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/162). +- Added a view page for References in the Reference Manager. See [frontend#304](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/304). +- Added a link to the parent technique page from the sub-technique page. See [frontend#309](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/309). +- Added a link to tactic pages from the matrix page. See [frontend#391](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/391). +- Added support for viewing techniques associated with a tactic on the tactic view page. See [frontend#390](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/390). +- Added ability to create and edit Campaign objects. See [frontend#376](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/376), [frontend#377](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/377), and [frontend#384](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/384). +- Added the ability to automatically find and add tactics related to techniques when creating or editing a collection. See [frontend#388](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/388). +- Added the option to include associated Note objects in the Collection bundle export. See [frontend#389](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/389). + +#### Improvements + +- Added authentication and authorization to the Workbench. Only authorized users can access the data of the Workbench instance. Documentation pages may be viewed by unauthenticated users. See [frontend#192](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/192). +- Added user registration and approval. Administrators can approve registrants and set their permission levels on the administrator user accounts page. See [frontend#193](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/193). +- Added user login and logout functionality. Pending users cannot log in until the Adminstrator has approved their account. See [frontend#266](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/266). +- Added support for individual attribution. If a user is logged in, the application will display the individual user who has edited an object in place of the organization-level identity. Individual attribution is not supported when the Workbench instance is set up with anonymous authentication. See [frontend#191](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/191). +- Added support for marking definitions. See [frontend#188](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/188). +- Relationships which have been deprecated are hidden in the list of relationships without requiring a page refresh. See [frontend#321](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/321). +- Changing a user's role to `admin`, `editor` or `visitor` automatically sets the user's status to `active`. A user's status is automatically set to `inactive` if their role is changed to `none`. See [frontend#318](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/318). +- Added options to the relationship edit dialog to increment the source and/or target object versions when creating a new relationship. See [frontend#307](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/307). +- The source and target objects' version numbers and last modified dates are shown alongside their names when creating a new relationship to provide more context. See [frontend#313](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/313). +- When creating a new Reference object, the `retrieved` field will default to the current date. See [frontend#305](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/305). +- The external references field at the bottom of object pages are automatically updated to reflect citation changes to the `description` and `x_mitre_detection` fields before the object is saved. See [frontend#329](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/329). +- Added validation to ensure a technique has been assigned at least one tactic. See [frontend#273](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/273). +- Removed the comma key as a keycode separator for list input fields (i.e. `contributors`, `system requirements`, `CAPEC IDs`, etc.). See [frontend#335](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/335). +- Whitespace is trimmed during the serialization of string fields for all STIX objects and external references. See [frontend#187](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/187). +- Lists of objects can now be filtered by domains and platforms. See [frontend#392](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/392). +- Added validation for Reference URLs. See [frontend#407](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/407). + + +#### Fixes + +- Added missing fields from User Account objects: `created`, `modified`, and `displayName`. See [frontend#319](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/319). +- Fixed a bug where spaces would break the search in object tables and show no results. See [frontend#303](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/303). +- Fixed an issue where other external references (such as MTC IDs or CAPEC IDs) were being identified as the object's ATT&CK ID, when the object had not yet been assigned an ATT&CK ID. See [frontend#322](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/322). +- Fixed an issue where Matrix ATT&CK IDs (a.k.a. domain identifiers) were being validated and preventing users from saving. This caused issues for domains which have multiple matrices with the same domain identifier. See [frontend#315](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/315). +- Fixed the unexpected calls being made to the REST API before the user is authenticated. See [frontend#314](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/314). +- Fixed a bug where the external reference links at the bottom of object pages did not redirect to the reference's associated URL. See [frontend#306](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/306). +- Fixed a bug where the search functionality would break with special characters because the query was not correctly encoded in the request. See [frontend#332](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/332). +- Fixed an issue where Note objects were not registered as a valid class, resulting in errors when trying to retrieve all objects from the REST API. See [frontend#338](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/338). +- Fixed an issue where the Software/Group `aliases` field expected the object name as the first array entry, causing display issues in downstream applications. See [frontend#370](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/370). +- Increased request timeout in nginx. See [frontend#387](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/387). ## 21 October 2021 @@ -195,164 +208,164 @@ Additionally, Workbench v1.2.0 introduces the ability to create, edit, and view ATT&CK Workbench v1.1.0 includes support for ATT&CK Spec v2.1.0 and coincides with the ATT&CK v10.0 release. Users who do not upgrade to Workbench v1.1.0 may encounter issues with the new ATT&CK data: -- If the user added the ATT&CK collection index prior to the ATT&CK v10.0 release, it may lose track of imported Enterprise collections. These collections can still be found in the "imported collections" tab of the collection manager, but won't be reflected in the collection manager. Collection subscriptions for Enterprise may also be lost. Upgrading to ATT&CK Workbench v1.1.0 will fix this issue and restore prior collection subscriptions. -- If the user imports ATT&CK v10.0 using ATT&CK Workbench 1.0.X, data sources and data components will not be imported into their local knowledge base. You can re-import the collection after upgrading Workbench to v1.1.0 to acquire the data sources and data components even if you had already imported it when running a prior version of Workbench. +- If the user added the ATT&CK collection index prior to the ATT&CK v10.0 release, it may lose track of imported Enterprise collections. These collections can still be found in the "imported collections" tab of the collection manager, but won't be reflected in the collection manager. Collection subscriptions for Enterprise may also be lost. Upgrading to ATT&CK Workbench v1.1.0 will fix this issue and restore prior collection subscriptions. +- If the user imports ATT&CK v10.0 using ATT&CK Workbench 1.0.X, data sources and data components will not be imported into their local knowledge base. You can re-import the collection after upgrading Workbench to v1.1.0 to acquire the data sources and data components even if you had already imported it when running a prior version of Workbench. ATT&CK Workbench version 1.1.0 includes improvements to how data is imported which should circumvent the above issues for future releases of ATT&CK. -#### Improvements in 1.1.0 - -- Added object type documentation on list pages. See [frontend#221](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/221). -- Added support for ATT&CK Spec v2.1.0: - - Added support for data sources and data components, and viewing/editing interfaces for these object types and their relationships with techniques. See [frontend#67](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/67), [frontend#66](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/66). - - Added support for `x_mitre_attack_spec_version` on all object types. -- Improved the flexibility and robustness of collection imports: - - Workbench will now check the ATT&CK Spec version of imported data and warn the user if the ATT&CK Spec version is unsupported (ex. if the Workbench instance is too outdated to support the data it is trying to import). The user can choose to bypass this warning. - - Workbench can now import the same collection multiple times in case objects in the initial import could not be imported due to an error. - - The user will now be provided with a downloadable list of objects that could not be saved (and the reason why) in the event of import errors. - - REST API will now log import errors for individual objects to the console when the log level is set to `verbose`. - - Frontend will now log import errors to the console when the application environment is not set to production. -- Added validation for missing ATT&CK IDs on objects that support them. The user will now be warned if they neglect to assign an ATT&CK ID to an object which supports it. When exporting a collection, the user will similarly be warned if any contained objects are missing ATT&CK IDs. See [frontend#231](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/231). -- REST API now supports setting the log level through an environment variable. See [rest-api#108](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/108). -- REST API no longer sets the `upgrade-insecure-requests` directive of the `Content-Security-Policy` header in responses. This will facilitate the deployment of ATT&CK Workbench in an internal environment without requiring the system to be configured to support HTTPS. See [rest-api#96](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/96). - -#### Fixes in 1.1.0 - -- Fixed an issue where the navigation header could be inaccessible when navigating within the application or when the page resized due to user input. -- Frontend will no longer claim objects were imported when they were actually discarded due to import errors such as spec violations. -- Imported STIX bundles will no longer require (but still allow) the `spec_version` field on the bundle itself. This was causing issues importing collections created by the Workbench. Objects within the bundle still require the `spec_version` field per the STIX 2.1 spec. See [rest-api#103](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/103). -- Fixed an issue where the REST API would save references when importing a collection bundle even though the `previewOnly` flag had been set. See [rest-api#120](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/120). +#### Improvements + +- Added object type documentation on list pages. See [frontend#221](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/221). +- Added support for ATT&CK Spec v2.1.0: + - Added support for data sources and data components, and viewing/editing interfaces for these object types and their relationships with techniques. See [frontend#67](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/67), [frontend#66](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/66). + - Added support for `x_mitre_attack_spec_version` on all object types. +- Improved the flexibility and robustness of collection imports: + - Workbench will now check the ATT&CK Spec version of imported data and warn the user if the ATT&CK Spec version is unsupported (ex. if the Workbench instance is too outdated to support the data it is trying to import). The user can choose to bypass this warning. + - Workbench can now import the same collection multiple times in case objects in the initial import could not be imported due to an error. + - The user will now be provided with a downloadable list of objects that could not be saved (and the reason why) in the event of import errors. + - REST API will now log import errors for individual objects to the console when the log level is set to `verbose`. + - Frontend will now log import errors to the console when the application environment is not set to production. +- Added validation for missing ATT&CK IDs on objects that support them. The user will now be warned if they neglect to assign an ATT&CK ID to an object which supports it. When exporting a collection, the user will similarly be warned if any contained objects are missing ATT&CK IDs. See [frontend#231](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/231). +- REST API now supports setting the log level through an environment variable. See [rest-api#108](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/108). +- REST API no longer sets the `upgrade-insecure-requests` directive of the `Content-Security-Policy` header in responses. This will facilitate the deployment of ATT&CK Workbench in an internal environment without requiring the system to be configured to support HTTPS. See [rest-api#96](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/96). + +#### Fixes + +- Fixed an issue where the navigation header could be inaccessible when navigating within the application or when the page resized due to user input. +- Frontend will no longer claim objects were imported when they were actually discarded due to import errors such as spec violations. +- Imported STIX bundles will no longer require (but still allow) the `spec_version` field on the bundle itself. This was causing issues importing collections created by the Workbench. Objects within the bundle still require the `spec_version` field per the STIX 2.1 spec. See [rest-api#103](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/103). +- Fixed an issue where the REST API would save references when importing a collection bundle even though the `previewOnly` flag had been set. See [rest-api#120](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/120). ## 20 August 2021 ### ATT&CK Workbench version 1.0.2 -#### Fixes in 1.0.2 +#### Fixes -- Error snackbars will now show appropriate messages instead of `[object ProgressEvent]` when communication with the REST API is interrupted or cannot be established. See [frontend#227](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/227). -- Fixed a bug where tactic shortnames were computed incorrectly for tactics with more than one space in the name (E.g `"Command and Control"`). See [frontend#239](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/239). - - If you have edited a technique under a tactic with more than one space in the name, remove and re-add the tactic under the technique edit interface to ensure that the tactic reference is formatted properly. - - If you have created a tactic with more than one space in the name, save a new version of the tactic and the proper shortname should be saved. You do not need to make any edits when saving the tactic page for the shortname to be fixed. +- Error snackbars will now show appropriate messages instead of `[object ProgressEvent]` when communication with the REST API is interrupted or cannot be established. See [frontend#227](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/227). +- Fixed a bug where tactic shortnames were computed incorrectly for tactics with more than one space in the name (E.g `"Command and Control"`). See [frontend#239](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/239). + - If you have edited a technique under a tactic with more than one space in the name, remove and re-add the tactic under the technique edit interface to ensure that the tactic reference is formatted properly. + - If you have created a tactic with more than one space in the name, save a new version of the tactic and the proper shortname should be saved. You do not need to make any edits when saving the tactic page for the shortname to be fixed. ## 8 July 2021 ### ATT&CK Workbench version 1.0.1 -#### Improvements in 1.0.1 +#### Improvements -- Added a system for configuring the Collection Manager with self-signed certs when using the docker setup. Documentation for this configuration will be improved in a subsequent release. +- Added a system for configuring the Collection Manager with self-signed certs when using the docker setup. Documentation for this configuration will be improved in a subsequent release. -#### Fixes in 1.0.1 +#### Fixes -- Fixed an error encountered when using the `attack-objects` API with large datasets. This error was preventing users from loading the "create a collection" page when Enterprise ATT&CK collections were imported. See [rest-api#87](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/87). +- Fixed an error encountered when using the `attack-objects` API with large datasets. This error was preventing users from loading the "create a collection" page when Enterprise ATT&CK collections were imported. See [rest-api#87](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/87). ## 21 June 2021 ### ATT&CK Workbench version 1.0.0 -#### Improvements in 1.0.0 +#### Improvements -- Performance improvements when adding, editing, and validating relationships. -- Improved error messages when importing collections that are too large or malformed. See [frontend#198](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/198). -- Improved page titles and breadcrumb on "object not found" pages. -- User can now import collections from file. See [frontend#207](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/207). -- Collection index update interval is now set in the REST API configuration instead of hardcoded in the frontend. See [frontend#200](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/200). +- Performance improvements when adding, editing, and validating relationships. +- Improved error messages when importing collections that are too large or malformed. See [frontend#198](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/198). +- Improved page titles and breadcrumb on "object not found" pages. +- User can now import collections from file. See [frontend#207](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/207). +- Collection index update interval is now set in the REST API configuration instead of hardcoded in the frontend. See [frontend#200](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/200). -#### Fixes in 1.0.0 +#### Fixes -- Fixed vertically misaligned timestamps across several UIs. -- Fixed missing timestamp on collection version lists within collection indexes. -- Fixed object status popover showing the wrong status if opened too soon after the page loads. Also improved performance of the status popover code. -- Collection import UI no longer gets stuck if it runs into a problem fetching/importing/previewing the collection. See [frontend#198](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/198) -- Object status popover now closes properly when the user starts editing the object. See [frontend#199](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/199). +- Fixed vertically misaligned timestamps across several UIs. +- Fixed missing timestamp on collection version lists within collection indexes. +- Fixed object status popover showing the wrong status if opened too soon after the page loads. Also improved performance of the status popover code. +- Collection import UI no longer gets stuck if it runs into a problem fetching/importing/previewing the collection. See [frontend#198](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/198) +- Object status popover now closes properly when the user starts editing the object. See [frontend#199](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/199). ## 7 May 2021 ### ATT&CK Workbench version 0.4.0 -#### Improvements in 0.4.0 +#### Improvements -- Added a favicon. See [frontend#137](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/137). -- Added dynamic page title to make it easier to distinguish multiple Workbench tabs in the browser. See [frontend#130](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/130). -- Added a list of recommended indexes available when adding a collection index. See [frontend#194](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/194). -- Added ability to set workflow state when objects are saved. See [frontend#184](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/184). -- Updated occurrences of "aliases" to "associated groups" or "associated software" for consistency across the application. See [frontend#176](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/176). -- Improved logging and added log level to environment configuration to suppress unnecessary logs from production deployments. See [frontend#209](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/209). -- Updated the reference editor to enforce correct formatting when creating a new reference. See [frontend#177](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/177). +- Added a favicon. See [frontend#137](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/137). +- Added dynamic page title to make it easier to distinguish multiple Workbench tabs in the browser. See [frontend#130](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/130). +- Added a list of recommended indexes available when adding a collection index. See [frontend#194](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/194). +- Added ability to set workflow state when objects are saved. See [frontend#184](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/184). +- Updated occurrences of "aliases" to "associated groups" or "associated software" for consistency across the application. See [frontend#176](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/176). +- Improved logging and added log level to environment configuration to suppress unnecessary logs from production deployments. See [frontend#209](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/209). +- Updated the reference editor to enforce correct formatting when creating a new reference. See [frontend#177](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/177). ## 21 April 2021 ### ATT&CK Workbench version 0.3.0 -#### New Features in 0.3.0 +#### New Features -- Added attribution of edits and tracking of organization identity. See [frontend#61](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/124) and [frontend#182](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/61). -- Added ability to revoke and deprecate objects. See [frontend#164](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/164). -- Added tracking of workflow state. See [frontend#3](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/3). -- Added ability to create and edit collections. See [frontend#4](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/4), [frontend#5](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/5), and [frontend#112](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/112). -- Added support and documentation for [ATT&CK Navigator](https://github.com/mitre-attack/attack-navigator) integration. See [frontend#153](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/153). -- Added support and documentation for [ATT&CK Website](https://github.com/mitre-attack/attack-website/) integration. See [frontend#152](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/152). +- Added attribution of edits and tracking of organization identity. See [frontend#61](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/124) and [frontend#182](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/61). +- Added ability to revoke and deprecate objects. See [frontend#164](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/164). +- Added tracking of workflow state. See [frontend#3](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/3). +- Added ability to create and edit collections. See [frontend#4](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/4), [frontend#5](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/5), and [frontend#112](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/112). +- Added support and documentation for [ATT&CK Navigator](https://github.com/mitre-attack/attack-navigator) integration. See [frontend#153](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/153). +- Added support and documentation for [ATT&CK Website](https://github.com/mitre-attack/attack-website/) integration. See [frontend#152](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/152). -#### Improvements in 0.3.0 +#### Improvements -- Improved display of object domains. See [frontend#166](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/166). +- Improved display of object domains. See [frontend#166](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/166). ## 19 March 2021 ### ATT&CK Workbench version 0.2.0 -#### New Features in 0.2.0 +#### New Features -- Added support for MTC and CAPEC IDs. See [frontend#124](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/124). -- Added ability to create and edit objects. See [frontend#44](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/44) and [frontend#145](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/145). - - Added ability to edit group/software aliases. See [frontend#118](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/118). - - Added ability to edit various list properties such as platforms, tactics, and domains. See [frontend#31](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/31). - - Added rich-text description editor. See [frontend#32](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/32). - - Added ability to convert techniques to sub-techniques, and vice versa. - - Added ability to edit ATT&CK IDs. See [frontend#55](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/55). - - Added validation system to warn user of malformed data. - - Added ability to reorder tactics on matrices. See [frontend#116](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/116). - - Added ability to edit object version numbers, and a UI for incrementing versions when objects are saved. See [frontend#56](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/56). -- Added ability to create and edit notes (annotations) on objects. See [frontend#59](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/59). -- Added citations/references support. - - Added automatic detection of citations on descriptions and aliases. See [frontend#115](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/115). - - Added references manager tool. See [frontend#115](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/115) and [frontend#133](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/133). +- Added support for MTC and CAPEC IDs. See [frontend#124](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/124). +- Added ability to create and edit objects. See [frontend#44](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/44) and [frontend#145](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/145). + - Added ability to edit group/software aliases. See [frontend#118](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/118). + - Added ability to edit various list properties such as platforms, tactics, and domains. See [frontend#31](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/31). + - Added rich-text description editor. See [frontend#32](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/32). + - Added ability to convert techniques to sub-techniques, and vice versa. + - Added ability to edit ATT&CK IDs. See [frontend#55](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/55). + - Added validation system to warn user of malformed data. + - Added ability to reorder tactics on matrices. See [frontend#116](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/116). + - Added ability to edit object version numbers, and a UI for incrementing versions when objects are saved. See [frontend#56](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/56). +- Added ability to create and edit notes (annotations) on objects. See [frontend#59](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/59). +- Added citations/references support. + - Added automatic detection of citations on descriptions and aliases. See [frontend#115](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/115). + - Added references manager tool. See [frontend#115](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/115) and [frontend#133](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/133). -#### Improvements in 0.2.0 +#### Improvements -- Lists of objects can now be searched and filtered. See [frontend#128](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/128) and [frontend#127](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/127). -- Lists of objects now display ATT&CK IDs when relevant. See [frontend#119](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/119). -- When viewing an object, fields which have no value(s) will now be hidden. See [frontend#120](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/120). -- Improved display of sub-techniques. See [frontend#125](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/125). -- Layout and formatting improvements to [USAGE](/docs/usage.md) document. +- Lists of objects can now be searched and filtered. See [frontend#128](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/128) and [frontend#127](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/127). +- Lists of objects now display ATT&CK IDs when relevant. See [frontend#119](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/119). +- When viewing an object, fields which have no value(s) will now be hidden. See [frontend#120](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/120). +- Improved display of sub-techniques. See [frontend#125](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/125). +- Layout and formatting improvements to [USAGE](/docs/usage.md) document. -#### Fixes in 0.2.0 +#### Fixes -- Fixed broken pagination on relationship tables. See [frontend#126](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/126). +- Fixed broken pagination on relationship tables. See [frontend#126](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/126). ## 16 February 2021 ### ATT&CK Workbench version 0.1.1 -#### New Features in 0.1.1 +#### New Features -- Added Dockerfiles, docker-compose, [and documentation on how to use them](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/tree/master/docs/docker-compose.md). See [frontend#108](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/108), [frontend#109](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/109) [rest-api#14](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/14), and [collection-manager#13](https://github.com/center-for-threat-informed-defense/attack-workbench-collection-manager/issues/13). +- Added Dockerfiles, docker-compose, [and documentation on how to use them](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/tree/master/docs/docker-compose.md). See [frontend#108](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/108), [frontend#109](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/109) [rest-api#14](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/14), and [collection-manager#13](https://github.com/center-for-threat-informed-defense/attack-workbench-collection-manager/issues/13). -#### Fixes in 0.1.1 +#### Fixes -- Fixed a crash that could occur with specific queries on the REST API. See [rest-api#28](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/28). +- Fixed a crash that could occur with specific queries on the REST API. See [rest-api#28](https://github.com/center-for-threat-informed-defense/attack-workbench-rest-api/issues/28). ## 19 January 2021 ### ATT&CK Workbench version 0.1.0 -#### New Features in 0.1.0 +#### New Features -- Created object view pages for matrix, technique, tactic, mitigation, group, and software objects. -- Added the ability to browse and import collection indexes. - - Collection indexes can be imported via URL. - - A preview of the collection index is shown before confirming the import. -- Added the ability to import, view, and subscribe to collections. - - Collections listed within an index can be subscribed to, which will pull new versions when they are published. - - Collections can also be manually imported via URL. When importing, a preview of the collection and its contents is shown before confirming the import. At this step, users can preview the objects in the collection and select which ones they want to import. Changes in the import are displayed relative to the state of the knowledge base similar to the update pages on the [ATT&CK Website](https://attack.mitre.org/resources/updates/). - - An interface provides the ability to review prior imports, which provides a list of changes at the time of the import identical to that shown during the import of the collection. +- Created object view pages for matrix, technique, tactic, mitigation, group, and software objects. +- Added the ability to browse and import collection indexes. + - Collection indexes can be imported via URL. + - A preview of the collection index is shown before confirming the import. +- Added the ability to import, view, and subscribe to collections. + - Collections listed within an index can be subscribed to, which will pull new versions when they are published. + - Collections can also be manually imported via URL. When importing, a preview of the collection and its contents is shown before confirming the import. At this step, users can preview the objects in the collection and select which ones they want to import. Changes in the import are displayed relative to the state of the knowledge base similar to the update pages on the [ATT&CK Website](https://attack.mitre.org/resources/updates/). + - An interface provides the ability to review prior imports, which provides a list of changes at the time of the import identical to that shown during the import of the collection. From fd3f825570f71a161b1e9266082a7014de173256 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:15:48 -0400 Subject: [PATCH 16/22] 222 collection index md (#512) * markdown support for collection index descriptions * update changelog --- .../collection-index-view.component.html | 13 +++++++------ docs/changelog.md | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/app/views/stix/collection/collection-index/collection-index-view/collection-index-view.component.html b/app/src/app/views/stix/collection/collection-index/collection-index-view/collection-index-view.component.html index 20453f6e..aa75867d 100644 --- a/app/src/app/views/stix/collection/collection-index/collection-index-view/collection-index-view.component.html +++ b/app/src/app/views/stix/collection/collection-index/collection-index-view/collection-index-view.component.html @@ -24,12 +24,13 @@

{{config.index.collection_index.name}}

-
-
- {{config.index.collection_index.description}} -
- -
+
diff --git a/docs/changelog.md b/docs/changelog.md index 85e57a35..f5cfaae1 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -44,6 +44,7 @@ #### Improvements - Navigation menu collapses under a separate hamburger menu rather than the identity icon. See [frontend#494](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/494). +- Markdown support for collection index descriptions. See [frontend#222](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/222). #### Fixes From abbe81d404915520a3394b204dae2bd0cd649434 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 14:29:09 -0400 Subject: [PATCH 17/22] hide stix list controls in reference dialog --- .../reference-edit-dialog.component.html | 4 ++-- .../app/components/stix/stix-list/stix-list.component.html | 2 +- .../app/components/stix/stix-list/stix-list.component.ts | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.html b/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.html index cf98dc1b..4cd17fd4 100644 --- a/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.html +++ b/app/src/app/components/reference-edit-dialog/reference-edit-dialog.component.html @@ -206,7 +206,7 @@

Objects citing this reference

@@ -215,7 +215,7 @@

Relationships citing this reference

stixObjects: relationships, type: 'relationship', clickBehavior: 'dialog', - showFilters: false + showControls: false }">
diff --git a/app/src/app/components/stix/stix-list/stix-list.component.html b/app/src/app/components/stix/stix-list/stix-list.component.html index f3929589..3dc24a46 100644 --- a/app/src/app/components/stix/stix-list/stix-list.component.html +++ b/app/src/app/components/stix/stix-list/stix-list.component.html @@ -3,7 +3,7 @@ -
+
diff --git a/app/src/app/components/stix/stix-list/stix-list.component.ts b/app/src/app/components/stix/stix-list/stix-list.component.ts index d4e2c341..56f52fe4 100644 --- a/app/src/app/components/stix/stix-list/stix-list.component.ts +++ b/app/src/app/components/stix/stix-list/stix-list.component.ts @@ -66,6 +66,7 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { // options provided to the user for grouping and filtering public filterOptions: FilterGroup[] = []; + public showControls: boolean = true; // current grouping and filtering selections public filter: string[] = []; @@ -151,7 +152,7 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { if (values.properties) { // extract domain->platforms properties from allowedValues structure let properties = values.properties.find(p => p.propertyName == 'x_mitre_platforms'); - if (properties && properties.domains) { + if (properties?.domains) { properties.domains.forEach(domain => { domainMap.set(domain.domainName, domain.allowedValues); }); @@ -163,6 +164,7 @@ export class StixListComponent implements OnInit, AfterViewInit, OnDestroy { }, complete: () => { // build the stix list table + this.showControls = this.config.showControls ?? true; this.buildTable(); this.setUpControls(); // get objects from backend if data is not from config @@ -941,6 +943,8 @@ export interface StixListConfig { showLinks?: boolean; /** default true, if false hides the filter dropdown menu */ showFilters?: boolean; + /** default true, if false hides all search/filter/control options */ + showControls?: boolean; /** display the 'show deprecated' filter, default false * this may be relevant when displaying a list of embedded relationships, where * the list of STIX objects is provided in the 'stixObjects' configuration From 5d7babbb9e0f9ca20cb111a925b699b778a8c1c7 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 14:38:09 -0400 Subject: [PATCH 18/22] minor change --- app/src/app/components/stix/stix-list/stix-list.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/app/components/stix/stix-list/stix-list.component.html b/app/src/app/components/stix/stix-list/stix-list.component.html index 3dc24a46..88bac6ee 100644 --- a/app/src/app/components/stix/stix-list/stix-list.component.html +++ b/app/src/app/components/stix/stix-list/stix-list.component.html @@ -4,7 +4,7 @@
-
+
From 966b5e798c4bf4c3c1f027a8daa052ff6458bc61 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:00:06 -0400 Subject: [PATCH 19/22] Fix/213 (#513) * note edit mode only when header is clicked * update changelog * update note subtitle --- .../notes-editor/notes-editor.component.html | 10 +++++----- .../notes-editor/notes-editor.component.scss | 6 ++++-- .../timestamp-property/timestamp-property.component.ts | 2 +- .../timestamp-view/timestamp-view.component.html | 6 +++--- .../timestamp-view/timestamp-view.component.ts | 2 +- docs/changelog.md | 1 + 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/src/app/components/resources-drawer/notes-editor/notes-editor.component.html b/app/src/app/components/resources-drawer/notes-editor/notes-editor.component.html index bf0f8b69..82a70211 100644 --- a/app/src/app/components/resources-drawer/notes-editor/notes-editor.component.html +++ b/app/src/app/components/resources-drawer/notes-editor/notes-editor.component.html @@ -26,8 +26,8 @@
- - + + @@ -38,9 +38,9 @@ [(ngModel)]="note.title"> - - - + + + diff --git a/app/src/app/components/resources-drawer/notes-editor/notes-editor.component.scss b/app/src/app/components/resources-drawer/notes-editor/notes-editor.component.scss index ae04256b..db975fb6 100644 --- a/app/src/app/components/resources-drawer/notes-editor/notes-editor.component.scss +++ b/app/src/app/components/resources-drawer/notes-editor/notes-editor.component.scss @@ -38,7 +38,6 @@ .sticky-note { padding: 0px; margin-top: 12px; - cursor: pointer; button.mat-button-disabled { opacity: 0.5; } &.edit-outline { @@ -67,12 +66,15 @@ .mat-form-field-underline { display: none; } mat-card-header { + cursor: pointer; textarea { margin-top: 12px; overflow: hidden; + &:read-only { cursor: pointer; } } .mat-card-header-text { width: 100%; } - .history { + .note-subtitle { + margin-bottom: 12px; font-size: 13px; @extend .text-label; } diff --git a/app/src/app/components/stix/timestamp-property/timestamp-property.component.ts b/app/src/app/components/stix/timestamp-property/timestamp-property.component.ts index d16b737a..3342df74 100644 --- a/app/src/app/components/stix/timestamp-property/timestamp-property.component.ts +++ b/app/src/app/components/stix/timestamp-property/timestamp-property.component.ts @@ -57,5 +57,5 @@ export interface TimestampPropertyConfig { /* if true, the username of the user who created the object will be displayed before the timestamp. Default: false */ - displayCreatorUsernameWithTimestamp?: boolean; + showDisplayName?: boolean; } \ No newline at end of file diff --git a/app/src/app/components/stix/timestamp-property/timestamp-view/timestamp-view.component.html b/app/src/app/components/stix/timestamp-property/timestamp-view/timestamp-view.component.html index 931972d0..f967064b 100644 --- a/app/src/app/components/stix/timestamp-property/timestamp-view/timestamp-view.component.html +++ b/app/src/app/components/stix/timestamp-property/timestamp-view/timestamp-view.component.html @@ -1,6 +1,6 @@
- - {{displayName}}, - +
+ {{displayName}} +
{{config.humanize? humanized : timestamp}}
\ No newline at end of file diff --git a/app/src/app/components/stix/timestamp-property/timestamp-view/timestamp-view.component.ts b/app/src/app/components/stix/timestamp-property/timestamp-view/timestamp-view.component.ts index c4dc7d5d..dd00697b 100644 --- a/app/src/app/components/stix/timestamp-property/timestamp-view/timestamp-view.component.ts +++ b/app/src/app/components/stix/timestamp-property/timestamp-view/timestamp-view.component.ts @@ -22,7 +22,7 @@ export class TimestampViewComponent implements OnInit { } ngOnInit(): void { - if (this.config.displayCreatorUsernameWithTimestamp) { + if (this.config.showDisplayName) { const object = Array.isArray(this.config.object) ? this.config.object[0] : this.config.object; const createdByAccountId = object.workflow.created_by_user_account; if (!createdByAccountId) { diff --git a/docs/changelog.md b/docs/changelog.md index f5cfaae1..b3c98f01 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -51,6 +51,7 @@ - Fixed an issue where revoking or deprecating an object would deprecate all `revoked-by` relationships with the object. See [frontend#467](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/467). - Fixed an issue where first/last seen Campaign dates were parsed in local time, causing the dates to be displayed incorrectly in certain timezones. See [frontend#508](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/pull/508). - Fixed a bug where the "create a collection from group" button was being displayed on the group list page. +- Notes will only start editing when the header is clicked, enabling the contents of the note to easily be clicked or copied. See [frontend#213](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/issues/213). ## 21 September 2023 From dc1b70dd5cf9bf9d9bbc5dada7455fc6ae9c1112 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:56:46 -0400 Subject: [PATCH 20/22] fix collection import for assets --- .../collection-import.component.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/app/views/stix/collection/collection-import/collection-import-workflow/collection-import.component.ts b/app/src/app/views/stix/collection/collection-import/collection-import-workflow/collection-import.component.ts index 49d47b15..ba582e7e 100644 --- a/app/src/app/views/stix/collection/collection-import/collection-import-workflow/collection-import.component.ts +++ b/app/src/app/views/stix/collection/collection-import/collection-import-workflow/collection-import.component.ts @@ -97,7 +97,10 @@ export class CollectionImportComponent implements OnInit { "course-of-action": "mitigations", "x-mitre-tactic": "tactics", "x-mitre-data-source": "datasources", - "x-mitre-data-component": "datacomponents" + "x-mitre-data-component": "datacomponents", + "x-mitre-asset": "assets", + "x-mitre-matrix": "matrices", + } constructor(public route: ActivatedRoute, @@ -588,7 +591,7 @@ export class CollectionImportComponent implements OnInit { new Campaign(raw) ); break; - case 'asset': // asset + case 'x-mitre-asset': // asset this.object_import_categories.asset[category].push( new Asset(raw) ); From bb01132b565a5b053c17df585df0c08077b63203 Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Tue, 31 Oct 2023 11:39:30 -0400 Subject: [PATCH 21/22] update collection import review --- app/src/app/classes/stix/collection.ts | 2 +- .../collection-import-review.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/app/classes/stix/collection.ts b/app/src/app/classes/stix/collection.ts index 3b56711a..d1a16e96 100644 --- a/app/src/app/classes/stix/collection.ts +++ b/app/src/app/classes/stix/collection.ts @@ -285,7 +285,7 @@ export class Collection extends StixObject { case "marking-definition": // marking definition this.stix_contents.push(new MarkingDefinition(obj)) break; - case "asset": // asset + case "x-mitre-asset": // asset this.stix_contents.push(new Asset(obj)) break; } diff --git a/app/src/app/views/stix/collection/collection-import/collection-import-review/collection-import-review.component.ts b/app/src/app/views/stix/collection/collection-import/collection-import-review/collection-import-review.component.ts index e74dcfc3..9dbbbf0c 100644 --- a/app/src/app/views/stix/collection/collection-import/collection-import-review/collection-import-review.component.ts +++ b/app/src/app/views/stix/collection/collection-import/collection-import-review/collection-import-review.component.ts @@ -111,7 +111,7 @@ export class CollectionImportReviewComponent extends StixViewPage implements OnI case "campaign": // campaign this.collection_import_categories.campaign[category].push(object); break; - case "asset": // asset + case "x-mitre-asset": // asset this.collection_import_categories.asset[category].push(object); break; } From 0fc32e6c97037aeb76a985a4fd7027a57b9bbbae Mon Sep 17 00:00:00 2001 From: Charissa Miller <48832936+clemiller@users.noreply.github.com> Date: Tue, 31 Oct 2023 11:43:14 -0400 Subject: [PATCH 22/22] update changelog --- docs/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index b3c98f01..97eaafca 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -32,7 +32,7 @@ # Changelog -## Changes Staged on Develop +## 31 October 2023 ### ATT&CK Workbench version 2.1.0