@mitre/inspec-objects 0.0.1 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,11 +5,15 @@ export default class Control {
5
5
  code?: string | null;
6
6
  desc?: string | null;
7
7
  descs?: ExecJSON.ControlDescription[] | {
8
- [key: string]: string;
8
+ [key: string]: string | undefined;
9
9
  } | null;
10
10
  impact?: number;
11
11
  ref?: string;
12
- refs?: string[];
12
+ refs?: (string | {
13
+ ref?: string;
14
+ url?: string;
15
+ uri?: string;
16
+ })[];
13
17
  tags: {
14
18
  check?: string;
15
19
  fix?: string;
@@ -19,7 +23,7 @@ export default class Control {
19
23
  satisfies?: string[];
20
24
  rid?: string;
21
25
  stig_id?: string;
22
- fix_id?: string;
26
+ fix_id?: string | null;
23
27
  cci?: string[];
24
28
  cis_controls?: Record<string, string[]>[];
25
29
  nist?: string[];
@@ -6,6 +6,8 @@ const flat_1 = require("flat");
6
6
  const global_1 = require("../utilities/global");
7
7
  class Control {
8
8
  constructor(data) {
9
+ this.tags = {};
10
+ this.refs = [];
9
11
  this.tags = {};
10
12
  if (data) {
11
13
  Object.entries(data).forEach(([key, value]) => {
@@ -55,7 +57,12 @@ class Control {
55
57
  }
56
58
  if (this.refs) {
57
59
  this.refs.forEach((ref) => {
58
- result += ` ref '${(0, global_1.escapeQuotes)(ref)}'\n`;
60
+ if (typeof ref === 'string') {
61
+ result += ` ref '${(0, global_1.escapeQuotes)(ref)}'\n`;
62
+ }
63
+ else {
64
+ result += ` ref '${(0, global_1.escapeQuotes)(ref.ref || '')}', url: '${(0, global_1.escapeQuotes)(ref.url || '')}'`;
65
+ }
59
66
  });
60
67
  }
61
68
  Object.entries(this.tags).forEach(([tag, value]) => {
@@ -0,0 +1,2 @@
1
+ import { OvalDefinitionValue } from '../types/oval';
2
+ export declare function processOVAL(oval: string): Record<string, OvalDefinitionValue>;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.processOVAL = void 0;
4
+ const xccdf_1 = require("../utilities/xccdf");
5
+ function processOVAL(oval) {
6
+ const parsed = (0, xccdf_1.convertEncodedXmlIntoJson)(oval);
7
+ const extractedDefinitions = {};
8
+ for (const ovalDefinitions of parsed.oval_definitions) {
9
+ for (const definitionList of ovalDefinitions.definitions) {
10
+ for (const definition of definitionList.definition) {
11
+ extractedDefinitions[definition["@_id"]] = definition;
12
+ }
13
+ }
14
+ }
15
+ return extractedDefinitions;
16
+ }
17
+ exports.processOVAL = processOVAL;
@@ -1,2 +1,8 @@
1
1
  import Profile from '../objects/profile';
2
- export declare function processXCCDF(xml: string): Profile;
2
+ import { BenchmarkGroup, BenchmarkRule } from '../types/xccdf';
3
+ import { OvalDefinitionValue } from '../types/oval';
4
+ export declare type GroupContextualizedRule = BenchmarkRule & {
5
+ group: Omit<BenchmarkGroup, 'Rule' | 'Group'>;
6
+ };
7
+ export declare function extractAllRules(groups: BenchmarkGroup[]): GroupContextualizedRule[];
8
+ export declare function processXCCDF(xml: string, removeNewlines?: boolean, ovalDefinitions?: Record<string, OvalDefinitionValue>): Profile;
@@ -1,67 +1,248 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.processXCCDF = void 0;
3
+ exports.processXCCDF = exports.extractAllRules = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const CciNistMappingData_1 = require("@mitre/hdf-converters/lib/src/mappings/CciNistMappingData");
6
5
  const profile_1 = tslib_1.__importDefault(require("../objects/profile"));
7
6
  const xccdf_1 = require("../utilities/xccdf");
8
7
  const control_1 = tslib_1.__importDefault(require("../objects/control"));
9
8
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
10
- function processXCCDF(xml) {
9
+ const CciNistMappingData_1 = require("../mappings/CciNistMappingData");
10
+ function extractAllRules(groups) {
11
+ const rules = [];
12
+ groups.forEach((group) => {
13
+ if (group.Rule) {
14
+ rules.push(...(group.Rule.map((rule) => {
15
+ return {
16
+ ...rule,
17
+ group: lodash_1.default.omit(group, ['Rule', 'Group'])
18
+ };
19
+ })));
20
+ }
21
+ if (group.Group) {
22
+ rules.push(...extractAllRules(group.Group));
23
+ }
24
+ });
25
+ return rules;
26
+ }
27
+ exports.extractAllRules = extractAllRules;
28
+ function processXCCDF(xml, removeNewlines = false, ovalDefinitions) {
11
29
  const parsedXML = (0, xccdf_1.convertEncodedXmlIntoJson)(xml);
12
- const groups = parsedXML.Benchmark.Group;
30
+ const rules = extractAllRules(parsedXML.Benchmark[0].Group);
13
31
  const profile = new profile_1.default({
14
- name: parsedXML.Benchmark['@_id'],
15
- title: parsedXML.Benchmark.title,
16
- summary: parsedXML.Benchmark.description
32
+ name: parsedXML.Benchmark[0]['@_id'],
33
+ title: parsedXML.Benchmark[0].title[0]['#text'],
34
+ summary: parsedXML.Benchmark[0].description[0]['#text']
17
35
  });
18
- groups.forEach(group => {
19
- var _a, _b, _c;
20
- const extractedDescription = (0, xccdf_1.convertEncodedHTMLIntoJson)((_a = group.Rule) === null || _a === void 0 ? void 0 : _a.description);
21
- const control = new control_1.default({
22
- id: group['@_id'],
23
- title: group.Rule['@_severity'] ? group.Rule.title : `[[[MISSING SEVERITY FROM STIG]]] ${group.Rule.title}`,
24
- desc: (_b = extractedDescription.VulnDiscussion) === null || _b === void 0 ? void 0 : _b.split('Satisfies: ')[0],
25
- impact: (0, xccdf_1.severityStringToImpact)(group.Rule['@_severity'] || 'critical'),
26
- descs: {
27
- check: group.Rule.check['check-content'],
28
- fix: group.Rule.fixtext['#text']
29
- },
30
- tags: lodash_1.default.omitBy({
31
- severity: (0, xccdf_1.impactNumberToSeverityString)((0, xccdf_1.severityStringToImpact)(group.Rule['@_severity'] || 'critical')),
32
- gtitle: group.title,
33
- satisfies: ((_c = extractedDescription.VulnDiscussion) === null || _c === void 0 ? void 0 : _c.includes('Satisfies: ')) && extractedDescription.VulnDiscussion.split('Satisfies: ').length >= 1 ? extractedDescription.VulnDiscussion.split('Satisfies: ')[1].split(',').map(satisfaction => satisfaction.trim()) : undefined,
34
- gid: group['@_id'],
35
- rid: group.Rule['@_id'],
36
- stig_id: group.Rule.version,
37
- fix_id: group.Rule.fix['@_id'],
38
- false_negatives: extractedDescription.FalseNegatives,
39
- false_positives: extractedDescription.FalsePositives,
40
- documentable: extractedDescription.Documentable,
41
- mitigations: extractedDescription.Mitigations,
42
- severity_override_guidance: extractedDescription.SeverityOverrideGuidance,
43
- potential_impacts: extractedDescription.PotentialImpacts,
44
- third_party_tools: extractedDescription.ThirdPartyTools,
45
- mitigation_control: extractedDescription.MitigationControl,
46
- mitigation_controls: extractedDescription.MitigationControls,
47
- responsibility: extractedDescription.Responsibility,
48
- ia_controls: extractedDescription.IAControls
49
- }, i => !Boolean(i))
36
+ rules.forEach(rule => {
37
+ var _a, _b, _c, _d;
38
+ let extractedDescription;
39
+ if (Array.isArray(rule.description)) {
40
+ extractedDescription = rule.description[0]['#text'];
41
+ }
42
+ else {
43
+ extractedDescription = (0, xccdf_1.convertEncodedHTMLIntoJson)(rule.description);
44
+ }
45
+ const control = new control_1.default();
46
+ control.id = rule['@_id'];
47
+ if (removeNewlines) {
48
+ const title = (0, xccdf_1.removeXMLSpecialCharacters)(rule['@_severity'] ? rule.title : `[[[MISSING SEVERITY FROM STIG]]] ${rule.title}`);
49
+ control.title = title.replace(/\n/g, '{{{{newlineHERE}}}}');
50
+ const desc = (0, xccdf_1.removeXMLSpecialCharacters)(typeof extractedDescription === 'string' ? extractedDescription : ((_a = extractedDescription.VulnDiscussion) === null || _a === void 0 ? void 0 : _a.split('Satisfies: ')[0]) || 'Missing Description');
51
+ control.desc = desc === null || desc === void 0 ? void 0 : desc.replace(/\n/g, '{{{{newlineHERE}}}}');
52
+ }
53
+ else {
54
+ control.title = (0, xccdf_1.removeXMLSpecialCharacters)(rule['@_severity'] ? rule.title : `[[[MISSING SEVERITY FROM STIG]]] ${rule.title}`);
55
+ control.desc = (0, xccdf_1.removeXMLSpecialCharacters)(typeof extractedDescription === 'string' ? extractedDescription : ((_b = extractedDescription.VulnDiscussion) === null || _b === void 0 ? void 0 : _b.split('Satisfies: ')[0]) || 'Missing Description');
56
+ }
57
+ control.impact = (0, xccdf_1.severityStringToImpact)(rule['@_severity'] || 'critical', rule.group['@_id']);
58
+ if (!control.descs || Array.isArray(control.descs)) {
59
+ control.descs = {};
60
+ }
61
+ if (rule.check) {
62
+ if (rule.check.some((ruleValue) => 'check-content' in ruleValue)) {
63
+ if (removeNewlines) {
64
+ const check = (0, xccdf_1.removeXMLSpecialCharacters)(rule.check ? rule.check[0]['check-content'] : 'Missing description');
65
+ control.descs.check = check.replace(/\n/g, '{{{{newlineHERE}}}}');
66
+ }
67
+ else {
68
+ control.descs.check = (0, xccdf_1.removeXMLSpecialCharacters)(rule.check ? rule.check[0]['check-content'] : 'Missing description');
69
+ }
70
+ }
71
+ else if (rule.check.some((ruleValue) => 'check-content-ref' in ruleValue) && ovalDefinitions) {
72
+ let referenceID = null;
73
+ for (const checkContent of rule.check) {
74
+ if ('check-content-ref' in checkContent && checkContent['@_system'].includes('oval')) {
75
+ for (const checkContentRef of checkContent['check-content-ref']) {
76
+ if (checkContentRef['@_name']) {
77
+ referenceID = checkContentRef['@_name'];
78
+ }
79
+ }
80
+ }
81
+ }
82
+ if (referenceID && referenceID in ovalDefinitions) {
83
+ if (removeNewlines) {
84
+ const check = (0, xccdf_1.removeXMLSpecialCharacters)(ovalDefinitions[referenceID].metadata[0].title);
85
+ control.descs.check = check.replace(/\n/g, '{{{{newlineHERE}}}}');
86
+ }
87
+ else {
88
+ control.descs.check = (0, xccdf_1.removeXMLSpecialCharacters)(ovalDefinitions[referenceID].metadata[0].title);
89
+ }
90
+ }
91
+ else if (referenceID) {
92
+ console.warn(`Could not find OVAL definition for ${referenceID}`);
93
+ }
94
+ }
95
+ }
96
+ if (removeNewlines) {
97
+ const fix = (0, xccdf_1.removeXMLSpecialCharacters)(rule.fixtext ? rule.fixtext[0]['#text'] : (rule.fix ? rule.fix[0]['#text'] || 'Missing fix text' : 'Missing fix text'));
98
+ control.descs.fix = fix.replace(/\n/g, '{{{{newlineHERE}}}}');
99
+ }
100
+ else {
101
+ control.descs.fix = (0, xccdf_1.removeXMLSpecialCharacters)(rule.fixtext ? rule.fixtext[0]['#text'] : (rule.fix ? rule.fix[0]['#text'] || 'Missing fix text' : 'Missing fix text'));
102
+ }
103
+ control.tags.severity = (0, xccdf_1.impactNumberToSeverityString)((0, xccdf_1.severityStringToImpact)(rule['@_severity'] || 'critical', control.id));
104
+ control.tags.gid = rule.group['@_id'],
105
+ control.tags.rid = rule['@_id'];
106
+ control.tags.stig_id = rule['version'];
107
+ if (typeof rule.group.title === "string") {
108
+ control.tags.gtitle = (0, xccdf_1.removeXMLSpecialCharacters)(rule.group.title);
109
+ }
110
+ else {
111
+ control.tags.gtitle = (0, xccdf_1.removeXMLSpecialCharacters)(lodash_1.default.get(rule.group, 'title[0].#text'));
112
+ }
113
+ if (rule['fix'] && rule['fix'].length > 0) {
114
+ control.tags.fix_id = rule['fix'][0]['@_id'];
115
+ }
116
+ else {
117
+ control.tags.fix_id = null;
118
+ }
119
+ if (rule['rationale']) {
120
+ control.tags.rationale = rule['rationale'][0]['#text'];
121
+ }
122
+ else {
123
+ control.tags.rationale = null;
124
+ }
125
+ if (typeof extractedDescription === 'object') {
126
+ control.tags.satisfies = ((_c = extractedDescription.VulnDiscussion) === null || _c === void 0 ? void 0 : _c.includes('Satisfies: ')) && extractedDescription.VulnDiscussion.split('Satisfies: ').length >= 1 ? extractedDescription.VulnDiscussion.split('Satisfies: ')[1].split(',').map(satisfaction => satisfaction.trim()) : undefined;
127
+ control.tags.false_negatives = extractedDescription.FalseNegatives || undefined;
128
+ control.tags.false_positives = extractedDescription.FalsePositives || undefined;
129
+ control.tags.documentable = typeof extractedDescription.Documentable === 'boolean' ? extractedDescription.Documentable : undefined;
130
+ control.tags.mitigations = extractedDescription.Mitigations || undefined;
131
+ control.tags.severity_override_guidance = extractedDescription.SeverityOverrideGuidance || undefined;
132
+ control.tags.potential_impacts = extractedDescription.PotentialImpacts || undefined;
133
+ control.tags.third_party_tools = extractedDescription.ThirdPartyTools || undefined;
134
+ control.tags.mitigation_control = extractedDescription.MitigationControl || undefined;
135
+ control.tags.mitigation_controls = extractedDescription.MitigationControls || undefined;
136
+ control.tags.responsibility = extractedDescription.Responsibility || undefined;
137
+ control.tags.ia_controls = extractedDescription.IAControls || undefined;
138
+ }
139
+ control.tags = lodash_1.default.mapValues(lodash_1.default.omitBy(control.tags, (value) => value === undefined), (value) => {
140
+ if (typeof value === 'string') {
141
+ return (0, xccdf_1.removeXMLSpecialCharacters)(value);
142
+ }
143
+ else {
144
+ return value;
145
+ }
50
146
  });
51
- if ('ident' in group.Rule) {
52
- const identifiers = Array.isArray(group.Rule.ident) ? group.Rule.ident : [group.Rule.ident];
53
- // Grab CCI/NIST/Legacy identifiers
54
- identifiers.forEach(identifier => {
147
+ // Get all identifiers from the rule
148
+ if (rule.ident) {
149
+ rule.ident.forEach((identifier) => {
55
150
  var _a, _b, _c;
56
- const identifierText = identifier['#text'];
57
- if (identifier['@_system'].toLowerCase().endsWith('cci')) {
58
- (_a = control.tags.cci) === null || _a === void 0 ? void 0 : _a.push(identifierText);
59
- if (identifierText in CciNistMappingData_1.data) {
60
- (_b = control.tags.nist) === null || _b === void 0 ? void 0 : _b.push(lodash_1.default.get(CciNistMappingData_1.data, identifierText));
151
+ // Get CCIs
152
+ if (identifier['@_system'].toLowerCase().includes('cci')) {
153
+ if (!('cci' in control.tags)) {
154
+ control.tags.cci = [];
155
+ }
156
+ (_a = control.tags.cci) === null || _a === void 0 ? void 0 : _a.push(identifier['#text']);
157
+ }
158
+ // Get legacy identifiers
159
+ else if (identifier['@_system'].toLowerCase().includes('legacy')) {
160
+ if (!('legacy' in control.tags)) {
161
+ control.tags.legacy = [];
162
+ }
163
+ (_b = control.tags.legacy) === null || _b === void 0 ? void 0 : _b.push(identifier['#text']);
164
+ }
165
+ // Get NIST identifiers
166
+ else if (identifier['@_system'].toLowerCase().includes('nist')) {
167
+ if (!('nist' in control.tags)) {
168
+ control.tags.nist = [];
61
169
  }
170
+ (_c = control.tags.nist) === null || _c === void 0 ? void 0 : _c.push(identifier['#text']);
171
+ }
172
+ else {
173
+ // console.log('Alert')
174
+ // console.log(identifier['@_system'])
175
+ // console.log(identifier['#text'])
176
+ }
177
+ });
178
+ }
179
+ (_d = rule.reference) === null || _d === void 0 ? void 0 : _d.forEach((reference) => {
180
+ var _a, _b, _c, _d;
181
+ if (lodash_1.default.get(reference, '@_href') === '') {
182
+ (_a = control.refs) === null || _a === void 0 ? void 0 : _a.push(lodash_1.default.get(reference, '#text'));
183
+ }
184
+ else {
185
+ try {
186
+ const referenceText = lodash_1.default.get(reference, '#text') || '';
187
+ const referenceURL = lodash_1.default.get(reference, '@_href') || '';
188
+ if (referenceURL) {
189
+ const parsedURL = new URL(lodash_1.default.get(reference, '@_href'));
190
+ if (parsedURL.protocol.toLowerCase().includes('http') || parsedURL.protocol.toLowerCase().includes('https')) {
191
+ (_b = control.refs) === null || _b === void 0 ? void 0 : _b.push({
192
+ ref: referenceText,
193
+ url: referenceURL
194
+ });
195
+ }
196
+ else {
197
+ (_c = control.refs) === null || _c === void 0 ? void 0 : _c.push({
198
+ ref: referenceText,
199
+ uri: referenceURL
200
+ });
201
+ }
202
+ }
203
+ else {
204
+ if ('title' in reference) {
205
+ (_d = control.refs) === null || _d === void 0 ? void 0 : _d.push(lodash_1.default.get(reference, 'title'));
206
+ }
207
+ }
208
+ // Add the reference to the control tags when seperated by §
209
+ if (typeof referenceText === 'string' && referenceText.indexOf('§') !== -1) {
210
+ const referenceParts = referenceText.split('§');
211
+ if (referenceParts.length == 2) {
212
+ let [identifierType, identifier] = referenceText.split('§');
213
+ identifierType = identifierType.toLowerCase();
214
+ if (!(identifierType in control.tags)) {
215
+ control.tags[identifierType] = [identifier];
216
+ }
217
+ else if (Array.isArray(control.tags[identifierType])) {
218
+ control.tags[identifierType] = lodash_1.default.union(control.tags[identifierType], [identifier]);
219
+ }
220
+ else {
221
+ console.warn(`Attempted to push identifier to control tags when identifier already exists: ${identifierType}: ${identifier}`);
222
+ }
223
+ }
224
+ else {
225
+ console.warn("Reference parts of invalid length:");
226
+ console.log(referenceParts);
227
+ }
228
+ }
229
+ }
230
+ catch (e) {
231
+ console.warn(`Error parsing ref for control ${control.id}: `);
232
+ console.warn(JSON.stringify(reference, null, 2));
233
+ console.warn(e);
234
+ }
235
+ }
236
+ });
237
+ // Associate any CCIs with NIST tags
238
+ if (control.tags.cci) {
239
+ control.tags.cci.forEach((cci) => {
240
+ var _a;
241
+ if (!('nist' in control.tags)) {
242
+ control.tags.nist = [];
62
243
  }
63
- if (identifier['@_system'].toLowerCase().endsWith('legacy')) {
64
- (_c = control.tags.legacy) === null || _c === void 0 ? void 0 : _c.push(identifierText);
244
+ if (cci in CciNistMappingData_1.data) {
245
+ (_a = control.tags.nist) === null || _a === void 0 ? void 0 : _a.push(lodash_1.default.get(CciNistMappingData_1.data, cci));
65
246
  }
66
247
  });
67
248
  }
@@ -1,3 +1,4 @@
1
1
  import Profile from '../objects/profile';
2
2
  import { ProfileDiff } from '../types/diff';
3
+ export declare function removeNewlines(control?: Record<string, unknown>): Record<string, unknown>;
3
4
  export declare function diffProfile(fromProfile: Profile, toProfile: Profile): ProfileDiff;
@@ -1,9 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.diffProfile = void 0;
3
+ exports.diffProfile = exports.removeNewlines = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const json_diff_1 = require("json-diff");
6
6
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
7
+ function removeNewlines(control) {
8
+ if (!control) {
9
+ return {};
10
+ }
11
+ return lodash_1.default.mapValues(control, (value) => {
12
+ if (typeof value === 'string') {
13
+ return value.replace(/\n/g, '{{{{newlineHERE}}}}').trim();
14
+ }
15
+ else if (typeof value === 'object' && value !== null) {
16
+ return removeNewlines(value);
17
+ }
18
+ return value;
19
+ });
20
+ }
21
+ exports.removeNewlines = removeNewlines;
7
22
  function diffProfile(fromProfile, toProfile) {
8
23
  const profileDiff = {
9
24
  addedControlIDs: [],
@@ -14,7 +29,7 @@ function diffProfile(fromProfile, toProfile) {
14
29
  const toControlIDs = toProfile.controls.map((control) => control.id).sort();
15
30
  // Find new controls
16
31
  const controlIDDiff = (0, json_diff_1.diff)(fromControlIDs, toControlIDs);
17
- controlIDDiff.forEach((diffValue) => {
32
+ controlIDDiff === null || controlIDDiff === void 0 ? void 0 : controlIDDiff.forEach((diffValue) => {
18
33
  if (diffValue[0] === '-') {
19
34
  profileDiff.removedControlIDs.push(diffValue[1]);
20
35
  }
@@ -34,13 +49,15 @@ function diffProfile(fromProfile, toProfile) {
34
49
  const toControl = toProfile.controls.find((control) => control.id === fromControl.id);
35
50
  if (toControl) {
36
51
  const controlDiff = (0, json_diff_1.diff)(fromControl, toControl);
52
+ console.log(controlDiff);
37
53
  if (controlDiff) {
38
54
  Object.entries(controlDiff).forEach(([key, value]) => {
55
+ console.log(value);
39
56
  if (lodash_1.default.has(value, '__new')) {
40
57
  lodash_1.default.set(profileDiff, 'changedControls.' + fromControl.id + '.' + key.replace('.', '\\.'), lodash_1.default.get(controlDiff, key + '.__new'));
41
58
  }
42
59
  else if (typeof value === 'object') {
43
- Object.entries(value).forEach(([subKey, subValue]) => {
60
+ Object.entries(value).forEach(([subKey]) => {
44
61
  lodash_1.default.set(profileDiff, 'changedControls.' + fromControl.id + '.' + key.replace('.', '\\.') + '.' + subKey.replace('.', '\\.'), lodash_1.default.get(controlDiff, key + '.' + subKey + '.__new'));
45
62
  });
46
63
  }
@@ -4,3 +4,5 @@ declare const escapeQuotes: (s: string) => string;
4
4
  declare const escapeDoubleQuotes: (s: string) => string;
5
5
  declare const wrapAndEscapeQuotes: (s: string, lineLength?: number) => string;
6
6
  export { escapeQuotes, escapeDoubleQuotes, wrapAndEscapeQuotes };
7
+ export declare function getFirstPath(object: Record<string, unknown>, paths: string[]): string;
8
+ export declare function hasPath(file: Record<string, unknown>, path: string | string[]): boolean;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.wrapAndEscapeQuotes = exports.escapeDoubleQuotes = exports.escapeQuotes = exports.unformatText = exports.wrap = void 0;
3
+ exports.hasPath = exports.getFirstPath = exports.wrapAndEscapeQuotes = exports.escapeDoubleQuotes = exports.escapeQuotes = exports.unformatText = exports.wrap = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
4
6
  // Breaks lines down to lineLength number of characters
5
7
  function wrap(s, lineLength = 80) {
6
8
  return s.replace(new RegExp(`(?![^\n]{1,${lineLength}}$)([^\n]{1,${lineLength}})`, "g"), "$1\n");
@@ -16,3 +18,24 @@ const escapeDoubleQuotes = (s) => s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
16
18
  exports.escapeDoubleQuotes = escapeDoubleQuotes;
17
19
  const wrapAndEscapeQuotes = (s, lineLength) => escapeDoubleQuotes(wrap(s, lineLength)); // Escape backslashes and quotes, and wrap long lines
18
20
  exports.wrapAndEscapeQuotes = wrapAndEscapeQuotes;
21
+ function getFirstPath(object, paths) {
22
+ const index = lodash_1.default.findIndex(paths, (p) => hasPath(object, p));
23
+ if (index === -1) {
24
+ throw new Error(`Attestation is missing one of these paths: ${paths.join(', ')}`);
25
+ }
26
+ else {
27
+ return lodash_1.default.get(object, paths[index]);
28
+ }
29
+ }
30
+ exports.getFirstPath = getFirstPath;
31
+ function hasPath(file, path) {
32
+ let pathArray;
33
+ if (typeof path === 'string') {
34
+ pathArray = [path];
35
+ }
36
+ else {
37
+ pathArray = path;
38
+ }
39
+ return lodash_1.default.some(pathArray, (p) => lodash_1.default.has(file, p));
40
+ }
41
+ exports.hasPath = hasPath;
@@ -1,5 +1,6 @@
1
1
  import { DecodedDescription } from '../types/xccdf';
2
2
  export declare function convertEncodedXmlIntoJson(encodedXml: string): any;
3
- export declare function severityStringToImpact(string: string): number;
3
+ export declare function removeXMLSpecialCharacters(input: string): string;
4
+ export declare function severityStringToImpact(string: string, id: string): number;
4
5
  export declare function impactNumberToSeverityString(impact: number): string;
5
6
  export declare function convertEncodedHTMLIntoJson(encodedHTML?: string): DecodedDescription;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertEncodedHTMLIntoJson = exports.impactNumberToSeverityString = exports.severityStringToImpact = exports.convertEncodedXmlIntoJson = void 0;
3
+ exports.convertEncodedHTMLIntoJson = exports.impactNumberToSeverityString = exports.severityStringToImpact = exports.removeXMLSpecialCharacters = exports.convertEncodedXmlIntoJson = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const fast_xml_parser_1 = tslib_1.__importDefault(require("fast-xml-parser"));
6
6
  const htmlparser = tslib_1.__importStar(require("htmlparser2"));
@@ -8,11 +8,17 @@ const lodash_1 = tslib_1.__importDefault(require("lodash"));
8
8
  function convertEncodedXmlIntoJson(encodedXml) {
9
9
  return fast_xml_parser_1.default.parse(encodedXml, {
10
10
  ignoreAttributes: false,
11
+ ignoreNameSpace: true,
11
12
  attributeNamePrefix: '@_',
13
+ arrayMode: true
12
14
  });
13
15
  }
14
16
  exports.convertEncodedXmlIntoJson = convertEncodedXmlIntoJson;
15
- function severityStringToImpact(string) {
17
+ function removeXMLSpecialCharacters(input) {
18
+ return input.replace(/&amp;/gm, '&').replace(/&lt;/gm, '<').replace(/&gt;/gm, '>');
19
+ }
20
+ exports.removeXMLSpecialCharacters = removeXMLSpecialCharacters;
21
+ function severityStringToImpact(string, id) {
16
22
  var _a, _b, _c, _d, _e;
17
23
  if ((_a = string.match(/none|na|n\/a|not[\s()*_|]?applicable/i)) === null || _a === void 0 ? void 0 : _a.length) {
18
24
  return 0.0;
@@ -29,7 +35,8 @@ function severityStringToImpact(string) {
29
35
  if ((_e = string.match(/crit(ical)?|severe/)) === null || _e === void 0 ? void 0 : _e.length) {
30
36
  return 1.0;
31
37
  }
32
- throw new Error(`${string}' is not a valid severity value. It should be one of the approved keywords`);
38
+ console.log(`${string} is not a valid severity value. It should be one of the approved keywords. ${id} will be treated as medium severity`);
39
+ return 0.5;
33
40
  }
34
41
  exports.severityStringToImpact = severityStringToImpact;
35
42
  function impactNumberToSeverityString(impact) {
Binary file
Binary file