@mitre/inspec-objects 2.0.4 → 2.1.0
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.
- package/.github/workflows/auto-approve-and-merge.yml +1 -0
- package/.github/workflows/build.yml +6 -2
- package/.github/workflows/draft-release.yml +4 -1
- package/.github/workflows/e2e-test.yml +7 -3
- package/.github/workflows/linter.yml +6 -2
- package/.github/workflows/push-to-gpr.yml +7 -2
- package/.github/workflows/push-to-npm.yml +10 -4
- package/eslint.config.js +41 -0
- package/lib/index.d.ts +2 -4
- package/lib/index.js +4 -4
- package/lib/mappings/{CciNistMappingData.js → cci-nist-mapping-data.js} +1 -1
- package/lib/objects/control.js +41 -81
- package/lib/objects/profile.js +6 -6
- package/lib/parsers/json.js +5 -7
- package/lib/parsers/oval.js +23 -24
- package/lib/parsers/xccdf.d.ts +1 -1
- package/lib/parsers/xccdf.js +122 -137
- package/lib/utilities/{diffMarkdown.js → diff-markdown.js} +10 -11
- package/lib/utilities/diff.js +46 -48
- package/lib/utilities/global.js +9 -15
- package/lib/utilities/logging.js +1 -1
- package/lib/utilities/update.js +25 -28
- package/lib/utilities/xccdf.js +21 -32
- package/package.json +14 -13
- package/tsconfig.build.json +1 -1
- package/tsconfig.json +2 -2
- package/vitest.config.ts +3 -3
- package/.eslintignore +0 -2
- package/.eslintrc +0 -41
- /package/lib/mappings/{CciNistMappingData.d.ts → cci-nist-mapping-data.d.ts} +0 -0
- /package/lib/utilities/{diffMarkdown.d.ts → diff-markdown.d.ts} +0 -0
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
name: Build and Pack TS-InSpec-Objects
|
|
2
|
+
|
|
2
3
|
on:
|
|
3
4
|
push:
|
|
4
5
|
branches: [ main ]
|
|
5
6
|
pull_request:
|
|
6
7
|
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
7
11
|
jobs:
|
|
8
12
|
build:
|
|
9
13
|
name: Build and Pack TS-InSpec-Objects
|
|
10
14
|
runs-on: ubuntu-24.04
|
|
11
15
|
|
|
12
16
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
17
|
+
- uses: actions/checkout@v5
|
|
14
18
|
|
|
15
19
|
- name: Setup Node.js
|
|
16
|
-
uses: actions/setup-node@
|
|
20
|
+
uses: actions/setup-node@v6
|
|
17
21
|
with:
|
|
18
22
|
node-version: 22
|
|
19
23
|
cache: 'npm'
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
name: Run TS-InSpec-Objects E2E Tests
|
|
2
|
+
|
|
2
3
|
on:
|
|
3
4
|
push:
|
|
4
5
|
branches: [ main ]
|
|
5
6
|
pull_request:
|
|
6
7
|
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
7
11
|
jobs:
|
|
8
12
|
build:
|
|
9
13
|
name: Run TS-InSpec-Objects E2E Tests
|
|
10
14
|
runs-on: ubuntu-24.04
|
|
11
15
|
|
|
12
16
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
17
|
+
- uses: actions/checkout@v5
|
|
14
18
|
|
|
15
19
|
- name: Setup Node.js
|
|
16
|
-
uses: actions/setup-node@
|
|
20
|
+
uses: actions/setup-node@v6
|
|
17
21
|
with:
|
|
18
22
|
node-version: 22
|
|
19
23
|
cache: 'npm'
|
|
@@ -22,4 +26,4 @@ jobs:
|
|
|
22
26
|
run: npm ci
|
|
23
27
|
|
|
24
28
|
- name: Run e2e tests
|
|
25
|
-
run: npm test
|
|
29
|
+
run: npm run test:ci
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
name: Lint TS-InSpec-Objects
|
|
2
|
+
|
|
2
3
|
on:
|
|
3
4
|
push:
|
|
4
5
|
branches: [ main ]
|
|
5
6
|
pull_request:
|
|
6
7
|
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
7
11
|
jobs:
|
|
8
12
|
build:
|
|
9
13
|
name: Lint TS-InSpec-Objects
|
|
@@ -11,10 +15,10 @@ jobs:
|
|
|
11
15
|
|
|
12
16
|
steps:
|
|
13
17
|
- name: Checkout code
|
|
14
|
-
uses: actions/checkout@
|
|
18
|
+
uses: actions/checkout@v5
|
|
15
19
|
|
|
16
20
|
- name: Setup Node.js
|
|
17
|
-
uses: actions/setup-node@
|
|
21
|
+
uses: actions/setup-node@v6
|
|
18
22
|
with:
|
|
19
23
|
node-version: 22
|
|
20
24
|
cache: 'npm'
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
name: Build and Release NPM to GPR (GitHub Package Registry)
|
|
2
|
+
|
|
2
3
|
on:
|
|
3
4
|
release:
|
|
4
5
|
types: [published]
|
|
5
6
|
workflow_dispatch:
|
|
6
7
|
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
packages: write
|
|
11
|
+
|
|
7
12
|
jobs:
|
|
8
13
|
build-deploy:
|
|
9
14
|
runs-on: ubuntu-24.04
|
|
10
15
|
steps:
|
|
11
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v5
|
|
12
17
|
|
|
13
18
|
- name: Setup node
|
|
14
|
-
uses: actions/setup-node@
|
|
19
|
+
uses: actions/setup-node@v6
|
|
15
20
|
with:
|
|
16
21
|
node-version: 22
|
|
17
22
|
registry-url: 'https://npm.pkg.github.com'
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
name: Push @mitre/inspec-objects to NPM
|
|
2
|
+
|
|
2
3
|
on:
|
|
3
4
|
release:
|
|
4
5
|
types: [published]
|
|
5
6
|
workflow_dispatch:
|
|
6
7
|
|
|
8
|
+
permissions:
|
|
9
|
+
id-token: write # required for trusted publishing's use of OIDC
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
7
12
|
jobs:
|
|
8
13
|
build-deploy:
|
|
9
14
|
runs-on: ubuntu-24.04
|
|
10
15
|
steps:
|
|
11
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v5
|
|
12
17
|
|
|
13
18
|
- name: setup node
|
|
14
|
-
uses: actions/setup-node@
|
|
19
|
+
uses: actions/setup-node@v6
|
|
15
20
|
with:
|
|
16
21
|
node-version: 22
|
|
17
22
|
registry-url: 'https://registry.npmjs.org'
|
|
18
23
|
|
|
24
|
+
- name: Manually update npm to 11.5.1 or later which is the required version for trusted publishing to work # this step can be removed after the ubuntu runner has the correct minimum version of npm installed
|
|
25
|
+
run: npm install -g npm@latest
|
|
26
|
+
|
|
19
27
|
- name: Install project dependencies
|
|
20
28
|
run: npm ci
|
|
21
29
|
|
|
@@ -30,5 +38,3 @@ jobs:
|
|
|
30
38
|
|
|
31
39
|
- name: Publish inspec-objects to NPM
|
|
32
40
|
run: npm publish --access public mitre-inspec-objects-*.tgz
|
|
33
|
-
env:
|
|
34
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import js from '@eslint/js';
|
|
3
|
+
import stylistic from '@stylistic/eslint-plugin';
|
|
4
|
+
import tseslint from 'typescript-eslint';
|
|
5
|
+
import unicorn from 'eslint-plugin-unicorn';
|
|
6
|
+
import n from 'eslint-plugin-n';
|
|
7
|
+
|
|
8
|
+
export default defineConfig([
|
|
9
|
+
{
|
|
10
|
+
ignores: ['node_modules/**', 'lib/**'],
|
|
11
|
+
},
|
|
12
|
+
js.configs.recommended,
|
|
13
|
+
...tseslint.configs.recommended,
|
|
14
|
+
unicorn.configs.recommended,
|
|
15
|
+
stylistic.configs.customize({
|
|
16
|
+
braceStyle: '1tbs',
|
|
17
|
+
indent: [2, { SwitchCase: 1 }],
|
|
18
|
+
semi: true,
|
|
19
|
+
quoteProps: 'as-needed',
|
|
20
|
+
quotes: 'single',
|
|
21
|
+
}),
|
|
22
|
+
{
|
|
23
|
+
languageOptions: {
|
|
24
|
+
parser: tseslint.parser,
|
|
25
|
+
ecmaVersion: 'latest',
|
|
26
|
+
sourceType: 'module',
|
|
27
|
+
},
|
|
28
|
+
plugins: {
|
|
29
|
+
'@typescript-eslint': tseslint.plugin,
|
|
30
|
+
unicorn,
|
|
31
|
+
n,
|
|
32
|
+
},
|
|
33
|
+
rules: {
|
|
34
|
+
'@stylistic/quotes': ['error', 'single', { avoidEscape: true }],
|
|
35
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
36
|
+
'unicorn/no-null': 'off',
|
|
37
|
+
'unicorn/prefer-node-protocol': 'off',
|
|
38
|
+
'unicorn/prevent-abbreviations': 'off',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
]);
|
package/lib/index.d.ts
CHANGED
|
@@ -3,7 +3,5 @@ export * from './parsers/oval';
|
|
|
3
3
|
export * from './parsers/xccdf';
|
|
4
4
|
export * from './utilities/diff';
|
|
5
5
|
export * from './utilities/update';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export { Control };
|
|
9
|
-
export { Profile };
|
|
6
|
+
export { default as Control } from './objects/control';
|
|
7
|
+
export { default as Profile } from './objects/profile';
|
package/lib/index.js
CHANGED
|
@@ -7,7 +7,7 @@ tslib_1.__exportStar(require("./parsers/oval"), exports);
|
|
|
7
7
|
tslib_1.__exportStar(require("./parsers/xccdf"), exports);
|
|
8
8
|
tslib_1.__exportStar(require("./utilities/diff"), exports);
|
|
9
9
|
tslib_1.__exportStar(require("./utilities/update"), exports);
|
|
10
|
-
|
|
11
|
-
exports
|
|
12
|
-
|
|
13
|
-
exports
|
|
10
|
+
var control_1 = require("./objects/control");
|
|
11
|
+
Object.defineProperty(exports, "Control", { enumerable: true, get: function () { return tslib_1.__importDefault(control_1).default; } });
|
|
12
|
+
var profile_1 = require("./objects/profile");
|
|
13
|
+
Object.defineProperty(exports, "Profile", { enumerable: true, get: function () { return tslib_1.__importDefault(profile_1).default; } });
|
package/lib/objects/control.js
CHANGED
|
@@ -3,8 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.objectifyDescriptions = objectifyDescriptions;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
6
|
-
const flat_1 = require("flat");
|
|
7
|
-
const flat_2 = require("flat");
|
|
8
6
|
const global_1 = require("../utilities/global");
|
|
9
7
|
const logging_1 = require("../utilities/logging");
|
|
10
8
|
/**
|
|
@@ -19,9 +17,9 @@ const logging_1 = require("../utilities/logging");
|
|
|
19
17
|
function objectifyDescriptions(descs) {
|
|
20
18
|
if (Array.isArray(descs)) {
|
|
21
19
|
const descriptions = {};
|
|
22
|
-
|
|
20
|
+
for (const description of descs) {
|
|
23
21
|
descriptions[description.label] = description.data;
|
|
24
|
-
}
|
|
22
|
+
}
|
|
25
23
|
return descriptions;
|
|
26
24
|
}
|
|
27
25
|
return descs || {};
|
|
@@ -56,13 +54,12 @@ class Control {
|
|
|
56
54
|
* If provided, the properties of the data object will be assigned to the instance.
|
|
57
55
|
*/
|
|
58
56
|
constructor(data) {
|
|
59
|
-
this.tags = {};
|
|
60
57
|
this.refs = [];
|
|
61
58
|
this.tags = {};
|
|
62
59
|
if (data) {
|
|
63
|
-
|
|
60
|
+
for (const [key, value] of Object.entries(structuredClone(data))) {
|
|
64
61
|
lodash_1.default.set(this, key, value);
|
|
65
|
-
}
|
|
62
|
+
}
|
|
66
63
|
}
|
|
67
64
|
}
|
|
68
65
|
/**
|
|
@@ -73,13 +70,7 @@ class Control {
|
|
|
73
70
|
* @returns {Control} A new Control object created from the unformatted data.
|
|
74
71
|
*/
|
|
75
72
|
toUnformattedObject() {
|
|
76
|
-
|
|
77
|
-
Object.entries(flattened).forEach(([key, value]) => {
|
|
78
|
-
if (typeof value === 'string') {
|
|
79
|
-
lodash_1.default.set(flattened, key, value);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
return new Control((0, flat_2.unflatten)(flattened));
|
|
73
|
+
return new Control(this);
|
|
83
74
|
}
|
|
84
75
|
/**
|
|
85
76
|
* Converts the control object to a string representation in a specific format.
|
|
@@ -108,11 +99,11 @@ class Control {
|
|
|
108
99
|
result += ` desc "${this.desc}"\n`;
|
|
109
100
|
}
|
|
110
101
|
if (this.descs) {
|
|
111
|
-
Object.entries(this.descs)
|
|
102
|
+
for (const [key, subDesc] of Object.entries(this.descs)) {
|
|
112
103
|
if (subDesc) {
|
|
113
104
|
result += ` desc '${key}', "${subDesc}"\n`;
|
|
114
105
|
}
|
|
115
|
-
}
|
|
106
|
+
}
|
|
116
107
|
}
|
|
117
108
|
if (this.impact) {
|
|
118
109
|
result += ` impact ${this.impact}\n`;
|
|
@@ -121,34 +112,18 @@ class Control {
|
|
|
121
112
|
result += ` impact ${this.impact.toFixed(1)}\n`;
|
|
122
113
|
}
|
|
123
114
|
if (this.refs) {
|
|
124
|
-
this.refs
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
result += ` ref "${ref}"\n`;
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
result += ` ref ${((_a = ref.ref) === null || _a === void 0 ? void 0 : _a.toString()) || ''}, url: ${ref.url || ''}`;
|
|
131
|
-
}
|
|
132
|
-
});
|
|
115
|
+
for (const ref of this.refs) {
|
|
116
|
+
result += typeof ref === 'string' ? ` ref "${ref}"\n` : ` ref ${ref.ref?.toString() || ''}, url: ${ref.url || ''}`;
|
|
117
|
+
}
|
|
133
118
|
}
|
|
134
|
-
Object.entries(this.tags)
|
|
119
|
+
for (const [tag, value] of Object.entries(this.tags)) {
|
|
135
120
|
if (typeof value === 'object') {
|
|
136
|
-
|
|
137
|
-
result += ` tag ${tag}: ${JSON.stringify(value)}\n`;
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
result += ` tag '${tag}': ${(value == null ? 'nil' : value)}\n`;
|
|
141
|
-
}
|
|
121
|
+
result += Array.isArray(value) && typeof value[0] === 'string' ? ` tag ${tag}: ${JSON.stringify(value)}\n` : ` tag '${tag}': ${(value == undefined ? 'nil' : value)}\n`;
|
|
142
122
|
}
|
|
143
123
|
else if (typeof value === 'string') {
|
|
144
|
-
|
|
145
|
-
result += ` tag "${tag}": "${value}"\n`;
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
result += ` tag '${tag}': '${value}'\n`;
|
|
149
|
-
}
|
|
124
|
+
result += value.includes('"') ? ` tag "${tag}": "${value}"\n` : ` tag '${tag}': '${value}'\n`;
|
|
150
125
|
}
|
|
151
|
-
}
|
|
126
|
+
}
|
|
152
127
|
if (this.describe) {
|
|
153
128
|
result += '\n';
|
|
154
129
|
result += this.describe;
|
|
@@ -184,57 +159,47 @@ class Control {
|
|
|
184
159
|
if (this.title) {
|
|
185
160
|
result += ` title ${(0, global_1.escapeQuotes)(this.title)}\n`;
|
|
186
161
|
}
|
|
187
|
-
else {
|
|
188
|
-
|
|
189
|
-
logger.error(`${this.id} does not have a title`);
|
|
190
|
-
}
|
|
162
|
+
else if (verbose) {
|
|
163
|
+
logger.error(`${this.id} does not have a title`);
|
|
191
164
|
}
|
|
192
165
|
// This is the known 'default' description - on previous version this content was repeated on descriptions processed by "descs"
|
|
193
166
|
if (this.desc) {
|
|
194
167
|
result += ` desc ${(0, global_1.escapeQuotes)(this.desc)}\n`;
|
|
195
168
|
}
|
|
196
|
-
else {
|
|
197
|
-
|
|
198
|
-
logger.error(`${this.id} does not have a desc`);
|
|
199
|
-
}
|
|
169
|
+
else if (verbose) {
|
|
170
|
+
logger.error(`${this.id} does not have a desc`);
|
|
200
171
|
}
|
|
201
172
|
if (this.descs) {
|
|
202
|
-
Object.entries(this.descs)
|
|
173
|
+
for (const [key, subDesc] of Object.entries(this.descs)) {
|
|
203
174
|
if (subDesc) {
|
|
204
175
|
if (key.match('default') && this.desc) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
logger.error(`${this.id} has a subdescription called "default" with contents that do not match the main description. "Default" should not be used as a keyword for unique sub-descriptions.`);
|
|
211
|
-
}
|
|
176
|
+
// The "default" keyword may have the same content as the desc content for backward compatibility with different historical InSpec versions.
|
|
177
|
+
// In that case, we can ignore writing the "default" subdescription field.
|
|
178
|
+
// If they are different, however, someone may be trying to use the keyword "default" for a unique subdescription, which should not be done.
|
|
179
|
+
if (subDesc != this.desc && verbose) {
|
|
180
|
+
logger.error(`${this.id} has a subdescription called "default" with contents that do not match the main description. "Default" should not be used as a keyword for unique sub-descriptions.`);
|
|
212
181
|
}
|
|
213
182
|
}
|
|
214
183
|
else {
|
|
215
184
|
result += ` desc '${key}', ${(0, global_1.escapeQuotes)(subDesc)}\n`;
|
|
216
185
|
}
|
|
217
186
|
}
|
|
218
|
-
else {
|
|
219
|
-
|
|
220
|
-
logger.warn(`${this.id} does not have a desc for the value ${key}`);
|
|
221
|
-
}
|
|
187
|
+
else if (verbose) {
|
|
188
|
+
logger.warn(`${this.id} does not have a desc for the value ${key}`);
|
|
222
189
|
}
|
|
223
|
-
}
|
|
190
|
+
}
|
|
224
191
|
}
|
|
225
192
|
if (this.impact !== undefined) {
|
|
226
193
|
result += ` impact ${(this.impact <= 0 ? this.impact.toFixed(1) : this.impact)}\n`;
|
|
227
194
|
}
|
|
228
|
-
else {
|
|
229
|
-
|
|
230
|
-
logger.error(`${this.id} does not have an impact`);
|
|
231
|
-
}
|
|
195
|
+
else if (verbose) {
|
|
196
|
+
logger.error(`${this.id} does not have an impact`);
|
|
232
197
|
}
|
|
233
|
-
|
|
198
|
+
// -------------------------------------------------------------------------
|
|
234
199
|
// This may not be necessary, leaving commented code for posterity. Once we
|
|
235
200
|
// have implemented the process and determined that there isn't any side
|
|
236
201
|
// effects we can remove the commented code
|
|
237
|
-
|
|
202
|
+
// -------------------------------------------------------------------------
|
|
238
203
|
// if (this.refs) {
|
|
239
204
|
// this.refs.forEach((ref) => {
|
|
240
205
|
// if (typeof ref === 'string') {
|
|
@@ -244,25 +209,25 @@ class Control {
|
|
|
244
209
|
// }
|
|
245
210
|
// });
|
|
246
211
|
// }
|
|
247
|
-
Object.entries(this.tags)
|
|
212
|
+
for (const [tag, value] of Object.entries(this.tags)) {
|
|
248
213
|
if (value) {
|
|
249
214
|
if (typeof value === 'object') {
|
|
250
215
|
if (Array.isArray(value) && typeof value[0] === 'string') {
|
|
251
216
|
// The goal is to keep the style similar to cookstyle formatting
|
|
252
217
|
result += ` tag ${tag}: ${JSON.stringify(value)
|
|
253
|
-
.
|
|
218
|
+
.replaceAll('"', "'") // replace the double quotes with single quotes, ex: ["V-72029","SV-86653"] -> ['V-72029','SV-86653']
|
|
254
219
|
.split("','") // split the items in the string
|
|
255
220
|
.join("', '")}\n`; // join them together using single quote and a space, ex: ['V-72029','SV-86653'] -> ['V-72029', 'SV-86653']
|
|
256
221
|
}
|
|
257
222
|
else {
|
|
258
223
|
// Convert JSON Object to Ruby Hash
|
|
259
224
|
const stringifiedObject = JSON.stringify(value, null, 2)
|
|
260
|
-
.
|
|
261
|
-
.
|
|
262
|
-
.
|
|
263
|
-
.
|
|
264
|
-
.
|
|
265
|
-
.
|
|
225
|
+
.replaceAll('\n', '\n ')
|
|
226
|
+
.replaceAll(/\{\n {6}/g, '{')
|
|
227
|
+
.replaceAll(/\[\n {8}/g, '[')
|
|
228
|
+
.replaceAll(/\n {6}\]/g, ']')
|
|
229
|
+
.replaceAll(/\n {4}\}/g, '}')
|
|
230
|
+
.replaceAll('": [', '" => [');
|
|
266
231
|
result += ` tag ${tag}: ${stringifiedObject}\n`;
|
|
267
232
|
}
|
|
268
233
|
}
|
|
@@ -272,17 +237,12 @@ class Control {
|
|
|
272
237
|
}
|
|
273
238
|
else {
|
|
274
239
|
const nilTagList = ['severity', 'satisfies'];
|
|
275
|
-
|
|
276
|
-
result += ` tag ${tag}: nil\n`;
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
result += ` tag '${tag}'\n`;
|
|
280
|
-
}
|
|
240
|
+
result += nilTagList.includes(tag) ? ` tag ${tag}: nil\n` : ` tag '${tag}'\n`;
|
|
281
241
|
if (verbose) {
|
|
282
242
|
logger.info(`${this.id} does not have a value for tag: ${tag}`);
|
|
283
243
|
}
|
|
284
244
|
}
|
|
285
|
-
}
|
|
245
|
+
}
|
|
286
246
|
if (this.describe) {
|
|
287
247
|
result += '\n';
|
|
288
248
|
result += this.describe;
|
package/lib/objects/profile.js
CHANGED
|
@@ -53,9 +53,9 @@ class Profile {
|
|
|
53
53
|
this.files = [];
|
|
54
54
|
this.controls = [];
|
|
55
55
|
if (data) {
|
|
56
|
-
|
|
56
|
+
for (const [key, value] of Object.entries(data)) {
|
|
57
57
|
lodash_1.default.set(this, key, value);
|
|
58
|
-
}
|
|
58
|
+
}
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
@@ -79,7 +79,7 @@ class Profile {
|
|
|
79
79
|
version: this.version,
|
|
80
80
|
supports: this.supports,
|
|
81
81
|
depends: this.depends,
|
|
82
|
-
//inspec_version: this.inspec_version,
|
|
82
|
+
// inspec_version: this.inspec_version,
|
|
83
83
|
inspec_version: yaml_1.default.stringify(`${this.inspec_version}`, { defaultStringType: 'QUOTE_DOUBLE' }),
|
|
84
84
|
});
|
|
85
85
|
}
|
|
@@ -95,12 +95,12 @@ class Profile {
|
|
|
95
95
|
*/
|
|
96
96
|
toUnformattedObject() {
|
|
97
97
|
const unformattedProfile = new Profile(this);
|
|
98
|
-
|
|
98
|
+
for (const [key, value] of Object.entries(this)) {
|
|
99
99
|
if (typeof value === 'string') {
|
|
100
100
|
lodash_1.default.set(unformattedProfile, key, (0, global_1.unformatText)(value));
|
|
101
101
|
}
|
|
102
|
-
}
|
|
103
|
-
unformattedProfile.controls = this.controls.map(
|
|
102
|
+
}
|
|
103
|
+
unformattedProfile.controls = this.controls.map(control => control.toUnformattedObject());
|
|
104
104
|
return unformattedProfile;
|
|
105
105
|
}
|
|
106
106
|
}
|
package/lib/parsers/json.js
CHANGED
|
@@ -29,7 +29,7 @@ function processEvaluation(evaluationInput) {
|
|
|
29
29
|
description: lodash_1.default.get(topLevelProfile.data, 'description'),
|
|
30
30
|
version: topLevelProfile.data.version,
|
|
31
31
|
});
|
|
32
|
-
topLevelProfile.contains
|
|
32
|
+
for (const control of topLevelProfile.contains) {
|
|
33
33
|
profile.controls.push(new control_1.default({
|
|
34
34
|
id: control.data.id,
|
|
35
35
|
title: control.data.title,
|
|
@@ -38,7 +38,7 @@ function processEvaluation(evaluationInput) {
|
|
|
38
38
|
descs: (0, control_1.objectifyDescriptions)(control.hdf.wraps.descriptions),
|
|
39
39
|
tags: control.hdf.wraps.tags,
|
|
40
40
|
}));
|
|
41
|
-
}
|
|
41
|
+
}
|
|
42
42
|
return profile;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
@@ -59,7 +59,7 @@ function processProfileJSON(profileInput) {
|
|
|
59
59
|
description: lodash_1.default.get(profileInput.data, 'description'),
|
|
60
60
|
version: profileInput.data.version,
|
|
61
61
|
});
|
|
62
|
-
profileInput.data.controls
|
|
62
|
+
for (const control of profileInput.data.controls) {
|
|
63
63
|
const newControl = new control_1.default({
|
|
64
64
|
id: control.id,
|
|
65
65
|
title: control.title,
|
|
@@ -72,17 +72,15 @@ function processProfileJSON(profileInput) {
|
|
|
72
72
|
newControl.describe = (0, update_1.getExistingDescribeFromControl)(newControl);
|
|
73
73
|
// Migrate check and fix text from tags to descriptions
|
|
74
74
|
if (newControl.tags.check && !newControl.descs.check) {
|
|
75
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
76
75
|
lodash_1.default.set(newControl.descs, 'check', control.tags.check);
|
|
77
76
|
lodash_1.default.set(newControl.tags, 'check', undefined);
|
|
78
77
|
}
|
|
79
78
|
if (newControl.tags.fix && !newControl.descs.fix) {
|
|
80
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
81
79
|
lodash_1.default.set(newControl.descs, 'fix', control.tags.fix);
|
|
82
80
|
lodash_1.default.set(newControl.tags, 'fix', undefined);
|
|
83
81
|
}
|
|
84
82
|
profile.controls.push(newControl);
|
|
85
|
-
}
|
|
83
|
+
}
|
|
86
84
|
return profile;
|
|
87
85
|
}
|
|
88
86
|
/**
|
|
@@ -110,7 +108,7 @@ function processExecJSON(execJSON) {
|
|
|
110
108
|
*/
|
|
111
109
|
function processInSpecProfile(json) {
|
|
112
110
|
const convertedFile = (0, inspecjs_1.convertFile)(json, true);
|
|
113
|
-
let profile
|
|
111
|
+
let profile;
|
|
114
112
|
if (convertedFile['1_0_ExecJson']) {
|
|
115
113
|
profile = processEvaluation((0, inspecjs_1.contextualizeEvaluation)(convertedFile['1_0_ExecJson'])).toUnformattedObject();
|
|
116
114
|
}
|