securenow 8.7.0 → 8.8.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/cli/security.js +49 -0
- package/cli.js +865 -865
- package/package.json +193 -193
package/cli/security.js
CHANGED
|
@@ -51,6 +51,9 @@ async function alertRulesRoute(args, flags) {
|
|
|
51
51
|
if (sub === 'delete' || sub === 'rm' || sub === 'remove') {
|
|
52
52
|
return alertRuleDelete(args.slice(1), flags);
|
|
53
53
|
}
|
|
54
|
+
if (sub === 'duplicate' || sub === 'clone') {
|
|
55
|
+
return alertRuleDuplicate(args.slice(1), flags);
|
|
56
|
+
}
|
|
54
57
|
if (sub === 'test') {
|
|
55
58
|
return alertRuleTest(args.slice(1), flags);
|
|
56
59
|
}
|
|
@@ -111,6 +114,52 @@ async function alertRuleSetMode(args, flags, mode) {
|
|
|
111
114
|
else ui.info('Detect-only — no mitigation will act. Promote when confident: securenow alerts rules promote <id>');
|
|
112
115
|
}
|
|
113
116
|
|
|
117
|
+
// Duplicate any rule (including a read-only system template) into a new CUSTOM rule you
|
|
118
|
+
// own. System rules are view-only examples — fork one with this to enable / edit it. The
|
|
119
|
+
// copy defaults to Disabled (opt in with --enable / --status active); SQL, instant.block,
|
|
120
|
+
// schedule, scope, and mode are copied from the source.
|
|
121
|
+
async function alertRuleDuplicate(args, flags) {
|
|
122
|
+
requireAuth();
|
|
123
|
+
const id = args[0];
|
|
124
|
+
if (!id) {
|
|
125
|
+
ui.error('Usage: securenow alerts rules duplicate <rule-id> [--enable] [--status active|disabled|paused] [--name "..."] [--mode test|prod]');
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
const body = {};
|
|
129
|
+
if (flags.enable) body.status = 'Active';
|
|
130
|
+
else if (flags.disable) body.status = 'Disabled';
|
|
131
|
+
else if (flags.pause) body.status = 'Paused';
|
|
132
|
+
else if (flags.status) {
|
|
133
|
+
const s = String(flags.status).toLowerCase();
|
|
134
|
+
body.status = s === 'active' ? 'Active' : s === 'paused' ? 'Paused' : 'Disabled';
|
|
135
|
+
}
|
|
136
|
+
if (flags.name) body.name = String(flags.name);
|
|
137
|
+
if (flags.mode === 'test' || flags.mode === 'prod') body.mode = flags.mode;
|
|
138
|
+
|
|
139
|
+
const spin = ui.spinner(`Duplicating ${ui.truncate(id, 12)}`);
|
|
140
|
+
let data;
|
|
141
|
+
try {
|
|
142
|
+
data = await api.post(`/alert-rules/${id}/duplicate`, body);
|
|
143
|
+
spin.stop('Duplicated');
|
|
144
|
+
} catch (err) {
|
|
145
|
+
spin.fail(`Failed to duplicate: ${err.message}`);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (flags.json) { ui.json(data); return; }
|
|
150
|
+
const r = data.alertRule || {};
|
|
151
|
+
const newId = r.id || r._id || '';
|
|
152
|
+
console.log('');
|
|
153
|
+
ui.success(`Created custom rule ${newId}`);
|
|
154
|
+
console.log(` Name ${r.name || ''}`);
|
|
155
|
+
console.log(` Status ${r.status || ''}`);
|
|
156
|
+
console.log(` Mode ${r.mode || ''}`);
|
|
157
|
+
console.log(` Exec mode ${r.executionMode || ''}`);
|
|
158
|
+
console.log(` Custom ${r.isSystem ? 'NO — still a system rule (unexpected)' : 'yes (editable / enable-able)'}`);
|
|
159
|
+
if (data.duplicatedFromSystem) ui.info('Forked from a read-only system template — edit or enable this custom copy freely.');
|
|
160
|
+
if (r.status !== 'Active') ui.info(`Disabled by default. Enable with: securenow alerts rules update ${newId} --enable`);
|
|
161
|
+
}
|
|
162
|
+
|
|
114
163
|
async function alertRulesList(args, flags) {
|
|
115
164
|
requireAuth();
|
|
116
165
|
// Server-side filters (API supports ?mode/status/active/isSystem).
|