Skip to content

Commit

Permalink
v0.4.12
Browse files Browse the repository at this point in the history
  • Loading branch information
SecSimon committed May 20, 2023
1 parent 2291518 commit 34540ad
Show file tree
Hide file tree
Showing 81 changed files with 879 additions and 443 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 0.4.12

* Project information: separate tabs for general, tasks and notes, changes, and progress tracker
* Out of scope: visualized as dotted line
* Diagram: allow flexible resizing
* Object Tree: filter for element/component
* UI improvements: name field width, reorder components, table row height, visualization of optional steps, software component with optional port
* Fix: undefined generation settings in new diagram

## 0.4.11

* Added file info dialog with (incomplete) list of changes
Expand Down
4 changes: 2 additions & 2 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ttmodeler",
"version": "0.4.11",
"version": "0.4.12",
"description": "Thing Threat Modeler for Internet of Things Devices",
"homepage": "https://www.simon-liebl.de/TTM",
"author": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ttmodeler",
"version": "0.4.11",
"version": "0.4.12",
"description": "Thing Threat Modeler for Internet of Things Devices",
"homepage": "https://www.simon-liebl.de/TTM",
"author": {
Expand Down
15 changes: 14 additions & 1 deletion src/app/configuration/configuration.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { LocalStorageService, LocStorageKeys } from '../util/local-storage.servi
import { ThemeService } from '../util/theme.service';

import { WarningDialogComponent } from './warning-dialog/warning-dialog.component';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { NavTreeBase } from '../shared/components/nav-tree/nav-tree-base';

@Component({
selector: 'app-configuration',
Expand All @@ -22,7 +24,8 @@ export class ConfigurationComponent extends SideNavBase implements OnInit {
this._selectedNode = val;
}

constructor(public theme: ThemeService, public dataService: DataService, private locStorageService: LocalStorageService, private dialog: MatDialog) {
constructor(public theme: ThemeService, public dataService: DataService, private locStorageService: LocalStorageService, private dialog: MatDialog,
private router: Router, private route: ActivatedRoute) {
super();
}

Expand All @@ -48,6 +51,16 @@ export class ConfigurationComponent extends SideNavBase implements OnInit {
});
}
}

this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
this.route.queryParams.subscribe(params => {
if (params['index'] != null) {
this.SetSelectedTabIndex(params['index']);
}
});
}
});
}

public GetSelectedTabIndex() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import 'stylesTheme.scss';
@import 'stylesTable.scss';

