build-firewall-plugin 0.0.7 → 0.0.8
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/build/index.d.ts +7 -0
- package/build/index.js +63 -15
- package/package.json +1 -1
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { Compiler, RspackPluginInstance } from "@rspack/core";
|
|
2
|
+
/**
|
|
3
|
+
* @type for plugin input options
|
|
4
|
+
*/
|
|
2
5
|
type Options = {
|
|
3
6
|
/**
|
|
4
7
|
* Path to your JSON file with project rules
|
|
@@ -27,6 +30,10 @@ type Options = {
|
|
|
27
30
|
* node_modules, assets, images, types, intefaces, styles file and directories
|
|
28
31
|
*/
|
|
29
32
|
exceptions?: string[];
|
|
33
|
+
/**
|
|
34
|
+
* type of output
|
|
35
|
+
*/
|
|
36
|
+
outputType?: 'default' | 'object';
|
|
30
37
|
};
|
|
31
38
|
export declare class BuildFirewallPlugin implements RspackPluginInstance {
|
|
32
39
|
private readonly config;
|
package/build/index.js
CHANGED
|
@@ -50,7 +50,7 @@ const isValidSchema = (value) => {
|
|
|
50
50
|
&& Array.isArray(layer.allow) && Array.isArray(layer.deny)));
|
|
51
51
|
};
|
|
52
52
|
/**
|
|
53
|
-
* @function resolveLayer
|
|
53
|
+
* @function resolveLayer normilizes module resource
|
|
54
54
|
*/
|
|
55
55
|
function resolveLayer(resource, layers) {
|
|
56
56
|
const normalized = resource.replace(/\\/g, '/');
|
|
@@ -61,6 +61,26 @@ function resolveLayer(resource, layers) {
|
|
|
61
61
|
}
|
|
62
62
|
return null;
|
|
63
63
|
}
|
|
64
|
+
;
|
|
65
|
+
/**
|
|
66
|
+
* @function prepareOutput is for object type output
|
|
67
|
+
*/
|
|
68
|
+
function prepareOutput(params) {
|
|
69
|
+
const { total, modules, warnings, layers } = params;
|
|
70
|
+
return {
|
|
71
|
+
plugin: 'Build Firewall Plugin',
|
|
72
|
+
message_type: 'output',
|
|
73
|
+
hooks: ['thisCompilation', 'finishModules'],
|
|
74
|
+
warnings: params.warnings,
|
|
75
|
+
modules_checked: params.modules,
|
|
76
|
+
total_modules: params.total,
|
|
77
|
+
layers: {
|
|
78
|
+
amount: params.layers.amount,
|
|
79
|
+
kind: params.layers.items,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
;
|
|
64
84
|
class BuildFirewallPlugin {
|
|
65
85
|
constructor(options) {
|
|
66
86
|
this.config = {
|
|
@@ -69,6 +89,7 @@ class BuildFirewallPlugin {
|
|
|
69
89
|
report: false,
|
|
70
90
|
generateFile: false,
|
|
71
91
|
mode: template.mode,
|
|
92
|
+
outputType: 'default',
|
|
72
93
|
layers: template.layers,
|
|
73
94
|
name: 'build-firewall-plugin.rules.json',
|
|
74
95
|
};
|
|
@@ -80,17 +101,18 @@ class BuildFirewallPlugin {
|
|
|
80
101
|
this.shouldRunAgain = false;
|
|
81
102
|
compiler.hooks.thisCompilation.tap('BuildFirewallPluginThisCompilation', (compilation) => {
|
|
82
103
|
compilation.hooks.finishModules.tap('BuildFirewallPluginThisCompilationFinishModules', (modules) => {
|
|
104
|
+
console.log('[Build Firewall Plugin] Starting... \n');
|
|
83
105
|
/**
|
|
84
106
|
* Creating or Validating a rules file
|
|
85
107
|
*/
|
|
108
|
+
const pathToFile = path_1.default.resolve(compiler.context, this.config.name);
|
|
86
109
|
if (!this.config.path) {
|
|
87
110
|
try {
|
|
88
|
-
const pathToFile = path_1.default.resolve(compiler.context, this.config.name);
|
|
89
111
|
fs_1.default.writeFileSync(pathToFile, JSON.stringify(template));
|
|
90
112
|
this.shouldRunAgain = true;
|
|
91
113
|
this.config.path = pathToFile;
|
|
92
|
-
console.log(`[Build Firewall Plugin] Created a template of ${this.config.name} file successfully`);
|
|
93
|
-
console.log(`[Build Firewall Plugin] Check and edit a ${this.config.name} file if it is not passing for your project`);
|
|
114
|
+
console.log(`[Build Firewall Plugin] Created a template of ${this.config.name} file successfully \n`);
|
|
115
|
+
console.log(`[Build Firewall Plugin] Check and edit a ${this.config.name} file if it is not passing for your project \n`);
|
|
94
116
|
}
|
|
95
117
|
catch (e) {
|
|
96
118
|
console.error(`[Build Firewall Plugin] Could not create a rules file: \n ${e}`);
|
|
@@ -100,24 +122,23 @@ class BuildFirewallPlugin {
|
|
|
100
122
|
}
|
|
101
123
|
else {
|
|
102
124
|
try {
|
|
103
|
-
const pathToFile = path_1.default.resolve(compiler.context, this.config.name);
|
|
104
125
|
const rawFile = fs_1.default.readFileSync(pathToFile).toString();
|
|
105
126
|
const extention = path_1.default.extname(pathToFile);
|
|
106
127
|
const isJSON = extention.endsWith('.json');
|
|
107
128
|
if (!isJSON) {
|
|
108
|
-
console.error(`[Build Firewall Plugin] Your ${this.config.name} file is not a JSON`);
|
|
129
|
+
console.error(`[Build Firewall Plugin] Your ${this.config.name} file is not a JSON \n`);
|
|
109
130
|
return;
|
|
110
131
|
}
|
|
111
132
|
;
|
|
112
133
|
if (rawFile.length < 0) {
|
|
113
|
-
console.error(`[Build Firewall Plugin] Your ${this.config.name} file is empty`);
|
|
134
|
+
console.error(`[Build Firewall Plugin] Your ${this.config.name} file is empty \n`);
|
|
114
135
|
return;
|
|
115
136
|
}
|
|
116
137
|
;
|
|
117
138
|
const parsedFile = JSON.parse(rawFile);
|
|
118
139
|
const isObject = typeof parsedFile === 'object';
|
|
119
140
|
if (!isObject) {
|
|
120
|
-
console.error(`[Build Firewall Plugin] Your ${this.config.name} file value is not an object`);
|
|
141
|
+
console.error(`[Build Firewall Plugin] Your ${this.config.name} file value is not an object \n`);
|
|
121
142
|
return;
|
|
122
143
|
}
|
|
123
144
|
;
|
|
@@ -130,16 +151,16 @@ class BuildFirewallPlugin {
|
|
|
130
151
|
mode: 'warn'
|
|
131
152
|
}
|
|
132
153
|
}
|
|
133
|
-
`);
|
|
154
|
+
\n`);
|
|
134
155
|
return;
|
|
135
156
|
}
|
|
136
157
|
;
|
|
137
158
|
this.config.layers = parsedFile.layers;
|
|
138
159
|
this.config.mode = parsedFile.mode || 'warn';
|
|
139
|
-
console.log(`Your ${this.config.name} file is valid
|
|
160
|
+
console.log(`[Build Firewall Plugin] Your ${this.config.name} file is valid! \n`);
|
|
140
161
|
}
|
|
141
162
|
catch (e) {
|
|
142
|
-
console.error(`[Build Firewall Plugin] Error while validating your ${this.config.name} file \n ${e}`);
|
|
163
|
+
console.error(`[Build Firewall Plugin] Error while validating your ${this.config.name} file \n ${e} \n`);
|
|
143
164
|
return;
|
|
144
165
|
}
|
|
145
166
|
;
|
|
@@ -150,6 +171,10 @@ class BuildFirewallPlugin {
|
|
|
150
171
|
/**
|
|
151
172
|
* plugin logic
|
|
152
173
|
*/
|
|
174
|
+
let checkedModules = 0;
|
|
175
|
+
let warningsAmount = 0;
|
|
176
|
+
let totalModules = Array.from(modules).length;
|
|
177
|
+
const outputLayers = Object.keys(this.config.layers);
|
|
153
178
|
for (const module of modules) {
|
|
154
179
|
const fromResource = module.nameForCondition();
|
|
155
180
|
if (!fromResource)
|
|
@@ -157,11 +182,16 @@ class BuildFirewallPlugin {
|
|
|
157
182
|
const fromLayer = resolveLayer(fromResource, this.config.layers);
|
|
158
183
|
if (!fromLayer)
|
|
159
184
|
continue;
|
|
185
|
+
const seen = new Set();
|
|
160
186
|
for (const dependency of module.dependencies) {
|
|
161
187
|
const toModule = compilation.moduleGraph.getModule(dependency);
|
|
162
188
|
const toModuleResource = toModule === null || toModule === void 0 ? void 0 : toModule.nameForCondition();
|
|
163
189
|
if (!toModuleResource)
|
|
164
190
|
continue;
|
|
191
|
+
const moduleKey = `${fromResource}::${toModuleResource}`;
|
|
192
|
+
const hasLogged = seen.has(moduleKey);
|
|
193
|
+
if (hasLogged)
|
|
194
|
+
continue;
|
|
165
195
|
const isException = this.config.exceptions.some(e => toModuleResource.includes(e));
|
|
166
196
|
if (isException) {
|
|
167
197
|
continue;
|
|
@@ -176,13 +206,31 @@ class BuildFirewallPlugin {
|
|
|
176
206
|
const rules = this.config.layers[fromLayer];
|
|
177
207
|
if (!rules)
|
|
178
208
|
continue;
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
209
|
+
const isDenied = rules.deny.includes(toLayer);
|
|
210
|
+
const hasAllow = rules.allow.length > 0;
|
|
211
|
+
const isAllowed = !hasAllow || rules.allow.includes(toLayer);
|
|
212
|
+
checkedModules++;
|
|
213
|
+
if (isDenied || !isAllowed) {
|
|
214
|
+
seen.add(moduleKey);
|
|
215
|
+
warningsAmount++;
|
|
216
|
+
if (this.config.outputType === 'default') {
|
|
217
|
+
console.log(`\n [Build Firewall Plugin] Module ${toModuleResource} is not allowed to import in ${fromResource} \n`);
|
|
218
|
+
}
|
|
183
219
|
}
|
|
184
220
|
}
|
|
185
221
|
}
|
|
222
|
+
if (this.config.outputType === 'object') {
|
|
223
|
+
const output = prepareOutput({
|
|
224
|
+
total: totalModules,
|
|
225
|
+
modules: checkedModules,
|
|
226
|
+
warnings: warningsAmount,
|
|
227
|
+
layers: {
|
|
228
|
+
items: outputLayers,
|
|
229
|
+
amount: outputLayers.length,
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
console.log(JSON.stringify(output, null, 2));
|
|
233
|
+
}
|
|
186
234
|
});
|
|
187
235
|
});
|
|
188
236
|
}
|