-
+
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 @@
-
\ 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 @@
+
+
+
+
+
+ login
+
+
+ register
+
+
+
+
+
+
+
+
+
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 @@
editedit_off
- 0 || isNew" (click)="delete()">delete
+ 0 || isNew" (click)="delete()">delete
@@ -193,6 +193,32 @@
{{reference.source_name}}
+
+
+
Objects citing this reference
+
+ No objects in the knowledge base cite this reference.
+
+
+
+ 0">
+
Objects citing this reference
+
+
+ 0">
+
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 @@
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 @@