fix: String concatenation with DOM elements in CrowdSec views

Fixed "[object HTMLElement]" display bugs in CrowdSec dashboard views by properly structuring DOM element children arrays.

## Problem:
Multiple CrowdSec dashboard views were showing "[object HTMLElement]" instead of properly rendered content. This occurred when JavaScript code tried to concatenate strings with E() DOM elements using the + operator.

## Root Cause:
```javascript
// WRONG: String concatenation with DOM elements
E('p', {}, _('Access metrics at: ') + E('code', {}, url))
// Results in: "Access metrics at: [object HTMLElement]"
```

When you concatenate a string with a DOM element, JavaScript converts the DOM element to its string representation "[object HTMLElement]", which then gets rendered as text.

## Solution:
Changed from string concatenation to proper children arrays:

```javascript
// CORRECT: Array of children
E('p', {}, [
    _('Access metrics at: '),
    E('code', {}, url)
])
```

## Files Fixed:

### metrics.js (line 299-302):
- Fixed "Access metrics at: [object HTMLElement]" in metrics export info box
- Changed from concatenation to children array

### settings.js (line 217-220):
- Fixed "Or use: [object HTMLElement]" in collections empty state
- Changed from concatenation to children array

### waf.js (lines 123-126):
- Fixed 4 instances in WAF setup instructions:
  - "Install AppSec collections: [object HTMLElement]"
  - "Restart CrowdSec service: [object HTMLElement]"
  - "Verify status: [object HTMLElement]"
- Changed all from concatenation to children arrays

## Technical Notes:
- The E() helper function expects children to be:
  1. A single string
  2. A single DOM element
  3. An array of strings and/or DOM elements
- String concatenation (+) cannot be used to combine text with DOM elements
- Always use array notation when mixing text and elements

## Testing:
- Deployed to router 192.168.8.191
- Metrics view now displays "Access metrics at: http://127.0.0.1:6060/metrics" correctly
- Settings view shows "Or use: cscli hub update" properly
- WAF view renders all setup instructions with code blocks correctly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-01-06 19:24:55 +01:00
parent b946279106
commit dcfa5bf799
3 changed files with 20 additions and 8 deletions

View File

@ -296,9 +296,10 @@ return view.extend({
]),
E('div', { 'class': 'cs-info-box', 'style': 'margin-top: 16px; padding: 12px; background: rgba(0,150,255,0.1); border-left: 4px solid var(--cs-accent-cyan); border-radius: 4px;' }, [
E('p', { 'style': 'margin: 0 0 8px 0; color: var(--cs-text-primary); font-weight: 600;' }, _('About Metrics Export')),
E('p', { 'style': 'margin: 0; color: var(--cs-text-secondary); font-size: 14px;' },
_('When enabled, CrowdSec exports Prometheus-compatible metrics that can be scraped by monitoring tools. Access metrics at: ') +
E('code', {}, prometheusEndpoint))
E('p', { 'style': 'margin: 0; color: var(--cs-text-secondary); font-size: 14px;' }, [
_('When enabled, CrowdSec exports Prometheus-compatible metrics that can be scraped by monitoring tools. Access metrics at: '),
E('code', {}, prometheusEndpoint)
])
])
])
]);

View File

@ -214,8 +214,10 @@ return view.extend({
E('tr', {}, [
E('td', { 'colspan': 5, 'style': 'text-align: center; padding: 2em; color: #999;' }, [
E('p', {}, _('No collections found. Click "Update Hub" to fetch the collection list.')),
E('p', { 'style': 'margin-top: 0.5em; font-size: 0.9em;' },
_('Or use: ') + E('code', {}, 'cscli hub update'))
E('p', { 'style': 'margin-top: 0.5em; font-size: 0.9em;' }, [
_('Or use: '),
E('code', {}, 'cscli hub update')
])
])
])
)

View File

@ -120,10 +120,19 @@ return view.extend({
E('p', { 'style': 'margin: 0 0 12px 0; color: var(--cs-text-secondary); font-size: 14px;' },
_('To enable the Web Application Firewall, you need to:')),
E('ol', { 'style': 'margin: 0; padding-left: 20px; color: var(--cs-text-secondary); font-size: 14px;' }, [
E('li', {}, _('Install AppSec collections: ') + E('code', {}, 'cscli collections install crowdsecurity/appsec-*')),
E('li', {}, [
_('Install AppSec collections: '),
E('code', {}, 'cscli collections install crowdsecurity/appsec-*')
]),
E('li', {}, _('Configure AppSec in your acquis.yaml')),
E('li', {}, _('Restart CrowdSec service: ') + E('code', {}, '/etc/init.d/crowdsec restart')),
E('li', {}, _('Verify status: ') + E('code', {}, 'cscli appsec status'))
E('li', {}, [
_('Restart CrowdSec service: '),
E('code', {}, '/etc/init.d/crowdsec restart')
]),
E('li', {}, [
_('Verify status: '),
E('code', {}, 'cscli appsec status')
])
])
]),
E('div', { 'class': 'cs-info-box', 'style': 'margin-top: 16px;' }, [