Skip to content

Commit c6452cb

Browse files
committed
SP-706 Adds local cryptography to SDK HTML report
1 parent 0ebdbec commit c6452cb

File tree

7 files changed

+192
-38
lines changed

7 files changed

+192
-38
lines changed

Diff for: CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
### [0.13.1](https://github.com/scanoss/scanoss.js/compare/v0.13.0...v0.13.1) (2024-05-15)
6+
57
### [0.13.0](https://github.com/scanoss/scanoss.js/compare/v0.12.2...v0.13.0) (2024-05-13)
68

79
### [0.12.2](https://github.com/scanoss/scanoss.js/compare/v0.12.0...v0.12.2) (2024-05-10)

Diff for: assets/ReportHTMLTemplate/index.html

+82-37
Original file line numberDiff line numberDiff line change
@@ -658,29 +658,61 @@ <h4>License obligations</h4>
658658
</template>
659659
</section>
660660

661-
<!-- cryptography -->
662-
<section aria-labelledby="nav-cryptography-tab" class="tab-pane fade" id="nav-cryptography" role="tabpanel"
663-
tabindex="0">
664-
<table class="table main-table" id="table-cryptography">
665-
<thead>
666-
<tr>
667-
<th>Component</th>
668-
<th>Version</th>
669-
<th>Cryptography</th>
670-
</tr>
671-
</thead>
672-
<tbody>
673-
</tbody>
674-
</table>
675-
676-
<template id="tpl-cryptography-row">
677-
<tr>
678-
<td></td>
679-
<td></td>
680-
<td></td>
681-
</tr>
682-
</template>
683-
</section>
661+
<!-- cryptography -->
662+
<section aria-labelledby="nav-cryptography-tab" class="tab-pane fade" id="nav-cryptography" role="tabpanel"
663+
tabindex="0">
664+
<nav>
665+
<div class="nav nav-tabs" id="nav-tab-crypto" role="tablist">
666+
<button aria-controls="pane-local-cryptography" class="nav-link visible active" aria-selected="false" data-bs-target="#pane-local-cryptography"
667+
data-bs-toggle="tab" id="crypto-file-tab" role="tab" type="button">Files</button>
668+
<button aria-controls="pane-component-cryptography" class="nav-link visible" aria-selected="true" data-bs-target="#pane-component-cryptography"
669+
data-bs-toggle="tab" id="crypto-component-tab" role="tab" type="button">Components</button>
670+
</div>
671+
</nav>
672+
673+
<div class="tab-content" id="myTabContent">
674+
<div class="tab-pane" id="pane-component-cryptography" aria-labelledby="crypto-component-tab" role="tabpanel" tabindex="0">
675+
<table class="table main-table" id="table-cryptography" >
676+
<thead>
677+
<tr>
678+
<th>Component</th>
679+
<th>Version</th>
680+
<th>Cryptography</th>
681+
</tr>
682+
</thead>
683+
<tbody>
684+
</tbody>
685+
</table>
686+
687+
<template id="tpl-cryptography-row">
688+
<tr>
689+
<td></td>
690+
<td></td>
691+
<td></td>
692+
</tr>
693+
</template>
694+
</div>
695+
<div class="tab-pane active" id="pane-local-cryptography" role="tabpanel" aria-labelledby="crypto-file-tab" tabindex="0">
696+
<table class="table main-table" id="table-local-cryptography">
697+
<thead>
698+
<tr>
699+
<th>File</th>
700+
<th>Cryptography</th>
701+
</tr>
702+
</thead>
703+
<tbody>
704+
</tbody>
705+
</table>
706+
707+
<template id="tpl-local-cryptography-row">
708+
<tr>
709+
<td></td>
710+
<td></td>
711+
</tr>
712+
</template>
713+
</div>
714+
</div>
715+
</section>
684716

685717
<!-- quality -->
686718
<section aria-labelledby="nav-quality-tab" class="tab-pane fade" id="nav-quality" role="tabpanel"
@@ -809,7 +841,8 @@ <h4>License obligations</h4>
809841
renderDependenciesTable();
810842
renderVulnerabilitiesTable();
811843
renderCopyrightTable();
812-
renderCryptographyTable();
844+
renderComponentCryptographyTable();
845+
renderLocalCryptographyTable();
813846
renderQualityTable();
814847
renderHealthTable();
815848
}
@@ -842,7 +875,7 @@ <h4>License obligations</h4>
842875
if (data.dependencies) showTab('nav-dependencies-tab');
843876
if (data.vulnerabilities) showTab('nav-vulnerabilities-tab');
844877
if (existVersionKey('copyrights', data.component)) showTab('nav-copyrights-tab');
845-
if (existVersionKey('cryptography', data.component)) showTab('nav-cryptography-tab');
878+
if (data.cryptography) showTab('nav-cryptography-tab');
846879
if (existVersionKey('quality', data.component)) showTab('nav-quality-tab');
847880
if (existComponentKey('health', data.component)) showTab('nav-health-tab');
848881
}
@@ -1135,24 +1168,36 @@ <h4>License obligations</h4>
11351168
}
11361169
}
11371170

