Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "lc-detectionforge",
"description": "A comprehensive detection engineering environment for crafting, validating, and testing LimaCharlie detection rules",
"version": "1.3.0",
"version": "1.4.0",
"private": true,
"type": "module",
"license": "AGPL-3.0-or-later",
Expand Down
48 changes: 48 additions & 0 deletions src/components/Config.vue
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,36 @@
</div>
</div>

<!-- Application Settings Section -->
<div class="config-section">
<h3>Application Settings</h3>

<div class="info-text">
Configure application behavior and preferences. These settings are saved locally and
persist between sessions.
</div>

<div class="settings-group" style="margin-bottom: var(--space-2xl)">
<h4>Import Settings</h4>
<div class="setting-item">
<label class="checkbox-label">
<input v-model="autoOpenFirstImportedRule" type="checkbox" />
Automatically open first imported rule
</label>
</div>
</div>

<div class="settings-group">
<h4>Export Settings</h4>
<div class="setting-item">
<label class="checkbox-label">
<input v-model="includeIaCBoilerplate" type="checkbox" />
Include header text in IaC export
</label>
</div>
</div>
</div>

<div class="footer">
<p>
Made with <span class="heart">💙</span> by
Expand Down Expand Up @@ -463,6 +493,14 @@ const isAddingOrg = ref(false)
const isFetchingMissingUrls = ref(false)
const isTestingApi = ref(false)

// Application settings
const includeIaCBoilerplate = ref(
localStorage.getItem('detectionforge_include_iac_boilerplate') !== 'false',
)
const autoOpenFirstImportedRule = ref(
localStorage.getItem('detectionforge_auto_open_top_rule') === 'true',
)

// Bulk import state
const showBulkImportDialog = ref(false)
const bulkOidInput = ref('')
Expand Down Expand Up @@ -1303,6 +1341,16 @@ watch([hasCredentials, organizations], async () => {
}
})

// Watch for IaC boilerplate checkbox changes to persist state
watch(includeIaCBoilerplate, (newValue) => {
localStorage.setItem('detectionforge_include_iac_boilerplate', newValue.toString())
})

// Watch for auto-open first imported rule checkbox changes to persist state
watch(autoOpenFirstImportedRule, (newValue) => {
localStorage.setItem('detectionforge_auto_open_top_rule', newValue.toString())
})

// Initialize on mount
onMounted(async () => {
loadSavedCredentials()
Expand Down
27 changes: 9 additions & 18 deletions src/components/Rules.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1423,13 +1423,6 @@ hives:
></textarea>
</div>

<div class="import-options">
<label class="checkbox-wrapper">
<input v-model="autoOpenTopRule" type="checkbox" :disabled="isImportingIaC" />
<span class="checkbox-label">Automatically open first imported rule</span>
</label>
</div>

<div class="import-actions">
<button
type="submit"
Expand Down Expand Up @@ -1643,9 +1636,6 @@ const iacImportResult = ref<{
importedRules: Array<{ name: string; success: boolean; error?: string }>
} | null>(null)

// Auto-open top rule checkbox state (persistent)
const autoOpenTopRule = ref(localStorage.getItem('detectionforge_auto_open_top_rule') === 'true')

// Event Schemas functionality
const selectedEventType = ref('')
const selectedPrefix = ref('evt') // Default to 'evt' prefix
Expand Down Expand Up @@ -2966,12 +2956,18 @@ function exportToIaC() {
}

// Create proper LimaCharlie IaC YAML format
const iacContent = `# LimaCharlie Detection Rule - Infrastructure as Code
const includeBoilerplate =
localStorage.getItem('detectionforge_include_iac_boilerplate') !== 'false'
const headerComments = includeBoilerplate
? `# LimaCharlie Detection Rule - Infrastructure as Code
# Generated by DetectionForge
# Generated on: ${new Date().toISOString()}
# Rule: ${currentRule.name}

version: 3
`
: ''

const iacContent = `${headerComments}version: 3
hives:
dr-general:
"${currentRule.name}":
Expand Down Expand Up @@ -4886,7 +4882,7 @@ async function importFromIaC() {
)

// Auto-open the first successfully imported rule if checkbox is checked
if (autoOpenTopRule.value) {
if (localStorage.getItem('detectionforge_auto_open_top_rule') === 'true') {
const firstSuccessfulImport = importedRules.find((rule) => rule.success)
if (firstSuccessfulImport) {
// Find the rule ID by name from the saved rules
Expand Down Expand Up @@ -4926,9 +4922,4 @@ async function importFromIaC() {
watch(selectedPrefix, () => {
onPrefixChange()
})

// Watch for auto-open checkbox changes to persist state
watch(autoOpenTopRule, (newValue) => {
localStorage.setItem('detectionforge_auto_open_top_rule', newValue.toString())
})
</script>
13 changes: 13 additions & 0 deletions src/utils/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ export interface ChangelogEntry {
}

export const CHANGELOG: ChangelogEntry[] = [
{
version: '1.4.0',
date: '2025-07-02',
changes: {
added: [
'Application Settings - Configuration section for preferences',
'IaC Header Text Preferences - "Include header text in IaC export" checkbox under Appication Settings',
],
changed: [
'Moved "Automatically open first imported rule" preferences checkbox to Application Settings',
],
},
},
{
version: '1.3.0',
date: '2025-06-27',
Expand Down