.selected-entry {
td {
Expand Down
18 changes: 9 additions & 9 deletions src/app/home/home.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,24 @@ <h2>
<span>{{'pages.home.menu.saveProject' | translate}}</span>
</button>
<button mat-menu-item [disabled]="!dataService.Project" (click)="dataService.ExportFile(true)" matTooltip="{{'pages.home.menu.downloadProject.tt' | translate}}" matTooltipShowDelay="1000">
<mat-icon matBadge="P" matBadgeOverlap="true" matBadgeColor="primary" matBadgeSize="small" matBadgePosition="below">file_download</mat-icon>
<mat-icon>file_download</mat-icon>
<span>{{'pages.home.menu.downloadProject' | translate}}</span>
</button>
<button mat-menu-item [disabled]="!dataService.Project" class="exportBtn" (click)="dataService.ExportFile(false)" matTooltip="{{'pages.home.menu.downloadConfig.tt' | translate}}" matTooltipShowDelay="1000">
<mat-icon matBadge="C" matBadgeOverlap="true" matBadgeColor="primary" matBadgeSize="small" matBadgePosition="below">file_download</mat-icon>
<mat-icon>file_download</mat-icon>
<span>{{'pages.home.menu.downloadConfig' | translate}}</span>
</button>
<button mat-menu-item [disabled]="!dataService.SelectedGHProject" (click)="dataService.OnExportConfig()" matTooltip="{{'pages.home.menu.exportConfig.tt' | translate}}" matTooltipShowDelay="1000">
<mat-icon>output</mat-icon>
<span>{{'pages.home.menu.exportConfig' | translate}}</span>
</button>
<button mat-menu-item [disabled]="!dataService.Project" class="exportBtn" [matMenuTriggerFor]="exchangeMenu" matTooltip="{{'pages.home.menu.exchangeConfig.tt' | translate}}" matTooltipShowDelay="1000">
<mat-icon matBadge="C" matBadgeOverlap="true" matBadgeColor="primary" matBadgeSize="small" matBadgePosition="below">wifi_protected_setup</mat-icon>
<mat-icon>wifi_protected_setup</mat-icon>
<span>{{'pages.home.menu.exchangeConfig' | translate}}</span>
</button>
<mat-menu #exchangeMenu="matMenu">
<button mat-menu-item [disabled]="true">
<mat-icon matBadge="C" matBadgeOverlap="true" matBadgeColor="primary" matBadgeSize="small" matBadgePosition="below">file_upload</mat-icon>
<mat-icon>file_upload</mat-icon>
{{'pages.home.menu.importConfig' | translate}}
</button>
<button mat-menu-item (click)="dataService.ExchangeConfigWithDefault()">Default Configuration</button>
Expand All @@ -58,7 +58,7 @@ <h2>
<mat-divider></mat-divider>
<input hidden type="file" accept=".ttmp" #projectUploader (change)="dataService.ImportFile(true, $event)"/>
<button mat-menu-item (click)="projectUploader.click()" matTooltip="{{'pages.home.menu.importProject.tt' | translate}}" matTooltipShowDelay="1000">
<mat-icon matBadge="P" matBadgeOverlap="true" matBadgeColor="primary" matBadgeSize="small" matBadgePosition="below">file_upload</mat-icon>
<mat-icon>file_upload</mat-icon>
<span>{{'pages.home.menu.importProject' | translate}}</span>
</button>
</mat-menu>
Expand All @@ -78,7 +78,7 @@ <h2>
<div id="project">
<mat-icon class="iconBtn" style="vertical-align: top; font-size: 20px; margin-right: 5px;" matTooltip="{{'pages.home.storedOnline' | translate}}" matTooltipShowDelay="1000">cloud_queue</mat-icon>
<button class="color-primary astext" (click)="dataService.LoadProject(proj)">{{proj.name}}</button>
in {{GetRepoName(proj)}}
<span style="font-size: small; margin-left: 5px;">in {{GetRepoName(proj)}}</span>
<mat-icon *ngIf="IsProtected(proj)" class="iconBtn" style="vertical-align: top; margin-right: 5px;" matTooltip="{{'pages.home.notWritable' | translate}}" matTooltipShowDelay="1000">edit_off</mat-icon>
<button mat-icon-button class="show-on-hover iconBtn" style="margin-right: 5px;" [matMenuTriggerFor]="moreGHProject" matTooltip="{{'general.More' | translate}}" matTooltipShowDelay="1000">
<mat-icon>more_vert</mat-icon>
Expand All @@ -101,7 +101,7 @@ <h2>
<div id="project">
<mat-icon class="iconBtn" style="vertical-align: top; font-size: 20px; margin-right: 5px;" matTooltip="{{'pages.home.storedOffline' | translate}}" matTooltipShowDelay="1000">file_present</mat-icon>
<button class="color-primary astext" (click)="dataService.LoadProjectFS(proj)">{{GetFileName(proj)}}</button>
in {{GetFilePath(proj)}}
<span style="font-size: small; margin-left: 5px;">in {{GetFilePath(proj)}}</span>
<button mat-icon-button class="show-on-hover iconBtn" style="margin-right: 5px;" [matMenuTriggerFor]="moreFSProject" matTooltip="{{'general.More' | translate}}" matTooltipShowDelay="1000">
<mat-icon>more_vert</mat-icon>
</button>
Expand All @@ -127,7 +127,7 @@ <h2>
<mat-menu #confMenu="matMenu">
<input hidden type="file" accept=".ttmc" #configUploader (change)="dataService.ImportFile(false, $event)"/>
<button mat-menu-item (click)="configUploader.click()">
<mat-icon matBadge="C" matBadgeOverlap="true" matBadgeColor="primary" matBadgeSize="small" matBadgePosition="below">file_upload</mat-icon>
<mat-icon>file_upload</mat-icon>
<span>{{'pages.home.menu.importConfig' | translate}}</span>
</button>
</mat-menu>
Expand All @@ -137,7 +137,7 @@ <h2>
<div id="config">
<mat-icon class="iconBtn" style="vertical-align: top; font-size: 20px; margin-right: 5px;" matTooltip="{{'pages.home.storedOnline' | translate}}" matTooltipShowDelay="1000">cloud_queue</mat-icon>
<button class="color-primary astext" (click)="dataService.LoadConfig(conf)">{{conf.name}}</button>
in {{GetRepoName(conf)}}
<span style="font-size: small; margin-left: 5px;">in {{GetRepoName(conf)}}</span>
<mat-icon *ngIf="IsProtected(conf)" class="iconBtn" style="vertical-align: top; margin-right: 5px;" matTooltip="{{'pages.home.notWritable' | translate}}" matTooltipShowDelay="1000">edit_off</mat-icon>
<button mat-icon-button class="show-on-hover iconBtn" style="margin-right: 5px;" [matMenuTriggerFor]="moreGHConfig" matTooltip="{{'general.More' | translate}}" matTooltipShowDelay="1000">
<mat-icon>more_vert</mat-icon>
Expand Down
23 changes: 22 additions & 1 deletion src/app/model/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ export class MyComponent extends ViewElementBase {
this.Data['typeID'] = type.ID;
this.setTypeProperties(type);
this.TypeID = type.ComponentTypeID;
if (this.TypeID == MyComponentTypeIDs.Software) {
// not a good solution but can't find a better one
this.AddProperty('properties.Version', 'Version', '', true, PropertyEditTypes.TextBox, true);
this.AddProperty('properties.Port', 'Port', '', true, PropertyEditTypes.PortBox, true);
}
}
public get TypeID(): MyComponentTypeIDs { return this.Data['TypeID']; }
public set TypeID(val: MyComponentTypeIDs) { this.Data['TypeID'] = val; }
Expand All @@ -132,11 +137,23 @@ export class MyComponent extends ViewElementBase {

public get Version(): string { return this.Data['Version']; }
public set Version(val: string) { this.Data['Version'] = val; }
public get Port(): string { return this.Data['Port']; }
public set Port(val: string) { this.Data['Port'] = val; }
public get Notes(): INote[] { return this.Data['Notes']; }
public set Notes(val: INote[]) { this.Data['Notes'] = val; }
public get NotesPerQuestion(): {} { return this.Data['notesPerQuestion']; }
public set NotesPerQuestion(val: {}) { this.Data['notesPerQuestion'] = val; }

public get SyncNameToTypeName(): boolean { return this.Data['SyncNameToTypeName']; }
public set SyncNameToTypeName(val: boolean) { this.Data['SyncNameToTypeName'] = val; }

public get Name(): string { return this.Data['Name'].replace(/\n/g, ' '); }
public set Name(val: string) {
this.Data['Name'] = val;
if (this.SyncNameToTypeName) this.Type.Name = val;
this.NameChanged.emit(val);
}

constructor(data: {}, type: MyComponentType, pf: ProjectFile, cf: ConfigFile) {
super(data);
this.project = pf;
Expand All @@ -153,6 +170,7 @@ export class MyComponent extends ViewElementBase {
if (!this.Data['Notes']) this.Data['Notes'] = [];
if (!this.Data['notesPerQuestion']) this.Data['notesPerQuestion'] = {};
if (!this.Version) this.Version = '';
if (!this.Port) this.Port = '';

cf.GetThreatQuestions().filter(x => x.ComponentType.ID == type.ID).forEach(x => this.AddThreatQuestion(x));
}
Expand Down Expand Up @@ -194,7 +212,10 @@ export class MyComponent extends ViewElementBase {

this.AddProperty('properties.IsActive', 'IsActive', '', true, PropertyEditTypes.CheckBox, true);
this.AddProperty('properties.IsThirdParty', 'IsThirdParty', '', true, PropertyEditTypes.CheckBox, true);
if (this.TypeID == MyComponentTypeIDs.Software) this.AddProperty('properties.Version', 'Version', '', true, PropertyEditTypes.TextBox, true);
if (this.TypeID == MyComponentTypeIDs.Software) {
this.AddProperty('properties.Version', 'Version', '', true, PropertyEditTypes.TextBox, true);
this.AddProperty('properties.Port', 'Port', '', true, PropertyEditTypes.PortBox, true);
}
this.AddProperty('properties.Questionnaire', '', '', false, PropertyEditTypes.OpenQuestionnaire, true);
this.AddProperty('general.Notes', '', '', false, PropertyEditTypes.OpenNotes, true);
}
Expand Down
10 changes: 8 additions & 2 deletions src/app/model/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export enum PropertyEditTypes {
LowMediumHighSelect = 'Low Medium High Select',
MyDataSelect = 'Data Select',
PhysicalElementSelect = 'Physical Element Select',
PortBox = 'Port Box',
ProtocolSelect = 'Protocol Select',
OpenNotes = 'Open Notes',
OpenQuestionnaire = 'Open Questionnaire',
Expand Down Expand Up @@ -209,7 +210,7 @@ export abstract class DatabaseBase implements IDatabaseBase {
public set Description(val: string) { this.Data['Description'] = val; }

public NameChanged = new EventEmitter<string>();
public DataChanged = new EventEmitter<IDataChanged>(); // property name as parameter
public DataChanged = new EventEmitter<IDataChanged>();

constructor(data: {}) {
this.Data = data;
Expand Down Expand Up @@ -282,7 +283,12 @@ export abstract class ViewElementBase extends DatabaseBase {
public set UserCheckedElement(val: boolean) { this.Data['UserCheckedElement'] = val; }

public get OutOfScope(): boolean { return this.Data['OutOfScope']; }
public set OutOfScope(val: boolean) { this.Data['OutOfScope'] = val; }
public set OutOfScope(val: boolean) {
this.Data['OutOfScope'] = val;
this.OutOfScopeChanged.emit(val);
}

public OutOfScopeChanged = new EventEmitter<boolean>();

constructor(data: {}) {
super(data);
Expand Down
5 changes: 4 additions & 1 deletion src/app/model/dfd-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,11 +505,13 @@ export class DFDElementRef extends DFDElement {
public GetProperty(id: string) {
if (id == 'Ref') return this.Ref;
else if (id == 'diagramID') return this.diagramID;
else if (id == 'OutOfScope') return this.OutOfScope;
return this.Ref.GetProperty(id);
}

public SetProperty(id: string, value: any) {
this.Ref.SetProperty(id, value);
if (id == 'OutOfScope') this.OutOfScope = value;
else this.Ref.SetProperty(id, value);
}

protected initProperties() {
Expand All @@ -523,6 +525,7 @@ export class DFDElementRef extends DFDElement {
this.Ref.NameChanged.subscribe(x => this.NameChanged.emit(x));
this.Ref.DataChanged.subscribe(x => this.DataChanged.emit(x));
this.Ref.TypeChanged.subscribe(x => this.TypeChanged.emit(x));
this.Ref.OutOfScopeChanged.subscribe(x => this.OutOfScopeChanged.emit(x));
}

public static InstantiateRef(ref: DFDElement, pf: ProjectFile, cf: ConfigFile): DFDElement {
Expand Down
2 changes: 2 additions & 0 deletions src/app/model/diagram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export abstract class Diagram extends DatabaseBase {
if (!this.Settings) {
this.Settings = { GenerationThreatLibrary: true, GenerationAssetBased: false, GenerationMnemonics: {}, GenerationRules: {} };
}
if (!this.Settings.GenerationMnemonics) this.Settings.GenerationMnemonics = {};
if (!this.Settings.GenerationRules) this.Settings.GenerationRules = {};
}

public static FromJSON(data, pf: ProjectFile, cf: ConfigFile): Diagram {
Expand Down
1 change: 1 addition & 0 deletions src/app/model/system-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ export class SystemContextContainerRef extends SystemContextContainer {
if (!this.Ref) return;
this.Ref.NameChanged.subscribe(x => this.NameChanged.emit(x));
this.Ref.DataChanged.subscribe(x => this.DataChanged.emit(x));
this.Ref.OutOfScopeChanged.subscribe(x => this.OutOfScopeChanged.emit(x));
}

public static InstantiateRef(ref: SystemContextContainer, pf: ProjectFile, cf: ConfigFile): ContextElement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
<as-split-area [size]="GetSplitSize(0, 1, $any('*'))" [order]=2 [class.bg-color-light3]="!theme.IsDarkMode" [class.bg-color-dark3]="theme.IsDarkMode">
<as-split direction="vertical" unit="pixel" [gutterSize]="3" [restrictMove]="true" (dragEnd)="OnSplitSizeChange($event, 2)">
<div style="font-weight: bold; text-align: center;">{{'general.SystemThreats' | translate}}</div>
<div mat-subheader style="padding-bottom: 0px;">{{ 'general.Threats' | translate }} <button mat-icon-button (click)="AddThreat()" matTooltip="{{'general.Add' | translate}}" matTooltipShowDelay="1000" style="margin-left: 15px;"><mat-icon>add</mat-icon></button></div>
<div mat-subheader style="padding-bottom: 0px;">{{ 'general.Threats' | translate }}
<button mat-icon-button (click)="AddThreat()" matTooltip="{{'general.Add' | translate}}" matTooltipShowDelay="1000" style="margin-left: 15px;"><mat-icon>add</mat-icon></button>
<button mat-icon-button [matMenuTriggerFor]="moreMenu" matTooltip="{{'general.More' | translate}}" matTooltipShowDelay="1000" style="float: right;"><mat-icon>more_vert</mat-icon></button>
<mat-menu #moreMenu="matMenu">
<button mat-menu-item [disabled]="systemThreats.length < 2" (click)="ResetNumbers()">{{'pages.modeling.threattable.resetNumbers' | translate}}</button>
</mat-menu>
</div>
<as-split-area style="margin-bottom: 10px;" [size]="GetSplitSize(2, 0, 200)" [order]=1 [class.splitter-light2]="!theme.IsDarkMode" [class.splitter-dark2]="theme.IsDarkMode">
<div style="padding: 10px;">
<mat-list cdkDropList (cdkDropListDropped)="drop($event, systemThreats)" class="prop-list reorder-list">
Expand All @@ -24,7 +30,7 @@
[class.highlight-light]="selectedThreat === dt && !theme.IsDarkMode" [class.highlight-dark]="selectedThreat === dt && theme.IsDarkMode"
matTooltip="{{dt.Name}}" matTooltipShowDelay="1000">
<mat-icon mat-list-icon>chevron_right</mat-icon>
<div mat-line>{{dt.Name}}</div>
<div mat-line>{{dt.GetLongName()}}</div>
<div mat-line>{{'properties.Impact' | translate}}: {{GetLMHName(dt.Impact) | translate}}</div>
<button mat-icon-button style="margin-left: auto;" (click)="DeleteThreat(dt)" matTooltip="{{'general.Delete' | translate}}" matTooltipShowDelay="1000"><mat-icon>delete</mat-icon></button>
</mat-list-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ export class ThreatIdentificationComponent implements OnInit {
this.selectedThreat = dt;
}

public ResetNumbers() {
const arr = this.systemThreats;
for (let i = 0; i < arr.length; i++) {
arr[i].Number = (i+1).toString();
}
}

public GetLMHValues() {
return LowMediumHighNumberUtil.GetKeys();
}
Expand Down
Loading

0 comments on commit 34540ad

Please sign in to comment.