1138-
function renderCryptographyTable() {
1171+
function renderComponentCryptographyTable() {
11391172
const template = document.querySelector("#tpl-cryptography-row");
11401173
const table = document.querySelector("#table-cryptography tbody");
11411174

1142-
const { component: componentData } = data;
1175+
const { cryptography } = data;
11431176

1144-
if (!componentData) return false;
1177+
if (!cryptography && !cryptography.components) return false;
11451178

1146-
for (const compData of componentData) {
1147-
for (const version of compData.versions) {
1148-
if (!version.cryptography) continue
1149-
const clon = template.content.cloneNode(true);
1150-
clon.querySelector('td:nth-child(1)').innerHTML = compData.name;
1151-
clon.querySelector('td:nth-child(2)').innerHTML = version.version;
1152-
clon.querySelector('td:nth-child(3)').innerHTML = version.cryptography.map(e => `${e.algorithm} (${e.strength})`).join('');
1179+
for (const crypto of cryptography.components) {
1180+
const clon = template.content.cloneNode(true);
1181+
clon.querySelector('td:nth-child(1)').innerHTML = crypto.purl;
1182+
clon.querySelector('td:nth-child(2)').innerHTML = crypto.version;
1183+
clon.querySelector('td:nth-child(3)').innerHTML = crypto.algorithms.map(e => `${e.algorithm} (${e.strength})`).join(' - ');
1184+
table.appendChild(clon);
1185+
}
1186+
}
11531187

1154-
table.appendChild(clon);
1155-
}
1188+
function renderLocalCryptographyTable(){
1189+
const template = document.querySelector("#tpl-local-cryptography-row");
1190+
const table = document.querySelector("#table-local-cryptography tbody");
1191+
1192+
const { cryptography } = data;
1193+
1194+
if (!cryptography && !cryptography.files) return false;
1195+
1196+
for (const crypto of cryptography.files) {
1197+
const clon = template.content.cloneNode(true);
1198+
clon.querySelector('td:nth-child(1)').innerHTML = crypto.file;
1199+
clon.querySelector('td:nth-child(2)').innerHTML = crypto.algorithms.map(e => `${e.algorithm} (${e.strength})`).join(' - ');
1200+
table.appendChild(clon);
11561201
}
11571202
}
11581203

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "scanoss",
3-
"version": "0.13.0",
3+
"version": "0.13.1",
44
"description": "The SCANOSS JS package provides a simple, easy to consume module for interacting with SCANOSS APIs/Engine.",
55
"main": "build/main/index.js",
66
"typings": "build/main/index.d.ts",

Diff for: src/cli/commands/scan.ts

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import { DecompressionFilter } from '../../sdk/tree/Filters/DecompressionFilter'
2929
import { DecompressionManager } from '../../sdk/Decompress/DecompressionManager';
3030
import path from 'path';
3131
import { LicenseObligationDataProvider } from '../../sdk/Report/DataLayer/DataProviders/LicenseObligationDataProvider';
32+
import {
33+
CryptographyDataProvider
34+
} from '../../sdk/Report/DataLayer/DataProviders/CryptographyDataProvider';
3235

3336
export async function scanHandler(
3437
rootPath: string,
@@ -192,6 +195,9 @@ export async function scanHandler(
192195
scannersResults.dependencies
193196
)
194197
);
198+
199+
dataProviderManager.addDataProvider(new CryptographyDataProvider(null,scannersResults.scanner));
200+
195201
const report = new Report(dataProviderManager);
196202
scannerResultsString = await report.getHTML();
197203
}

Diff for: src/sdk/Report/DataLayer/DataLayerTypes.ts

+21
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import {
2+
CryptoAlgorithm,
3+
ICryptoItem
4+
} from '../../Cryptography/CryptographyTypes';
5+
import { CryptoItem } from '../../Cryptography/Scanneable/CryptoItem';
6+
17
/************* Component interface definition *************/
28
export interface ComponentDataLayer {
39
key: string; // purl[0]
@@ -43,6 +49,7 @@ export interface Health {
4349
stars: number;
4450
forks: number;
4551
}
52+
4653
/************* Component interface definition *************/
4754

4855
/************* Dependency interface definition *************/
@@ -116,6 +123,19 @@ export interface SummaryDataLayer {
116123
totalFiles: number;
117124
}
118125

126+
127+
export interface ComponentCryptography {
128+
purl: string;
129+
version: string;
130+
algorithms: Array<CryptoAlgorithm>;
131+
}
132+
133+
/*********************** Files ****************************/
134+
export interface CryptographyDataLayer {
135+
files: Array<CryptoItem>;
136+
components: Array<ComponentCryptography>;
137+
}
138+
119139
// Each layer is created to group by differents criteria.
120140
export interface IDataLayers {
121141
licenses: LicenseDataLayer[];
@@ -124,6 +144,7 @@ export interface IDataLayers {
124144
dependencies: DependencyDataLayer[];
125145
vulnerabilities: VulnerabilityDataLayer[];
126146
summary: SummaryDataLayer;
147+
cryptography: CryptographyDataLayer;
127148
}
128149

129150
export interface DataProvider {

Diff for: src/sdk/Report/DataLayer/DataProviderManager.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export class DataProviderManager {
1919
summary: null,
2020
licenses: null,
2121
licensesObligations: null,
22+
cryptography: null,
2223
};
2324

2425
for (const layer of this.dataLayersProviders)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import {
2+
ComponentCryptography,
3+
DataProvider,
4+
IDataLayers
5+
} from '../DataLayerTypes';
6+
import {
7+
ScannerComponent,
8+
ScannerResults
9+
} from '../../../scanner/ScannerTypes';
10+
import { IDependencyResponse } from '../../../Dependencies/DependencyTypes';
11+
import {
12+
CryptoAlgorithm,
13+
ICryptoItem
14+
} from '../../../Cryptography/CryptographyTypes';
15+
16+
export class CryptographyDataProvider implements DataProvider {
17+
private files: Array<ICryptoItem>;
18+
private scanRawResults: ScannerResults;
19+
private componentList: Array<ScannerComponent>;
20+
constructor(files: Array<ICryptoItem>, scanRawResults: ScannerResults,) {
21+
this.files = files;
22+
this.scanRawResults = scanRawResults;
23+
}
24+
async getData():Promise<IDataLayers> {
25+
26+
if(!this.files && !this.scanRawResults) return <IDataLayers>{ cryptography: null }
27+
28+
this.componentList = Object.values(this.scanRawResults).flat();
29+
this.componentList = this.componentList.filter(
30+
(component) => component.id !== 'none'
31+
);
32+
33+
const componentCryptography = this.getCrypto(this.componentList);
34+
35+
return <IDataLayers>{
36+
cryptography:{
37+
files: this.files,
38+
components: componentCryptography,
39+
}
40+
}
41+
}
42+
43+
private getCrypto(scanComponents: Array<ScannerComponent>):Array<ComponentCryptography> {
44+
const componentCrypto = [];
45+
scanComponents.forEach((c)=>{
46+
if(c.cryptography.length > 0){
47+
const crypto = {
48+
purl: c.purl,
49+
version: c.version,
50+
algorithms: c.cryptography
51+
}
52+
componentCrypto.push(crypto);
53+
}
54+
});
55+
return this.normalizeAlgorithms(componentCrypto)
56+
}
57+
58+
private normalizeAlgorithms(crypto: Array<ComponentCryptography>):Array<ComponentCryptography> {
59+
crypto.forEach((c)=>{
60+
c.algorithms = this.removeRepeatedAlgorithms(c.algorithms);
61+
})
62+
63+
return crypto;
64+
65+
}
66+
67+
private removeRepeatedAlgorithms(algorithms: Array<CryptoAlgorithm>):Array<CryptoAlgorithm> {
68+
const algorithmsMapper = new Map<string, { algorithm: string, strength: string }>();
69+
algorithms.forEach((a) => {
70+
const algorithmToLowerCase = a.algorithm.toLowerCase();
71+
algorithmsMapper.set(algorithmToLowerCase, {...a, algorithm: algorithmToLowerCase})
72+
});
73+
return Array.from(algorithmsMapper.values());
74+
}
75+
76+
getLayerName(): string {
77+
return '';
78+
}
79+
}

0 commit comments

Comments
 (0)