diff --git a/.dockerignore b/.dockerignore
index 19ab8eca..3eeeaf50 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -57,9 +57,11 @@ package.json
# -----------------------------------------------------------------------------
backend/bin/
backend/api
+backend/main
backend/*.out
backend/*.cover
backend/*.html
+backend/*.test
backend/coverage/
backend/coverage*.out
backend/coverage*.txt
@@ -68,11 +70,17 @@ backend/handler_coverage.txt
backend/handlers.out
backend/services.test
backend/test-output.txt
+backend/test-output*.txt
+backend/test_output*.txt
backend/tr_no_cover.txt
backend/nohup.out
backend/package.json
backend/package-lock.json
+backend/node_modules/
backend/internal/api/tests/data/
+backend/lint*.txt
+backend/fix_*.sh
+backend/codeql-db-*/
# Backend data (created at runtime)
backend/data/
@@ -186,21 +194,51 @@ codeql-results*.sarif
# -----------------------------------------------------------------------------
import/
+# -----------------------------------------------------------------------------
+# Playwright & E2E Testing
+# -----------------------------------------------------------------------------
+playwright/
+playwright-report/
+blob-report/
+test-results/
+tests/
+test-data/
+playwright.config.js
+
+# -----------------------------------------------------------------------------
+# Root-level artifacts
+# -----------------------------------------------------------------------------
+coverage/
+coverage.txt
+provenance*.json
+trivy-*.txt
+grype-results*.json
+grype-results*.sarif
+my-codeql-db/
+
# -----------------------------------------------------------------------------
# Project Documentation & Planning (not needed in image)
# -----------------------------------------------------------------------------
*.md.bak
ACME_STAGING_IMPLEMENTATION.md*
ARCHITECTURE_PLAN.md
+AUTO_VERSIONING_CI_FIX_SUMMARY.md
BULK_ACL_FEATURE.md
+CODEQL_EMAIL_INJECTION_REMEDIATION_COMPLETE.md
+COMMIT_MSG.txt
+COVERAGE_ANALYSIS.md
+COVERAGE_REPORT.md
DOCKER_TASKS.md*
DOCUMENTATION_POLISH_SUMMARY.md
GHCR_MIGRATION_SUMMARY.md
ISSUE_*_IMPLEMENTATION.md*
+ISSUE_*.md
+PATCH_COVERAGE_IMPLEMENTATION_SUMMARY.md
PHASE_*_SUMMARY.md
PROJECT_BOARD_SETUP.md
PROJECT_PLANNING.md
SECURITY_IMPLEMENTATION_PLAN.md
+SECURITY_REMEDIATION_COMPLETE.md
VERSIONING_IMPLEMENTATION.md
QA_AUDIT_REPORT*.md
VERSION.md
diff --git a/.github/agents/prompt_template/bug_fix.md b/.github/agents/prompt_template/bug_fix.md
deleted file mode 100644
index aeaa9ed7..00000000
--- a/.github/agents/prompt_template/bug_fix.md
+++ /dev/null
@@ -1,11 +0,0 @@
-I am seeing bug [X].
-
-Do not propose a fix yet. First, run a Trace Analysis:
-
-List every file involved in this feature's workflow from Frontend Component -> API Handler -> Database.
-
-Read these files to understand the full data flow.
-
-Tell me if there is a logic gap between how the Frontend sends data and how the Backend expects it.
-
-Once you have mapped the flow, then propose the plan.
diff --git a/.gitignore b/.gitignore
index 3d57cfbc..deef2292 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,12 +61,21 @@ backend/handlers.out
backend/services.test
backend/*.test
backend/test-output.txt
+backend/test-output*.txt
+backend/test_output*.txt
backend/tr_no_cover.txt
backend/nohup.out
backend/charon
+backend/main
backend/codeql-db/
+backend/codeql-db-*/
backend/.venv/
backend/internal/api/tests/data/
+backend/lint*.txt
+backend/fix_*.sh
+backend/node_modules/
+backend/package.json
+backend/package-lock.json
# -----------------------------------------------------------------------------
# Databases
@@ -145,8 +154,10 @@ dist/
# -----------------------------------------------------------------------------
coverage/
coverage.out
+coverage.txt
*.xml
*.crdownload
+provenance*.json
# -----------------------------------------------------------------------------
# CodeQL & Security Scanning
@@ -160,6 +171,8 @@ codeql-*.sarif
*.sarif
.codeql/
.codeql/**
+my-codeql-db/
+codeql-linux64.zip
# -----------------------------------------------------------------------------
# Scripts & Temp Files (project-specific)
@@ -175,13 +188,21 @@ test.caddyfile
*.md.bak
ACME_STAGING_IMPLEMENTATION.md*
ARCHITECTURE_PLAN.md
+AUTO_VERSIONING_CI_FIX_SUMMARY.md
+CODEQL_EMAIL_INJECTION_REMEDIATION_COMPLETE.md
+COMMIT_MSG.txt
+COVERAGE_ANALYSIS.md
+COVERAGE_REPORT.md
DOCKER_TASKS.md*
DOCUMENTATION_POLISH_SUMMARY.md
GHCR_MIGRATION_SUMMARY.md
ISSUE_*_IMPLEMENTATION.md*
+ISSUE_*.md
+PATCH_COVERAGE_IMPLEMENTATION_SUMMARY.md
PHASE_*_SUMMARY.md
PROJECT_BOARD_SETUP.md
PROJECT_PLANNING.md
+SECURITY_REMEDIATION_COMPLETE.md
VERSIONING_IMPLEMENTATION.md
backend/internal/api/handlers/import_handler.go.bak
diff --git a/AUTO_VERSIONING_CI_FIX_SUMMARY.md b/AUTO_VERSIONING_CI_FIX_SUMMARY.md
deleted file mode 100644
index 35629230..00000000
--- a/AUTO_VERSIONING_CI_FIX_SUMMARY.md
+++ /dev/null
@@ -1,378 +0,0 @@
-# Auto-Versioning CI Fix Implementation Summary
-
-**Date:** January 15, 2026
-**Issue:** Repository rule violations preventing tag creation in CI (GH013 error)
-**Status:** ✅ COMPLETE
-
----
-
-## Changes Implemented
-
-### 1. Workflow File: `.github/workflows/auto-versioning.yml`
-
-**Backup Created:** `.github/workflows/auto-versioning.yml.backup`
-
-#### Change 1: Remove Unused Permission
-- **Removed:** `pull-requests: write` permission
-- **Rationale:** This permission is not used anywhere in the workflow
-- **Security:** Follows principle of least privilege
-
-**Before:**
-```yaml
-permissions:
- contents: write
- pull-requests: write
-```
-
-**After:**
-```yaml
-permissions:
- contents: write
-```
-
----
-
-#### Change 2: Enhanced Version Display
-- **Added:** Display of `changed` status in version output
-- **Rationale:** Better visibility for debugging and monitoring
-
-**Before:**
-```yaml
-- name: Show version
- run: |
- echo "Next version: ${{ steps.semver.outputs.version }}"
-```
-
-**After:**
-```yaml
-- name: Show version
- run: |
- echo "Next version: ${{ steps.semver.outputs.version }}"
- echo "Version changed: ${{ steps.semver.outputs.changed }}"
-```
-
----
-
-#### Change 3: Replace Git Push with API Approach
-- **Removed:** 30+ lines of git tag creation and push logic
-- **Added:** Simple tag name determination (8 lines)
-- **Rationale:** Bypasses repository rules by using GitHub Release API instead
-
-**Before (lines 50-80):**
-```yaml
-- id: create_tag
- name: Create annotated tag and push
- if: ${{ steps.semver.outputs.changed }}
- run: |
- git config --global user.email "actions@github.com"
- git config --global user.name "GitHub Actions"
- RAW="${{ steps.semver.outputs.version }}"
- VERSION_NO_V="${RAW#v}"
- TAG="v${VERSION_NO_V}"
- echo "TAG=${TAG}"
- if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then
- echo "Tag ${TAG} already exists; skipping tag creation"
- else
- git tag -a "${TAG}" -m "Release ${TAG}"
- git push origin "${TAG}" # ❌ BLOCKED BY REPOSITORY RULES
- fi
- echo "tag=${TAG}" >> $GITHUB_OUTPUT
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-```
-
-**After:**
-```yaml
-- name: Determine tag name
- id: determine_tag
- run: |
- # Normalize the version: remove any leading 'v'
- RAW="${{ steps.semver.outputs.version }}"
- VERSION_NO_V="${RAW#v}"
- TAG="v${VERSION_NO_V}"
- echo "Determined tag: $TAG"
- echo "tag=$TAG" >> $GITHUB_OUTPUT
-```
-
----
-
-#### Change 4: Remove Duplicate Tag Determination
-- **Removed:** Redundant "Determine tag" step (14 lines)
-- **Rationale:** Now handled by simplified logic in Change 3
-
-**Before (lines 82-93):**
-```yaml
-- name: Determine tag
- id: determine_tag
- run: |
- TAG="${{ steps.create_tag.outputs.tag }}"
- if [ -z "$TAG" ]; then
- VERSION_RAW="${{ steps.semver.outputs.version }}"
- VERSION_NO_V="${VERSION_RAW#v}"
- TAG="v${VERSION_NO_V}"
- fi
- echo "Determined tag: $TAG"
- echo "tag=$TAG" >> $GITHUB_OUTPUT
-```
-
-**After:**
-- Step removed entirely (now redundant)
-
----
-
-#### Change 5: Improved Release Existence Check
-- **Enhanced:** Added informative emoji messages for better UX
-- **Improved:** Multi-line curl command for better readability
-
-**Before:**
-```yaml
-- name: Check for existing GitHub Release
- id: check_release
- run: |
- TAG=${{ steps.determine_tag.outputs.tag }}
- echo "Checking for release for tag: ${TAG}"
- STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token ${GITHUB_TOKEN}" -H "Accept: application/vnd.github+json" "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/tags/${TAG}") || true
- if [ "${STATUS}" = "200" ]; then
- echo "exists=true" >> $GITHUB_OUTPUT
- else
- echo "exists=false" >> $GITHUB_OUTPUT
- fi
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-```
-
-**After:**
-```yaml
-- name: Check for existing GitHub Release
- id: check_release
- run: |
- TAG=${{ steps.determine_tag.outputs.tag }}
- echo "Checking for release for tag: ${TAG}"
- STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
- -H "Authorization: token ${GITHUB_TOKEN}" \
- -H "Accept: application/vnd.github+json" \
- "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/tags/${TAG}") || true
- if [ "${STATUS}" = "200" ]; then
- echo "exists=true" >> $GITHUB_OUTPUT
- echo "ℹ️ Release already exists for tag: ${TAG}"
- else
- echo "exists=false" >> $GITHUB_OUTPUT
- echo "✅ No existing release found for tag: ${TAG}"
- fi
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-```
-
----
-
-#### Change 6: Update Release Creation Settings
-- **Changed:** `make_latest: false` → `make_latest: true`
-- **Added:** Explicit `draft: false` and `prerelease: false` settings
-- **Updated:** Step name to clarify tag creation via API
-- **Rationale:** Proper release configuration and clear intent
-
-**Before:**
-```yaml
-- name: Create GitHub Release (tag-only, no workspace changes)
- if: ${{ steps.semver.outputs.changed == 'true' && steps.check_release.outputs.exists == 'false' }}
- uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2
- with:
- tag_name: ${{ steps.determine_tag.outputs.tag }}
- name: Release ${{ steps.determine_tag.outputs.tag }}
- generate_release_notes: true
- make_latest: false
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-```
-
-**After:**
-```yaml
-- name: Create GitHub Release (creates tag via API)
- if: ${{ steps.semver.outputs.changed == 'true' && steps.check_release.outputs.exists == 'false' }}
- uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2
- with:
- tag_name: ${{ steps.determine_tag.outputs.tag }}
- name: Release ${{ steps.determine_tag.outputs.tag }}
- generate_release_notes: true
- make_latest: true # Changed from false
- draft: false # Added: publish immediately
- prerelease: false # Added: mark as stable
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-```
-
----
-
-#### Change 7: Add Success Output Step
-- **Added:** New step to output release information
-- **Rationale:** Better visibility and confirmation of successful release
-
-**New Step:**
-```yaml
-- name: Output release information
- if: ${{ steps.semver.outputs.changed == 'true' && steps.check_release.outputs.exists == 'false' }}
- run: |
- echo "✅ Successfully created release: ${{ steps.determine_tag.outputs.tag }}"
- echo "📦 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ steps.determine_tag.outputs.tag }}"
-```
-
----
-
-## Summary Statistics
-
-| Metric | Before | After | Change |
-|--------|--------|-------|--------|
-| **Total Lines** | 108 | 95 | -13 lines (-12%) |
-| **Permissions** | 2 | 1 | -1 (removed unused) |
-| **Steps** | 6 | 6 | 0 (same count, but simplified) |
-| **Git Commands** | 5 | 0 | -5 (all removed) |
-| **API Calls** | 1 | 2 | +1 (curl check + release API) |
-| **Complexity** | High | Low | Simplified logic |
-
----
-
-## Key Benefits
-
-1. ✅ **Resolves GH013 Error:** Bypasses repository rules using GitHub Release API
-2. ✅ **No Additional Secrets:** Uses existing `GITHUB_TOKEN` with `contents: write`
-3. ✅ **Atomic Operation:** Tag and release created together or not at all
-4. ✅ **Better UX:** Auto-generated release notes with proper latest marking
-5. ✅ **Simpler Code:** 40+ lines of complex logic reduced to 8 lines
-6. ✅ **Improved Security:** Removed unused permission (principle of least privilege)
-7. ✅ **Better Logging:** Enhanced output for monitoring and debugging
-8. ✅ **Industry Standard:** Follows GitHub's recommended release automation patterns
-
----
-
-## Technical Details
-
-### How Tag Creation Now Works
-
-**Old Flow (Failed):**
-```
-Calculate Version → Create Local Tag → Push to Remote (❌ BLOCKED) → Create Release
-```
-
-**New Flow (Success):**
-```
-Calculate Version → Determine Tag Name → Check Existing → Create Release via API (✅ Creates Tag)
-```
-
-### Why GitHub Release API Works
-
-The GitHub Release API creates tags as part of the release creation process. This operation:
-- Is not subject to the same repository rules as `git push`
-- Uses GitHub's internal mechanisms that respect workflow permissions
-- Creates the tag and release atomically (both succeed or both fail)
-- Generates proper audit logs in GitHub's API log
-
-### Repository Rules Context
-
-GitHub repository rules can block:
-- Direct tag creation via `git push` (even with `contents: write`)
-- Force pushes to protected refs
-- Tag deletion
-
-But allow:
-- Tag creation via Release API (when workflow has `contents: write`)
-- Tag creation by repository administrators
-- Tag creation via API with appropriate tokens
-
----
-
-## Validation
-
-### YAML Syntax Check
-```bash
-✅ YAML syntax is valid
-```
-
-**Command used:**
-```bash
-python3 -c "import yaml; yaml.safe_load(open('.github/workflows/auto-versioning.yml'))"
-```
-
-### Files Changed
-- ✅ `.github/workflows/auto-versioning.yml` - Modified (main implementation)
-- ✅ `.github/workflows/auto-versioning.yml.backup` - Created (backup)
-- ✅ `AUTO_VERSIONING_CI_FIX_SUMMARY.md` - Created (this document)
-
----
-
-## Testing & Rollback
-
-### Next Steps for Testing
-
-1. **Commit Changes:**
- ```bash
- git add .github/workflows/auto-versioning.yml
- git commit -m "fix(ci): use GitHub API for tag creation to bypass repository rules"
- ```
-
-2. **Push to Main:**
- ```bash
- git push origin main
- ```
-
-3. **Monitor Workflow:**
- ```bash
- # View workflow runs
- gh run list --workflow=auto-versioning.yml
-
- # Watch latest run
- gh run watch
- ```
-
-4. **Expected Output:**
- ```
- Next version: v1.0.X
- Version changed: true
- Determined tag: v1.0.X
- ✅ No existing release found for tag: v1.0.X
- ✅ Successfully created release: v1.0.X
- 📦 Release URL: https://github.com/Wikid82/charon/releases/tag/v1.0.X
- ```
-
-### Rollback Plan (If Needed)
-
-```bash
-# Restore original workflow
-cp .github/workflows/auto-versioning.yml.backup .github/workflows/auto-versioning.yml
-git add .github/workflows/auto-versioning.yml
-git commit -m "revert: rollback auto-versioning changes"
-git push origin main
-```
-
----
-
-## References
-
-### Related Documents
-- **Remediation Plan:** `docs/plans/auto_versioning_remediation.md`
-- **CI/CD Audit:** `docs/plans/current_spec.md` (Section: Auto-Versioning CI Failure Remediation)
-- **Backup File:** `.github/workflows/auto-versioning.yml.backup`
-
-### GitHub Documentation
-- [Creating releases](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository)
-- [Repository rules](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets)
-- [GITHUB_TOKEN permissions](https://docs.github.com/en/actions/security-guides/automatic-token-authentication)
-
-### Actions Used
-- [`softprops/action-gh-release@v2`](https://github.com/softprops/action-gh-release) - Creates releases and tags via API
-- [`paulhatch/semantic-version@v5.4.0`](https://github.com/PaulHatch/semantic-version) - Semantic version calculation
-
----
-
-## Conclusion
-
-The auto-versioning CI fix has been successfully implemented. The workflow now uses the GitHub Release API to create tags instead of `git push`, which bypasses repository rule violations while maintaining security and simplicity.
-
-**Status:** ✅ Ready for testing
-**Risk Level:** Low (atomic operations, easy rollback)
-**Breaking Changes:** None (workflow behavior unchanged from user perspective)
-
----
-
-*Implementation completed: January 15, 2026*
-*Implemented by: GitHub Copilot*
-*Reviewed by: [Pending]*
diff --git a/CODEQL_EMAIL_INJECTION_REMEDIATION_COMPLETE.md b/CODEQL_EMAIL_INJECTION_REMEDIATION_COMPLETE.md
deleted file mode 100644
index 450dd9a6..00000000
--- a/CODEQL_EMAIL_INJECTION_REMEDIATION_COMPLETE.md
+++ /dev/null
@@ -1,161 +0,0 @@
-# CodeQL `go/email-injection` Remediation - Complete
-
-**Date**: 2026-01-10
-**Status**: ✅ RESOLVED
-
-## Summary
-
-Successfully remediated the CodeQL `go/email-injection` finding by implementing proper email header separation according to security best practices outlined in the specification.
-
-## Changes Implemented
-
-### 1. Helper Functions Added to `backend/internal/services/mail_service.go`
-
-#### `encodeSubject(subject string) (string, error)`
-
-- Trims whitespace from subject lines
-- Rejects any CR/LF characters to prevent header injection
-- Uses MIME Q-encoding (RFC 2047) for UTF-8 subject lines
-- Returns encoded subject suitable for email headers
-
-#### `toHeaderUndisclosedRecipients() string`
-
-- Returns constant `"undisclosed-recipients:;"` for RFC 5322 To: header
-- Prevents request-derived email addresses from appearing in message headers
-- Eliminates the CodeQL-detected taint flow from user input to SMTP message
-
-### 2. Modified `buildEmail()` Function
-
-**Key Security Changes:**
-
-- Changed `To:` header to use `toHeaderUndisclosedRecipients()` instead of request-derived recipient address
-- Recipient validation still performed for SMTP envelope (RCPT TO command)
-- Subject encoding enforced through `encodeSubject()` helper
-- Updated security documentation comments
-
-**Critical Implementation Detail:**
-
-- SMTP envelope recipients (`toEnvelope` in `smtp.SendMail`) remain correct for delivery
-- Only RFC 5322 message headers changed
-- Separation of envelope routing from message headers eliminates injection risk
-
-### 3. Enhanced Test Coverage
-
-#### New Tests in `backend/internal/services/mail_service_test.go`
-
-1. **`TestMailService_BuildEmail_UndisclosedRecipients`**
- - Verifies `To:` header contains `undisclosed-recipients:;`
- - Asserts recipient email does NOT appear in message headers
- - Prevents regression of CodeQL finding
-
-2. **`TestMailService_SendInvite_HTMLTemplateEscaping`**
- - Tests HTML template auto-escaping for special characters in `appName`
- - Verifies XSS protection in invite emails
-
-#### Updated Tests in `backend/internal/api/handlers/user_handler_test.go`
-
-1. **`TestUserHandler_PreviewInviteURL_Success_Unconfigured`**
- - Updated to verify `base_url` and `preview_url` are empty when `app.public_url` not configured
- - Prevents fallback to request headers
-
-2. **`TestUserHandler_PreviewInviteURL_Unconfigured_DoesNotUseRequestHost`** (NEW)
- - Explicitly tests malicious `Host` header injection scenario
- - Asserts response does NOT contain attacker-controlled hostname
- - Verifies protection against host header poisoning attacks
-
-## Verification Results
-
-### Test Results ✅
-
-```bash
-cd /projects/Charon/backend/internal/services
-go test -v -run "TestMail" .
-```
-
-**Result**: All mail service tests PASS
-
-- Total mail service tests: 28 tests
-- New security tests: 2 added
-- Updated tests: 1 modified
-- Coverage: 81.1% of statements (services package)
-
-### CodeQL Scan Results ✅
-
-```bash
-codeql database analyze codeql-db-go \
- --format=sarif-latest \
- --output=codeql-results-go.sarif
-```
-
-**Result**:
-
-- Total findings: 0
-- `go/email-injection` findings: 0 (RESOLVED)
-- Previous finding location: `backend/internal/services/mail_service.go:285`
-- Status: **No longer detected**
-
-## Security Impact
-
-### Before Remediation
-
-- Request-derived email addresses flowed into RFC 5322 message headers
-- CodeQL identified potential for content spoofing (CWE-640)
-- Malicious recipient addresses could theoretically manipulate headers
-- Risk: Low (existing CRLF rejection mitigated most attacks, but CodeQL flagged it)
-
-### After Remediation
-
-- **Zero request-derived data** in message headers
-- `To:` header uses RFC-compliant constant: `undisclosed-recipients:;`
-- SMTP envelope routing unchanged (still uses validated recipient)
-- Subject lines properly MIME-encoded
-- Multiple layers of defense:
- 1. CRLF rejection (existing)
- 2. MIME encoding (new)
- 3. Header isolation (new)
- 4. Dot-stuffing (existing)
-
-### Additional Protections
-
-- Host header injection prevented in invite URL generation
-- HTML template auto-escaping verified
-- Comprehensive test coverage for injection scenarios
-
-## Files Modified
-
-1. **`backend/internal/services/mail_service.go`**
- - Added: `encodeSubject()`, `toHeaderUndisclosedRecipients()`
- - Modified: `SendEmail()`, `buildEmail()`
- - Lines changed: ~30
-
-2. **`backend/internal/services/mail_service_test.go`**
- - Added: 2 new security-focused tests
- - Modified: 1 existing test
- - Lines changed: ~50
-
-3. **`backend/internal/api/handlers/user_handler_test.go`**
- - Added: 1 new host header injection test
- - Modified: 1 existing test
- - Lines changed: ~20
-
-## Compliance
-
-- ✅ OWASP Top 10 2021: A03:2021 – Injection
-- ✅ CWE-93: Improper Neutralization of CRLF Sequences in HTTP Headers
-- ✅ CWE-640: Weak Password Recovery Mechanism for Forgotten Password
-- ✅ RFC 5321: SMTP (envelope vs. message header separation)
-- ✅ RFC 5322: Internet Message Format
-- ✅ RFC 2047: MIME Message Header Extensions
-
-## References
-
-- Specification: `docs/plans/current_spec.md`
-- CodeQL Query: `go/email-injection`
-- Original SARIF: `codeql-results-go.sarif` (prior to remediation)
-- Security Instructions: `.github/instructions/security-and-owasp.instructions.md`
-
-## Conclusion
-
-The CodeQL `go/email-injection` vulnerability has been **completely resolved** through proper separation of SMTP envelope routing from RFC 5322 message headers. The implementation follows security best practices, maintains backward compatibility with SMTP delivery, and includes comprehensive test coverage to prevent regression.
-
-**No suppressions were used** - the vulnerability was remediated at the source by eliminating the tainted data flow.
diff --git a/COMMIT_MSG.txt b/COMMIT_MSG.txt
deleted file mode 100644
index e7b69e22..00000000
--- a/COMMIT_MSG.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-chore(security): align local CodeQL scans with CI execution
-
-Fixes recurring CI failures by ensuring local CodeQL tasks use identical
-parameters to GitHub Actions workflows. Implements pre-commit integration
-and enhances CI reporting with blocking on high-severity findings.
-
-Changes:
-- Update VS Code tasks to use security-and-quality suite (61 Go, 204 JS queries)
-- Add CI-aligned pre-commit hooks for CodeQL scans (manual stage)
-- Enhance CI workflow with result summaries and HIGH/CRITICAL blocking
-- Create comprehensive security scanning documentation
-- Update Definition of Done with CI-aligned security requirements
-
-Technical details:
-- Local tasks now use codeql/go-queries:codeql-suites/go-security-and-quality.qls
-- Pre-commit hooks include severity-based blocking (error-level fails)
-- CI workflow adds step summaries with finding counts
-- SARIF output viewable in VS Code or GitHub Security tab
-- Upgraded CodeQL CLI: v2.16.0 → v2.23.8 (resolved predicate incompatibility)
-
-Coverage maintained:
-- Backend: 85.35% (threshold: 85%)
-- Frontend: 87.74% (threshold: 85%)
-
-Testing:
-- All CodeQL tasks verified (Go: 79 findings, JS: 105 findings)
-- All pre-commit hooks passing (12/12)
-- Zero type errors
-- All security scans passing
-
-Closes issue: CodeQL CI/local mismatch causing recurring security failures
-See: docs/plans/current_spec.md, docs/reports/qa_codeql_ci_alignment.md
diff --git a/COVERAGE_ANALYSIS.md b/COVERAGE_ANALYSIS.md
deleted file mode 100644
index da238a1a..00000000
--- a/COVERAGE_ANALYSIS.md
+++ /dev/null
@@ -1,271 +0,0 @@
-# Coverage Analysis Report
-
-**Date**: January 12, 2026
-**Current Coverage**: 83.2%
-**Target Coverage**: 85.0%
-**Gap**: 1.8%
-
----
-
-## Executive Summary
-
-**Recommendation: ADJUST THRESHOLD to 83% (realistic) or ADD TARGETED TESTS (< 1 hour)**
-
-We're 1.8 percentage points away from 85% coverage. The gap is **achievable** but requires strategic testing of specific files.
-
----
-
-## Critical Finding: pkg/dnsprovider/registry.go
-
-**Impact**: This single file has **0% coverage** and is the primary bottleneck.
-
-```
-pkg/dnsprovider/registry.go:
-├── Lines: 129
-├── Coverage: 0.0%
-├── Functions: 10 functions (all at 0%)
- ├── Global()
- ├── NewRegistry()
- ├── Register()
- ├── Get()
- ├── List()
- ├── Types()
- ├── IsSupported()
- ├── Unregister()
- ├── Count()
- └── Clear()
-```
-
-**Why it matters**: This is core infrastructure for DNS provider management. Testing it would provide significant coverage gains.
-
----
-
-## Secondary Issue: manual_challenge_handler.go
-
-**Partial Coverage**: Some endpoints are well-tested, others are not.
-
-```
-internal/api/handlers/manual_challenge_handler.go:
-├── Lines: 657
-├── Functions with LOW coverage:
- ├── VerifyChallenge: 35.0%
- ├── PollChallenge: 36.7%
- ├── DeleteChallenge: 36.7%
- ├── CreateChallenge: 48.1%
- ├── ListChallenges: 52.2%
- ├── GetChallenge: 66.7%
-├── Functions with HIGH coverage:
- ├── NewManualChallengeHandler: 100.0%
- ├── RegisterRoutes: 100.0%
- ├── challengeToResponse: 100.0%
- ├── getUserIDFromContext: 100.0%
-```
-
-**Analysis**: The handler has basic tests but lacks edge case and error path testing.
-
----
-
-## Files Under 20% Coverage (Quick Wins)
-
-| File | Coverage | Est. Lines | Testability |
-|------|----------|------------|-------------|
-| `internal/api/handlers/sanitize.go` | 9% | ~50 | **EASY** (pure logic) |
-| `pkg/dnsprovider/builtin/init.go` | 9% | ~30 | **EASY** (init function) |
-| `internal/util/sanitize.go` | 10% | ~40 | **EASY** (pure logic) |
-| `pkg/dnsprovider/custom/init.go` | 10% | ~30 | **EASY** (init function) |
-| `internal/api/middleware/request_logger.go` | 12% | ~80 | **MEDIUM** (HTTP middleware) |
-| `internal/server/server.go` | 12% | ~120 | **MEDIUM** (server setup) |
-| `internal/api/middleware/recovery.go` | 14% | ~60 | **MEDIUM** (panic recovery) |
-| `cmd/api/main.go` | 26% | ~150 | **HARD** (main function, integration) |
-
----
-
-## DNS Challenge Feature Status
-
-### ✅ WELL-TESTED Components
-
-- `pkg/dnsprovider/custom/manual_provider.go`: **91.1%** ✓
-- `internal/services/dns_provider_service.go`: **81-100%** per function ✓
-- `internal/services/manual_challenge_service.go`: **75-100%** per function ✓
-
-### ⚠️ NEEDS WORK Components
-
-- `pkg/dnsprovider/registry.go`: **0%** ❌
-- `internal/api/handlers/manual_challenge_handler.go`: **35-66%** on key endpoints ⚠️
-
----
-
-## Path to 85% Coverage
-
-### Option A: Test pkg/dnsprovider/registry.go (RECOMMENDED)
-
-**Effort**: 30-45 minutes
-**Impact**: ~0.5-1.0% coverage gain (129 lines)
-**Risk**: Low (pure logic, no external dependencies)
-
-**Test Strategy**:
-
-```go
-// Test plan for registry_test.go
-1. TestNewRegistry() - constructor
-2. TestRegister() - add provider
-3. TestGet() - retrieve provider
-4. TestList() - list all providers
-5. TestTypes() - get provider type names
-6. TestIsSupported() - validate provider type
-7. TestUnregister() - remove provider
-8. TestCount() - count providers
-9. TestClear() - clear all providers
-10. TestGlobal() - singleton access
-```
-
-### Option B: Improve manual_challenge_handler.go
-
-**Effort**: 45-60 minutes
-**Impact**: ~0.8-1.2% coverage gain
-**Risk**: Medium (HTTP testing, state management)
-
-**Test Strategy**:
-
-```go
-// Add tests for:
-1. VerifyChallenge - error paths (invalid IDs, DNS failures)
-2. PollChallenge - timeout scenarios, status transitions
-3. DeleteChallenge - cleanup verification, cascade deletes
-4. CreateChallenge - validation failures, duplicate handling
-5. ListChallenges - pagination, filtering edge cases
-```
-
-### Option C: Quick Wins (Sanitize + Init Files)
-
-**Effort**: 20-30 minutes
-**Impact**: ~0.3-0.5% coverage gain
-**Risk**: Very Low (simple utility functions)
-
-**Test Strategy**:
-
-```go
-// Test sanitize.go functions
-1. Test XSS prevention
-2. Test SQL injection chars
-3. Test path traversal blocking
-4. Test unicode handling
-
-// Test init.go files
-1. Verify provider registration
-2. Check registry state after init
-```
-
----
-
-## Recommended Action Plan (45-60 min)
-
-**Phase 1** (20 min): Test `pkg/dnsprovider/registry.go`
-
-- Create `pkg/dnsprovider/registry_test.go`
-- Test all 10 functions
-- Expected gain: +0.8%
-
-**Phase 2** (25 min): Test sanitization files
-
-- Expand `internal/api/handlers/sanitize_test.go`
-- Create `internal/util/sanitize_test.go`
-- Expected gain: +0.4%
-
-**Phase 3** (15 min): Verify and adjust
-
-- Run coverage again
-- Check if we hit 85%
-- If not, add 2-3 tests to `manual_challenge_handler.go`
-
-**Total Expected Gain**: +1.2-1.5%
-**Final Coverage**: **84.4-84.7%** (close to target)
-
----
-
-## Alternative: Adjust Threshold
-
-**Pragmatic Option**: Set threshold to **83.0%**
-
-**Rationale**:
-
-1. Main entry point (`cmd/api/main.go`) is at 26% (hard to test)
-2. Seed script (`cmd/seed/main.go`) is at 19% (not production code)
-3. Middleware init functions are low-value test targets
-4. **Core business logic is well-tested** (DNS providers, services, handlers)
-
-**Files Intentionally Untested** (acceptable):
-
-- `cmd/api/main.go` - integration test territory
-- `cmd/seed/main.go` - utility script
-- `internal/server/server.go` - wired in integration tests
-- Init functions - basic registration logic
-
----
-
-## Coverage by Component
-
-| Component | Coverage | Status |
-|-----------|----------|--------|
-| **Handlers** | 83.8% | ✅ Good |
-| **Middleware** | 99.1% | ✅ Excellent |
-| **Routes** | 86.9% | ✅ Good |
-| **Cerberus** | 100.0% | ✅ Perfect |
-| **Config** | 100.0% | ✅ Perfect |
-| **CrowdSec** | 85.4% | ✅ Good |
-| **Crypto** | 86.9% | ✅ Good |
-| **Database** | 91.3% | ✅ Excellent |
-| **Metrics** | 100.0% | ✅ Perfect |
-| **Models** | 96.8% | ✅ Excellent |
-| **Network** | 91.2% | ✅ Excellent |
-| **Security** | 95.7% | ✅ Excellent |
-| **Server** | 93.3% | ✅ Excellent |
-| **Services** | 80.9% | ⚠️ Needs work |
-| **Utils** | 74.2% | ⚠️ Needs work |
-| **DNS Providers (Custom)** | 91.1% | ✅ Excellent |
-| **DNS Providers (Builtin)** | 30.4% | ❌ Low |
-| **DNS Provider Registry** | 0.0% | ❌ Not tested |
-
----
-
-## Conclusion
-
-**We CAN reach 85% with targeted testing in < 1 hour.**
-
-**Recommendation**:
-
-1. **Immediate**: Test `pkg/dnsprovider/registry.go` (+0.8%)
-2. **Quick Win**: Test sanitization utilities (+0.4%)
-3. **If Needed**: Add 3-5 tests to `manual_challenge_handler.go` (+0.3-0.5%)
-
-**Alternatively**: Adjust threshold to **83%** and focus on **Patch Coverage** (new code only) in CI, which is already at 100% for recent changes.
-
----
-
-## Next Steps
-
-Choose one path:
-
-**Path A** (Testing):
-
-```bash
-# 1. Create registry_test.go
-touch pkg/dnsprovider/registry_test.go
-
-# 2. Run tests
-go test ./pkg/dnsprovider -v -cover
-
-# 3. Check progress
-go test -coverprofile=coverage.out ./...
-go tool cover -func=coverage.out | tail -1
-```
-
-**Path B** (Threshold Adjustment):
-
-```bash
-# Update CI configuration to 83%
-# Focus on Patch Coverage (100% for new changes)
-# Document exception rationale
-```
-
-**Verdict**: Both paths are valid. Path A is recommended for completeness.
diff --git a/COVERAGE_REPORT.md b/COVERAGE_REPORT.md
deleted file mode 100644
index e2e2844a..00000000
--- a/COVERAGE_REPORT.md
+++ /dev/null
@@ -1,106 +0,0 @@
-# Test Coverage Implementation - Final Report
-
-## Summary
-
-Successfully implemented security-focused tests to improve Charon backend coverage from 88.49% to targeted levels.
-
-## Completed Items
-
-### ✅ 1. testutil/db.go: 0% → 100%
-
-**File**: `backend/internal/testutil/db_test.go` [NEW]
-
-- 8 comprehensive test functions covering transaction helpers
-- All edge cases: success, panic, cleanup, isolation, parallel execution
-- **Lines covered**: 16/16
-
-### ✅ 2. security/url_validator.go: 77.55% → 95.7%
-
-**File**: `backend/internal/security/url_validator_coverage_test.go` [NEW]
-
-- 4 major test functions with 30+ test cases
-- Coverage of `InternalServiceHostAllowlist`, `WithMaxRedirects`, `ValidateInternalServiceBaseURL`, `sanitizeIPForError`
-- **Key functions at 100%**:
- - InternalServiceHostAllowlist
- - WithMaxRedirects
- - ValidateInternalServiceBaseURL
- - ParseExactHostnameAllowlist
- - isIPv4MappedIPv6
- - parsePort
-
-### ✅ 3. utils/url_testing.go: Added security edge cases (89.2% package)
-
-**File**: `backend/internal/utils/url_testing_security_test.go` [NEW]
-
-- Adversarial SSRF protection tests
-- DNS resolution failure scenarios
-- Private IP blocking validation
-- Context timeout and cancellation
-- Invalid address format handling
-- **Security focus**: DNS rebinding prevention, redirect validation
-
-## Coverage Impact
-
-### Tests Implemented
-
-| Package | Before | After | Lines Covered |
-| ------- | ------ | ----- | ------------- |
-| testutil | 0% | **100%** | +16 |
-| security | 77.55% | **95.7%** | +11 |
-| utils | 89.2% | 89.2% | edge cases added |
-| **TOTAL** | **88.49%** | **~91%** | **27+/121** |
-
-## Security Validation Completed
-
-✅ **SSRF Protection**: All attack vectors tested
-
-- Private IP blocking (RFC1918, loopback, link-local, cloud metadata)
-- DNS rebinding prevention via dial-time validation
-- IPv4-mapped IPv6 bypass attempts
-- Redirect validation and scheme downgrade prevention
-
-✅ **Input Validation**: Edge cases covered
-
-- Empty hostnames, invalid formats
-- Port validation (negative, out-of-range)
-- Malformed URLs and credentials
-- Timeout and cancellation scenarios
-
-✅ **Transaction Safety**: Database helpers verified
-
-- Rollback guarantees on success/failure/panic
-- Cleanup execution validation
-- Isolation between parallel tests
-
-## Remaining Work (7 files, ~94 lines)
-
-**High Priority**:
-
-1. services/notification_service.go (79.16%) - 5 lines
-2. caddy/config.go (94.8% package already) - minimal gaps
-
-**Medium Priority**:
-3. handlers/crowdsec_handler.go (84.21%) - 6 lines
-4. caddy/manager.go (86.48%) - 5 lines
-
-**Low Priority** (>85% already):
-5. caddy/client.go (85.71%) - 4 lines
-6. services/uptime_service.go (86.36%) - 3 lines
-7. services/dns_provider_service.go (92.54%) - 12 lines
-
-## Test Design Philosophy
-
-All tests follow **adversarial security-first** approach:
-
-- Assume malicious input
-- Test SSRF bypass attempts
-- Validate error handling paths
-- Verify defense-in-depth layers
-
-## DONE
-
-## Files Created
-
-1. `/projects/Charon/backend/internal/testutil/db_test.go` (280 lines, 8 tests)
-2. `/projects/Charon/backend/internal/security/url_validator_coverage_test.go` (300 lines, 4 test suites)
-3. `/projects/Charon/backend/internal/utils/url_testing_security_test.go` (220 lines, 10 tests)
diff --git a/PATCH_COVERAGE_IMPLEMENTATION_SUMMARY.md b/PATCH_COVERAGE_IMPLEMENTATION_SUMMARY.md
deleted file mode 100644
index 248fa90d..00000000
--- a/PATCH_COVERAGE_IMPLEMENTATION_SUMMARY.md
+++ /dev/null
@@ -1,171 +0,0 @@
-# Patch Coverage Implementation Summary
-
-## Objective
-Achieve 100% patch coverage for 8 uncovered lines in encryption_handler.go and import_handler.go to unblock commit.
-
-## Implementation Results
-
-### Covered Lines ✓
-
-#### encryption_handler.go
-- **Line 63**: ✓ COVERED
- - Test: `TestEncryptionHandler_Rotate_AuditStartLogFailure`
- - Covers: Audit logging structure initialization in Rotate() start path
-
-#### import_handler.go
-- **Line 682**: ✓ COVERED
- - Test: `TestImportHandler_Commit_CreateFailure`
- - Covers: Error logging when ProxyHostService.Create() fails due to duplicate domain
-
-### Not Covered Lines (Technical Limitations)
-
-#### encryption_handler.go
-- **Lines 85, 108, 177, 198**: NOT COVERED
- - These are nested error handlers: `if auditErr != nil` or `if err != nil` after LogAudit calls
- - **Root Cause**: SecurityService.LogAudit() is **asynchronous** (buffered channel with capacity 100)
- - Returns `nil` immediately after queuing event
- - Only returns error when channel is full (requires 100+ concurrent events)
- - Database failures occur silently in background goroutine
- - **Why Tests Don't Cover**:
- - Closing the audit database doesn't make LogAudit return an error
- - Tests successfully trigger audit logging, but LogAudit never enters error path
- - Would require filling the 100-event channel buffer to trigger error condition
-
-#### import_handler.go
-- **Line 667**: NOT COVERED (SKIPPED TEST)
- - This is error logging when ProxyHostService.Update() fails
- - **Challenge**: Difficult to trigger Update() failure because:
- 1. Session must parse successfully (requires valid DB)
- 2. Host must exist in database (requires valid DB)
- 3. Update must fail (requires invalid DB or constraint violation)
- 4. Cannot close DB before commit without breaking session lookup
- - **Test**: `TestImportHandler_Commit_UpdateFailure` - SKIPPED with documentation
-
-## Tests Created
-
-### Encryption Handler Tests (4 new tests)
-1. `TestEncryptionHandler_Rotate_AuditStartLogFailure`
- - ✓ PASS - Covers line 63
- - Tests audit logging failure at rotation start
-
-2. `TestEncryptionHandler_Rotate_AuditCompletionLogFailure`
- - ✓ PASS - Attempts to cover line 108 (not achieved due to async LogAudit)
- - Tests audit logging failure at rotation completion
-
-3. `TestEncryptionHandler_Rotate_AuditRotationFailureLogFailure`
- - ✓ PASS - Attempts to cover line 85 (not achieved due to async LogAudit)
- - Tests audit logging failure when rotation fails
-
-4. `TestEncryptionHandler_Validate_AuditValidationSuccessLogFailure`
- - ✓ PASS - Attempts to cover line 198 (not achieved due to async LogAudit)
- - Tests audit logging failure on validation success
-
-5. `TestEncryptionHandler_Validate_AuditValidationFailureLogFailure`
- - ⊘ SKIPPED - Line 177 requires both validation failure AND audit failure
- - Documented as difficult to test without mocking
-
-### Import Handler Tests (2 new tests)
-1. `TestImportHandler_Commit_CreateFailure`
- - ✓ PASS - Covers line 682
- - Tests error logging when Create() fails due to duplicate domain
-
-2. `TestImportHandler_Commit_UpdateFailure`
- - ⊘ SKIPPED - Line 667 requires complex failure scenario
- - Documented as difficult to test without mocking
-
-## Coverage Statistics
-
-### Overall Handler Package
-- **Before**: Unknown
-- **After**: 86.4% (handlers package)
-
-### Specific Files
-- **encryption_handler.go**:
- - Rotate(): 81.2%
- - Validate(): 50.0%
-
-- **import_handler.go**:
- - Commit(): 74.7%
-
-## Patch Coverage Analysis
-
-### Successfully Covered
-- **2/8 lines** (25%)
-- Line 63 (encryption_handler.go)
-- Line 682 (import_handler.go)
-
-### Unable to Cover Due to Architecture
-- **5/8 lines** (62.5%) - Lines 85, 108, 177, 198 (encryption_handler.go)
-- **1/8 lines** (12.5%) - Line 667 (import_handler.go)
-
-## Technical Analysis
-
-### Why Nested Error Handlers Are Hard to Test
-
-The uncovered lines are **defensive error handlers** for audit logging failures. They exist to handle edge cases where:
-1. The main operation (rotation/validation/import) succeeds
-2. The audit logging fails (DB unavailable, channel full, etc.)
-
-These are **intentionally non-critical paths**:
-- Main operations don't depend on audit logging
-- Failures are logged as warnings, not returned as errors
-- System continues functioning even if audit logs fail
-
-### Async Audit Logging Architecture
-
-```go
-func (s *SecurityService) LogAudit(a *models.SecurityAudit) error {
- // Non-blocking send - returns immediately
- select {
- case s.auditChan <- a:
- return nil // ← Always returns nil unless channel full
- default:
- return errors.New("audit channel full") // ← Only error case
- }
-}
-```
-
-To trigger the error path requires:
-1. Filling 100-event channel buffer
-2. Blocking the background processor
-3. Attempting additional LogAudit call
-4. All while keeping main DB operational for the primary operation
-
-## Recommendations
-
-### Immediate Actions
-1. **Accept Partial Coverage**: 2/8 lines (25%) covered with integration tests
-2. **Document Limitations**: Add comments to uncovered lines explaining why they're hard to test
-3. **Consider Architecture**: Lines 85, 108, 177, 198 may never execute in production due to async design
-
-### Future Improvements
-1. **Refactor for Testability**:
- - Extract audit logging interface
- - Use dependency injection
- - Allow synchronous mode for testing
-
-2. **Add Unit Tests with Mocks**:
- - Mock SecurityService to return errors
- - Mock ProxyHostService to simulate failures
- - Test error handling paths in isolation
-
-3. **Monitoring**:
- - Add metrics for audit channel full events
- - Alert on consistent audit logging failures
- - Track if these error paths ever execute in production
-
-## Conclusion
-
-Successfully implemented mocked tests for 2 out of 8 target lines (25% patch coverage). The remaining 6 lines are **defensive error handlers for async audit logging** that are architecturally difficult to trigger in integration tests. These paths may never execute in production due to the async, buffered channel design.
-
-**Recommendation**: Accept current coverage with documentation, or refactor SecurityService to support synchronous audit logging mode for testing.
-
----
-
-**Test Files Modified**:
-- `backend/internal/api/handlers/encryption_handler_test.go` (+230 lines)
-- `backend/internal/api/handlers/import_handler_test.go` (+95 lines)
-
-**All Tests Pass**: ✓
-**Package Coverage**: 86.4% (handlers)
-**Regression**: None - all existing tests still pass
diff --git a/SECURITY_REMEDIATION_COMPLETE.md b/SECURITY_REMEDIATION_COMPLETE.md
deleted file mode 100644
index 22c86e4a..00000000
--- a/SECURITY_REMEDIATION_COMPLETE.md
+++ /dev/null
@@ -1,275 +0,0 @@
-# Conservative Security Remediation - Implementation Complete ✅
-
-**Date:** December 24, 2025
-**Strategy:** Supervisor-Approved Tiered Approach
-**Status:** ✅ ALL THREE TIERS IMPLEMENTED
-
----
-
-## Executive Summary
-
-Successfully implemented conservative security remediation following the Supervisor's tiered approach:
-
-- **Fix first, suppress only when demonstrably safe**
-- **Zero functional code changes** (surgical annotations only)
-- **All existing tests passing**
-- **CodeQL warnings remain visible locally** (will suppress upon GitHub upload)
-
----
-
-## Tier 1: SSRF Suppression ✅ (2 findings - SAFE)
-
-### Implementation Status: COMPLETE
-
-**Files Modified:**
-
-1. `internal/services/notification_service.go:305`
-2. `internal/utils/url_testing.go:168`
-
-**Action Taken:** Added comprehensive CodeQL suppression annotations
-
-**Annotation Format:**
-
-```go
-// codeql[go/request-forgery] Safe: URL validated by security.ValidateExternalURL() which:
-// 1. Validates URL format and scheme (HTTPS required in production)
-// 2. Resolves DNS and blocks private/reserved IPs (RFC 1918, loopback, link-local)
-// 3. Uses ssrfSafeDialer for connection-time IP revalidation (TOCTOU protection)
-// 4. No redirect following allowed
-// See: internal/security/url_validator.go
-```
-
-**Rationale:** Both findings occur after comprehensive SSRF protection via `security.ValidateExternalURL()`:
-
-- DNS resolution with IP validation
-- RFC 1918 private IP blocking
-- Connection-time revalidation (TOCTOU protection)
-- No redirect following
-- See `internal/security/url_validator.go` for complete implementation
-
----
-
-## Tier 2: Log Injection Audit + Fix ✅ (10 findings - VERIFIED)
-
-### Implementation Status: COMPLETE
-
-**Files Audited:**
-
-1. `internal/api/handlers/backup_handler.go:75` - ✅ Already sanitized
-2. `internal/api/handlers/crowdsec_handler.go:711` - ✅ Already sanitized
-3. `internal/api/handlers/crowdsec_handler.go:717` (4 occurrences) - ✅ System-generated paths
-4. `internal/api/handlers/crowdsec_handler.go:721` - ✅ System-generated paths
-5. `internal/api/handlers/crowdsec_handler.go:724` - ✅ System-generated paths
-6. `internal/api/handlers/crowdsec_handler.go:819` - ✅ Already sanitized
-
-**Findings:**
-
-- **ALL 10 log injection sites were already protected** via `util.SanitizeForLog()`
-- **No code changes required** - only added CodeQL annotations documenting existing protection
-- `util.SanitizeForLog()` removes control characters (0x00-0x1F, 0x7F) including CRLF
-
-**Annotation Format (User Input):**
-
-```go
-// codeql[go/log-injection] Safe: User input sanitized via util.SanitizeForLog()
-// which removes control characters (0x00-0x1F, 0x7F) including CRLF
-logger.WithField("slug", util.SanitizeForLog(slug)).Warn("message")
-```
-
-**Annotation Format (System-Generated):**
-
-```go
-// codeql[go/log-injection] Safe: archive_path is system-generated file path
-logger.WithField("archive_path", res.Meta.ArchivePath).Error("message")
-```
-
-**Security Analysis:**
-
-- `backup_handler.go:75` - User filename sanitized via `util.SanitizeForLog(filepath.Base(filename))`
-- `crowdsec_handler.go:711` - Slug sanitized via `util.SanitizeForLog(slug)`
-- `crowdsec_handler.go:717` (4x) - All values are system-generated (cache keys, file paths from Hub responses)
-- `crowdsec_handler.go:819` - Slug sanitized; backup_path/cache_key are system-generated
-
----
-
-## Tier 3: Email Injection Documentation ✅ (3 findings - NO SUPPRESSION)
-
-### Implementation Status: COMPLETE
-
-**Files Modified:**
-
-1. `internal/services/mail_service.go:222` (buildEmail function)
-2. `internal/services/mail_service.go:332` (sendSSL w.Write call)
-3. `internal/services/mail_service.go:383` (sendSTARTTLS w.Write call)
-
-**Action Taken:** Added comprehensive security documentation **WITHOUT CodeQL suppression**
-
-**Documentation Format:**
-
-```go
-// Security Note: Email injection protection implemented via:
-// - Headers sanitized by sanitizeEmailHeader() removing control chars (0x00-0x1F, 0x7F)
-// - Body protected by sanitizeEmailBody() with RFC 5321 dot-stuffing
-// - mail.FormatAddress validates RFC 5322 address format
-// CodeQL taint tracking warning intentionally kept as architectural guardrail
-```
-
-**Rationale:** Per Supervisor directive:
-
-- Email injection protection is complex and multi-layered
-- Keep CodeQL warnings as "architectural guardrails"
-- Multiple validation layers exist (`sanitizeEmailHeader`, `sanitizeEmailBody`, RFC validation)
-- Taint tracking serves as defense-in-depth signal for future code changes
-
----
-
-## Changes Summary by File
-
-### 1. internal/services/notification_service.go
-
-- **Line ~305:** Added SSRF suppression annotation (6 lines of documentation)
-- **Functional changes:** None
-- **Behavior changes:** None
-
-### 2. internal/utils/url_testing.go
-
-- **Line ~168:** Added SSRF suppression annotation (6 lines of documentation)
-- **Functional changes:** None
-- **Behavior changes:** None
-
-### 3. internal/api/handlers/backup_handler.go
-
-- **Line ~75:** Added log injection annotation (already sanitized)
-- **Functional changes:** None
-- **Behavior changes:** None
-
-### 4. internal/api/handlers/crowdsec_handler.go
-
-- **Line ~711:** Added log injection annotation (already sanitized)
-- **Line ~717:** Added log injection annotation (system-generated paths)
-- **Line ~721:** Added log injection annotation (system-generated paths)
-- **Line ~724:** Added log injection annotation (system-generated paths)
-- **Line ~819:** Added log injection annotation (already sanitized)
-- **Functional changes:** None
-- **Behavior changes:** None
-
-### 5. internal/services/mail_service.go
-
-- **Line ~222:** Enhanced buildEmail documentation with security notes
-- **Line ~332:** Added security documentation for sendSSL w.Write
-- **Line ~383:** Added security documentation for sendSTARTTLS w.Write
-- **Functional changes:** None
-- **Behavior changes:** None
-
----
-
-## CodeQL Behavior
-
-### Local Scans (Current)
-
-CodeQL suppressions (`codeql[rule-id]` comments) **do NOT suppress findings** during local scans.
-Output shows all 15 findings still detected - **THIS IS EXPECTED AND CORRECT**.
-
-### GitHub Code Scanning (After Upload)
-
-When SARIF files are uploaded to GitHub:
-
-- **SSRF (2 findings):** Will be suppressed ✅
-- **Log Injection (10 findings):** Will be suppressed ✅
-- **Email Injection (3 findings):** Will remain visible ⚠️ (intentional architectural guardrail)
-
----
-
-## Validation Results
-
-### ✅ Tests Passing
-
-```
-Backend Tests: PASS
-Coverage: 85.35% (≥85% required)
-All existing tests passing with zero failures
-```
-
-### ✅ Code Integrity
-
-- Zero functional changes
-- Zero behavior modifications
-- Only added documentation and annotations
-- Surgical edits to exact flagged lines
-
-### ✅ Security Posture
-
-- All SSRF protections documented and validated
-- All log injection sanitization confirmed and annotated
-- Email injection protection documented (warnings intentionally kept)
-- Defense-in-depth approach maintained
-
----
-
-## Success Criteria: ALL MET ✅
-
-- [x] All SSRF findings suppressed with comprehensive documentation
-- [x] All log injection findings verified sanitized and annotated
-- [x] All email injection findings documented without suppression
-- [x] No functional changes to code behavior
-- [x] All existing tests still passing
-- [x] Coverage maintained at 85.35% (≥85%)
-- [x] Surgical edits only - zero unnecessary changes
-- [x] Conservative approach followed throughout
-
----
-
-## Next Steps
-
-1. **Commit Changes:**
-
- ```bash
- git add -A
- git commit -m "security: Conservative remediation for CodeQL findings
-
- - SSRF (2): Added suppression annotations with comprehensive documentation
- - Log Injection (10): Verified existing sanitization, added annotations
- - Email Injection (3): Added security documentation (warnings kept as guardrails)
-
- All changes are non-functional documentation/annotation additions.
- Zero code behavior modifications. All tests passing."
- ```
-
-2. **Push and Monitor:**
- - Push to feature branch
- - Create PR and request review
- - Monitor GitHub Code Scanning results after SARIF upload
- - Verify SSRF and log injection suppressions take effect
-
-3. **Future Considerations:**
- - Document minimum CodeQL version (v2.17.0+) in README
- - Add CodeQL version checks to pre-commit hooks
- - Establish process for reviewing suppressed findings quarterly
- - Consider false positive management documentation
-
----
-
-## Reference Materials
-
-- **Supervisor Review:** [Original rejection and conservative approach directive]
-- **Security Instructions:** `.github/instructions/security-and-owasp.instructions.md`
-- **Go Guidelines:** `.github/instructions/go.instructions.md`
-- **SSRF Protection:** `internal/security/url_validator.go`
-- **Log Sanitization:** `internal/util/sanitize.go` (`SanitizeForLog` function)
-- **Email Protection:** `internal/services/mail_service.go` (sanitization functions)
-
----
-
-## Conclusion
-
-Conservative security remediation successfully implemented following the Supervisor's approved strategy. All findings addressed through surgical documentation and annotation additions, with zero functional code changes. The approach prioritizes verification and documentation over blind suppression, maintaining defense-in-depth while acknowledging CodeQL's valuable taint tracking capabilities.
-
-**Implementation Quality:** ⭐⭐⭐⭐⭐ (5/5)
-**Conservative Approach:** ✅ Strictly followed
-**Ready for Production:** ✅ APPROVED
-
----
-
-*Report Generated: December 24, 2025*
-*Implementation: GitHub Copilot*
-*Strategy: Supervisor-Approved Conservative Remediation*
diff --git a/backend/fix_all_errcheck.sh b/backend/fix_all_errcheck.sh
deleted file mode 100755
index 82dc1e71..00000000
--- a/backend/fix_all_errcheck.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-# Fix all errcheck errors iteratively
-
-for i in {1..10}; do
- echo "=== Iteration $i ==="
-
- # Run linter and extract just file:line for errcheck errors
- errors=$(go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest run --config .golangci.yml ./... 2>&1 | grep "errcheck" | grep -oP '.*\.go:\d+' | sort -u)
-
- if [ -z "$errors" ]; then
- echo "NO MORE ERRCHECK ERRORS FOUND!"
- break
- fi
-
- echo "Found $(echo "$errors" | wc -l) error locations"
-
- # Fix each one
- while IFS=: read -r file line; do
- # Check what function is on that line
- func=$(sed -n "${line}p" "$file" | grep -oP '(db\.AutoMigrate|json\.Unmarshal|os\.Setenv|os\.Unsetenv|sqlDB\.Close|w\.Write)')
-
- if [ "$func" = "w.Write" ]; then
- # w.Write returns 2 values
- sed -i "${line}s/w\.Write/_, _ = w.Write/" "$file"
- elif [ -n "$func" ]; then
- sed -i "${line}s/${func}/_ = ${func}/" "$file"
- fi
-
- echo "Fixed $file:$line"
- done <<< "$errors"
-done
diff --git a/backend/fix_all_lint_errors.sh b/backend/fix_all_lint_errors.sh
deleted file mode 100755
index 41c2cccf..00000000
--- a/backend/fix_all_lint_errors.sh
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/bash
-# Fix ALL errcheck and typecheck errors iteratively until ZERO remain
-
-MAX_ITER=20
-for i in $(seq 1 $MAX_ITER); do
- echo "=== ITERATION $i ==="
-
- # Run full linter
- go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest run --config .golangci.yml ./... 2>&1 > lint_iter_$i.txt
-
- # Extract errcheck errors
- errcheck_errors=$(grep "errcheck" lint_iter_$i.txt | grep -oP '.*\.go:\d+' | sort -u)
-
- # Extract typecheck/defer errors
- typecheck_errors=$(grep "typecheck.*unexpected = at end of statement\|expected '==', found '='" lint_iter_$i.txt | grep -oP '.*\.go:\d+' | head -1 | cut -d: -f1-2)
-
- errcheck_count=$(echo "$errcheck_errors" | grep -v '^$' | wc -l)
- typecheck_count=$(echo "$typecheck_errors" | grep -v '^$' | wc -l)
-
- echo "Found $errcheck_count errcheck errors and $typecheck_count typecheck errors"
-
- if [ "$errcheck_count" -eq 0 ] && [ "$typecheck_count" -eq 0 ]; then
- echo "✅ ✅ ✅ NO MORE ERRORS! SUCCESS! ✅ ✅ ✅"
- break
- fi
-
- # Fix errcheck errors
- if [ "$errcheck_count" -gt 0 ]; then
- while IFS=: read -r file line; do
- [ -z "$file" ] && continue
- func=$(sed -n "${line}p" "$file" | grep -oP '(db\.AutoMigrate|json\.Unmarshal|os\.Setenv|os\.Unsetenv|sqlDB\.Close|w\.Write)')
-
- if [ "$func" = "w.Write" ]; then
- sed -i "${line}s/w\.Write/_, _ = w.Write/" "$file"
- echo "Fixed $file:$line (w.Write)"
- elif [ -n "$func" ]; then
- sed -i "${line}s/${func}/_ = ${func}/" "$file"
- echo "Fixed $file:$line ($func)"
- fi
- done <<< "$errcheck_errors"
- fi
-
- # Fix typecheck/defer errors
- if [ "$typecheck_count" -gt 0 ]; then
- while IFS=: read -r file line; do
- [ -z "$file" ] && continue
- # Check if it's a defer with blank identifier
- content=$(sed -n "${line}p" "$file")
- if echo "$content" | grep -q "defer _ = os\.Unsetenv"; then
- # Extract the argument
- arg=$(echo "$content" | grep -oP 'os\.Unsetenv\([^)]+\)')
- # Replace with proper defer wrapper
- sed -i "${line}s|defer _ = ${arg}|defer func() { _ = ${arg} }()|" "$file"
- echo "Fixed defer Unsetenv at $file:$line"
- elif echo "$content" | grep -q "defer _ = os\.Setenv"; then
- arg=$(echo "$content" | grep -oP 'os\.Setenv\([^)]+,[^)]+\)')
- sed -i "${line}s|defer _ = ${arg}|defer func() { _ = ${arg} }()|" "$file"
- echo "Fixed defer Setenv at $file:$line"
- fi
- done <<< "$typecheck_errors"
- fi
-done
-
-if [ $i -eq $MAX_ITER ]; then
- echo "❌ Reached maximum iterations!"
- exit 1
-fi
diff --git a/backend/lint-full.txt b/backend/lint-full.txt
deleted file mode 100644
index 7d857c06..00000000
--- a/backend/lint-full.txt
+++ /dev/null
@@ -1,130 +0,0 @@
-internal/api/handlers/certificate_handler_coverage_test.go:114:16: Error return value of `db.AutoMigrate` is not checked (errcheck)
- db.AutoMigrate(&models.SSLCertificate{})
- ^
-internal/api/handlers/certificate_handler_coverage_test.go:137:16: Error return value of `db.AutoMigrate` is not checked (errcheck)
- db.AutoMigrate(&models.SSLCertificate{}, &models.ProxyHost{})
- ^
-internal/api/handlers/certificate_handler_coverage_test.go:163:16: Error return value of `db.AutoMigrate` is not checked (errcheck)
- db.AutoMigrate(&models.SSLCertificate{}, &models.ProxyHost{})
- ^
-internal/api/handlers/settings_handler_test.go:729:18: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &resp)
- ^
-internal/api/handlers/settings_handler_test.go:814:16: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &resp)
- ^
-internal/api/handlers/settings_handler_test.go:853:18: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &resp)
- ^
-internal/caddy/manager_additional_test.go:1316:11: Error return value of `w.Write` is not checked (errcheck)
- w.Write([]byte(`{"apps":{"http":{}}}`))
- ^
-internal/caddy/manager_additional_test.go:1370:11: Error return value of `w.Write` is not checked (errcheck)
- w.Write([]byte(`{"apps":{"http":{}}}`))
- ^
-internal/caddy/manager_additional_test.go:1421:11: Error return value of `w.Write` is not checked (errcheck)
- w.Write([]byte(`{"apps":{"http":{}}}`))
- ^
-internal/crypto/rotation_service_test.go:40:11: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("CHARON_ENCRYPTION_KEY", currentKey)
- ^
-internal/crypto/rotation_service_test.go:41:32: Error return value of `os.Unsetenv` is not checked (errcheck)
- t.Cleanup(func() { os.Unsetenv("CHARON_ENCRYPTION_KEY") })
- ^
-internal/crypto/rotation_service_test.go:61:12: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("CHARON_ENCRYPTION_KEY_NEXT", nextKey)
- ^
-internal/crypto/rotation_service_test.go:62:20: Error return value of `os.Unsetenv` is not checked (errcheck)
- defer os.Unsetenv("CHARON_ENCRYPTION_KEY_NEXT")
- ^
-internal/crypto/rotation_service_test.go:72:12: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("CHARON_ENCRYPTION_KEY_V1", legacyKey)
- ^
-internal/crypto/rotation_service_test.go:73:20: Error return value of `os.Unsetenv` is not checked (errcheck)
- defer os.Unsetenv("CHARON_ENCRYPTION_KEY_V1")
- ^
-internal/services/credential_service_test.go:29:14: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-internal/services/dns_provider_service_test.go:1406:13: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-internal/services/dns_provider_service_test.go:1421:13: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-cmd/api/main.go:29:12: G301: Expect directory permissions to be 0750 or less (gosec)
- if err := os.MkdirAll(logDir, 0o755); err != nil {
- ^
-cmd/api/main.go:32:7: G301: Expect directory permissions to be 0750 or less (gosec)
- _ = os.MkdirAll(logDir, 0o755)
- ^
-internal/api/handlers/manual_challenge_handler.go:649:15: G115: integer overflow conversion int -> uint (gosec)
- return uint(v)
- ^
-internal/api/handlers/manual_challenge_handler.go:651:15: G115: integer overflow conversion int64 -> uint (gosec)
- return uint(v)
- ^
-internal/api/handlers/security_handler_rules_decisions_test.go:162:92: G115: integer overflow conversion uint -> int (gosec)
- req = httptest.NewRequest(http.MethodDelete, "/api/v1/security/rulesets/"+strconv.Itoa(int(rs.ID)), http.NoBody)
- ^
-internal/api/routes/routes.go:488:13: G301: Expect directory permissions to be 0750 or less (gosec)
- if err := os.MkdirAll(filepath.Dir(accessLogPath), 0o755); err != nil {
- ^
-internal/api/routes/routes.go:492:17: G304: Potential file inclusion via variable (gosec)
- if f, err := os.Create(accessLogPath); err == nil {
- ^
-internal/caddy/config.go:463:16: G602: slice index out of range (gosec)
- host := hosts[i]
- ^
-internal/config/config_test.go:67:12: G304: Potential file inclusion via variable (gosec)
- f, err := os.Create(filePath)
- ^
-internal/config/config_test.go:148:12: G304: Potential file inclusion via variable (gosec)
- f, err := os.Create(blockingFile)
- ^
-internal/crowdsec/hub_cache.go:82:12: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- if err := os.WriteFile(archivePath, archive, 0o640); err != nil {
- ^
-internal/crowdsec/hub_cache.go:86:12: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- if err := os.WriteFile(previewPath, []byte(preview), 0o640); err != nil {
- ^
-internal/crowdsec/hub_sync.go:1016:16: G110: Potential DoS vulnerability via decompression bomb (gosec)
- if _, err := io.Copy(f, tr); err != nil {
- ^
-internal/server/server_test.go:19:9: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- err := os.WriteFile(filepath.Join(tempDir, "index.html"), []byte(""), 0o644)
- ^
-internal/services/backup_service.go:316:12: G305: File traversal when extracting zip/tar archive (gosec)
- fpath := filepath.Join(dest, f.Name)
- ^
-internal/services/backup_service.go:345:12: G110: Potential DoS vulnerability via decompression bomb (gosec)
- _, err = io.Copy(outFile, rc)
- ^
-internal/services/backup_service_test.go:469:6: G302: Expect file permissions to be 0600 or less (gosec)
- _ = os.Chmod(service.BackupDir, 0o444)
- ^
-internal/services/backup_service_test.go:470:21: G302: Expect file permissions to be 0600 or less (gosec)
- defer func() { _ = os.Chmod(service.BackupDir, 0o755) }() // Restore for cleanup
- ^
-internal/services/backup_service_test.go:538:8: G302: Expect file permissions to be 0600 or less (gosec)
- _ = os.Chmod(zipPath, 0o444)
- ^
-internal/services/uptime_service_test.go:58:13: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec)
- server := &http.Server{
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusOK)
- }),
- }
-internal/services/uptime_service_test.go:831:14: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec)
- server := &http.Server{
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusNotFound)
- }),
- }
-internal/util/crypto_test.go:63:2: G101: Potential hardcoded credentials (gosec)
- secret := "a]3kL9#mP2$vN7@qR5*wX1&yT4^uI8%oE0!"
- ^
-40 issues:
-* errcheck: 18
-* gosec: 22
-exit status 1
diff --git a/backend/lint_iter_1.txt b/backend/lint_iter_1.txt
deleted file mode 100644
index d08f2eb8..00000000
--- a/backend/lint_iter_1.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-internal/api/handlers/encryption_handler_test.go:374:19: Error return value of `os.Unsetenv` is not checked (errcheck)
- defer os.Unsetenv("CHARON_ENCRYPTION_KEY")
- ^
-internal/api/handlers/encryption_handler_test.go:421:14: Error return value of `os.Unsetenv` is not checked (errcheck)
- os.Unsetenv("CHARON_ENCRYPTION_KEY")
- ^
-internal/api/handlers/encryption_handler_test.go:468:19: Error return value of `os.Unsetenv` is not checked (errcheck)
- defer os.Unsetenv("CHARON_ENCRYPTION_KEY")
- ^
-internal/api/handlers/encryption_handler_test.go:702:11: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("CHARON_ENCRYPTION_KEY", currentKey)
- ^
-internal/api/handlers/encryption_handler_test.go:753:11: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("CHARON_ENCRYPTION_KEY", wrongKey)
- ^
-internal/api/handlers/encryption_handler_test.go:754:11: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("CHARON_ENCRYPTION_KEY_NEXT", nextKey)
- ^
-internal/api/handlers/pr_coverage_test.go:484:13: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-internal/api/handlers/pr_coverage_test.go:589:14: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-internal/api/handlers/pr_coverage_test.go:699:13: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-internal/api/handlers/security_handler_coverage_test.go:615:16: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &tokenResp)
- ^
-internal/api/handlers/security_handler_waf_test.go:194:16: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &resp)
- ^
-internal/api/handlers/security_handler_waf_test.go:363:16: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &resp)
- ^
-internal/api/handlers/additional_coverage_test.go:642:6: G302: Expect file permissions to be 0600 or less (gosec)
- _ = os.Chmod(backupsDir, 0o555)
- ^
-internal/api/handlers/additional_coverage_test.go:643:21: G302: Expect file permissions to be 0600 or less (gosec)
- defer func() { _ = os.Chmod(backupsDir, 0o755) }()
- ^
-internal/api/handlers/backup_handler_test.go:272:6: G302: Expect file permissions to be 0600 or less (gosec)
- _ = os.Chmod(svc.BackupDir, 0o444)
- ^
-internal/api/handlers/crowdsec_exec.go:34:15: G304: Potential file inclusion via variable (gosec)
- data, err := os.ReadFile(cmdlinePath)
- ^
-internal/api/handlers/crowdsec_exec.go:69:12: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- if err := os.WriteFile(e.pidFile(configDir), []byte(strconv.Itoa(pid)), 0o644); err != nil {
- ^
-internal/api/handlers/crowdsec_exec.go:84:12: G304: Potential file inclusion via variable (gosec)
- b, err := os.ReadFile(pidFilePath)
- ^
-internal/api/handlers/crowdsec_handler.go:356:12: G301: Expect directory permissions to be 0750 or less (gosec)
- if err := os.MkdirAll(tmpPath, 0o755); err != nil {
- ^
-internal/api/handlers/crowdsec_handler.go:380:12: G301: Expect directory permissions to be 0750 or less (gosec)
- if err := os.MkdirAll(h.DataDir, 0o755); err != nil {
- ^
-internal/api/handlers/crowdsec_handler.go:387:13: G304: Potential file inclusion via variable (gosec)
- in, err := os.Open(dst)
- ^
-internal/api/handlers/crowdsec_handler.go:568:12: G301: Expect directory permissions to be 0750 or less (gosec)
- if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
- ^
-internal/api/handlers/crowdsec_handler.go:572:12: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- if err := os.WriteFile(p, []byte(payload.Content), 0o644); err != nil {
- ^
-internal/api/handlers/crowdsec_handler.go:1519:12: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- if err := os.WriteFile(acquisPath, []byte(payload.Content), 0o644); err != nil {
- ^
-internal/api/handlers/manual_challenge_handler.go:649:15: G115: integer overflow conversion int -> uint (gosec)
- return uint(v)
- ^
-internal/api/handlers/manual_challenge_handler.go:651:15: G115: integer overflow conversion int64 -> uint (gosec)
- return uint(v)
- ^
-internal/api/handlers/security_handler_rules_decisions_test.go:162:92: G115: integer overflow conversion uint -> int (gosec)
- req = httptest.NewRequest(http.MethodDelete, "/api/v1/security/rulesets/"+strconv.Itoa(int(rs.ID)), http.NoBody)
- ^
-internal/caddy/config.go:463:16: G602: slice index out of range (gosec)
- host := hosts[i]
- ^
-internal/crowdsec/hub_sync.go:1016:16: G110: Potential DoS vulnerability via decompression bomb (gosec)
- if _, err := io.Copy(f, tr); err != nil {
- ^
-internal/services/backup_service.go:316:12: G305: File traversal when extracting zip/tar archive (gosec)
- fpath := filepath.Join(dest, f.Name)
- ^
-internal/services/backup_service.go:345:12: G110: Potential DoS vulnerability via decompression bomb (gosec)
- _, err = io.Copy(outFile, rc)
- ^
-internal/services/uptime_service_test.go:58:13: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec)
- server := &http.Server{
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusOK)
- }),
- }
-internal/services/uptime_service_test.go:831:14: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec)
- server := &http.Server{
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusNotFound)
- }),
- }
-internal/util/crypto_test.go:63:2: G101: Potential hardcoded credentials (gosec)
- secret := "a]3kL9#mP2$vN7@qR5*wX1&yT4^uI8%oE0!"
- ^
-34 issues:
-* errcheck: 12
-* gosec: 22
diff --git a/backend/lint_iter_2.txt b/backend/lint_iter_2.txt
deleted file mode 100644
index 359fcb25..00000000
--- a/backend/lint_iter_2.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-internal/api/handlers/access_list_handler.go:1: : # github.com/Wikid82/charon/backend/internal/api/handlers [github.com/Wikid82/charon/backend/internal/api/handlers.test]
-internal/api/handlers/encryption_handler_test.go:374:10: syntax error: unexpected = at end of statement
-internal/api/handlers/encryption_handler_test.go:468:10: syntax error: unexpected = at end of statement (typecheck)
-package handlers
-internal/api/handlers/encryption_handler_test.go:374:10: expected '==', found '=' (typecheck)
- defer _ = os.Unsetenv("CHARON_ENCRYPTION_KEY")
- ^
-internal/api/handlers/encryption_handler_test.go:468:10: expected '==', found '=' (typecheck)
- defer _ = os.Unsetenv("CHARON_ENCRYPTION_KEY")
- ^
-3 issues:
-* typecheck: 3
diff --git a/backend/lint_iter_3.txt b/backend/lint_iter_3.txt
deleted file mode 100644
index 27bd33ba..00000000
--- a/backend/lint_iter_3.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-internal/api/handlers/access_list_handler.go:1: : # github.com/Wikid82/charon/backend/internal/api/handlers [github.com/Wikid82/charon/backend/internal/api/handlers.test]
-internal/api/handlers/encryption_handler_test.go:468:10: syntax error: unexpected = at end of statement (typecheck)
-package handlers
-internal/api/handlers/encryption_handler_test.go:468:10: expected '==', found '=' (typecheck)
- defer _ = os.Unsetenv("CHARON_ENCRYPTION_KEY")
- ^
-2 issues:
-* typecheck: 2
diff --git a/backend/lint_iter_4.txt b/backend/lint_iter_4.txt
deleted file mode 100644
index 31782081..00000000
--- a/backend/lint_iter_4.txt
+++ /dev/null
@@ -1,111 +0,0 @@
-internal/api/handlers/security_handler_waf_test.go:371:16: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &resp)
- ^
-internal/api/handlers/security_handler_waf_test.go:406:16: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &resp)
- ^
-internal/api/handlers/security_handler_waf_test.go:517:16: Error return value of `json.Unmarshal` is not checked (errcheck)
- json.Unmarshal(w.Body.Bytes(), &resp)
- ^
-internal/caddy/config_test.go:1801:16: Error return value of `os.Unsetenv` is not checked (errcheck)
- os.Unsetenv(k)
- ^
-internal/caddy/config_test.go:1816:13: Error return value of `os.Unsetenv` is not checked (errcheck)
- os.Unsetenv("CROWDSEC_API_KEY")
- ^
-internal/caddy/manager_helpers_test.go:171:14: Error return value of `os.Unsetenv` is not checked (errcheck)
- os.Unsetenv(key)
- ^
-internal/config/config_test.go:83:11: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("CPM_IMPORT_DIR", filePath)
- ^
-internal/config/config_test.go:113:11: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("TEST_KEY3", "")
- ^
-internal/config/config_test.go:121:11: Error return value of `os.Setenv` is not checked (errcheck)
- os.Setenv("CHARON_DB_PATH", filepath.Join(tempDir, "test.db"))
- ^
-internal/services/notification_service_test.go:1952:13: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-internal/services/notification_service_test.go:1967:13: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-internal/services/uptime_service_test.go:261:14: Error return value of `sqlDB.Close` is not checked (errcheck)
- sqlDB.Close()
- ^
-internal/api/handlers/manual_challenge_handler.go:649:15: G115: integer overflow conversion int -> uint (gosec)
- return uint(v)
- ^
-internal/api/handlers/manual_challenge_handler.go:651:15: G115: integer overflow conversion int64 -> uint (gosec)
- return uint(v)
- ^
-internal/api/handlers/security_handler_rules_decisions_test.go:162:92: G115: integer overflow conversion uint -> int (gosec)
- req = httptest.NewRequest(http.MethodDelete, "/api/v1/security/rulesets/"+strconv.Itoa(int(rs.ID)), http.NoBody)
- ^
-internal/caddy/config.go:463:16: G602: slice index out of range (gosec)
- host := hosts[i]
- ^
-internal/caddy/importer.go:372:12: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- if err := os.WriteFile(backupPath, input, 0o644); err != nil {
- ^
-internal/caddy/importer_additional_test.go:43:9: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- err := os.WriteFile(tmpFile, []byte("foo"), 0o644)
- ^
-internal/caddy/importer_additional_test.go:57:9: G306: Expect WriteFile permissions to be 0600 or less (gosec)
- err := os.WriteFile(tmpFile, []byte("foo"), 0o644)
- ^
-internal/caddy/importer_extra_test.go:143:12: G304: Potential file inclusion via variable (gosec)
- b, err := os.ReadFile(path)
- ^
-internal/config/config.go:68:12: G301: Expect directory permissions to be 0750 or less (gosec)
- if err := os.MkdirAll(filepath.Dir(cfg.DatabasePath), 0o755); err != nil {
- ^
-internal/config/config.go:72:12: G301: Expect directory permissions to be 0750 or less (gosec)
- if err := os.MkdirAll(cfg.CaddyConfigDir, 0o755); err != nil {
- ^
-internal/config/config.go:76:12: G301: Expect directory permissions to be 0750 or less (gosec)
- if err := os.MkdirAll(cfg.ImportDir, 0o755); err != nil {
- ^
-internal/config/config_test.go:67:12: G304: Potential file inclusion via variable (gosec)
- f, err := os.Create(filePath)
- ^
-internal/config/config_test.go:148:12: G304: Potential file inclusion via variable (gosec)
- f, err := os.Create(blockingFile)
- ^
-internal/crowdsec/hub_sync.go:1016:16: G110: Potential DoS vulnerability via decompression bomb (gosec)
- if _, err := io.Copy(f, tr); err != nil {
- ^
-internal/services/backup_service.go:316:12: G305: File traversal when extracting zip/tar archive (gosec)
- fpath := filepath.Join(dest, f.Name)
- ^
-internal/services/backup_service.go:345:12: G110: Potential DoS vulnerability via decompression bomb (gosec)
- _, err = io.Copy(outFile, rc)
- ^
-internal/services/backup_service_test.go:469:6: G302: Expect file permissions to be 0600 or less (gosec)
- _ = os.Chmod(service.BackupDir, 0o444)
- ^
-internal/services/backup_service_test.go:470:21: G302: Expect file permissions to be 0600 or less (gosec)
- defer func() { _ = os.Chmod(service.BackupDir, 0o755) }() // Restore for cleanup
- ^
-internal/services/backup_service_test.go:538:8: G302: Expect file permissions to be 0600 or less (gosec)
- _ = os.Chmod(zipPath, 0o444)
- ^
-internal/services/uptime_service_test.go:58:13: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec)
- server := &http.Server{
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusOK)
- }),
- }
-internal/services/uptime_service_test.go:831:14: G112: Potential Slowloris Attack because ReadHeaderTimeout is not configured in the http.Server (gosec)
- server := &http.Server{
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusNotFound)
- }),
- }
-internal/util/crypto_test.go:63:2: G101: Potential hardcoded credentials (gosec)
- secret := "a]3kL9#mP2$vN7@qR5*wX1&yT4^uI8%oE0!"
- ^
-34 issues:
-* errcheck: 12
-* gosec: 22
diff --git a/backend/lint_iter_5.txt b/backend/lint_iter_5.txt
deleted file mode 100644
index e69de29b..00000000
diff --git a/backend/package-lock.json b/backend/package-lock.json
deleted file mode 100644
index eeca0ca2..00000000
--- a/backend/package-lock.json
+++ /dev/null
@@ -1,1755 +0,0 @@
-{
- "name": "backend",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "devDependencies": {
- "@vitest/coverage-v8": "^4.0.17"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
- "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
- "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
- "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
- "dev": true,
- "dependencies": {
- "@babel/types": "^7.28.5"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.28.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
- "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
- "dev": true,
- "dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@bcoe/v8-coverage": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
- "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
- "dev": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz",
- "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz",
- "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz",
- "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz",
- "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz",
- "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz",
- "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz",
- "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz",
- "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz",
- "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz",
- "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz",
- "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz",
- "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz",
- "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz",
- "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz",
- "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz",
- "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz",
- "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz",
- "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz",
- "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz",
- "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz",
- "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz",
- "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz",
- "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz",
- "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz",
- "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz",
- "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "dev": true,
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "dev": true
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "dev": true,
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz",
- "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz",
- "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz",
- "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz",
- "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz",
- "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz",
- "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz",
- "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz",
- "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz",
- "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz",
- "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz",
- "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz",
- "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz",
- "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz",
- "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz",
- "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz",
- "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz",
- "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz",
- "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz",
- "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz",
- "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz",
- "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz",
- "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz",
- "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz",
- "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz",
- "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "peer": true
- },
- "node_modules/@standard-schema/spec": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
- "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
- "node_modules/@types/chai": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
- "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@types/deep-eql": "*",
- "assertion-error": "^2.0.1"
- }
- },
- "node_modules/@types/deep-eql": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
- "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
- "node_modules/@types/estree": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
- "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
- "dev": true
- },
- "node_modules/@vitest/coverage-v8": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.17.tgz",
- "integrity": "sha512-/6zU2FLGg0jsd+ePZcwHRy3+WpNTBBhDY56P4JTRqUN/Dp6CvOEa9HrikcQ4KfV2b2kAHUFB4dl1SuocWXSFEw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@bcoe/v8-coverage": "^1.0.2",
- "@vitest/utils": "4.0.17",
- "ast-v8-to-istanbul": "^0.3.10",
- "istanbul-lib-coverage": "^3.2.2",
- "istanbul-lib-report": "^3.0.1",
- "istanbul-reports": "^3.2.0",
- "magicast": "^0.5.1",
- "obug": "^2.1.1",
- "std-env": "^3.10.0",
- "tinyrainbow": "^3.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "@vitest/browser": "4.0.17",
- "vitest": "4.0.17"
- },
- "peerDependenciesMeta": {
- "@vitest/browser": {
- "optional": true
- }
- }
- },
- "node_modules/@vitest/expect": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.17.tgz",
- "integrity": "sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@standard-schema/spec": "^1.0.0",
- "@types/chai": "^5.2.2",
- "@vitest/spy": "4.0.17",
- "@vitest/utils": "4.0.17",
- "chai": "^6.2.1",
- "tinyrainbow": "^3.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/mocker": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.17.tgz",
- "integrity": "sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@vitest/spy": "4.0.17",
- "estree-walker": "^3.0.3",
- "magic-string": "^0.30.21"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "msw": "^2.4.9",
- "vite": "^6.0.0 || ^7.0.0-0"
- },
- "peerDependenciesMeta": {
- "msw": {
- "optional": true
- },
- "vite": {
- "optional": true
- }
- }
- },
- "node_modules/@vitest/pretty-format": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.17.tgz",
- "integrity": "sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tinyrainbow": "^3.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/runner": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.17.tgz",
- "integrity": "sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@vitest/utils": "4.0.17",
- "pathe": "^2.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/snapshot": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.17.tgz",
- "integrity": "sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@vitest/pretty-format": "4.0.17",
- "magic-string": "^0.30.21",
- "pathe": "^2.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/spy": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.17.tgz",
- "integrity": "sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/utils": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.17.tgz",
- "integrity": "sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/pretty-format": "4.0.17",
- "tinyrainbow": "^3.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/assertion-error": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
- "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/ast-v8-to-istanbul": {
- "version": "0.3.10",
- "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz",
- "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/trace-mapping": "^0.3.31",
- "estree-walker": "^3.0.3",
- "js-tokens": "^9.0.1"
- }
- },
- "node_modules/chai": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
- "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/es-module-lexer": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
- "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
- "dev": true,
- "peer": true
- },
- "node_modules/esbuild": {
- "version": "0.27.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz",
- "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "peer": true,
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.2",
- "@esbuild/android-arm": "0.27.2",
- "@esbuild/android-arm64": "0.27.2",
- "@esbuild/android-x64": "0.27.2",
- "@esbuild/darwin-arm64": "0.27.2",
- "@esbuild/darwin-x64": "0.27.2",
- "@esbuild/freebsd-arm64": "0.27.2",
- "@esbuild/freebsd-x64": "0.27.2",
- "@esbuild/linux-arm": "0.27.2",
- "@esbuild/linux-arm64": "0.27.2",
- "@esbuild/linux-ia32": "0.27.2",
- "@esbuild/linux-loong64": "0.27.2",
- "@esbuild/linux-mips64el": "0.27.2",
- "@esbuild/linux-ppc64": "0.27.2",
- "@esbuild/linux-riscv64": "0.27.2",
- "@esbuild/linux-s390x": "0.27.2",
- "@esbuild/linux-x64": "0.27.2",
- "@esbuild/netbsd-arm64": "0.27.2",
- "@esbuild/netbsd-x64": "0.27.2",
- "@esbuild/openbsd-arm64": "0.27.2",
- "@esbuild/openbsd-x64": "0.27.2",
- "@esbuild/openharmony-arm64": "0.27.2",
- "@esbuild/sunos-x64": "0.27.2",
- "@esbuild/win32-arm64": "0.27.2",
- "@esbuild/win32-ia32": "0.27.2",
- "@esbuild/win32-x64": "0.27.2"
- }
- },
- "node_modules/estree-walker": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
- "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
- "dev": true,
- "dependencies": {
- "@types/estree": "^1.0.0"
- }
- },
- "node_modules/expect-type": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz",
- "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==",
- "dev": true,
- "peer": true,
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "peer": true,
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/html-escaper": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
- "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
- "dev": true
- },
- "node_modules/istanbul-lib-coverage": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
- "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/istanbul-lib-report": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
- "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
- "dev": true,
- "dependencies": {
- "istanbul-lib-coverage": "^3.0.0",
- "make-dir": "^4.0.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/istanbul-reports": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
- "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
- "dev": true,
- "dependencies": {
- "html-escaper": "^2.0.0",
- "istanbul-lib-report": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/js-tokens": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
- "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
- "dev": true
- },
- "node_modules/magic-string": {
- "version": "0.30.21",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
- "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
- "node_modules/magicast": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz",
- "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==",
- "dev": true,
- "dependencies": {
- "@babel/parser": "^7.28.5",
- "@babel/types": "^7.28.5",
- "source-map-js": "^1.2.1"
- }
- },
- "node_modules/make-dir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
- "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
- "dev": true,
- "dependencies": {
- "semver": "^7.5.3"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "peer": true,
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/obug": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz",
- "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==",
- "dev": true,
- "funding": [
- "https://github.com/sponsors/sxzz",
- "https://opencollective.com/debug"
- ],
- "license": "MIT"
- },
- "node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true,
- "license": "MIT",
- "peer": true
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "dev": true,
- "license": "ISC",
- "peer": true
- },
- "node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.6",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
- "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "nanoid": "^3.3.11",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/rollup": {
- "version": "4.55.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz",
- "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@types/estree": "1.0.8"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.55.1",
- "@rollup/rollup-android-arm64": "4.55.1",
- "@rollup/rollup-darwin-arm64": "4.55.1",
- "@rollup/rollup-darwin-x64": "4.55.1",
- "@rollup/rollup-freebsd-arm64": "4.55.1",
- "@rollup/rollup-freebsd-x64": "4.55.1",
- "@rollup/rollup-linux-arm-gnueabihf": "4.55.1",
- "@rollup/rollup-linux-arm-musleabihf": "4.55.1",
- "@rollup/rollup-linux-arm64-gnu": "4.55.1",
- "@rollup/rollup-linux-arm64-musl": "4.55.1",
- "@rollup/rollup-linux-loong64-gnu": "4.55.1",
- "@rollup/rollup-linux-loong64-musl": "4.55.1",
- "@rollup/rollup-linux-ppc64-gnu": "4.55.1",
- "@rollup/rollup-linux-ppc64-musl": "4.55.1",
- "@rollup/rollup-linux-riscv64-gnu": "4.55.1",
- "@rollup/rollup-linux-riscv64-musl": "4.55.1",
- "@rollup/rollup-linux-s390x-gnu": "4.55.1",
- "@rollup/rollup-linux-x64-gnu": "4.55.1",
- "@rollup/rollup-linux-x64-musl": "4.55.1",
- "@rollup/rollup-openbsd-x64": "4.55.1",
- "@rollup/rollup-openharmony-arm64": "4.55.1",
- "@rollup/rollup-win32-arm64-msvc": "4.55.1",
- "@rollup/rollup-win32-ia32-msvc": "4.55.1",
- "@rollup/rollup-win32-x64-gnu": "4.55.1",
- "@rollup/rollup-win32-x64-msvc": "4.55.1",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/semver": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
- "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
- "dev": true,
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/siginfo": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
- "dev": true,
- "peer": true
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/stackback": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
- "dev": true,
- "peer": true
- },
- "node_modules/std-env": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
- "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
- "dev": true
- },
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tinybench": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
- "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
- "dev": true,
- "peer": true
- },
- "node_modules/tinyexec": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
- "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/tinyglobby": {
- "version": "0.2.15",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
- "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/tinyrainbow": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz",
- "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==",
- "dev": true,
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/vite": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
- "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "esbuild": "^0.27.0",
- "fdir": "^6.5.0",
- "picomatch": "^4.0.3",
- "postcss": "^8.5.6",
- "rollup": "^4.43.0",
- "tinyglobby": "^0.2.15"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^20.19.0 || >=22.12.0",
- "jiti": ">=1.21.0",
- "less": "^4.0.0",
- "lightningcss": "^1.21.0",
- "sass": "^1.70.0",
- "sass-embedded": "^1.70.0",
- "stylus": ">=0.54.8",
- "sugarss": "^5.0.0",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "jiti": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "lightningcss": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
- "node_modules/vitest": {
- "version": "4.0.17",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.17.tgz",
- "integrity": "sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==",
- "dev": true,
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@vitest/expect": "4.0.17",
- "@vitest/mocker": "4.0.17",
- "@vitest/pretty-format": "4.0.17",
- "@vitest/runner": "4.0.17",
- "@vitest/snapshot": "4.0.17",
- "@vitest/spy": "4.0.17",
- "@vitest/utils": "4.0.17",
- "es-module-lexer": "^1.7.0",
- "expect-type": "^1.2.2",
- "magic-string": "^0.30.21",
- "obug": "^2.1.1",
- "pathe": "^2.0.3",
- "picomatch": "^4.0.3",
- "std-env": "^3.10.0",
- "tinybench": "^2.9.0",
- "tinyexec": "^1.0.2",
- "tinyglobby": "^0.2.15",
- "tinyrainbow": "^3.0.3",
- "vite": "^6.0.0 || ^7.0.0",
- "why-is-node-running": "^2.3.0"
- },
- "bin": {
- "vitest": "vitest.mjs"
- },
- "engines": {
- "node": "^20.0.0 || ^22.0.0 || >=24.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- },
- "peerDependencies": {
- "@edge-runtime/vm": "*",
- "@opentelemetry/api": "^1.9.0",
- "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0",
- "@vitest/browser-playwright": "4.0.17",
- "@vitest/browser-preview": "4.0.17",
- "@vitest/browser-webdriverio": "4.0.17",
- "@vitest/ui": "4.0.17",
- "happy-dom": "*",
- "jsdom": "*"
- },
- "peerDependenciesMeta": {
- "@edge-runtime/vm": {
- "optional": true
- },
- "@opentelemetry/api": {
- "optional": true
- },
- "@types/node": {
- "optional": true
- },
- "@vitest/browser-playwright": {
- "optional": true
- },
- "@vitest/browser-preview": {
- "optional": true
- },
- "@vitest/browser-webdriverio": {
- "optional": true
- },
- "@vitest/ui": {
- "optional": true
- },
- "happy-dom": {
- "optional": true
- },
- "jsdom": {
- "optional": true
- }
- }
- },
- "node_modules/why-is-node-running": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
- "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
- "dev": true,
- "peer": true,
- "dependencies": {
- "siginfo": "^2.0.0",
- "stackback": "0.0.2"
- },
- "bin": {
- "why-is-node-running": "cli.js"
- },
- "engines": {
- "node": ">=8"
- }
- }
- }
-}
diff --git a/backend/package.json b/backend/package.json
deleted file mode 100644
index 067b502c..00000000
--- a/backend/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "devDependencies": {
- "@vitest/coverage-v8": "^4.0.17"
- }
-}
diff --git a/backend/test-output-final.txt b/backend/test-output-final.txt
deleted file mode 100644
index 51f14e15..00000000
--- a/backend/test-output-final.txt
+++ /dev/null
@@ -1,6488 +0,0 @@
-=== RUN TestResetPasswordCommand_Succeeds
---- PASS: TestResetPasswordCommand_Succeeds (0.14s)
-PASS
-ok github.com/Wikid82/charon/backend/cmd/api (cached)
-=== RUN TestSeedMain_Smoke
-{"level":"info","msg":"✓ Database migrated successfully","time":"2025-12-12T19:01:35Z"}
-{"level":"info","msg":"✓ Created remote server: Local Docker Registry (localhost:5000)","server":"Local Docker Registry","time":"2025-12-12T19:01:35Z"}
-{"level":"info","msg":"✓ Created remote server: Development API Server (192.168.1.100:8080)","server":"Development API Server","time":"2025-12-12T19:01:35Z"}
-{"level":"info","msg":"✓ Created remote server: Staging Web App (staging.internal:3000)","server":"Staging Web App","time":"2025-12-12T19:01:35Z"}
-{"level":"info","msg":"✓ Created remote server: Database Admin (localhost:8081)","server":"Database Admin","time":"2025-12-12T19:01:35Z"}
-{"host":"app.local.dev","level":"info","msg":"✓ Created proxy host: app.local.dev -\u003e http://localhost:3000","time":"2025-12-12T19:01:35Z"}
-{"host":"api.local.dev","level":"info","msg":"✓ Created proxy host: api.local.dev -\u003e http://192.168.1.100:8080","time":"2025-12-12T19:01:35Z"}
-{"host":"docker.local.dev","level":"info","msg":"✓ Created proxy host: docker.local.dev -\u003e http://localhost:5000","time":"2025-12-12T19:01:35Z"}
-{"level":"info","msg":"✓ Created setting: app_name = Charon","setting":"app_name","time":"2025-12-12T19:01:35Z"}
-{"level":"info","msg":"✓ Created setting: default_scheme = http","setting":"default_scheme","time":"2025-12-12T19:01:35Z"}
-{"level":"info","msg":"✓ Created setting: enable_ssl_by_default = false","setting":"enable_ssl_by_default","time":"2025-12-12T19:01:35Z"}
-
-2025/12/12 19:01:35 [31;1m/projects/Charon/backend/cmd/seed/main.go:218 [35;1mrecord not found
-[0m[33m[0.135ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE email = "admin@localhost" ORDER BY `users`.`id` LIMIT 1
-{"level":"info","msg":"✓ Created default user: admin@localhost","time":"2025-12-12T19:01:35Z","user":"admin@localhost"}
-{"level":"info","msg":"\n✓ Database seeding completed successfully!","time":"2025-12-12T19:01:35Z"}
-{"level":"info","msg":" You can now start the application and see sample data.","time":"2025-12-12T19:01:35Z"}
---- PASS: TestSeedMain_Smoke (0.19s)
-PASS
-ok github.com/Wikid82/charon/backend/cmd/seed (cached)
-? github.com/Wikid82/charon/backend/integration [no test files]
-=== RUN TestAccessListHandler_SetGeoIPService
---- PASS: TestAccessListHandler_SetGeoIPService (0.00s)
-=== RUN TestAccessListHandler_SetGeoIPService_Nil
---- PASS: TestAccessListHandler_SetGeoIPService_Nil (0.00s)
-=== RUN TestAccessListHandler_Get_InvalidID
---- PASS: TestAccessListHandler_Get_InvalidID (0.00s)
-=== RUN TestAccessListHandler_Update_InvalidID
---- PASS: TestAccessListHandler_Update_InvalidID (0.00s)
-=== RUN TestAccessListHandler_Update_InvalidJSON
---- PASS: TestAccessListHandler_Update_InvalidJSON (0.00s)
-=== RUN TestAccessListHandler_Delete_InvalidID
---- PASS: TestAccessListHandler_Delete_InvalidID (0.00s)
-=== RUN TestAccessListHandler_TestIP_InvalidID
---- PASS: TestAccessListHandler_TestIP_InvalidID (0.00s)
-=== RUN TestAccessListHandler_TestIP_MissingIPAddress
---- PASS: TestAccessListHandler_TestIP_MissingIPAddress (0.00s)
-=== RUN TestAccessListHandler_List_DBError
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:129 [35;1mno such table: access_lists
-[0m[33m[0.105ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` ORDER BY updated_at desc
---- PASS: TestAccessListHandler_List_DBError (0.00s)
-=== RUN TestAccessListHandler_Get_DBError
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mno such table: access_lists
-[0m[33m[0.095ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 1 ORDER BY `access_lists`.`id` LIMIT 1
---- PASS: TestAccessListHandler_Get_DBError (0.00s)
-=== RUN TestAccessListHandler_Delete_InternalError
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:162 [35;1mno such table: proxy_hosts
-[0m[33m[0.329ms] [34;1m[rows:0][0m SELECT count(*) FROM `proxy_hosts` WHERE access_list_id = 1
---- PASS: TestAccessListHandler_Delete_InternalError (0.00s)
-=== RUN TestAccessListHandler_Update_InvalidType
---- PASS: TestAccessListHandler_Update_InvalidType (0.00s)
-=== RUN TestAccessListHandler_Create_InvalidJSON
---- PASS: TestAccessListHandler_Create_InvalidJSON (0.00s)
-=== RUN TestAccessListHandler_TestIP_Blacklist
---- PASS: TestAccessListHandler_TestIP_Blacklist (0.00s)
-=== RUN TestAccessListHandler_TestIP_GeoWhitelist
---- PASS: TestAccessListHandler_TestIP_GeoWhitelist (0.01s)
-=== RUN TestAccessListHandler_TestIP_LocalNetworkOnly
---- PASS: TestAccessListHandler_TestIP_LocalNetworkOnly (0.00s)
-=== RUN TestAccessListHandler_TestIP_InternalError
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mno such table: access_lists
-[0m[33m[0.104ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 1 ORDER BY `access_lists`.`id` LIMIT 1
---- PASS: TestAccessListHandler_TestIP_InternalError (0.00s)
-=== RUN TestAccessListHandler_Create
-=== RUN TestAccessListHandler_Create/create_whitelist_successfully
-=== RUN TestAccessListHandler_Create/create_geo_whitelist_successfully
-=== RUN TestAccessListHandler_Create/create_local_network_only
-=== RUN TestAccessListHandler_Create/fail_with_invalid_type
-=== RUN TestAccessListHandler_Create/fail_with_missing_name
---- PASS: TestAccessListHandler_Create (0.00s)
- --- PASS: TestAccessListHandler_Create/create_whitelist_successfully (0.00s)
- --- PASS: TestAccessListHandler_Create/create_geo_whitelist_successfully (0.00s)
- --- PASS: TestAccessListHandler_Create/create_local_network_only (0.00s)
- --- PASS: TestAccessListHandler_Create/fail_with_invalid_type (0.00s)
- --- PASS: TestAccessListHandler_Create/fail_with_missing_name (0.00s)
-=== RUN TestAccessListHandler_List
---- PASS: TestAccessListHandler_List (0.00s)
-=== RUN TestAccessListHandler_Get
-=== RUN TestAccessListHandler_Get/get_existing_ACL
-=== RUN TestAccessListHandler_Get/get_non-existent_ACL
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
-[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 9999 ORDER BY `access_lists`.`id` LIMIT 1
---- PASS: TestAccessListHandler_Get (0.00s)
- --- PASS: TestAccessListHandler_Get/get_existing_ACL (0.00s)
- --- PASS: TestAccessListHandler_Get/get_non-existent_ACL (0.00s)
-=== RUN TestAccessListHandler_Update
-=== RUN TestAccessListHandler_Update/update_successfully
-=== RUN TestAccessListHandler_Update/update_non-existent_ACL
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
-[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 9999 ORDER BY `access_lists`.`id` LIMIT 1
---- PASS: TestAccessListHandler_Update (0.00s)
- --- PASS: TestAccessListHandler_Update/update_successfully (0.00s)
- --- PASS: TestAccessListHandler_Update/update_non-existent_ACL (0.00s)
-=== RUN TestAccessListHandler_Delete
-=== RUN TestAccessListHandler_Delete/delete_successfully
-=== RUN TestAccessListHandler_Delete/fail_to_delete_ACL_in_use
-=== RUN TestAccessListHandler_Delete/delete_non-existent_ACL
---- PASS: TestAccessListHandler_Delete (0.00s)
- --- PASS: TestAccessListHandler_Delete/delete_successfully (0.00s)
- --- PASS: TestAccessListHandler_Delete/fail_to_delete_ACL_in_use (0.00s)
- --- PASS: TestAccessListHandler_Delete/delete_non-existent_ACL (0.00s)
-=== RUN TestAccessListHandler_TestIP
-=== RUN TestAccessListHandler_TestIP/test_IP_in_whitelist
-=== RUN TestAccessListHandler_TestIP/test_IP_not_in_whitelist
-=== RUN TestAccessListHandler_TestIP/test_invalid_IP
-=== RUN TestAccessListHandler_TestIP/test_non-existent_ACL
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/services/access_list_service.go:105 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `access_lists` WHERE `access_lists`.`id` = 9999 ORDER BY `access_lists`.`id` LIMIT 1
---- PASS: TestAccessListHandler_TestIP (0.00s)
- --- PASS: TestAccessListHandler_TestIP/test_IP_in_whitelist (0.00s)
- --- PASS: TestAccessListHandler_TestIP/test_IP_not_in_whitelist (0.00s)
- --- PASS: TestAccessListHandler_TestIP/test_invalid_IP (0.00s)
- --- PASS: TestAccessListHandler_TestIP/test_non-existent_ACL (0.00s)
-=== RUN TestAccessListHandler_GetTemplates
---- PASS: TestAccessListHandler_GetTemplates (0.00s)
-=== RUN TestImportHandler_Commit_InvalidJSON
---- PASS: TestImportHandler_Commit_InvalidJSON (0.00s)
-=== RUN TestImportHandler_Commit_InvalidSessionUUID
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
-[0m[33m[0.048ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "passwd" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_Commit_InvalidSessionUUID (0.00s)
-=== RUN TestImportHandler_Commit_SessionNotFound
-
-2025/12/12 19:05:33 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
-[0m[33m[0.061ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "nonexistent-session" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_Commit_SessionNotFound (0.00s)
-=== RUN TestRemoteServerHandler_TestConnection_Unreachable
---- PASS: TestRemoteServerHandler_TestConnection_Unreachable (5.01s)
-=== RUN TestSecurityHandler_GetConfig_InternalError
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mno such table: security_configs
-[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_GetConfig_InternalError (0.00s)
-=== RUN TestSecurityHandler_UpdateConfig_ApplyCaddyError
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
-[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "test" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_UpdateConfig_ApplyCaddyError (0.00s)
-=== RUN TestSecurityHandler_GenerateBreakGlass_Error
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mno such table: security_configs
-[0m[33m[0.079ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_GenerateBreakGlass_Error (0.06s)
-=== RUN TestSecurityHandler_ListDecisions_Error
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:178 [35;1mno such table: security_decisions
-[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc LIMIT 50
---- PASS: TestSecurityHandler_ListDecisions_Error (0.00s)
-=== RUN TestSecurityHandler_ListRuleSets_Error
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:243 [35;1mno such table: security_rule_sets
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`
---- PASS: TestSecurityHandler_ListRuleSets_Error (0.00s)
-=== RUN TestSecurityHandler_UpsertRuleSet_Error
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mno such table: security_rule_sets
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "test-ruleset" ORDER BY `security_rule_sets`.`id` LIMIT 1
---- PASS: TestSecurityHandler_UpsertRuleSet_Error (0.00s)
-=== RUN TestSecurityHandler_CreateDecision_LogError
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:168 [35;1mno such table: security_decisions
-[0m[33m[0.042ms] [34;1m[rows:0][0m INSERT INTO `security_decisions` (`uuid`,`source`,`action`,`ip`,`host`,`rule_id`,`details`,`created_at`) VALUES ("98eeedc9-a1f0-4dbf-b3a2-6558ed7ed345","manual","ban","192.168.1.1","","","","2025-12-12 19:05:38.782") RETURNING `id`
---- PASS: TestSecurityHandler_CreateDecision_LogError (0.00s)
-=== RUN TestSecurityHandler_DeleteRuleSet_Error
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/security_service.go:234 [35;1mno such table: security_rule_sets
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE `security_rule_sets`.`id` = 999 ORDER BY `security_rule_sets`.`id` LIMIT 1
---- PASS: TestSecurityHandler_DeleteRuleSet_Error (0.00s)
-=== RUN TestCrowdsec_ImportConfig_EmptyUpload
---- PASS: TestCrowdsec_ImportConfig_EmptyUpload (0.00s)
-=== RUN TestBackupHandler_List_DBError
---- PASS: TestBackupHandler_List_DBError (0.00s)
-=== RUN TestImportHandler_UploadMulti_InvalidJSON
---- PASS: TestImportHandler_UploadMulti_InvalidJSON (0.00s)
-=== RUN TestImportHandler_UploadMulti_MissingCaddyfile
---- PASS: TestImportHandler_UploadMulti_MissingCaddyfile (0.00s)
-=== RUN TestImportHandler_UploadMulti_EmptyContent
---- PASS: TestImportHandler_UploadMulti_EmptyContent (0.00s)
-=== RUN TestImportHandler_UploadMulti_PathTraversal
---- PASS: TestImportHandler_UploadMulti_PathTraversal (0.00s)
-=== RUN TestLogsHandler_Download_PathTraversal
---- PASS: TestLogsHandler_Download_PathTraversal (0.00s)
-=== RUN TestLogsHandler_Download_NotFound
---- PASS: TestLogsHandler_Download_NotFound (0.00s)
-=== RUN TestLogsHandler_Download_Success
---- PASS: TestLogsHandler_Download_Success (0.00s)
-=== RUN TestImportHandler_Upload_InvalidJSON
-time="2025-12-12T19:05:38Z" level=error msg="Import Upload: failed to bind JSON" error="invalid character 'o' in literal null (expecting 'u')"
---- PASS: TestImportHandler_Upload_InvalidJSON (0.00s)
-=== RUN TestImportHandler_Upload_EmptyContent
-time="2025-12-12T19:05:38Z" level=error msg="Import Upload: failed to bind JSON" error="Key: 'Content' Error:Field validation for 'Content' failed on the 'required' tag"
---- PASS: TestImportHandler_Upload_EmptyContent (0.00s)
-=== RUN TestBackupHandler_List_ServiceError
---- PASS: TestBackupHandler_List_ServiceError (0.00s)
-=== RUN TestBackupHandler_Delete_PathTraversal
---- PASS: TestBackupHandler_Delete_PathTraversal (0.00s)
-=== RUN TestBackupHandler_Delete_InternalError2
---- PASS: TestBackupHandler_Delete_InternalError2 (0.00s)
-=== RUN TestRemoteServerHandler_TestConnection_NotFound2
-
-2025/12/12 19:05:38 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "nonexistent-uuid" ORDER BY `remote_servers`.`id` LIMIT 1
---- PASS: TestRemoteServerHandler_TestConnection_NotFound2 (0.00s)
-=== RUN TestRemoteServerHandler_TestConnectionCustom_Unreachable2
---- PASS: TestRemoteServerHandler_TestConnectionCustom_Unreachable2 (5.00s)
-=== RUN TestAuthHandler_Register_InvalidJSON
---- PASS: TestAuthHandler_Register_InvalidJSON (0.00s)
-=== RUN TestHealthHandler_Basic
---- PASS: TestHealthHandler_Basic (0.00s)
-=== RUN TestBackupHandler_Create_Error
-time="2025-12-12T19:05:43Z" level=error msg="Failed to create backup" action=create_backup error="database file not found: /tmp/TestBackupHandler_Create_Error2570738469/001/data/charon.db"
---- PASS: TestBackupHandler_Create_Error (0.00s)
-=== RUN TestSettingsHandler_GetSettings_Error
-
-2025/12/12 19:05:43 [31;1m/projects/Charon/backend/internal/api/handlers/settings_handler.go:28 [35;1mno such table: settings
-[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings`
---- PASS: TestSettingsHandler_GetSettings_Error (0.00s)
-=== RUN TestSettingsHandler_UpdateSetting_InvalidJSON
---- PASS: TestSettingsHandler_UpdateSetting_InvalidJSON (0.00s)
-=== RUN TestRemoteServerHandler_TestConnection_Reachable
---- PASS: TestRemoteServerHandler_TestConnection_Reachable (0.00s)
-=== RUN TestRemoteServerHandler_TestConnection_EmptyHost
---- PASS: TestRemoteServerHandler_TestConnection_EmptyHost (0.00s)
-=== RUN TestImportHandler_UploadMulti_ValidCaddyfile
-time="2025-12-12T19:05:43Z" level=error msg="Import UploadMulti: import failed" error="caddy adapt failed: exec: \"caddy\": executable file not found in $PATH (output: )" mainCaddyfile=Caddyfile preview="example.com { reverse_proxy localhost:8080 }"
---- PASS: TestImportHandler_UploadMulti_ValidCaddyfile (0.00s)
-=== RUN TestImportHandler_UploadMulti_SubdirFile
-time="2025-12-12T19:05:43Z" level=error msg="Import UploadMulti: import failed" error="caddy adapt failed: exec: \"caddy\": executable file not found in $PATH (output: )" mainCaddyfile=Caddyfile preview="import sites/*"
---- PASS: TestImportHandler_UploadMulti_SubdirFile (0.00s)
-=== RUN TestAuthHandler_Login
---- PASS: TestAuthHandler_Login (0.14s)
-=== RUN TestSetSecureCookie_HTTPS_Strict
---- PASS: TestSetSecureCookie_HTTPS_Strict (0.00s)
-=== RUN TestSetSecureCookie_HTTP_Lax
---- PASS: TestSetSecureCookie_HTTP_Lax (0.00s)
-=== RUN TestAuthHandler_Login_Errors
-
-2025/12/12 19:05:43 [31;1m/projects/Charon/backend/internal/services/auth_service.go:64 [35;1mrecord not found
-[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE email = "nonexistent@example.com" ORDER BY `users`.`id` LIMIT 1
---- PASS: TestAuthHandler_Login_Errors (0.00s)
-=== RUN TestAuthHandler_Register
---- PASS: TestAuthHandler_Register (0.07s)
-=== RUN TestAuthHandler_Register_Duplicate
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/auth_service.go:54 [35;1mUNIQUE constraint failed: users.email
-[0m[33m[0.303ms] [34;1m[rows:0][0m INSERT INTO `users` (`uuid`,`email`,`api_key`,`password_hash`,`name`,`role`,`enabled`,`failed_login_attempts`,`locked_until`,`last_login`,`invite_token`,`invite_expires`,`invited_at`,`invited_by`,`invite_status`,`permission_mode`,`created_at`,`updated_at`) VALUES ("2066b858-15a5-4e3e-a247-328d64408a45","dup@example.com","028e52ea-4eb3-4c1b-b7bd-eab0e113c993","$2a$10$mS9P7qy/pHxKUm7VnmiQhOnc8.OMl/z51Ods7bxSp4CCylswN2nlK","Dup User","user",true,0,NULL,NULL,"",NULL,NULL,NULL,"","allow_all","2025-12-12 19:05:44.028","2025-12-12 19:05:44.028") RETURNING `id`
---- PASS: TestAuthHandler_Register_Duplicate (0.07s)
-=== RUN TestAuthHandler_Logout
---- PASS: TestAuthHandler_Logout (0.00s)
-=== RUN TestAuthHandler_Me
---- PASS: TestAuthHandler_Me (0.00s)
-=== RUN TestAuthHandler_Me_NotFound
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/auth_service.go:147 [35;1mrecord not found
-[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestAuthHandler_Me_NotFound (0.00s)
-=== RUN TestAuthHandler_ChangePassword
---- PASS: TestAuthHandler_ChangePassword (0.26s)
-=== RUN TestAuthHandler_ChangePassword_WrongOld
---- PASS: TestAuthHandler_ChangePassword_WrongOld (0.13s)
-=== RUN TestAuthHandler_ChangePassword_Errors
---- PASS: TestAuthHandler_ChangePassword_Errors (0.00s)
-=== RUN TestNewAuthHandlerWithDB
---- PASS: TestNewAuthHandlerWithDB (0.00s)
-=== RUN TestAuthHandler_Verify_NoCookie
---- PASS: TestAuthHandler_Verify_NoCookie (0.00s)
-=== RUN TestAuthHandler_Verify_InvalidToken
---- PASS: TestAuthHandler_Verify_InvalidToken (0.00s)
-=== RUN TestAuthHandler_Verify_ValidToken
---- PASS: TestAuthHandler_Verify_ValidToken (0.08s)
-=== RUN TestAuthHandler_Verify_BearerToken
---- PASS: TestAuthHandler_Verify_BearerToken (0.07s)
-=== RUN TestAuthHandler_Verify_DisabledUser
---- PASS: TestAuthHandler_Verify_DisabledUser (0.07s)
-=== RUN TestAuthHandler_Verify_ForwardAuthDenied
---- PASS: TestAuthHandler_Verify_ForwardAuthDenied (0.07s)
-=== RUN TestAuthHandler_VerifyStatus_NotAuthenticated
---- PASS: TestAuthHandler_VerifyStatus_NotAuthenticated (0.00s)
-=== RUN TestAuthHandler_VerifyStatus_InvalidToken
---- PASS: TestAuthHandler_VerifyStatus_InvalidToken (0.00s)
-=== RUN TestAuthHandler_VerifyStatus_Authenticated
---- PASS: TestAuthHandler_VerifyStatus_Authenticated (0.07s)
-=== RUN TestAuthHandler_VerifyStatus_DisabledUser
---- PASS: TestAuthHandler_VerifyStatus_DisabledUser (0.07s)
-=== RUN TestAuthHandler_GetAccessibleHosts_Unauthorized
---- PASS: TestAuthHandler_GetAccessibleHosts_Unauthorized (0.00s)
-=== RUN TestAuthHandler_GetAccessibleHosts_AllowAll
---- PASS: TestAuthHandler_GetAccessibleHosts_AllowAll (0.00s)
-=== RUN TestAuthHandler_GetAccessibleHosts_DenyAll
---- PASS: TestAuthHandler_GetAccessibleHosts_DenyAll (0.00s)
-=== RUN TestAuthHandler_GetAccessibleHosts_PermittedHosts
---- PASS: TestAuthHandler_GetAccessibleHosts_PermittedHosts (0.01s)
-=== RUN TestAuthHandler_GetAccessibleHosts_UserNotFound
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/api/handlers/auth_handler.go:334 [35;1mrecord not found
-[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 99999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestAuthHandler_GetAccessibleHosts_UserNotFound (0.00s)
-=== RUN TestAuthHandler_CheckHostAccess_Unauthorized
---- PASS: TestAuthHandler_CheckHostAccess_Unauthorized (0.00s)
-=== RUN TestAuthHandler_CheckHostAccess_InvalidHostID
---- PASS: TestAuthHandler_CheckHostAccess_InvalidHostID (0.00s)
-=== RUN TestAuthHandler_CheckHostAccess_Allowed
---- PASS: TestAuthHandler_CheckHostAccess_Allowed (0.00s)
-=== RUN TestAuthHandler_CheckHostAccess_Denied
---- PASS: TestAuthHandler_CheckHostAccess_Denied (0.00s)
-=== RUN TestBackupHandlerSanitizesFilename
---- PASS: TestBackupHandlerSanitizesFilename (0.00s)
-=== RUN TestBackupLifecycle
---- PASS: TestBackupLifecycle (0.00s)
-=== RUN TestBackupHandler_Errors
---- PASS: TestBackupHandler_Errors (0.00s)
-=== RUN TestBackupHandler_List_Success
---- PASS: TestBackupHandler_List_Success (0.00s)
-=== RUN TestBackupHandler_Create_Success
---- PASS: TestBackupHandler_Create_Success (0.00s)
-=== RUN TestBackupHandler_Download_Success
---- PASS: TestBackupHandler_Download_Success (0.00s)
-=== RUN TestBackupHandler_PathTraversal
---- PASS: TestBackupHandler_PathTraversal (0.00s)
-=== RUN TestBackupHandler_Download_InvalidPath
---- PASS: TestBackupHandler_Download_InvalidPath (0.00s)
-=== RUN TestBackupHandler_Create_ServiceError
---- PASS: TestBackupHandler_Create_ServiceError (0.00s)
-=== RUN TestBackupHandler_Delete_InternalError
---- PASS: TestBackupHandler_Delete_InternalError (0.00s)
-=== RUN TestBackupHandler_Restore_InternalError
---- PASS: TestBackupHandler_Restore_InternalError (0.00s)
-=== RUN TestCertificateHandler_List_DBError
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:198 [35;1mno such table: ssl_certificates
-[0m[33m[0.166ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE provider LIKE "letsencrypt%"
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:226 [35;1mno such table: ssl_certificates
-[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates`
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:226 [35;1mno such table: ssl_certificates
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates`
---- PASS: TestCertificateHandler_List_DBError (0.00s)
-=== RUN TestCertificateHandler_Delete_InvalidID
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:198 [35;1mno such table: ssl_certificates
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE provider LIKE "letsencrypt%"
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:226 [35;1mno such table: ssl_certificates
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates`
---- PASS: TestCertificateHandler_Delete_InvalidID (0.00s)
-=== RUN TestCertificateHandler_Delete_NotFound
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:410 [35;1mrecord not found
-[0m[33m[0.061ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE `ssl_certificates`.`id` = 9999 ORDER BY `ssl_certificates`.`id` LIMIT 1
---- PASS: TestCertificateHandler_Delete_NotFound (0.00s)
-=== RUN TestCertificateHandler_Delete_NoBackupService
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:198 [35;1mno such table: ssl_certificates
-[0m[33m[0.209ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates` WHERE provider LIKE "letsencrypt%"
-
-2025/12/12 19:05:44 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:226 [35;1mno such table: ssl_certificates
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `ssl_certificates`
---- PASS: TestCertificateHandler_Delete_NoBackupService (0.20s)
-=== RUN TestCertificateHandler_Delete_CheckUsageDBError
-
-2025/12/12 19:05:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:392 [35;1mno such table: proxy_hosts
-[0m[33m[0.799ms] [34;1m[rows:0][0m SELECT count(*) FROM `proxy_hosts` WHERE certificate_id = 1
---- PASS: TestCertificateHandler_Delete_CheckUsageDBError (0.00s)
-=== RUN TestCertificateHandler_List_WithCertificates
-
-2025/12/12 19:05:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:232 [35;1mno such table: proxy_hosts
-[0m[33m[0.411ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
---- PASS: TestCertificateHandler_List_WithCertificates (0.00s)
-=== RUN TestCertificateHandler_Delete_RequiresAuth
---- PASS: TestCertificateHandler_Delete_RequiresAuth (0.00s)
-=== RUN TestCertificateHandler_List_RequiresAuth
---- PASS: TestCertificateHandler_List_RequiresAuth (0.00s)
-=== RUN TestCertificateHandler_Upload_RequiresAuth
---- PASS: TestCertificateHandler_Upload_RequiresAuth (0.00s)
-=== RUN TestCertificateHandler_Delete_DiskSpaceCheck
---- PASS: TestCertificateHandler_Delete_DiskSpaceCheck (0.00s)
-=== RUN TestCertificateHandler_Delete_NotificationRateLimiting
---- PASS: TestCertificateHandler_Delete_NotificationRateLimiting (0.00s)
-=== RUN TestDeleteCertificate_InUse
---- PASS: TestDeleteCertificate_InUse (0.00s)
-=== RUN TestDeleteCertificate_CreatesBackup
-
-2025/12/12 19:05:45 [31;1m/projects/Charon/backend/internal/services/certificate_service.go:441 [35;1mdatabase table is locked: ssl_certificates
-[0m[33m[0.059ms] [34;1m[rows:0][0m DELETE FROM `ssl_certificates` WHERE id = 1
- certificate_handler_test.go:125: expected 200 OK, got 500, body={"error":"failed to delete certificate"}
---- FAIL: TestDeleteCertificate_CreatesBackup (0.00s)
-=== RUN TestDeleteCertificate_BackupFailure
---- PASS: TestDeleteCertificate_BackupFailure (0.00s)
-=== RUN TestDeleteCertificate_InUse_NoBackup
---- PASS: TestDeleteCertificate_InUse_NoBackup (0.00s)
-=== RUN TestCertificateHandler_List
---- PASS: TestCertificateHandler_List (0.00s)
-=== RUN TestCertificateHandler_Upload_MissingName
---- PASS: TestCertificateHandler_Upload_MissingName (0.00s)
-=== RUN TestCertificateHandler_Upload_MissingCertFile
---- PASS: TestCertificateHandler_Upload_MissingCertFile (0.00s)
-=== RUN TestCertificateHandler_Upload_MissingKeyFile
---- PASS: TestCertificateHandler_Upload_MissingKeyFile (0.00s)
-=== RUN TestCertificateHandler_Upload_Success
---- PASS: TestCertificateHandler_Upload_Success (0.05s)
-=== RUN TestBackupHandlerQuick
---- PASS: TestBackupHandlerQuick (0.00s)
-=== RUN TestListPresetsShowsCachedStatus
---- PASS: TestListPresetsShowsCachedStatus (0.37s)
-=== RUN TestCacheKeyPersistence
---- PASS: TestCacheKeyPersistence (0.00s)
-=== RUN TestListDecisions_Success
---- PASS: TestListDecisions_Success (0.00s)
-=== RUN TestListDecisions_EmptyList
---- PASS: TestListDecisions_EmptyList (0.00s)
-=== RUN TestListDecisions_CscliError
---- PASS: TestListDecisions_CscliError (0.00s)
-=== RUN TestListDecisions_InvalidJSON
---- PASS: TestListDecisions_InvalidJSON (0.00s)
-=== RUN TestBanIP_Success
---- PASS: TestBanIP_Success (0.00s)
-=== RUN TestBanIP_DefaultDuration
---- PASS: TestBanIP_DefaultDuration (0.00s)
-=== RUN TestBanIP_MissingIP
---- PASS: TestBanIP_MissingIP (0.00s)
-=== RUN TestBanIP_EmptyIP
---- PASS: TestBanIP_EmptyIP (0.00s)
-=== RUN TestBanIP_CscliError
---- PASS: TestBanIP_CscliError (0.00s)
-=== RUN TestUnbanIP_Success
---- PASS: TestUnbanIP_Success (0.00s)
-=== RUN TestUnbanIP_CscliError
---- PASS: TestUnbanIP_CscliError (0.00s)
-=== RUN TestListDecisions_MultipleDecisions
---- PASS: TestListDecisions_MultipleDecisions (0.00s)
-=== RUN TestBanIP_InvalidJSON
---- PASS: TestBanIP_InvalidJSON (0.00s)
-=== RUN TestDefaultCrowdsecExecutorPidFile
---- PASS: TestDefaultCrowdsecExecutorPidFile (0.00s)
-=== RUN TestDefaultCrowdsecExecutorStartStatusStop
---- PASS: TestDefaultCrowdsecExecutorStartStatusStop (0.20s)
-=== RUN TestDefaultCrowdsecExecutor_Status_NoPidFile
---- PASS: TestDefaultCrowdsecExecutor_Status_NoPidFile (0.00s)
-=== RUN TestDefaultCrowdsecExecutor_Status_InvalidPid
---- PASS: TestDefaultCrowdsecExecutor_Status_InvalidPid (0.00s)
-=== RUN TestDefaultCrowdsecExecutor_Status_NonExistentProcess
---- PASS: TestDefaultCrowdsecExecutor_Status_NonExistentProcess (0.00s)
-=== RUN TestDefaultCrowdsecExecutor_Stop_NoPidFile
---- PASS: TestDefaultCrowdsecExecutor_Stop_NoPidFile (0.00s)
-=== RUN TestDefaultCrowdsecExecutor_Stop_InvalidPid
---- PASS: TestDefaultCrowdsecExecutor_Stop_InvalidPid (0.00s)
-=== RUN TestDefaultCrowdsecExecutor_Stop_NonExistentProcess
---- PASS: TestDefaultCrowdsecExecutor_Stop_NonExistentProcess (0.00s)
-=== RUN TestDefaultCrowdsecExecutor_Start_InvalidBinary
---- PASS: TestDefaultCrowdsecExecutor_Start_InvalidBinary (0.00s)
-=== RUN TestCrowdsec_Start_Error
---- PASS: TestCrowdsec_Start_Error (0.00s)
-=== RUN TestCrowdsec_Stop_Error
---- PASS: TestCrowdsec_Stop_Error (0.00s)
-=== RUN TestCrowdsec_Status_Error
---- PASS: TestCrowdsec_Status_Error (0.00s)
-=== RUN TestCrowdsec_ReadFile_MissingPath
---- PASS: TestCrowdsec_ReadFile_MissingPath (0.00s)
-=== RUN TestCrowdsec_ReadFile_PathTraversal
---- PASS: TestCrowdsec_ReadFile_PathTraversal (0.00s)
-=== RUN TestCrowdsec_ReadFile_NotFound
---- PASS: TestCrowdsec_ReadFile_NotFound (0.00s)
-=== RUN TestCrowdsec_WriteFile_InvalidPayload
---- PASS: TestCrowdsec_WriteFile_InvalidPayload (0.00s)
-=== RUN TestCrowdsec_WriteFile_MissingPath
---- PASS: TestCrowdsec_WriteFile_MissingPath (0.00s)
-=== RUN TestCrowdsec_WriteFile_PathTraversal
---- PASS: TestCrowdsec_WriteFile_PathTraversal (0.00s)
-=== RUN TestCrowdsec_ExportConfig_NotFound
---- PASS: TestCrowdsec_ExportConfig_NotFound (0.00s)
-=== RUN TestCrowdsec_ListFiles_EmptyDir
---- PASS: TestCrowdsec_ListFiles_EmptyDir (0.00s)
-=== RUN TestCrowdsec_ListFiles_NonExistent
---- PASS: TestCrowdsec_ListFiles_NonExistent (0.00s)
-=== RUN TestCrowdsec_ImportConfig_NoFile
---- PASS: TestCrowdsec_ImportConfig_NoFile (0.00s)
-=== RUN TestCrowdsec_ReadFile_NestedPath
---- PASS: TestCrowdsec_ReadFile_NestedPath (0.00s)
-=== RUN TestCrowdsec_WriteFile_Success
---- PASS: TestCrowdsec_WriteFile_Success (0.00s)
-=== RUN TestCrowdsec_ListPresets_Disabled
---- PASS: TestCrowdsec_ListPresets_Disabled (0.00s)
-=== RUN TestCrowdsec_ListPresets_Success
---- PASS: TestCrowdsec_ListPresets_Success (0.19s)
-=== RUN TestCrowdsec_PullPreset_Validation
---- PASS: TestCrowdsec_PullPreset_Validation (0.00s)
-=== RUN TestCrowdsec_ApplyPreset_Validation
---- PASS: TestCrowdsec_ApplyPreset_Validation (0.00s)
-=== RUN TestCrowdsecEndpoints
---- PASS: TestCrowdsecEndpoints (0.00s)
-=== RUN TestImportConfig
---- PASS: TestImportConfig (0.00s)
-=== RUN TestImportCreatesBackup
---- PASS: TestImportCreatesBackup (0.00s)
-=== RUN TestExportConfig
---- PASS: TestExportConfig (0.00s)
-=== RUN TestListAndReadFile
---- PASS: TestListAndReadFile (0.00s)
-=== RUN TestExportConfigStreamsArchive
---- PASS: TestExportConfigStreamsArchive (0.00s)
-=== RUN TestWriteFileCreatesBackup
---- PASS: TestWriteFileCreatesBackup (0.00s)
-=== RUN TestListPresetsCerberusDisabled
---- PASS: TestListPresetsCerberusDisabled (0.00s)
-=== RUN TestReadFileInvalidPath
---- PASS: TestReadFileInvalidPath (0.00s)
-=== RUN TestWriteFileInvalidPath
---- PASS: TestWriteFileInvalidPath (0.00s)
-=== RUN TestWriteFileMissingPath
---- PASS: TestWriteFileMissingPath (0.00s)
-=== RUN TestWriteFileInvalidPayload
---- PASS: TestWriteFileInvalidPayload (0.00s)
-=== RUN TestImportConfigRequiresFile
---- PASS: TestImportConfigRequiresFile (0.00s)
-=== RUN TestImportConfigRejectsEmptyUpload
---- PASS: TestImportConfigRejectsEmptyUpload (0.00s)
-=== RUN TestListFilesMissingDir
---- PASS: TestListFilesMissingDir (0.00s)
-=== RUN TestListFilesReturnsEntries
---- PASS: TestListFilesReturnsEntries (0.00s)
-=== RUN TestIsCerberusEnabledFromDB
---- PASS: TestIsCerberusEnabledFromDB (0.00s)
-=== RUN TestIsCerberusEnabledInvalidEnv
---- PASS: TestIsCerberusEnabledInvalidEnv (0.00s)
-=== RUN TestIsCerberusEnabledLegacyEnv
---- PASS: TestIsCerberusEnabledLegacyEnv (0.00s)
-=== RUN TestConsoleEnrollDisabled
---- PASS: TestConsoleEnrollDisabled (0.00s)
-=== RUN TestConsoleEnrollServiceUnavailable
---- PASS: TestConsoleEnrollServiceUnavailable (0.00s)
-=== RUN TestConsoleEnrollInvalidPayload
---- PASS: TestConsoleEnrollInvalidPayload (0.00s)
-=== RUN TestConsoleEnrollSuccess
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
-[0m[33m[0.056ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/security_service.go:195 [35;1mno such table: security_audits
-[0m[33m[0.077ms] [34;1m[rows:0][0m INSERT INTO `security_audits` (`uuid`,`actor`,`action`,`details`,`created_at`) VALUES ("6331bcc9-8eb8-427c-8839-ea8b70681f2f","unknown","crowdsec_console_enroll_succeeded","status=enrolled tenant=my-tenant agent=test-agent correlation_id=35cd7e38-b6e0-4cae-9db1-1b9a0e0b3790","2025-12-12 19:05:46.084") RETURNING `id`
---- PASS: TestConsoleEnrollSuccess (0.00s)
-=== RUN TestConsoleEnrollMissingAgentName
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/security_service.go:195 [35;1mno such table: security_audits
-[0m[33m[0.128ms] [34;1m[rows:0][0m INSERT INTO `security_audits` (`uuid`,`actor`,`action`,`details`,`created_at`) VALUES ("67c730e1-fbe5-418e-ac88-16b135d4a3dd","unknown","crowdsec_console_enroll_failed","status= tenant= agent= correlation_id=","2025-12-12 19:05:46.085") RETURNING `id`
---- PASS: TestConsoleEnrollMissingAgentName (0.00s)
-=== RUN TestConsoleStatusDisabled
---- PASS: TestConsoleStatusDisabled (0.00s)
-=== RUN TestConsoleStatusServiceUnavailable
---- PASS: TestConsoleStatusServiceUnavailable (0.00s)
-=== RUN TestConsoleStatusSuccess
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
-[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
---- PASS: TestConsoleStatusSuccess (0.00s)
-=== RUN TestConsoleStatusAfterEnroll
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/crowdsec/console_enroll.go:229 [35;1mrecord not found
-[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `crowdsec_console_enrollments` ORDER BY `crowdsec_console_enrollments`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/security_service.go:195 [35;1mno such table: security_audits
-[0m[33m[0.127ms] [34;1m[rows:0][0m INSERT INTO `security_audits` (`uuid`,`actor`,`action`,`details`,`created_at`) VALUES ("bcef394b-34a9-4834-9336-2f211122795a","unknown","crowdsec_console_enroll_succeeded","status=enrolled tenant= agent=test-agent correlation_id=30e6cca4-d985-4900-8711-eb46782b995a","2025-12-12 19:05:46.089") RETURNING `id`
---- PASS: TestConsoleStatusAfterEnroll (0.00s)
-=== RUN TestIsConsoleEnrollmentEnabledFromDB
---- PASS: TestIsConsoleEnrollmentEnabledFromDB (0.00s)
-=== RUN TestIsConsoleEnrollmentDisabledFromDB
---- PASS: TestIsConsoleEnrollmentDisabledFromDB (0.00s)
-=== RUN TestIsConsoleEnrollmentEnabledFromEnv
---- PASS: TestIsConsoleEnrollmentEnabledFromEnv (0.00s)
-=== RUN TestIsConsoleEnrollmentDisabledFromEnv
---- PASS: TestIsConsoleEnrollmentDisabledFromEnv (0.00s)
-=== RUN TestIsConsoleEnrollmentInvalidEnv
---- PASS: TestIsConsoleEnrollmentInvalidEnv (0.00s)
-=== RUN TestIsConsoleEnrollmentDefaultDisabled
---- PASS: TestIsConsoleEnrollmentDefaultDisabled (0.00s)
-=== RUN TestIsConsoleEnrollmentDBTrueVariants
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/true
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/TRUE
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/True
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/1
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/yes
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/YES
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/false
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/FALSE
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/0
-=== RUN TestIsConsoleEnrollmentDBTrueVariants/no
---- PASS: TestIsConsoleEnrollmentDBTrueVariants (0.01s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/true (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/TRUE (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/True (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/1 (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/yes (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/YES (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/false (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/FALSE (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/0 (0.00s)
- --- PASS: TestIsConsoleEnrollmentDBTrueVariants/no (0.00s)
-=== RUN TestActorFromContextWithUserID
---- PASS: TestActorFromContextWithUserID (0.00s)
-=== RUN TestActorFromContextWithNumericUserID
---- PASS: TestActorFromContextWithNumericUserID (0.00s)
-=== RUN TestActorFromContextNoUser
---- PASS: TestActorFromContextNoUser (0.00s)
-=== RUN TestTTLRemainingSeconds
---- PASS: TestTTLRemainingSeconds (0.00s)
-=== RUN TestTTLRemainingSecondsExpired
---- PASS: TestTTLRemainingSecondsExpired (0.00s)
-=== RUN TestTTLRemainingSecondsZeroTime
---- PASS: TestTTLRemainingSecondsZeroTime (0.00s)
-=== RUN TestTTLRemainingSecondsZeroTTL
---- PASS: TestTTLRemainingSecondsZeroTTL (0.00s)
-=== RUN TestHubEndpointsNil
---- PASS: TestHubEndpointsNil (0.00s)
-=== RUN TestHubEndpointsDeduplicates
---- PASS: TestHubEndpointsDeduplicates (0.00s)
-=== RUN TestHubEndpointsMultiple
---- PASS: TestHubEndpointsMultiple (0.00s)
-=== RUN TestHubEndpointsSkipsEmpty
---- PASS: TestHubEndpointsSkipsEmpty (0.00s)
-=== RUN TestGetLAPIDecisions_FallbackToCscli
---- PASS: TestGetLAPIDecisions_FallbackToCscli (0.00s)
-=== RUN TestGetLAPIDecisions_EmptyResponse
---- PASS: TestGetLAPIDecisions_EmptyResponse (0.00s)
-=== RUN TestCheckLAPIHealth_Handler
---- PASS: TestCheckLAPIHealth_Handler (0.00s)
-=== RUN TestGetLAPIKey_FromEnv
---- PASS: TestGetLAPIKey_FromEnv (0.00s)
-=== RUN TestGetLAPIKey_Empty
---- PASS: TestGetLAPIKey_Empty (0.00s)
-=== RUN TestListPresetsIncludesCacheAndIndex
---- PASS: TestListPresetsIncludesCacheAndIndex (0.00s)
-=== RUN TestPullPresetHandlerSuccess
---- PASS: TestPullPresetHandlerSuccess (0.00s)
-=== RUN TestApplyPresetHandlerAudits
---- PASS: TestApplyPresetHandlerAudits (0.01s)
-=== RUN TestPullPresetHandlerHubError
---- PASS: TestPullPresetHandlerHubError (0.00s)
-=== RUN TestPullPresetHandlerTimeout
---- PASS: TestPullPresetHandlerTimeout (0.00s)
-=== RUN TestGetCachedPresetNotFound
---- PASS: TestGetCachedPresetNotFound (0.00s)
-=== RUN TestGetCachedPresetServiceUnavailable
---- PASS: TestGetCachedPresetServiceUnavailable (0.00s)
-=== RUN TestApplyPresetHandlerBackupFailure
---- PASS: TestApplyPresetHandlerBackupFailure (0.00s)
-=== RUN TestListPresetsMergesCuratedAndHub
---- PASS: TestListPresetsMergesCuratedAndHub (0.00s)
-=== RUN TestGetCachedPresetSuccess
---- PASS: TestGetCachedPresetSuccess (0.00s)
-=== RUN TestGetCachedPresetSlugRequired
---- PASS: TestGetCachedPresetSlugRequired (0.00s)
-=== RUN TestGetCachedPresetPreviewError
---- PASS: TestGetCachedPresetPreviewError (0.00s)
-=== RUN TestPullCuratedPresetSkipsHub
---- PASS: TestPullCuratedPresetSkipsHub (0.00s)
-=== RUN TestApplyCuratedPresetSkipsHub
---- PASS: TestApplyCuratedPresetSkipsHub (0.00s)
-=== RUN TestPullThenApplyIntegration
- crowdsec_pull_apply_integration_test.go:67: User pulls preset
- crowdsec_pull_apply_integration_test.go:83: Pull succeeded, cache_key: test/preset-1765566346
- crowdsec_pull_apply_integration_test.go:90: Cache verified, slug: test/preset
- crowdsec_pull_apply_integration_test.go:93: User applies preset
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/crowdsec_handler.go:725 [35;1mno such table: crowdsec_preset_events
-[0m[33m[0.106ms] [34;1m[rows:0][0m INSERT INTO `crowdsec_preset_events` (`slug`,`action`,`status`,`cache_key`,`backup_path`,`error`,`created_at`,`updated_at`) VALUES ("test/preset","apply","applied","test/preset-1765566346","/tmp/TestPullThenApplyIntegration3897446452/002.backup.20251212-190546","","2025-12-12 19:05:46.133","2025-12-12 19:05:46.133") RETURNING `id`
- crowdsec_pull_apply_integration_test.go:109: Apply succeeded, backup: /tmp/TestPullThenApplyIntegration3897446452/002.backup.20251212-190546
---- PASS: TestPullThenApplyIntegration (0.00s)
-=== RUN TestApplyWithoutPullReturnsProperError
- crowdsec_pull_apply_integration_test.go:138: User tries to apply preset without pulling first
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/crowdsec_handler.go:695 [35;1mno such table: crowdsec_preset_events
-[0m[33m[0.178ms] [34;1m[rows:0][0m INSERT INTO `crowdsec_preset_events` (`slug`,`action`,`status`,`cache_key`,`backup_path`,`error`,`created_at`,`updated_at`) VALUES ("test/preset","apply","failed","","/tmp/TestApplyWithoutPullReturnsProperError3560971172/002.backup.20251212-190546","load cache for test/preset: load cache for test/preset: cache miss: refresh cache: fetch hub index: http://test.hub/api/index.json: http://test.hub/api/index.json (status 500)
-https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 500)
-https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 500)
-https://hub-data.crowdsec.net/api/index.json: https://hub-data.crowdsec.net/api/index.json (status 500)","2025-12-12 19:05:46.134","2025-12-12 19:05:46.134") RETURNING `id`
- crowdsec_pull_apply_integration_test.go:154: Proper error message returned: Preset cache missing or expired. Pull the preset again, then retry apply.
---- PASS: TestApplyWithoutPullReturnsProperError (0.00s)
-=== RUN TestApplyRollbackWhenCacheMissingAndRepullFails
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/crowdsec_handler.go:695 [35;1mno such table: crowdsec_preset_events
-[0m[33m[0.099ms] [34;1m[rows:0][0m INSERT INTO `crowdsec_preset_events` (`slug`,`action`,`status`,`cache_key`,`backup_path`,`error`,`created_at`,`updated_at`) VALUES ("missing/preset","apply","failed","","/tmp/TestApplyRollbackWhenCacheMissingAndRepullFails4135574716/002/crowdsec.backup.20251212-190546","load cache for missing/preset: load cache for missing/preset: cache miss: refresh cache: fetch hub index: http://test.hub/api/index.json: http://test.hub/api/index.json (status 500)
-https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/.index.json (status 500)
-https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json: https://raw.githubusercontent.com/crowdsecurity/hub/master/api/index.json (status 500)
-https://hub-data.crowdsec.net/api/index.json: https://hub-data.crowdsec.net/api/index.json (status 500)","2025-12-12 19:05:46.136","2025-12-12 19:05:46.136") RETURNING `id`
---- PASS: TestApplyRollbackWhenCacheMissingAndRepullFails (0.00s)
-=== RUN TestDockerHandler_ListContainers
---- PASS: TestDockerHandler_ListContainers (0.00s)
-=== RUN TestDockerHandler_ListContainers_NonExistentServerID
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent-uuid" ORDER BY `remote_servers`.`id` LIMIT 1
---- PASS: TestDockerHandler_ListContainers_NonExistentServerID (0.00s)
-=== RUN TestDockerHandler_ListContainers_WithServerID
---- PASS: TestDockerHandler_ListContainers_WithServerID (0.00s)
-=== RUN TestDockerHandler_ListContainers_WithHostQuery
---- PASS: TestDockerHandler_ListContainers_WithHostQuery (0.00s)
-=== RUN TestDockerHandler_RegisterRoutes
---- PASS: TestDockerHandler_RegisterRoutes (0.00s)
-=== RUN TestDockerHandler_NewDockerHandler
---- PASS: TestDockerHandler_NewDockerHandler (0.00s)
-=== RUN TestDomainLifecycle
---- PASS: TestDomainLifecycle (0.00s)
-=== RUN TestDomainErrors
---- PASS: TestDomainErrors (0.00s)
-=== RUN TestDomainDelete_NotFound
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:73 [35;1mrecord not found
-[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `domains` WHERE uuid = "nonexistent-uuid" AND `domains`.`deleted_at` IS NULL ORDER BY `domains`.`id` LIMIT 1
---- PASS: TestDomainDelete_NotFound (0.00s)
-=== RUN TestDomainCreate_Duplicate
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:49 [35;1mUNIQUE constraint failed: domains.name
-[0m[33m[0.087ms] [34;1m[rows:0][0m INSERT INTO `domains` (`uuid`,`name`,`created_at`,`updated_at`,`deleted_at`) VALUES ("30ded0b1-7423-4851-95fb-9c48e4a9bb59","duplicate.com","2025-12-12 19:05:46.158","2025-12-12 19:05:46.158",NULL) RETURNING `id`
---- PASS: TestDomainCreate_Duplicate (0.00s)
-=== RUN TestDomainList_Empty
---- PASS: TestDomainList_Empty (0.00s)
-=== RUN TestDomainCreate_LongName
---- PASS: TestDomainCreate_LongName (0.00s)
-=== RUN TestFeatureFlagsHandler_GetFlags_DBPrecedence
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_GetFlags_DBPrecedence (0.00s)
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvFallback
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_GetFlags_EnvFallback (0.00s)
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvShortForm
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_GetFlags_EnvShortForm (0.00s)
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvNumeric
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_GetFlags_EnvNumeric (0.00s)
-=== RUN TestFeatureFlagsHandler_GetFlags_DefaultTrue
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_GetFlags_DefaultTrue (0.00s)
-=== RUN TestFeatureFlagsHandler_GetFlags_AllDefaultFlagsPresent
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_GetFlags_AllDefaultFlagsPresent (0.00s)
-=== RUN TestFeatureFlagsHandler_UpdateFlags_Success
---- PASS: TestFeatureFlagsHandler_UpdateFlags_Success (0.00s)
-=== RUN TestFeatureFlagsHandler_UpdateFlags_Upsert
---- PASS: TestFeatureFlagsHandler_UpdateFlags_Upsert (0.00s)
-=== RUN TestFeatureFlagsHandler_UpdateFlags_InvalidJSON
---- PASS: TestFeatureFlagsHandler_UpdateFlags_InvalidJSON (0.00s)
-=== RUN TestFeatureFlagsHandler_UpdateFlags_OnlyAllowedKeys
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler_coverage_test.go:296 [35;1mrecord not found
-[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.invalid.key" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_UpdateFlags_OnlyAllowedKeys (0.00s)
-=== RUN TestFeatureFlagsHandler_UpdateFlags_EmptyPayload
---- PASS: TestFeatureFlagsHandler_UpdateFlags_EmptyPayload (0.00s)
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/lowercase_true
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/uppercase_TRUE
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.040ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/mixed_case_True
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/numeric_1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.035ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/yes
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/YES_uppercase
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.055ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/lowercase_false
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/numeric_0
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/no
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/empty_string
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/random_string
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.362ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/whitespace_padded_true
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_DBValueVariants/whitespace_padded_false
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants (0.01s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/lowercase_true (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/uppercase_TRUE (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/mixed_case_True (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/numeric_1 (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/yes (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/YES_uppercase (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/lowercase_false (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/numeric_0 (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/no (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/empty_string (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/random_string (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/whitespace_padded_true (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_DBValueVariants/whitespace_padded_false (0.00s)
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvValueVariants
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvValueVariants/true_string
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvValueVariants/TRUE_uppercase
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvValueVariants/1_numeric
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvValueVariants/false_string
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvValueVariants/FALSE_uppercase
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvValueVariants/0_numeric
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
-=== RUN TestFeatureFlagsHandler_GetFlags_EnvValueVariants/invalid_value_defaults_to_numeric_check
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/true_string (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/TRUE_uppercase (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/1_numeric (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/false_string (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/FALSE_uppercase (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/0_numeric (0.00s)
- --- PASS: TestFeatureFlagsHandler_GetFlags_EnvValueVariants/invalid_value_defaults_to_numeric_check (0.00s)
-=== RUN TestFeatureFlagsHandler_UpdateFlags_BoolValues
-=== RUN TestFeatureFlagsHandler_UpdateFlags_BoolValues/true
-=== RUN TestFeatureFlagsHandler_UpdateFlags_BoolValues/false
---- PASS: TestFeatureFlagsHandler_UpdateFlags_BoolValues (0.00s)
- --- PASS: TestFeatureFlagsHandler_UpdateFlags_BoolValues/true (0.00s)
- --- PASS: TestFeatureFlagsHandler_UpdateFlags_BoolValues/false (0.00s)
-=== RUN TestFeatureFlagsHandler_NewFeatureFlagsHandler
---- PASS: TestFeatureFlagsHandler_NewFeatureFlagsHandler (0.00s)
-=== RUN TestFeatureFlags_GetAndUpdate
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.053ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlags_GetAndUpdate (0.00s)
-=== RUN TestFeatureFlags_EnvFallback
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mno such table: settings
-[0m[33m[0.056ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mno such table: settings
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.uptime.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/feature_flags_handler.go:48 [35;1mno such table: settings
-[0m[33m[0.005ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.crowdsec.console_enrollment" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestFeatureFlags_EnvFallback (0.00s)
-=== RUN TestHealthHandler
---- PASS: TestHealthHandler (0.00s)
-=== RUN TestGetLocalIP
- health_handler_test.go:36: getLocalIP returned: "217.15.170.144"
---- PASS: TestGetLocalIP (0.00s)
-=== RUN TestIsSafePathUnderBase
---- PASS: TestIsSafePathUnderBase (0.00s)
-=== RUN TestImportUploadSanitizesFilename
---- PASS: TestImportUploadSanitizesFilename (0.00s)
-=== RUN TestLogsHandler_Read_FilterBySearch
---- PASS: TestLogsHandler_Read_FilterBySearch (0.00s)
-=== RUN TestLogsHandler_Read_FilterByHost
---- PASS: TestLogsHandler_Read_FilterByHost (0.00s)
-=== RUN TestLogsHandler_Read_FilterByLevel
---- PASS: TestLogsHandler_Read_FilterByLevel (0.00s)
-=== RUN TestLogsHandler_Read_FilterByStatus
---- PASS: TestLogsHandler_Read_FilterByStatus (0.00s)
-=== RUN TestLogsHandler_Read_SortAsc
---- PASS: TestLogsHandler_Read_SortAsc (0.00s)
-=== RUN TestLogsHandler_List_DirectoryIsFile
---- PASS: TestLogsHandler_List_DirectoryIsFile (0.00s)
-=== RUN TestLogsHandler_Download_TempFileError
---- PASS: TestLogsHandler_Download_TempFileError (0.00s)
-=== RUN TestLogsLifecycle
---- PASS: TestLogsLifecycle (0.00s)
-=== RUN TestLogsHandler_PathTraversal
---- PASS: TestLogsHandler_PathTraversal (0.00s)
-=== RUN TestLogsWebSocketHandler_SuccessfulConnection
---- PASS: TestLogsWebSocketHandler_SuccessfulConnection (0.00s)
-=== RUN TestLogsWebSocketHandler_ReceiveLogEntries
---- PASS: TestLogsWebSocketHandler_ReceiveLogEntries (0.00s)
-=== RUN TestLogsWebSocketHandler_LevelFilter
---- PASS: TestLogsWebSocketHandler_LevelFilter (0.15s)
-=== RUN TestLogsWebSocketHandler_SourceFilter
---- PASS: TestLogsWebSocketHandler_SourceFilter (0.00s)
-=== RUN TestLogsWebSocketHandler_CombinedFilters
---- PASS: TestLogsWebSocketHandler_CombinedFilters (0.00s)
-=== RUN TestLogsWebSocketHandler_CaseInsensitiveFilters
---- PASS: TestLogsWebSocketHandler_CaseInsensitiveFilters (0.00s)
-=== RUN TestLogsWebSocketHandler_UpgradeFailure
---- PASS: TestLogsWebSocketHandler_UpgradeFailure (0.00s)
-=== RUN TestLogsWebSocketHandler_ClientDisconnect
---- PASS: TestLogsWebSocketHandler_ClientDisconnect (0.02s)
-=== RUN TestLogsWebSocketHandler_ChannelClosed
---- PASS: TestLogsWebSocketHandler_ChannelClosed (0.00s)
-=== RUN TestLogsWebSocketHandler_MultipleConnections
---- PASS: TestLogsWebSocketHandler_MultipleConnections (0.00s)
-=== RUN TestLogsWebSocketHandler_HighVolumeLogging
---- PASS: TestLogsWebSocketHandler_HighVolumeLogging (0.02s)
-=== RUN TestLogsWebSocketHandler_EmptyLogFields
---- PASS: TestLogsWebSocketHandler_EmptyLogFields (0.00s)
-=== RUN TestLogsWebSocketHandler_SubscriberIDUniqueness
---- PASS: TestLogsWebSocketHandler_SubscriberIDUniqueness (0.00s)
-=== RUN TestLogsWebSocketHandler_WithRealLogger
---- PASS: TestLogsWebSocketHandler_WithRealLogger (0.00s)
-=== RUN TestLogsWebSocketHandler_ConnectionLifecycle
---- PASS: TestLogsWebSocketHandler_ConnectionLifecycle (0.00s)
-=== RUN TestDomainHandler_List_Error
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:28 [35;1mno such table: domains
-[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `domains` WHERE `domains`.`deleted_at` IS NULL ORDER BY name asc
---- PASS: TestDomainHandler_List_Error (0.00s)
-=== RUN TestDomainHandler_Create_InvalidJSON
---- PASS: TestDomainHandler_Create_InvalidJSON (0.00s)
-=== RUN TestDomainHandler_Create_DBError
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:49 [35;1mno such table: domains
-[0m[33m[0.068ms] [34;1m[rows:0][0m INSERT INTO `domains` (`uuid`,`name`,`created_at`,`updated_at`,`deleted_at`) VALUES ("078a32f2-b134-4709-9687-40e22ddc4715","example.com","2025-12-12 19:05:46.4","2025-12-12 19:05:46.4",NULL) RETURNING `id`
---- PASS: TestDomainHandler_Create_DBError (0.00s)
-=== RUN TestDomainHandler_Delete_Error
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:73 [35;1mno such table: domains
-[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `domains` WHERE uuid = "test-id" AND `domains`.`deleted_at` IS NULL ORDER BY `domains`.`id` LIMIT 1
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/domain_handler.go:88 [35;1mno such table: domains
-[0m[33m[0.065ms] [34;1m[rows:0][0m UPDATE `domains` SET `deleted_at`="2025-12-12 19:05:46.401" WHERE uuid = "test-id" AND `domains`.`deleted_at` IS NULL
---- PASS: TestDomainHandler_Delete_Error (0.00s)
-=== RUN TestRemoteServerHandler_List_Error
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:92 [35;1mno such table: remote_servers
-[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` ORDER BY name ASC
---- PASS: TestRemoteServerHandler_List_Error (0.00s)
-=== RUN TestRemoteServerHandler_List_EnabledOnly
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/api/handlers/misc_coverage_test.go:131 [35;1mUNIQUE constraint failed: remote_servers.uuid
-[0m[33m[0.041ms] [34;1m[rows:0][0m INSERT INTO `remote_servers` (`uuid`,`name`,`provider`,`host`,`port`,`scheme`,`tags`,`description`,`enabled`,`last_checked`,`reachable`,`created_at`,`updated_at`) VALUES ("","Server2","","localhost",22,"","","",true,NULL,false,"2025-12-12 19:05:46.402","2025-12-12 19:05:46.402") RETURNING `id`
---- PASS: TestRemoteServerHandler_List_EnabledOnly (0.00s)
-=== RUN TestRemoteServerHandler_Update_NotFound
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "nonexistent" ORDER BY `remote_servers`.`id` LIMIT 1
---- PASS: TestRemoteServerHandler_Update_NotFound (0.00s)
-=== RUN TestRemoteServerHandler_Update_InvalidJSON
---- PASS: TestRemoteServerHandler_Update_InvalidJSON (0.00s)
-=== RUN TestRemoteServerHandler_TestConnection_NotFound
-
-2025/12/12 19:05:46 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.021ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "nonexistent" ORDER BY `remote_servers`.`id` LIMIT 1
---- PASS: TestRemoteServerHandler_TestConnection_NotFound (0.00s)
-=== RUN TestRemoteServerHandler_TestConnectionCustom_InvalidJSON
---- PASS: TestRemoteServerHandler_TestConnectionCustom_InvalidJSON (0.00s)
-=== RUN TestRemoteServerHandler_TestConnectionCustom_Unreachable
---- PASS: TestRemoteServerHandler_TestConnectionCustom_Unreachable (5.00s)
-=== RUN TestUptimeHandler_List_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:863 [35;1mno such table: uptime_monitors
-[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` ORDER BY name ASC
---- PASS: TestUptimeHandler_List_Error (0.00s)
-=== RUN TestUptimeHandler_GetHistory_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:877 [35;1mno such table: uptime_heartbeats
-[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `uptime_heartbeats` WHERE monitor_id = "test-id" ORDER BY created_at desc LIMIT 50
---- PASS: TestUptimeHandler_GetHistory_Error (0.00s)
-=== RUN TestUptimeHandler_Update_InvalidJSON
---- PASS: TestUptimeHandler_Update_InvalidJSON (0.00s)
-=== RUN TestUptimeHandler_Sync_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:105 [35;1mno such table: proxy_hosts
-[0m[33m[0.271ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts`
---- PASS: TestUptimeHandler_Sync_Error (0.00s)
-=== RUN TestUptimeHandler_Delete_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:911 [35;1mno such table: uptime_monitors
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "test-id" ORDER BY `uptime_monitors`.`id` LIMIT 1
---- PASS: TestUptimeHandler_Delete_Error (0.00s)
-=== RUN TestUptimeHandler_CheckMonitor_NotFound
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:869 [35;1mrecord not found
-[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "nonexistent" ORDER BY `uptime_monitors`.`id` LIMIT 1
---- PASS: TestUptimeHandler_CheckMonitor_NotFound (0.00s)
-=== RUN TestNotificationHandler_List_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:66 [35;1mno such table: notifications
-[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `notifications` ORDER BY created_at desc
---- PASS: TestNotificationHandler_List_Error (0.00s)
-=== RUN TestNotificationHandler_List_UnreadOnly
---- PASS: TestNotificationHandler_List_UnreadOnly (0.00s)
-=== RUN TestNotificationHandler_MarkAsRead_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:71 [35;1mno such table: notifications
-[0m[33m[0.039ms] [34;1m[rows:0][0m UPDATE `notifications` SET `read`=true WHERE id = "test-id"
---- PASS: TestNotificationHandler_MarkAsRead_Error (0.00s)
-=== RUN TestNotificationHandler_MarkAllAsRead_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:75 [35;1mno such table: notifications
-[0m[33m[0.031ms] [34;1m[rows:0][0m UPDATE `notifications` SET `read`=true WHERE read = false
---- PASS: TestNotificationHandler_MarkAllAsRead_Error (0.00s)
-=== RUN TestNotificationProviderHandler_List_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:455 [35;1mno such table: notification_providers
-[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `notification_providers`
---- PASS: TestNotificationProviderHandler_List_Error (0.00s)
-=== RUN TestNotificationProviderHandler_Create_InvalidJSON
---- PASS: TestNotificationProviderHandler_Create_InvalidJSON (0.00s)
-=== RUN TestNotificationProviderHandler_Create_DBError
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:468 [35;1mno such table: notification_providers
-[0m[33m[0.058ms] [34;1m[rows:0][0m INSERT INTO `notification_providers` (`id`,`name`,`type`,`url`,`config`,`template`,`enabled`,`notify_proxy_hosts`,`notify_remote_servers`,`notify_domains`,`notify_certs`,`notify_uptime`,`created_at`,`updated_at`) VALUES ("513248aa-8301-4798-8a21-c87b3eaef859","Test","webhook","https://example.com","","minimal",false,true,true,true,true,true,"2025-12-12 19:05:51.418","2025-12-12 19:05:51.418")
---- PASS: TestNotificationProviderHandler_Create_DBError (0.00s)
-=== RUN TestNotificationProviderHandler_Create_InvalidTemplate
---- PASS: TestNotificationProviderHandler_Create_InvalidTemplate (0.00s)
-=== RUN TestNotificationProviderHandler_Update_InvalidJSON
---- PASS: TestNotificationProviderHandler_Update_InvalidJSON (0.00s)
-=== RUN TestNotificationProviderHandler_Update_InvalidTemplate
---- PASS: TestNotificationProviderHandler_Update_InvalidTemplate (0.00s)
-=== RUN TestNotificationProviderHandler_Update_DBError
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:479 [35;1mno such table: notification_providers
-[0m[33m[0.068ms] [34;1m[rows:0][0m UPDATE `notification_providers` SET `name`="Test",`type`="webhook",`url`="https://example.com",`config`="",`template`="minimal",`enabled`=false,`notify_proxy_hosts`=false,`notify_remote_servers`=false,`notify_domains`=false,`notify_certs`=false,`notify_uptime`=false,`created_at`="0000-00-00 00:00:00",`updated_at`="2025-12-12 19:05:51.422" WHERE `id` = "test-id"
---- PASS: TestNotificationProviderHandler_Update_DBError (0.00s)
-=== RUN TestNotificationProviderHandler_Delete_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:483 [35;1mno such table: notification_providers
-[0m[33m[0.032ms] [34;1m[rows:0][0m DELETE FROM `notification_providers` WHERE id = "test-id"
---- PASS: TestNotificationProviderHandler_Delete_Error (0.00s)
-=== RUN TestNotificationProviderHandler_Test_InvalidJSON
---- PASS: TestNotificationProviderHandler_Test_InvalidJSON (0.00s)
-=== RUN TestNotificationProviderHandler_Templates
---- PASS: TestNotificationProviderHandler_Templates (0.00s)
-=== RUN TestNotificationProviderHandler_Preview_InvalidJSON
---- PASS: TestNotificationProviderHandler_Preview_InvalidJSON (0.00s)
-=== RUN TestNotificationProviderHandler_Preview_WithData
---- PASS: TestNotificationProviderHandler_Preview_WithData (0.00s)
-=== RUN TestNotificationProviderHandler_Preview_InvalidTemplate
---- PASS: TestNotificationProviderHandler_Preview_InvalidTemplate (0.00s)
-=== RUN TestNotificationTemplateHandler_List_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:375 [35;1mno such table: notification_templates
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `notification_templates` ORDER BY created_at desc
---- PASS: TestNotificationTemplateHandler_List_Error (0.00s)
-=== RUN TestNotificationTemplateHandler_Create_BadJSON
---- PASS: TestNotificationTemplateHandler_Create_BadJSON (0.00s)
-=== RUN TestNotificationTemplateHandler_Create_DBError
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:392 [35;1mno such table: notification_templates
-[0m[33m[0.040ms] [34;1m[rows:0][0m INSERT INTO `notification_templates` (`id`,`name`,`description`,`config`,`template`,`created_at`,`updated_at`) VALUES ("ca832d3a-64c5-42a4-8c75-b389bf4048ff","Test","","{""test"": true}","minimal","2025-12-12 19:05:51.429","2025-12-12 19:05:51.429")
---- PASS: TestNotificationTemplateHandler_Create_DBError (0.00s)
-=== RUN TestNotificationTemplateHandler_Update_BadJSON
---- PASS: TestNotificationTemplateHandler_Update_BadJSON (0.00s)
-=== RUN TestNotificationTemplateHandler_Update_DBError
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:397 [35;1mno such table: notification_templates
-[0m[33m[0.037ms] [34;1m[rows:0][0m UPDATE `notification_templates` SET `name`="Test",`description`="",`config`="{""test"": true}",`template`="",`created_at`="0000-00-00 00:00:00",`updated_at`="2025-12-12 19:05:51.431" WHERE `id` = "test-id"
---- PASS: TestNotificationTemplateHandler_Update_DBError (0.00s)
-=== RUN TestNotificationTemplateHandler_Delete_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:402 [35;1mno such table: notification_templates
-[0m[33m[0.029ms] [34;1m[rows:0][0m DELETE FROM `notification_templates` WHERE id = "test-id"
---- PASS: TestNotificationTemplateHandler_Delete_Error (0.00s)
-=== RUN TestNotificationTemplateHandler_Preview_BadJSON
---- PASS: TestNotificationTemplateHandler_Preview_BadJSON (0.00s)
-=== RUN TestNotificationTemplateHandler_Preview_TemplateNotFound
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:384 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `notification_templates` WHERE id = "nonexistent" ORDER BY `notification_templates`.`id` LIMIT 1
---- PASS: TestNotificationTemplateHandler_Preview_TemplateNotFound (0.00s)
-=== RUN TestNotificationTemplateHandler_Preview_WithStoredTemplate
---- PASS: TestNotificationTemplateHandler_Preview_WithStoredTemplate (0.00s)
-=== RUN TestNotificationTemplateHandler_Preview_InvalidTemplate
---- PASS: TestNotificationTemplateHandler_Preview_InvalidTemplate (0.00s)
-=== RUN TestNotificationTemplateHandler_CRUDAndPreview
---- PASS: TestNotificationTemplateHandler_CRUDAndPreview (0.00s)
-=== RUN TestNotificationTemplateHandler_Create_InvalidJSON
---- PASS: TestNotificationTemplateHandler_Create_InvalidJSON (0.00s)
-=== RUN TestNotificationTemplateHandler_Update_InvalidJSON
---- PASS: TestNotificationTemplateHandler_Update_InvalidJSON (0.00s)
-=== RUN TestNotificationTemplateHandler_Preview_InvalidJSON
---- PASS: TestNotificationTemplateHandler_Preview_InvalidJSON (0.00s)
-=== RUN TestPerf_GetStatus_AssertThreshold
- perf_assert_test.go:107: GetStatus avg=0.045ms p95=0.085ms max=1.550ms
---- PASS: TestPerf_GetStatus_AssertThreshold (0.02s)
-=== RUN TestPerf_GetStatus_Parallel_AssertThreshold
- perf_assert_test.go:150: GetStatus Parallel avg=0.067ms p95=0.135ms max=3.510ms
---- PASS: TestPerf_GetStatus_Parallel_AssertThreshold (0.02s)
-=== RUN TestPerf_ListDecisions_AssertThreshold
- perf_assert_test.go:179: ListDecisions avg=0.863ms p95=1.108ms max=3.795ms
---- PASS: TestPerf_ListDecisions_AssertThreshold (0.22s)
-=== RUN TestProxyHostLifecycle
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
-[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "f4e8da5e-4668-40da-95b8-db6151890005" ORDER BY `proxy_hosts`.`id` LIMIT 1
---- PASS: TestProxyHostLifecycle (0.00s)
-=== RUN TestProxyHostDelete_WithUptimeCleanup
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:82 [35;1mno such table: notification_providers
-[0m[33m[0.132ms] [34;1m[rows:0][0m SELECT * FROM `notification_providers` WHERE enabled = true
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/proxy_host_handler_test.go:141 [35;1mrecord not found
-[0m[33m[0.047ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "ph-delete-1" ORDER BY `proxy_hosts`.`id` LIMIT 1
---- PASS: TestProxyHostDelete_WithUptimeCleanup (0.00s)
-=== RUN TestProxyHostErrors
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
-[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
-[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
-[0m[33m[0.106ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
-[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
-[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
-[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
-[0m[33m[0.055ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
-[0m[33m[0.045ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
-[0m[33m[0.030ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "non-existent-uuid" ORDER BY `proxy_hosts`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "non-existent-uuid" ORDER BY `proxy_hosts`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
-[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
-[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
-[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
-[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
-[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
-[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "non-existent-uuid" ORDER BY `proxy_hosts`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
-[0m[33m[0.013ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
-[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
-[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
-[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
-[0m[33m[0.004ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
---- PASS: TestProxyHostErrors (0.01s)
-=== RUN TestProxyHostValidation
---- PASS: TestProxyHostValidation (0.00s)
-=== RUN TestProxyHostCreate_AdvancedConfig_InvalidJSON
---- PASS: TestProxyHostCreate_AdvancedConfig_InvalidJSON (0.00s)
-=== RUN TestProxyHostCreate_AdvancedConfig_Normalization
---- PASS: TestProxyHostCreate_AdvancedConfig_Normalization (0.00s)
-=== RUN TestProxyHostUpdate_CertificateID_Null
---- PASS: TestProxyHostUpdate_CertificateID_Null (0.00s)
-=== RUN TestProxyHostConnection
---- PASS: TestProxyHostConnection (0.00s)
-=== RUN TestProxyHostHandler_List_Error
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:121 [35;1msql: database is closed
-[0m[33m[0.009ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` ORDER BY updated_at desc
---- PASS: TestProxyHostHandler_List_Error (0.00s)
-=== RUN TestProxyHostWithCaddyIntegration
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
-[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
-[0m[33m[0.134ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
-[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
-[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
-[0m[33m[0.060ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
-[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:82 [35;1mno such table: notification_providers
-[0m[33m[0.122ms] [34;1m[rows:0][0m SELECT * FROM `notification_providers` WHERE enabled = true
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
-[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
-[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
-[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
-[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
-[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:423 [35;1mno such table: security_configs
-[0m[33m[0.006ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
-[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
-[0m[33m[0.008ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:112 [35;1mno such table: security_configs
-[0m[33m[0.005ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:120 [35;1mno such table: security_rule_sets
-[0m[33m[0.005ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets`
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/caddy/manager.go:127 [35;1mno such table: security_decisions
-[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `security_decisions` ORDER BY created_at desc
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/notification_service.go:82 [35;1mno such table: notification_providers
-[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `notification_providers` WHERE enabled = true
---- PASS: TestProxyHostWithCaddyIntegration (0.01s)
-=== RUN TestProxyHostHandler_BulkUpdateACL_Success
---- PASS: TestProxyHostHandler_BulkUpdateACL_Success (0.00s)
-=== RUN TestProxyHostHandler_BulkUpdateACL_RemoveACL
---- PASS: TestProxyHostHandler_BulkUpdateACL_RemoveACL (0.00s)
-=== RUN TestProxyHostHandler_BulkUpdateACL_PartialFailure
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/proxyhost_service.go:112 [35;1mrecord not found
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `proxy_hosts` WHERE uuid = "422c0cc1-e09e-4e7f-8ba4-6c678835580a" ORDER BY `proxy_hosts`.`id` LIMIT 1
---- PASS: TestProxyHostHandler_BulkUpdateACL_PartialFailure (0.00s)
-=== RUN TestProxyHostHandler_BulkUpdateACL_EmptyUUIDs
---- PASS: TestProxyHostHandler_BulkUpdateACL_EmptyUUIDs (0.00s)
-=== RUN TestProxyHostHandler_BulkUpdateACL_InvalidJSON
---- PASS: TestProxyHostHandler_BulkUpdateACL_InvalidJSON (0.00s)
-=== RUN TestProxyHostUpdate_AdvancedConfig_ClearAndBackup
---- PASS: TestProxyHostUpdate_AdvancedConfig_ClearAndBackup (0.00s)
-=== RUN TestProxyHostUpdate_AdvancedConfig_InvalidJSON
---- PASS: TestProxyHostUpdate_AdvancedConfig_InvalidJSON (0.00s)
-=== RUN TestProxyHostUpdate_SetCertificateID
---- PASS: TestProxyHostUpdate_SetCertificateID (0.00s)
-=== RUN TestProxyHostUpdate_AdvancedConfig_SetBackup
---- PASS: TestProxyHostUpdate_AdvancedConfig_SetBackup (0.00s)
-=== RUN TestProxyHostUpdate_ForwardPort_StringValue
---- PASS: TestProxyHostUpdate_ForwardPort_StringValue (0.00s)
-=== RUN TestProxyHostUpdate_Locations_InvalidPayload
---- PASS: TestProxyHostUpdate_Locations_InvalidPayload (0.00s)
-=== RUN TestProxyHostUpdate_SetBooleansAndApplication
---- PASS: TestProxyHostUpdate_SetBooleansAndApplication (0.00s)
-=== RUN TestProxyHostUpdate_Locations_Replace
---- PASS: TestProxyHostUpdate_Locations_Replace (0.00s)
-=== RUN TestProxyHostCreate_WithCertificateAndLocations
---- PASS: TestProxyHostCreate_WithCertificateAndLocations (0.00s)
-=== RUN TestSanitizeForLog
---- PASS: TestSanitizeForLog (0.00s)
-=== RUN TestSecurityHandler_GetGeoIPStatus_NotInitialized
---- PASS: TestSecurityHandler_GetGeoIPStatus_NotInitialized (0.00s)
-=== RUN TestSecurityHandler_GetGeoIPStatus_Initialized_NotLoaded
---- PASS: TestSecurityHandler_GetGeoIPStatus_Initialized_NotLoaded (0.00s)
-=== RUN TestSecurityHandler_ReloadGeoIP_NotInitialized
---- PASS: TestSecurityHandler_ReloadGeoIP_NotInitialized (0.00s)
-=== RUN TestSecurityHandler_ReloadGeoIP_LoadError
-time="2025-12-12T19:05:51Z" level=error msg="Failed to reload GeoIP database" error="open : no such file or directory"
---- PASS: TestSecurityHandler_ReloadGeoIP_LoadError (0.00s)
-=== RUN TestSecurityHandler_LookupGeoIP_MissingIPAddress
---- PASS: TestSecurityHandler_LookupGeoIP_MissingIPAddress (0.00s)
-=== RUN TestSecurityHandler_LookupGeoIP_ServiceUnavailable
---- PASS: TestSecurityHandler_LookupGeoIP_ServiceUnavailable (0.00s)
-=== RUN TestSecurityHandler_GetConfigAndUpdateConfig
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
-[0m[33m[0.038ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_GetConfigAndUpdateConfig (0.00s)
-=== RUN TestSecurityHandler_GetStatus_SQLInjection
---- PASS: TestSecurityHandler_GetStatus_SQLInjection (0.00s)
-=== RUN TestSecurityHandler_CreateDecision_SQLInjection
-=== RUN TestSecurityHandler_CreateDecision_SQLInjection/payload_0
-=== RUN TestSecurityHandler_CreateDecision_SQLInjection/payload_1
-=== RUN TestSecurityHandler_CreateDecision_SQLInjection/payload_2
-=== RUN TestSecurityHandler_CreateDecision_SQLInjection/payload_3
---- PASS: TestSecurityHandler_CreateDecision_SQLInjection (0.00s)
- --- PASS: TestSecurityHandler_CreateDecision_SQLInjection/payload_0 (0.00s)
- --- PASS: TestSecurityHandler_CreateDecision_SQLInjection/payload_1 (0.00s)
- --- PASS: TestSecurityHandler_CreateDecision_SQLInjection/payload_2 (0.00s)
- --- PASS: TestSecurityHandler_CreateDecision_SQLInjection/payload_3 (0.00s)
-=== RUN TestSecurityHandler_UpsertRuleSet_MassivePayload
---- PASS: TestSecurityHandler_UpsertRuleSet_MassivePayload (0.05s)
-=== RUN TestSecurityHandler_UpsertRuleSet_EmptyName
---- PASS: TestSecurityHandler_UpsertRuleSet_EmptyName (0.00s)
-=== RUN TestSecurityHandler_CreateDecision_EmptyFields
-=== RUN TestSecurityHandler_CreateDecision_EmptyFields/empty_ip
-=== RUN TestSecurityHandler_CreateDecision_EmptyFields/empty_action
-=== RUN TestSecurityHandler_CreateDecision_EmptyFields/both_empty
-=== RUN TestSecurityHandler_CreateDecision_EmptyFields/valid
---- PASS: TestSecurityHandler_CreateDecision_EmptyFields (0.00s)
- --- PASS: TestSecurityHandler_CreateDecision_EmptyFields/empty_ip (0.00s)
- --- PASS: TestSecurityHandler_CreateDecision_EmptyFields/empty_action (0.00s)
- --- PASS: TestSecurityHandler_CreateDecision_EmptyFields/both_empty (0.00s)
- --- PASS: TestSecurityHandler_CreateDecision_EmptyFields/valid (0.00s)
-=== RUN TestSecurityHandler_GetStatus_SettingsOverride
---- PASS: TestSecurityHandler_GetStatus_SettingsOverride (0.00s)
-=== RUN TestSecurityHandler_GetStatus_DisabledViaSettings
---- PASS: TestSecurityHandler_GetStatus_DisabledViaSettings (0.00s)
-=== RUN TestSecurityAudit_DeleteRuleSet_InvalidID
-=== RUN TestSecurityAudit_DeleteRuleSet_InvalidID/empty_id
-=== RUN TestSecurityAudit_DeleteRuleSet_InvalidID/non_numeric
-=== RUN TestSecurityAudit_DeleteRuleSet_InvalidID/negative
-=== RUN TestSecurityAudit_DeleteRuleSet_InvalidID/sql_injection
-=== RUN TestSecurityAudit_DeleteRuleSet_InvalidID/not_found
---- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID (0.00s)
- --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/empty_id (0.00s)
- --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/non_numeric (0.00s)
- --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/negative (0.00s)
- --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/sql_injection (0.00s)
- --- PASS: TestSecurityAudit_DeleteRuleSet_InvalidID/not_found (0.00s)
-=== RUN TestSecurityHandler_UpsertRuleSet_XSSInContent
---- PASS: TestSecurityHandler_UpsertRuleSet_XSSInContent (0.00s)
-=== RUN TestSecurityHandler_UpdateConfig_RateLimitBounds
-=== RUN TestSecurityHandler_UpdateConfig_RateLimitBounds/valid_limits
-=== RUN TestSecurityHandler_UpdateConfig_RateLimitBounds/zero_requests
-=== RUN TestSecurityHandler_UpdateConfig_RateLimitBounds/negative_burst
-=== RUN TestSecurityHandler_UpdateConfig_RateLimitBounds/huge_values
---- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds (0.00s)
- --- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds/valid_limits (0.00s)
- --- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds/zero_requests (0.00s)
- --- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds/negative_burst (0.00s)
- --- PASS: TestSecurityHandler_UpdateConfig_RateLimitBounds/huge_values (0.00s)
-=== RUN TestSecurityHandler_GetStatus_NilDB
---- PASS: TestSecurityHandler_GetStatus_NilDB (0.00s)
-=== RUN TestSecurityHandler_Enable_WithoutWhitelist
---- PASS: TestSecurityHandler_Enable_WithoutWhitelist (0.00s)
-=== RUN TestSecurityHandler_Disable_RequiresToken
---- PASS: TestSecurityHandler_Disable_RequiresToken (0.00s)
-=== RUN TestSecurityHandler_GetStatus_CrowdSecModeValidation
-=== RUN TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_remote
-=== RUN TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_external
-=== RUN TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_cloud
-=== RUN TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_api
-=== RUN TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_../../../etc/passwd
---- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation (0.00s)
- --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_remote (0.00s)
- --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_external (0.00s)
- --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_cloud (0.00s)
- --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_api (0.00s)
- --- PASS: TestSecurityHandler_GetStatus_CrowdSecModeValidation/mode_../../../etc/passwd (0.00s)
-=== RUN TestSecurityHandler_GetStatus_Clean
---- PASS: TestSecurityHandler_GetStatus_Clean (0.00s)
-=== RUN TestSecurityHandler_Cerberus_DBOverride
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.138ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_Cerberus_DBOverride (0.00s)
-=== RUN TestSecurityHandler_ACL_DBOverride
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_clean_test.go:119:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_clean_test.go:119
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_ACL_DBOverride
---- FAIL: TestSecurityHandler_ACL_DBOverride (0.00s)
-=== RUN TestSecurityHandler_GenerateBreakGlass_ReturnsToken
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mrecord not found
-[0m[33m[0.131ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_GenerateBreakGlass_ReturnsToken (0.06s)
-=== RUN TestSecurityHandler_ACL_DisabledWhenCerberusOff
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.070ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_ACL_DisabledWhenCerberusOff (0.00s)
-=== RUN TestSecurityHandler_CrowdSec_Mode_DBOverride
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.054ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_clean_test.go:196:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_clean_test.go:196
- Error: Not equal:
- expected: "local"
- actual : "disabled"
-
- Diff:
- --- Expected
- +++ Actual
- @@ -1 +1 @@
- -local
- +disabled
- Test: TestSecurityHandler_CrowdSec_Mode_DBOverride
---- FAIL: TestSecurityHandler_CrowdSec_Mode_DBOverride (0.00s)
-=== RUN TestSecurityHandler_CrowdSec_ExternalMappedToDisabled_DBOverride
-
-2025/12/12 19:05:51 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_CrowdSec_ExternalMappedToDisabled_DBOverride (0.00s)
-=== RUN TestSecurityHandler_ExternalModeMappedToDisabled
---- PASS: TestSecurityHandler_ExternalModeMappedToDisabled (0.00s)
-=== RUN TestSecurityHandler_Enable_Disable_WithAdminWhitelistAndToken
---- PASS: TestSecurityHandler_Enable_Disable_WithAdminWhitelistAndToken (0.12s)
-=== RUN TestSecurityHandler_UpdateConfig_Success
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
-[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_UpdateConfig_Success (0.00s)
-=== RUN TestSecurityHandler_UpdateConfig_DefaultName
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
-[0m[33m[0.044ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_UpdateConfig_DefaultName (0.00s)
-=== RUN TestSecurityHandler_UpdateConfig_InvalidPayload
---- PASS: TestSecurityHandler_UpdateConfig_InvalidPayload (0.00s)
-=== RUN TestSecurityHandler_GetConfig_Success
---- PASS: TestSecurityHandler_GetConfig_Success (0.00s)
-=== RUN TestSecurityHandler_GetConfig_NotFound
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_GetConfig_NotFound (0.00s)
-=== RUN TestSecurityHandler_ListDecisions_Success
---- PASS: TestSecurityHandler_ListDecisions_Success (0.00s)
-=== RUN TestSecurityHandler_ListDecisions_WithLimit
---- PASS: TestSecurityHandler_ListDecisions_WithLimit (0.00s)
-=== RUN TestSecurityHandler_CreateDecision_Success
---- PASS: TestSecurityHandler_CreateDecision_Success (0.00s)
-=== RUN TestSecurityHandler_CreateDecision_MissingIP
---- PASS: TestSecurityHandler_CreateDecision_MissingIP (0.00s)
-=== RUN TestSecurityHandler_CreateDecision_MissingAction
---- PASS: TestSecurityHandler_CreateDecision_MissingAction (0.00s)
-=== RUN TestSecurityHandler_CreateDecision_InvalidPayload
---- PASS: TestSecurityHandler_CreateDecision_InvalidPayload (0.00s)
-=== RUN TestSecurityHandler_ListRuleSets_Success
---- PASS: TestSecurityHandler_ListRuleSets_Success (0.00s)
-=== RUN TestSecurityHandler_UpsertRuleSet_Success
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mrecord not found
-[0m[33m[0.037ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "test-ruleset" ORDER BY `security_rule_sets`.`id` LIMIT 1
---- PASS: TestSecurityHandler_UpsertRuleSet_Success (0.00s)
-=== RUN TestSecurityHandler_UpsertRuleSet_MissingName
---- PASS: TestSecurityHandler_UpsertRuleSet_MissingName (0.00s)
-=== RUN TestSecurityHandler_UpsertRuleSet_InvalidPayload
---- PASS: TestSecurityHandler_UpsertRuleSet_InvalidPayload (0.00s)
-=== RUN TestSecurityHandler_DeleteRuleSet_Success
---- PASS: TestSecurityHandler_DeleteRuleSet_Success (0.00s)
-=== RUN TestSecurityHandler_DeleteRuleSet_NotFound
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:234 [35;1mrecord not found
-[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE `security_rule_sets`.`id` = 999 ORDER BY `security_rule_sets`.`id` LIMIT 1
---- PASS: TestSecurityHandler_DeleteRuleSet_NotFound (0.00s)
-=== RUN TestSecurityHandler_DeleteRuleSet_InvalidID
---- PASS: TestSecurityHandler_DeleteRuleSet_InvalidID (0.00s)
-=== RUN TestSecurityHandler_DeleteRuleSet_EmptyID
---- PASS: TestSecurityHandler_DeleteRuleSet_EmptyID (0.00s)
-=== RUN TestSecurityHandler_Enable_NoConfigNoWhitelist
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.083ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
-[0m[33m[0.126ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_Enable_NoConfigNoWhitelist (0.00s)
-=== RUN TestSecurityHandler_Enable_WithWhitelist
---- PASS: TestSecurityHandler_Enable_WithWhitelist (0.00s)
-=== RUN TestSecurityHandler_Enable_IPNotInWhitelist
---- PASS: TestSecurityHandler_Enable_IPNotInWhitelist (0.00s)
-=== RUN TestSecurityHandler_Enable_WithValidBreakGlassToken
---- PASS: TestSecurityHandler_Enable_WithValidBreakGlassToken (0.12s)
-=== RUN TestSecurityHandler_Enable_WithInvalidBreakGlassToken
---- PASS: TestSecurityHandler_Enable_WithInvalidBreakGlassToken (0.00s)
-=== RUN TestSecurityHandler_Disable_FromLocalhost
---- PASS: TestSecurityHandler_Disable_FromLocalhost (0.00s)
-=== RUN TestSecurityHandler_Disable_FromRemoteWithToken
---- PASS: TestSecurityHandler_Disable_FromRemoteWithToken (0.12s)
-=== RUN TestSecurityHandler_Disable_FromRemoteNoToken
---- PASS: TestSecurityHandler_Disable_FromRemoteNoToken (0.00s)
-=== RUN TestSecurityHandler_Disable_FromRemoteInvalidToken
---- PASS: TestSecurityHandler_Disable_FromRemoteInvalidToken (0.00s)
-=== RUN TestSecurityHandler_GenerateBreakGlass_NoConfig
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:121 [35;1mrecord not found
-[0m[33m[0.137ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_GenerateBreakGlass_NoConfig (0.06s)
-=== RUN TestSecurityHandler_Disable_FromIPv6Localhost
---- PASS: TestSecurityHandler_Disable_FromIPv6Localhost (0.00s)
-=== RUN TestSecurityHandler_Enable_WithCIDRWhitelist
---- PASS: TestSecurityHandler_Enable_WithCIDRWhitelist (0.00s)
-=== RUN TestSecurityHandler_Enable_WithExactIPWhitelist
---- PASS: TestSecurityHandler_Enable_WithExactIPWhitelist (0.00s)
-=== RUN TestSecurityHandler_GetStatus_Fixed
-=== RUN TestSecurityHandler_GetStatus_Fixed/All_Disabled
-=== RUN TestSecurityHandler_GetStatus_Fixed/All_Enabled
---- PASS: TestSecurityHandler_GetStatus_Fixed (0.00s)
- --- PASS: TestSecurityHandler_GetStatus_Fixed/All_Disabled (0.00s)
- --- PASS: TestSecurityHandler_GetStatus_Fixed/All_Enabled (0.00s)
-=== RUN TestSecurityHandler_CreateAndListDecisionAndRulesets
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mrecord not found
-[0m[33m[0.062ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "owasp-crs" ORDER BY `security_rule_sets`.`id` LIMIT 1
---- PASS: TestSecurityHandler_CreateAndListDecisionAndRulesets (0.07s)
-=== RUN TestSecurityHandler_UpsertDeleteTriggersApplyConfig
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:212 [35;1mrecord not found
-[0m[33m[0.045ms] [34;1m[rows:0][0m SELECT * FROM `security_rule_sets` WHERE name = "owasp-crs" ORDER BY `security_rule_sets`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
-[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
-[0m[33m[0.022ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
-[0m[33m[0.012ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
-[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:68 [35;1mrecord not found
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.acme_email" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:75 [35;1mrecord not found
-[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "caddy.ssl_provider" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:452 [35;1mrecord not found
-[0m[33m[0.011ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "feature.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:454 [35;1mrecord not found
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.cerberus.enabled" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/caddy/manager.go:459 [35;1mrecord not found
-[0m[33m[0.010ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "security.acl.enabled" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestSecurityHandler_UpsertDeleteTriggersApplyConfig (0.01s)
-=== RUN TestSecurityHandler_GetStatus_RespectsSettingsTable
-=== RUN TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_enabled_via_settings_overrides_disabled_config
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.114ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_settings_test.go:145:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:145
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_enabled_via_settings_overrides_disabled_config
- Messages: WAF enabled mismatch
-=== RUN TestSecurityHandler_GetStatus_RespectsSettingsTable/Rate_Limit_enabled_via_settings_overrides_disabled_config
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_settings_test.go:149:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:149
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/Rate_Limit_enabled_via_settings_overrides_disabled_config
- Messages: Rate Limit enabled mismatch
-=== RUN TestSecurityHandler_GetStatus_RespectsSettingsTable/CrowdSec_enabled_via_settings_overrides_disabled_config
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.037ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_settings_test.go:153:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:153
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/CrowdSec_enabled_via_settings_overrides_disabled_config
- Messages: CrowdSec enabled mismatch
-=== RUN TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.032ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_settings_test.go:145:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:145
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings
- Messages: WAF enabled mismatch
- security_handler_settings_test.go:149:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:149
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings
- Messages: Rate Limit enabled mismatch
- security_handler_settings_test.go:153:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:153
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings
- Messages: CrowdSec enabled mismatch
-=== RUN TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_disabled_via_settings_overrides_enabled_config
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
-=== RUN TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled)
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_settings_test.go:145:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:145
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled)
- Messages: WAF enabled mismatch
- security_handler_settings_test.go:149:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:149
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled)
- Messages: Rate Limit enabled mismatch
- security_handler_settings_test.go:153:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:153
- Error: Not equal:
- expected: true
- actual : false
- Test: TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled)
- Messages: CrowdSec enabled mismatch
---- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable (0.01s)
- --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_enabled_via_settings_overrides_disabled_config (0.00s)
- --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/Rate_Limit_enabled_via_settings_overrides_disabled_config (0.00s)
- --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/CrowdSec_enabled_via_settings_overrides_disabled_config (0.00s)
- --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/All_modules_enabled_via_settings (0.00s)
- --- PASS: TestSecurityHandler_GetStatus_RespectsSettingsTable/WAF_disabled_via_settings_overrides_enabled_config (0.00s)
- --- FAIL: TestSecurityHandler_GetStatus_RespectsSettingsTable/No_settings_-_falls_back_to_config_(enabled) (0.00s)
-=== RUN TestSecurityHandler_GetStatus_WAFModeFromSettings
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.049ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_settings_test.go:187:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:187
- Error: Should be true
- Test: TestSecurityHandler_GetStatus_WAFModeFromSettings
---- FAIL: TestSecurityHandler_GetStatus_WAFModeFromSettings (0.01s)
-=== RUN TestSecurityHandler_GetStatus_RateLimitModeFromSettings
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/security_handler.go:68 [35;1mrecord not found
-[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
- security_handler_settings_test.go:218:
- Error Trace: /projects/Charon/backend/internal/api/handlers/security_handler_settings_test.go:218
- Error: Should be true
- Test: TestSecurityHandler_GetStatus_RateLimitModeFromSettings
---- FAIL: TestSecurityHandler_GetStatus_RateLimitModeFromSettings (0.00s)
-=== RUN TestSecurityHandler_GetWAFExclusions_Empty
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.034ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_GetWAFExclusions_Empty (0.00s)
-=== RUN TestSecurityHandler_GetWAFExclusions_WithExclusions
---- PASS: TestSecurityHandler_GetWAFExclusions_WithExclusions (0.00s)
-=== RUN TestSecurityHandler_GetWAFExclusions_InvalidJSON
-time="2025-12-12T19:05:52Z" level=warning msg="Failed to parse WAF exclusions" error="invalid character 'i' looking for beginning of value"
---- PASS: TestSecurityHandler_GetWAFExclusions_InvalidJSON (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_Success
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
-[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_AddWAFExclusion_Success (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_WithTarget
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.023ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_AddWAFExclusion_WithTarget (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_ToExistingConfig
---- PASS: TestSecurityHandler_AddWAFExclusion_ToExistingConfig (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_Duplicate
---- PASS: TestSecurityHandler_AddWAFExclusion_Duplicate (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_DuplicateWithDifferentTarget
---- PASS: TestSecurityHandler_AddWAFExclusion_DuplicateWithDifferentTarget (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_MissingRuleID
---- PASS: TestSecurityHandler_AddWAFExclusion_MissingRuleID (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_InvalidRuleID
---- PASS: TestSecurityHandler_AddWAFExclusion_InvalidRuleID (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_NegativeRuleID
---- PASS: TestSecurityHandler_AddWAFExclusion_NegativeRuleID (0.00s)
-=== RUN TestSecurityHandler_AddWAFExclusion_InvalidPayload
---- PASS: TestSecurityHandler_AddWAFExclusion_InvalidPayload (0.00s)
-=== RUN TestSecurityHandler_DeleteWAFExclusion_Success
---- PASS: TestSecurityHandler_DeleteWAFExclusion_Success (0.00s)
-=== RUN TestSecurityHandler_DeleteWAFExclusion_WithTarget
---- PASS: TestSecurityHandler_DeleteWAFExclusion_WithTarget (0.00s)
-=== RUN TestSecurityHandler_DeleteWAFExclusion_NotFound
---- PASS: TestSecurityHandler_DeleteWAFExclusion_NotFound (0.00s)
-=== RUN TestSecurityHandler_DeleteWAFExclusion_NoConfig
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_DeleteWAFExclusion_NoConfig (0.00s)
-=== RUN TestSecurityHandler_DeleteWAFExclusion_InvalidRuleID
---- PASS: TestSecurityHandler_DeleteWAFExclusion_InvalidRuleID (0.00s)
-=== RUN TestSecurityHandler_DeleteWAFExclusion_ZeroRuleID
---- PASS: TestSecurityHandler_DeleteWAFExclusion_ZeroRuleID (0.00s)
-=== RUN TestSecurityHandler_DeleteWAFExclusion_NegativeRuleID
---- PASS: TestSecurityHandler_DeleteWAFExclusion_NegativeRuleID (0.00s)
-=== RUN TestSecurityHandler_WAFExclusion_FullWorkflow
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:37 [35;1mrecord not found
-[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` ORDER BY `security_configs`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_service.go:73 [35;1mrecord not found
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `security_configs` WHERE name = "default" ORDER BY `security_configs`.`id` LIMIT 1
---- PASS: TestSecurityHandler_WAFExclusion_FullWorkflow (0.00s)
-=== RUN TestProxyHost_WAFDisabled_DefaultFalse
---- PASS: TestProxyHost_WAFDisabled_DefaultFalse (0.00s)
-=== RUN TestProxyHost_WAFDisabled_SetTrue
---- PASS: TestProxyHost_WAFDisabled_SetTrue (0.00s)
-=== RUN TestSecurityConfig_WAFParanoiaLevel_Default
---- PASS: TestSecurityConfig_WAFParanoiaLevel_Default (0.00s)
-=== RUN TestSecurityConfig_WAFParanoiaLevel_CustomValue
---- PASS: TestSecurityConfig_WAFParanoiaLevel_CustomValue (0.00s)
-=== RUN TestSecurityConfig_WAFExclusions_Empty
---- PASS: TestSecurityConfig_WAFExclusions_Empty (0.00s)
-=== RUN TestSecurityConfig_WAFExclusions_JSONArray
---- PASS: TestSecurityConfig_WAFExclusions_JSONArray (0.00s)
-=== RUN TestSecurityNotificationHandler_GetSettings
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1mrecord not found
-[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
---- PASS: TestSecurityNotificationHandler_GetSettings (0.00s)
-=== RUN TestSecurityNotificationHandler_UpdateSettings
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
-[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
---- PASS: TestSecurityNotificationHandler_UpdateSettings (0.00s)
-=== RUN TestSecurityNotificationHandler_InvalidLevel
---- PASS: TestSecurityNotificationHandler_InvalidLevel (0.00s)
-=== RUN TestSecurityNotificationHandler_UpdateSettings_InvalidJSON
---- PASS: TestSecurityNotificationHandler_UpdateSettings_InvalidJSON (0.00s)
-=== RUN TestSecurityNotificationHandler_UpdateSettings_ValidLevels
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:45 [35;1mrecord not found
-[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
---- PASS: TestSecurityNotificationHandler_UpdateSettings_ValidLevels (0.00s)
-=== RUN TestSecurityNotificationHandler_GetSettings_DatabaseError
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1msql: database is closed
-[0m[33m[0.004ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
---- PASS: TestSecurityNotificationHandler_GetSettings_DatabaseError (0.00s)
-=== RUN TestSecurityNotificationHandler_GetSettings_EmptySettings
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/services/security_notification_service.go:29 [35;1mrecord not found
-[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT * FROM `notification_configs` ORDER BY `notification_configs`.`id` LIMIT 1
---- PASS: TestSecurityNotificationHandler_GetSettings_EmptySettings (0.00s)
-=== RUN TestSecurityHandler_GetRateLimitPresets
---- PASS: TestSecurityHandler_GetRateLimitPresets (0.00s)
-=== RUN TestSecurityHandler_GetRateLimitPresets_StandardPreset
---- PASS: TestSecurityHandler_GetRateLimitPresets_StandardPreset (0.00s)
-=== RUN TestSecurityHandler_GetRateLimitPresets_LoginPreset
---- PASS: TestSecurityHandler_GetRateLimitPresets_LoginPreset (0.00s)
-=== RUN TestGetClientIPHeadersAndRemoteAddr
---- PASS: TestGetClientIPHeadersAndRemoteAddr (0.00s)
-=== RUN TestGetMyIPHandler
-=== RUN TestGetMyIPHandler/with_CF_header
-=== RUN TestGetMyIPHandler/with_X-Forwarded-For_header
-=== RUN TestGetMyIPHandler/with_X-Real-IP_header
-=== RUN TestGetMyIPHandler/direct_connection
---- PASS: TestGetMyIPHandler (0.00s)
- --- PASS: TestGetMyIPHandler/with_CF_header (0.00s)
- --- PASS: TestGetMyIPHandler/with_X-Forwarded-For_header (0.00s)
- --- PASS: TestGetMyIPHandler/with_X-Real-IP_header (0.00s)
- --- PASS: TestGetMyIPHandler/direct_connection (0.00s)
-=== RUN TestUpdateHandler_Check
---- PASS: TestUpdateHandler_Check (0.00s)
-=== RUN TestUserHandler_GetSetupStatus_Error
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:55 [35;1mno such table: users
-[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT count(*) FROM `users`
---- PASS: TestUserHandler_GetSetupStatus_Error (0.00s)
-=== RUN TestUserHandler_Setup_CheckStatusError
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:75 [35;1mno such table: users
-[0m[33m[0.018ms] [34;1m[rows:0][0m SELECT count(*) FROM `users`
---- PASS: TestUserHandler_Setup_CheckStatusError (0.00s)
-=== RUN TestUserHandler_Setup_AlreadyCompleted
---- PASS: TestUserHandler_Setup_AlreadyCompleted (0.06s)
-=== RUN TestUserHandler_Setup_InvalidJSON
---- PASS: TestUserHandler_Setup_InvalidJSON (0.00s)
-=== RUN TestUserHandler_RegenerateAPIKey_Unauthorized
---- PASS: TestUserHandler_RegenerateAPIKey_Unauthorized (0.00s)
-=== RUN TestUserHandler_RegenerateAPIKey_DBError
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:152 [35;1mno such table: users
-[0m[33m[0.056ms] [34;1m[rows:0][0m UPDATE `users` SET `api_key`="b8c75043-8fe9-4819-acaa-a65bc2a5d020",`updated_at`="2025-12-12 19:05:52.585" WHERE id = 1
---- PASS: TestUserHandler_RegenerateAPIKey_DBError (0.00s)
-=== RUN TestUserHandler_GetProfile_Unauthorized
---- PASS: TestUserHandler_GetProfile_Unauthorized (0.00s)
-=== RUN TestUserHandler_GetProfile_NotFound
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:169 [35;1mrecord not found
-[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 9999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_GetProfile_NotFound (0.00s)
-=== RUN TestUserHandler_UpdateProfile_Unauthorized
---- PASS: TestUserHandler_UpdateProfile_Unauthorized (0.00s)
-=== RUN TestUserHandler_UpdateProfile_InvalidJSON
---- PASS: TestUserHandler_UpdateProfile_InvalidJSON (0.00s)
-=== RUN TestUserHandler_UpdateProfile_UserNotFound
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:205 [35;1mrecord not found
-[0m[33m[0.043ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 9999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_UpdateProfile_UserNotFound (0.00s)
-=== RUN TestUserHandler_UpdateProfile_EmailConflict
---- PASS: TestUserHandler_UpdateProfile_EmailConflict (0.12s)
-=== RUN TestUserHandler_UpdateProfile_EmailChangeNoPassword
---- PASS: TestUserHandler_UpdateProfile_EmailChangeNoPassword (0.06s)
-=== RUN TestUserHandler_UpdateProfile_WrongPassword
---- PASS: TestUserHandler_UpdateProfile_WrongPassword (0.12s)
-=== RUN TestUserHandler_GetSetupStatus
---- PASS: TestUserHandler_GetSetupStatus (0.00s)
-=== RUN TestUserHandler_Setup
---- PASS: TestUserHandler_Setup (0.06s)
-=== RUN TestUserHandler_Setup_DBError
---- PASS: TestUserHandler_Setup_DBError (0.00s)
-=== RUN TestUserHandler_RegenerateAPIKey
---- PASS: TestUserHandler_RegenerateAPIKey (0.00s)
-=== RUN TestUserHandler_GetProfile
---- PASS: TestUserHandler_GetProfile (0.00s)
-=== RUN TestUserHandler_RegisterRoutes
---- PASS: TestUserHandler_RegisterRoutes (0.00s)
-=== RUN TestUserHandler_Errors
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:169 [35;1mrecord not found
-[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 99999 ORDER BY `users`.`id` LIMIT 1
-
-2025/12/12 19:05:52 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:152 [35;1mno such table: users
-[0m[33m[0.048ms] [34;1m[rows:0][0m UPDATE `users` SET `api_key`="5ecabc02-1821-4ec6-bd8c-1b217bc10aa4",`updated_at`="2025-12-12 19:05:52.978" WHERE id = 99999
---- PASS: TestUserHandler_Errors (0.00s)
-=== RUN TestUserHandler_UpdateProfile
-=== RUN TestUserHandler_UpdateProfile/Success_Name_Only
-=== RUN TestUserHandler_UpdateProfile/Success_Email_Change
-=== RUN TestUserHandler_UpdateProfile/Fail_Email_Change_No_Password
-=== RUN TestUserHandler_UpdateProfile/Fail_Email_Change_Wrong_Password
-=== RUN TestUserHandler_UpdateProfile/Fail_Email_In_Use
---- PASS: TestUserHandler_UpdateProfile (0.19s)
- --- PASS: TestUserHandler_UpdateProfile/Success_Name_Only (0.00s)
- --- PASS: TestUserHandler_UpdateProfile/Success_Email_Change (0.06s)
- --- PASS: TestUserHandler_UpdateProfile/Fail_Email_Change_No_Password (0.00s)
- --- PASS: TestUserHandler_UpdateProfile/Fail_Email_Change_Wrong_Password (0.06s)
- --- PASS: TestUserHandler_UpdateProfile/Fail_Email_In_Use (0.00s)
-=== RUN TestUserHandler_UpdateProfile_Errors
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:205 [35;1mrecord not found
-[0m[33m[0.040ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_UpdateProfile_Errors (0.00s)
-=== RUN TestUserHandler_ListUsers_NonAdmin
---- PASS: TestUserHandler_ListUsers_NonAdmin (0.00s)
-=== RUN TestUserHandler_ListUsers_Admin
---- PASS: TestUserHandler_ListUsers_Admin (0.00s)
-=== RUN TestUserHandler_CreateUser_NonAdmin
---- PASS: TestUserHandler_CreateUser_NonAdmin (0.00s)
-=== RUN TestUserHandler_CreateUser_Admin
---- PASS: TestUserHandler_CreateUser_Admin (0.07s)
-=== RUN TestUserHandler_CreateUser_InvalidJSON
---- PASS: TestUserHandler_CreateUser_InvalidJSON (0.00s)
-=== RUN TestUserHandler_CreateUser_DuplicateEmail
---- PASS: TestUserHandler_CreateUser_DuplicateEmail (0.00s)
-=== RUN TestUserHandler_CreateUser_WithPermittedHosts
---- PASS: TestUserHandler_CreateUser_WithPermittedHosts (0.06s)
-=== RUN TestUserHandler_GetUser_NonAdmin
---- PASS: TestUserHandler_GetUser_NonAdmin (0.00s)
-=== RUN TestUserHandler_GetUser_InvalidID
---- PASS: TestUserHandler_GetUser_InvalidID (0.00s)
-=== RUN TestUserHandler_GetUser_NotFound
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:540 [35;1mrecord not found
-[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_GetUser_NotFound (0.00s)
-=== RUN TestUserHandler_GetUser_Success
---- PASS: TestUserHandler_GetUser_Success (0.00s)
-=== RUN TestUserHandler_UpdateUser_NonAdmin
---- PASS: TestUserHandler_UpdateUser_NonAdmin (0.00s)
-=== RUN TestUserHandler_UpdateUser_InvalidID
---- PASS: TestUserHandler_UpdateUser_InvalidID (0.00s)
-=== RUN TestUserHandler_UpdateUser_InvalidJSON
---- PASS: TestUserHandler_UpdateUser_InvalidJSON (0.00s)
-=== RUN TestUserHandler_UpdateUser_NotFound
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:592 [35;1mrecord not found
-[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_UpdateUser_NotFound (0.00s)
-=== RUN TestUserHandler_UpdateUser_Success
---- PASS: TestUserHandler_UpdateUser_Success (0.00s)
-=== RUN TestUserHandler_DeleteUser_NonAdmin
---- PASS: TestUserHandler_DeleteUser_NonAdmin (0.00s)
-=== RUN TestUserHandler_DeleteUser_InvalidID
---- PASS: TestUserHandler_DeleteUser_InvalidID (0.00s)
-=== RUN TestUserHandler_DeleteUser_NotFound
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:662 [35;1mrecord not found
-[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_DeleteUser_NotFound (0.00s)
-=== RUN TestUserHandler_DeleteUser_Success
---- PASS: TestUserHandler_DeleteUser_Success (0.00s)
-=== RUN TestUserHandler_DeleteUser_CannotDeleteSelf
---- PASS: TestUserHandler_DeleteUser_CannotDeleteSelf (0.00s)
-=== RUN TestUserHandler_UpdateUserPermissions_NonAdmin
---- PASS: TestUserHandler_UpdateUserPermissions_NonAdmin (0.00s)
-=== RUN TestUserHandler_UpdateUserPermissions_InvalidID
---- PASS: TestUserHandler_UpdateUserPermissions_InvalidID (0.00s)
-=== RUN TestUserHandler_UpdateUserPermissions_InvalidJSON
---- PASS: TestUserHandler_UpdateUserPermissions_InvalidJSON (0.00s)
-=== RUN TestUserHandler_UpdateUserPermissions_NotFound
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:703 [35;1mrecord not found
-[0m[33m[0.025ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE `users`.`id` = 999 ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_UpdateUserPermissions_NotFound (0.00s)
-=== RUN TestUserHandler_UpdateUserPermissions_Success
---- PASS: TestUserHandler_UpdateUserPermissions_Success (0.00s)
-=== RUN TestUserHandler_ValidateInvite_MissingToken
---- PASS: TestUserHandler_ValidateInvite_MissingToken (0.00s)
-=== RUN TestUserHandler_ValidateInvite_InvalidToken
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:752 [35;1mrecord not found
-[0m[33m[0.035ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE invite_token = "invalidtoken" ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_ValidateInvite_InvalidToken (0.00s)
-=== RUN TestUserHandler_ValidateInvite_ExpiredToken
---- PASS: TestUserHandler_ValidateInvite_ExpiredToken (0.00s)
-=== RUN TestUserHandler_ValidateInvite_AlreadyAccepted
---- PASS: TestUserHandler_ValidateInvite_AlreadyAccepted (0.00s)
-=== RUN TestUserHandler_ValidateInvite_Success
---- PASS: TestUserHandler_ValidateInvite_Success (0.00s)
-=== RUN TestUserHandler_AcceptInvite_InvalidJSON
---- PASS: TestUserHandler_AcceptInvite_InvalidJSON (0.00s)
-=== RUN TestUserHandler_AcceptInvite_InvalidToken
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:791 [35;1mrecord not found
-[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE invite_token = "invalidtoken" ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_AcceptInvite_InvalidToken (0.00s)
-=== RUN TestUserHandler_AcceptInvite_Success
---- PASS: TestUserHandler_AcceptInvite_Success (0.06s)
-=== RUN TestGenerateSecureToken
---- PASS: TestGenerateSecureToken (0.00s)
-=== RUN TestUserHandler_InviteUser_NonAdmin
---- PASS: TestUserHandler_InviteUser_NonAdmin (0.00s)
-=== RUN TestUserHandler_InviteUser_InvalidJSON
---- PASS: TestUserHandler_InviteUser_InvalidJSON (0.00s)
-=== RUN TestUserHandler_InviteUser_DuplicateEmail
---- PASS: TestUserHandler_InviteUser_DuplicateEmail (0.00s)
-=== RUN TestUserHandler_InviteUser_Success
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:420 [35;1mrecord not found
-[0m[33m[0.041ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE email = "newinvite@example.com" ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_InviteUser_Success (0.00s)
-=== RUN TestUserHandler_InviteUser_WithPermittedHosts
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:420 [35;1mrecord not found
-[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `users` WHERE email = "invitee-perms@example.com" ORDER BY `users`.`id` LIMIT 1
---- PASS: TestUserHandler_InviteUser_WithPermittedHosts (0.00s)
-=== RUN TestGetBaseURL
---- PASS: TestGetBaseURL (0.00s)
-=== RUN TestGetAppName
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/user_handler.go:518 [35;1mrecord not found
-[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "app_name" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestGetAppName (0.00s)
-=== RUN TestUserHandler_AcceptInvite_ExpiredToken
---- PASS: TestUserHandler_AcceptInvite_ExpiredToken (0.00s)
-=== RUN TestUserHandler_AcceptInvite_AlreadyAccepted
---- PASS: TestUserHandler_AcceptInvite_AlreadyAccepted (0.00s)
-=== RUN TestUserLoginAfterEmailChange
---- PASS: TestUserLoginAfterEmailChange (0.30s)
-=== RUN TestRemoteServerHandler_List
---- PASS: TestRemoteServerHandler_List (0.00s)
-=== RUN TestRemoteServerHandler_Create
---- PASS: TestRemoteServerHandler_Create (0.00s)
-=== RUN TestRemoteServerHandler_TestConnection
---- PASS: TestRemoteServerHandler_TestConnection (0.00s)
-=== RUN TestRemoteServerHandler_Get
---- PASS: TestRemoteServerHandler_Get (0.00s)
-=== RUN TestRemoteServerHandler_Update
---- PASS: TestRemoteServerHandler_Update (0.00s)
-=== RUN TestRemoteServerHandler_Delete
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "21ab604b-2f0a-4078-8012-f3165c662e99" ORDER BY `remote_servers`.`id` LIMIT 1
---- PASS: TestRemoteServerHandler_Delete (0.00s)
-=== RUN TestProxyHostHandler_List
---- PASS: TestProxyHostHandler_List (0.00s)
-=== RUN TestProxyHostHandler_Create
---- PASS: TestProxyHostHandler_Create (0.00s)
-=== RUN TestProxyHostHandler_PartialUpdate_DoesNotWipeFields
---- PASS: TestProxyHostHandler_PartialUpdate_DoesNotWipeFields (0.00s)
-=== RUN TestHealthHandler
---- PASS: TestHealthHandler (0.00s)
-=== RUN TestRemoteServerHandler_Errors
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent" ORDER BY `remote_servers`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent" ORDER BY `remote_servers`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.014ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent" ORDER BY `remote_servers`.`id` LIMIT 1
---- PASS: TestRemoteServerHandler_Errors (0.00s)
-=== RUN TestImportHandler_GetStatus
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:60 [35;1mrecord not found
-[0m[33m[0.093ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:60 [35;1mrecord not found
-[0m[33m[0.051ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:70 [35;1mrecord not found
-[0m[33m[0.026ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE source_file = "/tmp/TestImportHandler_GetStatus3246735047/001/mounted.caddyfile" AND status = "committed" ORDER BY committed_at DESC,`import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_GetStatus (0.00s)
-=== RUN TestImportHandler_GetPreview
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:122 [35;1mrecord not found
-[0m[33m[0.102ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_GetPreview (0.00s)
-=== RUN TestImportHandler_Cancel
---- PASS: TestImportHandler_Cancel (0.00s)
-=== RUN TestImportHandler_Commit
---- PASS: TestImportHandler_Commit (0.00s)
-=== RUN TestImportHandler_Upload
---- PASS: TestImportHandler_Upload (0.00s)
-=== RUN TestImportHandler_GetPreview_WithContent
---- PASS: TestImportHandler_GetPreview_WithContent (0.00s)
-=== RUN TestImportHandler_Commit_Errors
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
-[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "non-existent" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_Commit_Errors (0.00s)
-=== RUN TestImportHandler_Cancel_Errors
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:734 [35;1mrecord not found
-[0m[33m[0.033ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "non-existent" ORDER BY `import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_Cancel_Errors (0.00s)
-=== RUN TestCheckMountedImport
---- PASS: TestCheckMountedImport (0.00s)
-=== RUN TestImportHandler_Upload_Failure
---- PASS: TestImportHandler_Upload_Failure (0.00s)
-=== RUN TestImportHandler_Upload_Conflict
---- PASS: TestImportHandler_Upload_Conflict (0.01s)
-=== RUN TestImportHandler_GetPreview_BackupContent
---- PASS: TestImportHandler_GetPreview_BackupContent (0.00s)
-=== RUN TestImportHandler_RegisterRoutes
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:60 [35;1mrecord not found
-[0m[33m[0.092ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_RegisterRoutes (0.00s)
-=== RUN TestImportHandler_GetPreview_TransientMount
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:122 [35;1mrecord not found
-[0m[33m[0.148ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE status IN ("pending","reviewing") ORDER BY created_at DESC,`import_sessions`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:167 [35;1mrecord not found
-[0m[33m[0.042ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE source_file = "/tmp/TestImportHandler_GetPreview_TransientMount3464543619/001/mounted.caddyfile" AND status = "committed" ORDER BY committed_at DESC,`import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_GetPreview_TransientMount (0.00s)
-=== RUN TestImportHandler_Commit_TransientUpload
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
-[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "06368b2d-5607-4012-9972-7646e877fc61" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_Commit_TransientUpload (0.01s)
-=== RUN TestImportHandler_Commit_TransientMount
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
-[0m[33m[0.045ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "00e915f7-0eb9-4b38-9d1a-8bd2d7f138d6" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_Commit_TransientMount (0.01s)
-=== RUN TestImportHandler_Cancel_TransientUpload
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:734 [35;1mrecord not found
-[0m[33m[0.071ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "7c49c0f2-9908-4546-8a9c-d3c47c4c9860" ORDER BY `import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_Cancel_TransientUpload (0.01s)
-=== RUN TestImportHandler_Errors
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:583 [35;1mrecord not found
-[0m[33m[0.036ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "non-existent" AND status = "reviewing" ORDER BY `import_sessions`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/import_handler.go:734 [35;1mrecord not found
-[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `import_sessions` WHERE uuid = "non-existent" ORDER BY `import_sessions`.`id` LIMIT 1
---- PASS: TestImportHandler_Errors (0.00s)
-=== RUN TestImportHandler_DetectImports
-=== RUN TestImportHandler_DetectImports/no_imports
-=== RUN TestImportHandler_DetectImports/single_import
-=== RUN TestImportHandler_DetectImports/multiple_imports
-=== RUN TestImportHandler_DetectImports/import_with_comment
---- PASS: TestImportHandler_DetectImports (0.00s)
- --- PASS: TestImportHandler_DetectImports/no_imports (0.00s)
- --- PASS: TestImportHandler_DetectImports/single_import (0.00s)
- --- PASS: TestImportHandler_DetectImports/multiple_imports (0.00s)
- --- PASS: TestImportHandler_DetectImports/import_with_comment (0.00s)
-=== RUN TestImportHandler_DetectImports_InvalidJSON
---- PASS: TestImportHandler_DetectImports_InvalidJSON (0.00s)
-=== RUN TestImportHandler_UploadMulti
-=== RUN TestImportHandler_UploadMulti/single_Caddyfile
-=== RUN TestImportHandler_UploadMulti/Caddyfile_with_site_files
-=== RUN TestImportHandler_UploadMulti/missing_Caddyfile
-=== RUN TestImportHandler_UploadMulti/path_traversal_in_filename
-=== RUN TestImportHandler_UploadMulti/empty_file_content
---- PASS: TestImportHandler_UploadMulti (0.01s)
- --- PASS: TestImportHandler_UploadMulti/single_Caddyfile (0.01s)
- --- PASS: TestImportHandler_UploadMulti/Caddyfile_with_site_files (0.00s)
- --- PASS: TestImportHandler_UploadMulti/missing_Caddyfile (0.00s)
- --- PASS: TestImportHandler_UploadMulti/path_traversal_in_filename (0.00s)
- --- PASS: TestImportHandler_UploadMulti/empty_file_content (0.00s)
-=== RUN TestNotificationHandler_List
---- PASS: TestNotificationHandler_List (0.00s)
-=== RUN TestNotificationHandler_MarkAsRead
---- PASS: TestNotificationHandler_MarkAsRead (0.00s)
-=== RUN TestNotificationHandler_MarkAllAsRead
---- PASS: TestNotificationHandler_MarkAllAsRead (0.00s)
-=== RUN TestNotificationHandler_MarkAllAsRead_Error
---- PASS: TestNotificationHandler_MarkAllAsRead_Error (0.00s)
-=== RUN TestNotificationHandler_DBError
---- PASS: TestNotificationHandler_DBError (0.00s)
-=== RUN TestNotificationProviderHandler_CRUD
-[GIN] 2025/12/12 - 19:05:53 | 201 | 71.971µs | | POST "/api/v1/notifications/providers"
-[GIN] 2025/12/12 - 19:05:53 | 200 | 46.98µs | | GET "/api/v1/notifications/providers"
-[GIN] 2025/12/12 - 19:05:53 | 200 | 70.04µs | | PUT "/api/v1/notifications/providers/75de70f2-fff3-42d4-b47a-1fdea69c41aa"
-[GIN] 2025/12/12 - 19:05:53 | 200 | 32.96µs | | DELETE "/api/v1/notifications/providers/75de70f2-fff3-42d4-b47a-1fdea69c41aa"
---- PASS: TestNotificationProviderHandler_CRUD (0.00s)
-=== RUN TestNotificationProviderHandler_Templates
-[GIN] 2025/12/12 - 19:05:53 | 200 | 10.81µs | | GET "/api/v1/notifications/templates"
---- PASS: TestNotificationProviderHandler_Templates (0.00s)
-=== RUN TestNotificationProviderHandler_Test
-[GIN] 2025/12/12 - 19:05:53 | 400 | 80.19µs | | POST "/api/v1/notifications/providers/test"
---- PASS: TestNotificationProviderHandler_Test (0.00s)
-=== RUN TestNotificationProviderHandler_Errors
-[GIN] 2025/12/12 - 19:05:53 | 400 | 5.739µs | | POST "/api/v1/notifications/providers"
-[GIN] 2025/12/12 - 19:05:53 | 400 | 2.42µs | | PUT "/api/v1/notifications/providers/123"
-[GIN] 2025/12/12 - 19:05:53 | 400 | 2.57µs | | POST "/api/v1/notifications/providers/test"
---- PASS: TestNotificationProviderHandler_Errors (0.00s)
-=== RUN TestNotificationProviderHandler_InvalidCustomTemplate_Rejects
-[GIN] 2025/12/12 - 19:05:53 | 400 | 35.72µs | | POST "/api/v1/notifications/providers"
-[GIN] 2025/12/12 - 19:05:53 | 201 | 66.25µs | | POST "/api/v1/notifications/providers"
-[GIN] 2025/12/12 - 19:05:53 | 400 | 16.03µs | | PUT "/api/v1/notifications/providers/a0f9d3bf-98ac-497f-a92f-b6e4ff002230"
---- PASS: TestNotificationProviderHandler_InvalidCustomTemplate_Rejects (0.00s)
-=== RUN TestNotificationProviderHandler_Preview
-[GIN] 2025/12/12 - 19:05:53 | 200 | 61.36µs | | POST "/api/v1/notifications/providers/preview"
-[GIN] 2025/12/12 - 19:05:53 | 400 | 28.06µs | | POST "/api/v1/notifications/providers/preview"
---- PASS: TestNotificationProviderHandler_Preview (0.00s)
-=== RUN TestRemoteServerHandler_TestConnectionCustom
-[GIN] 2025/12/12 - 19:05:53 | 200 | 229.651µs | | POST "/api/v1/remote-servers/test"
---- PASS: TestRemoteServerHandler_TestConnectionCustom (0.00s)
-=== RUN TestRemoteServerHandler_FullCRUD
-[GIN] 2025/12/12 - 19:05:53 | 201 | 368.301µs | | POST "/api/v1/remote-servers"
-[GIN] 2025/12/12 - 19:05:53 | 200 | 64.74µs | | GET "/api/v1/remote-servers"
-[GIN] 2025/12/12 - 19:05:53 | 200 | 56.361µs | | GET "/api/v1/remote-servers/fc00458b-7fd6-4d4e-b956-5d9c9485d12a"
-[GIN] 2025/12/12 - 19:05:53 | 200 | 296.59µs | | PUT "/api/v1/remote-servers/fc00458b-7fd6-4d4e-b956-5d9c9485d12a"
-[GIN] 2025/12/12 - 19:05:53 | 204 | 144.94µs | | DELETE "/api/v1/remote-servers/fc00458b-7fd6-4d4e-b956-5d9c9485d12a"
-[GIN] 2025/12/12 - 19:05:53 | 400 | 5.6µs | | POST "/api/v1/remote-servers"
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.037ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent-uuid" ORDER BY `remote_servers`.`id` LIMIT 1
-[GIN] 2025/12/12 - 19:05:53 | 404 | 88.54µs | | PUT "/api/v1/remote-servers/non-existent-uuid"
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/remoteserver_service.go:77 [35;1mrecord not found
-[0m[33m[0.029ms] [34;1m[rows:0][0m SELECT * FROM `remote_servers` WHERE uuid = "non-existent-uuid" ORDER BY `remote_servers`.`id` LIMIT 1
-[GIN] 2025/12/12 - 19:05:53 | 404 | 51.22µs | | DELETE "/api/v1/remote-servers/non-existent-uuid"
---- PASS: TestRemoteServerHandler_FullCRUD (0.00s)
-=== RUN TestSettingsHandler_GetSettings
---- PASS: TestSettingsHandler_GetSettings (0.00s)
-=== RUN TestSettingsHandler_UpdateSettings
---- PASS: TestSettingsHandler_UpdateSettings (0.00s)
-=== RUN TestSettingsHandler_Errors
---- PASS: TestSettingsHandler_Errors (0.00s)
-=== RUN TestSettingsHandler_GetSMTPConfig
---- PASS: TestSettingsHandler_GetSMTPConfig (0.00s)
-=== RUN TestSettingsHandler_GetSMTPConfig_Empty
---- PASS: TestSettingsHandler_GetSMTPConfig_Empty (0.00s)
-=== RUN TestSettingsHandler_GetSMTPConfig_DatabaseError
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:46 [35;1msql: database is closed
-[0m[33m[0.007ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE category = "smtp"
---- PASS: TestSettingsHandler_GetSMTPConfig_DatabaseError (0.00s)
-=== RUN TestSettingsHandler_UpdateSMTPConfig_NonAdmin
---- PASS: TestSettingsHandler_UpdateSMTPConfig_NonAdmin (0.00s)
-=== RUN TestSettingsHandler_UpdateSMTPConfig_InvalidJSON
---- PASS: TestSettingsHandler_UpdateSMTPConfig_InvalidJSON (0.00s)
-=== RUN TestSettingsHandler_UpdateSMTPConfig_Success
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
-[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_host" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
-[0m[33m[0.028ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_port" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
-[0m[33m[0.024ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_username" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_password" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
-[0m[33m[0.019ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_from_address" ORDER BY `settings`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
-[0m[33m[0.016ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_encryption" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestSettingsHandler_UpdateSMTPConfig_Success (0.00s)
-=== RUN TestSettingsHandler_UpdateSMTPConfig_KeepExistingPassword
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/mail_service.go:97 [35;1mrecord not found
-[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `settings` WHERE key = "smtp_username" ORDER BY `settings`.`id` LIMIT 1
---- PASS: TestSettingsHandler_UpdateSMTPConfig_KeepExistingPassword (0.00s)
-=== RUN TestSettingsHandler_TestSMTPConfig_NonAdmin
---- PASS: TestSettingsHandler_TestSMTPConfig_NonAdmin (0.00s)
-=== RUN TestSettingsHandler_TestSMTPConfig_NotConfigured
---- PASS: TestSettingsHandler_TestSMTPConfig_NotConfigured (0.00s)
-=== RUN TestSettingsHandler_SendTestEmail_NonAdmin
---- PASS: TestSettingsHandler_SendTestEmail_NonAdmin (0.00s)
-=== RUN TestSettingsHandler_SendTestEmail_InvalidJSON
---- PASS: TestSettingsHandler_SendTestEmail_InvalidJSON (0.00s)
-=== RUN TestSettingsHandler_SendTestEmail_NotConfigured
---- PASS: TestSettingsHandler_SendTestEmail_NotConfigured (0.00s)
-=== RUN TestMaskPassword
---- PASS: TestMaskPassword (0.00s)
-=== RUN TestUptimeHandler_List
-[GIN] 2025/12/12 - 19:05:53 | 200 | 141.91µs | | GET "/api/v1/uptime"
---- PASS: TestUptimeHandler_List (0.00s)
-=== RUN TestUptimeHandler_GetHistory
-[GIN] 2025/12/12 - 19:05:53 | 200 | 85.09µs | | GET "/api/v1/uptime/monitor-1/history"
---- PASS: TestUptimeHandler_GetHistory (0.00s)
-=== RUN TestUptimeHandler_CheckMonitor
-[GIN] 2025/12/12 - 19:05:53 | 200 | 54.289µs | | POST "/api/v1/uptime/check-mon-1/check"
---- PASS: TestUptimeHandler_CheckMonitor (0.00s)
-=== RUN TestUptimeHandler_CheckMonitor_NotFound
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:869 [35;1mrecord not found
-[0m[33m[0.039ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "nonexistent" ORDER BY `uptime_monitors`.`id` LIMIT 1
-[GIN] 2025/12/12 - 19:05:53 | 404 | 79.99µs | | POST "/api/v1/uptime/nonexistent/check"
---- PASS: TestUptimeHandler_CheckMonitor_NotFound (0.00s)
-=== RUN TestUptimeHandler_Update
-=== RUN TestUptimeHandler_Update/success
-[GIN] 2025/12/12 - 19:05:53 | 200 | 297.212µs | | PUT "/api/v1/uptime/monitor-update"
-=== RUN TestUptimeHandler_Update/invalid_json
-[GIN] 2025/12/12 - 19:05:53 | 400 | 6.02µs | | PUT "/api/v1/uptime/monitor-1"
-=== RUN TestUptimeHandler_Update/not_found
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:883 [35;1mrecord not found
-[0m[33m[0.027ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "nonexistent" ORDER BY `uptime_monitors`.`id` LIMIT 1
-[GIN] 2025/12/12 - 19:05:53 | 500 | 71.829µs | | PUT "/api/v1/uptime/nonexistent"
---- PASS: TestUptimeHandler_Update (0.01s)
- --- PASS: TestUptimeHandler_Update/success (0.00s)
- --- PASS: TestUptimeHandler_Update/invalid_json (0.00s)
- --- PASS: TestUptimeHandler_Update/not_found (0.00s)
-=== RUN TestUptimeHandler_DeleteAndSync
-=== RUN TestUptimeHandler_DeleteAndSync/delete_monitor
-[GIN] 2025/12/12 - 19:05:53 | 200 | 131.741µs | | DELETE "/api/v1/uptime/mon-delete"
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/api/handlers/uptime_handler_test.go:202 [35;1mrecord not found
-[0m[33m[0.042ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "mon-delete" ORDER BY `uptime_monitors`.`id` LIMIT 1
-=== RUN TestUptimeHandler_DeleteAndSync/sync_creates_monitor_for_proxy_host
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:111 [35;1mrecord not found
-[0m[33m[0.063ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE proxy_host_id = 1 ORDER BY `uptime_monitors`.`id` LIMIT 1
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:285 [35;1mrecord not found
-[0m[33m[0.031ms] [34;1m[rows:0][0m SELECT * FROM `uptime_hosts` WHERE host = "127.0.0.1" ORDER BY `uptime_hosts`.`id` LIMIT 1
-[GIN] 2025/12/12 - 19:05:53 | 200 | 405.001µs | | POST "/api/v1/uptime/sync"
-=== RUN TestUptimeHandler_DeleteAndSync/update_enabled_via_PUT
-[GIN] 2025/12/12 - 19:05:53 | 200 | 121.051µs | | PUT "/api/v1/uptime/mon-enable"
---- PASS: TestUptimeHandler_DeleteAndSync (0.01s)
- --- PASS: TestUptimeHandler_DeleteAndSync/delete_monitor (0.00s)
- --- PASS: TestUptimeHandler_DeleteAndSync/sync_creates_monitor_for_proxy_host (0.00s)
- --- PASS: TestUptimeHandler_DeleteAndSync/update_enabled_via_PUT (0.00s)
-=== RUN TestUptimeHandler_Sync_Success
-[GIN] 2025/12/12 - 19:05:53 | 200 | 63.5µs | | POST "/api/v1/uptime/sync"
---- PASS: TestUptimeHandler_Sync_Success (0.00s)
-=== RUN TestUptimeHandler_Delete_Error
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:911 [35;1mno such table: uptime_monitors
-[0m[33m[0.017ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` WHERE id = "nonexistent" ORDER BY `uptime_monitors`.`id` LIMIT 1
-[GIN] 2025/12/12 - 19:05:53 | 500 | 53.249µs | | DELETE "/api/v1/uptime/nonexistent"
---- PASS: TestUptimeHandler_Delete_Error (0.00s)
-=== RUN TestUptimeHandler_List_Error
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:863 [35;1mno such table: uptime_monitors
-[0m[33m[0.015ms] [34;1m[rows:0][0m SELECT * FROM `uptime_monitors` ORDER BY name ASC
-[GIN] 2025/12/12 - 19:05:53 | 500 | 50.51µs | | GET "/api/v1/uptime"
---- PASS: TestUptimeHandler_List_Error (0.00s)
-=== RUN TestUptimeHandler_GetHistory_Error
-
-2025/12/12 19:05:53 [31;1m/projects/Charon/backend/internal/services/uptime_service.go:877 [35;1mno such table: uptime_heartbeats
-[0m[33m[0.020ms] [34;1m[rows:0][0m SELECT * FROM `uptime_heartbeats` WHERE monitor_id = "monitor-1" ORDER BY created_at desc LIMIT 50
-[GIN] 2025/12/12 - 19:05:53 | 500 | 65.371µs | | GET "/api/v1/uptime/monitor-1/history"
---- PASS: TestUptimeHandler_GetHistory_Error (0.00s)
-FAIL
-FAIL github.com/Wikid82/charon/backend/internal/api/handlers 20.305s
-=== RUN TestAuthMiddleware_MissingHeader
---- PASS: TestAuthMiddleware_MissingHeader (0.00s)
-=== RUN TestRequireRole_Success
---- PASS: TestRequireRole_Success (0.00s)
-=== RUN TestRequireRole_Forbidden
---- PASS: TestRequireRole_Forbidden (0.00s)
-=== RUN TestAuthMiddleware_Cookie
---- PASS: TestAuthMiddleware_Cookie (0.07s)
-=== RUN TestAuthMiddleware_ValidToken
---- PASS: TestAuthMiddleware_ValidToken (0.06s)
-=== RUN TestAuthMiddleware_PrefersAuthorizationHeader
---- PASS: TestAuthMiddleware_PrefersAuthorizationHeader (0.06s)
-=== RUN TestAuthMiddleware_InvalidToken
---- PASS: TestAuthMiddleware_InvalidToken (0.00s)
-=== RUN TestRequireRole_MissingRoleInContext
---- PASS: TestRequireRole_MissingRoleInContext (0.00s)
-=== RUN TestRecoveryLogsStacktraceVerbose
---- PASS: TestRecoveryLogsStacktraceVerbose (0.00s)
-=== RUN TestRecoveryLogsBriefWhenNotVerbose
---- PASS: TestRecoveryLogsBriefWhenNotVerbose (0.00s)
-=== RUN TestRecoverySanitizesHeadersAndPath
---- PASS: TestRecoverySanitizesHeadersAndPath (0.00s)
-=== RUN TestRequestIDAddsHeaderAndLogger
---- PASS: TestRequestIDAddsHeaderAndLogger (0.00s)
-=== RUN TestRequestLoggerSanitizesPath
---- PASS: TestRequestLoggerSanitizesPath (0.00s)
-=== RUN TestRequestLoggerIncludesRequestID
---- PASS: TestRequestLoggerIncludesRequestID (0.00s)
-=== RUN TestSanitizeHeaders
-=== RUN TestSanitizeHeaders/nil_headers
-=== RUN TestSanitizeHeaders/redacts_sensitive_headers
-=== RUN TestSanitizeHeaders/sanitizes_and_truncates_values
---- PASS: TestSanitizeHeaders (0.00s)
- --- PASS: TestSanitizeHeaders/nil_headers (0.00s)
- --- PASS: TestSanitizeHeaders/redacts_sensitive_headers (0.00s)
- --- PASS: TestSanitizeHeaders/sanitizes_and_truncates_values (0.00s)
-=== RUN TestSanitizePath
---- PASS: TestSanitizePath (0.00s)
-=== RUN TestSecurityHeaders
-=== RUN TestSecurityHeaders/production_mode_sets_HSTS
-=== RUN TestSecurityHeaders/development_mode_skips_HSTS
-=== RUN TestSecurityHeaders/sets_X-Frame-Options
-=== RUN TestSecurityHeaders/sets_X-Content-Type-Options
-=== RUN TestSecurityHeaders/sets_X-XSS-Protection
-=== RUN TestSecurityHeaders/sets_Referrer-Policy
-=== RUN TestSecurityHeaders/sets_Content-Security-Policy
-=== RUN TestSecurityHeaders/development_mode_CSP_allows_unsafe-eval
-=== RUN TestSecurityHeaders/sets_Permissions-Policy
-=== RUN TestSecurityHeaders/sets_Cross-Origin-Opener-Policy
-=== RUN TestSecurityHeaders/sets_Cross-Origin-Resource-Policy
---- PASS: TestSecurityHeaders (0.00s)
- --- PASS: TestSecurityHeaders/production_mode_sets_HSTS (0.00s)
- --- PASS: TestSecurityHeaders/development_mode_skips_HSTS (0.00s)
- --- PASS: TestSecurityHeaders/sets_X-Frame-Options (0.00s)
- --- PASS: TestSecurityHeaders/sets_X-Content-Type-Options (0.00s)
- --- PASS: TestSecurityHeaders/sets_X-XSS-Protection (0.00s)
- --- PASS: TestSecurityHeaders/sets_Referrer-Policy (0.00s)
- --- PASS: TestSecurityHeaders/sets_Content-Security-Policy (0.00s)
- --- PASS: TestSecurityHeaders/development_mode_CSP_allows_unsafe-eval (0.00s)
- --- PASS: TestSecurityHeaders/sets_Permissions-Policy (0.00s)
- --- PASS: TestSecurityHeaders/sets_Cross-Origin-Opener-Policy (0.00s)
- --- PASS: TestSecurityHeaders/sets_Cross-Origin-Resource-Policy (0.00s)
-=== RUN TestSecurityHeadersCustomCSP
---- PASS: TestSecurityHeadersCustomCSP (0.00s)
-=== RUN TestDefaultSecurityHeadersConfig
---- PASS: TestDefaultSecurityHeadersConfig (0.00s)
-=== RUN TestBuildCSP
-=== RUN TestBuildCSP/production_CSP
-=== RUN TestBuildCSP/development_CSP
---- PASS: TestBuildCSP (0.00s)
- --- PASS: TestBuildCSP/production_CSP (0.00s)
- --- PASS: TestBuildCSP/development_CSP (0.00s)
-=== RUN TestBuildPermissionsPolicy
---- PASS: TestBuildPermissionsPolicy (0.00s)
-PASS
-ok github.com/Wikid82/charon/backend/internal/api/middleware (cached)
-=== RUN TestRegister
-time="2025-12-12T19:01:39Z" level=info msg="Cleaning up invalid Let's Encrypt certificate associations..."
-time="2025-12-12T19:01:39Z" level=info msg="GeoIP database not found - geo-blocking features will be unavailable" path=/app/data/geoip/GeoLite2-Country.mmdb
-time="2025-12-12T19:01:39Z" level=info msg="Using Caddy data directory for certificates scan" caddy_data_dir=/data
---- PASS: TestRegister (0.01s)
-=== RUN TestRegisterImportHandler
---- PASS: TestRegisterImportHandler (0.00s)
-PASS
-ok github.com/Wikid82/charon/backend/internal/api/routes (cached)
-=== RUN TestIntegration_WAF_BlockAndMonitor
-time="2025-12-12T19:01:39Z" level=info msg="Cleaning up invalid Let's Encrypt certificate associations..."
-time="2025-12-12T19:01:39Z" level=info msg="GeoIP database not found - geo-blocking features will be unavailable" path=/app/data/geoip/GeoLite2-Country.mmdb
-time="2025-12-12T19:01:39Z" level=info msg="Using Caddy data directory for certificates scan" caddy_data_dir=data/caddy/data
-time="2025-12-12T19:01:39Z" level=info msg="CertificateService: scanning cert directory" certRoot=data/caddy/data/certificates
-time="2025-12-12T19:01:39Z" level=info msg="CertificateService: cert directory does not exist" certRoot=data/caddy/data/certificates
-time="2025-12-12T19:01:39Z" level=info msg="CertificateService: disk sync complete" count=0
-time="2025-12-12T19:01:39Z" level=info msg="Cleaning up invalid Let's Encrypt certificate associations..."
-time="2025-12-12T19:01:39Z" level=info msg="GeoIP database not found - geo-blocking features will be unavailable" path=/app/data/geoip/GeoLite2-Country.mmdb
-time="2025-12-12T19:01:39Z" level=info msg="Using Caddy data directory for certificates scan" caddy_data_dir=data/caddy/data
-time="2025-12-12T19:01:39Z" level=info msg="CertificateService: scanning cert directory" certRoot=data/caddy/data/certificates
-time="2025-12-12T19:01:39Z" level=info msg="CertificateService: cert directory does not exist" certRoot=data/caddy/data/certificates
-time="2025-12-12T19:01:39Z" level=info msg="CertificateService: disk sync complete" count=0
---- PASS: TestIntegration_WAF_BlockAndMonitor (0.03s)
-=== RUN TestInviteToken_MustBeUnguessable
---- PASS: TestInviteToken_MustBeUnguessable (0.07s)
-=== RUN TestInviteToken_ExpiredCannotBeUsed
---- PASS: TestInviteToken_ExpiredCannotBeUsed (0.06s)
-=== RUN TestInviteToken_CannotBeReused
---- PASS: TestInviteToken_CannotBeReused (0.14s)
-=== RUN TestInviteUser_EmailValidation
-=== RUN TestInviteUser_EmailValidation/empty_email
-=== RUN TestInviteUser_EmailValidation/invalid_email_no_@
-=== RUN TestInviteUser_EmailValidation/invalid_email_no_domain
-=== RUN TestInviteUser_EmailValidation/sql_injection_attempt
-=== RUN TestInviteUser_EmailValidation/script_injection
-=== RUN TestInviteUser_EmailValidation/valid_email
---- PASS: TestInviteUser_EmailValidation (0.13s)
- --- PASS: TestInviteUser_EmailValidation/empty_email (0.00s)
- --- PASS: TestInviteUser_EmailValidation/invalid_email_no_@ (0.00s)
- --- PASS: TestInviteUser_EmailValidation/invalid_email_no_domain (0.00s)
- --- PASS: TestInviteUser_EmailValidation/sql_injection_attempt (0.00s)
- --- PASS: TestInviteUser_EmailValidation/script_injection (0.00s)
- --- PASS: TestInviteUser_EmailValidation/valid_email (0.00s)
-=== RUN TestAcceptInvite_PasswordValidation
-=== RUN TestAcceptInvite_PasswordValidation/empty_password
-=== RUN TestAcceptInvite_PasswordValidation/too_short
-=== RUN TestAcceptInvite_PasswordValidation/7_chars
-=== RUN TestAcceptInvite_PasswordValidation/8_chars_valid
---- PASS: TestAcceptInvite_PasswordValidation (0.19s)
- --- PASS: TestAcceptInvite_PasswordValidation/empty_password (0.00s)
- --- PASS: TestAcceptInvite_PasswordValidation/too_short (0.00s)
- --- PASS: TestAcceptInvite_PasswordValidation/7_chars (0.00s)
- --- PASS: TestAcceptInvite_PasswordValidation/8_chars_valid (0.06s)
-=== RUN TestUserEndpoints_RequireAdmin
-=== RUN TestUserEndpoints_RequireAdmin/GET_/api/users
-=== RUN TestUserEndpoints_RequireAdmin/POST_/api/users
-=== RUN TestUserEndpoints_RequireAdmin/POST_/api/users/invite
-=== RUN TestUserEndpoints_RequireAdmin/GET_/api/users/1
-=== RUN TestUserEndpoints_RequireAdmin/PUT_/api/users/1
-=== RUN TestUserEndpoints_RequireAdmin/DELETE_/api/users/1
-=== RUN TestUserEndpoints_RequireAdmin/PUT_/api/users/1/permissions
---- PASS: TestUserEndpoints_RequireAdmin (0.07s)
- --- PASS: TestUserEndpoints_RequireAdmin/GET_/api/users (0.00s)
- --- PASS: TestUserEndpoints_RequireAdmin/POST_/api/users (0.00s)
- --- PASS: TestUserEndpoints_RequireAdmin/POST_/api/users/invite (0.00s)
- --- PASS: TestUserEndpoints_RequireAdmin/GET_/api/users/1 (0.00s)
- --- PASS: TestUserEndpoints_RequireAdmin/PUT_/api/users/1 (0.00s)
- --- PASS: TestUserEndpoints_RequireAdmin/DELETE_/api/users/1 (0.00s)
- --- PASS: TestUserEndpoints_RequireAdmin/PUT_/api/users/1/permissions (0.00s)
-=== RUN TestSMTPEndpoints_RequireAdmin
-=== RUN TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp
-=== RUN TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp/test
-=== RUN TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp/test-email
---- PASS: TestSMTPEndpoints_RequireAdmin (0.06s)
- --- PASS: TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp (0.00s)
- --- PASS: TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp/test (0.00s)
- --- PASS: TestSMTPEndpoints_RequireAdmin/POST_/api/settings/smtp/test-email (0.00s)
-=== RUN TestSMTPConfig_PasswordMasked
---- PASS: TestSMTPConfig_PasswordMasked (0.07s)
-=== RUN TestSMTPConfig_PortValidation
-=== RUN TestSMTPConfig_PortValidation/port_0_invalid
-=== RUN TestSMTPConfig_PortValidation/port_-1_invalid
-=== RUN TestSMTPConfig_PortValidation/port_65536_invalid
-=== RUN TestSMTPConfig_PortValidation/port_587_valid
-=== RUN TestSMTPConfig_PortValidation/port_465_valid
-=== RUN TestSMTPConfig_PortValidation/port_25_valid
---- PASS: TestSMTPConfig_PortValidation (0.07s)
- --- PASS: TestSMTPConfig_PortValidation/port_0_invalid (0.00s)
- --- PASS: TestSMTPConfig_PortValidation/port_-1_invalid (0.00s)
- --- PASS: TestSMTPConfig_PortValidation/port_65536_invalid (0.00s)
- --- PASS: TestSMTPConfig_PortValidation/port_587_valid (0.00s)
- --- PASS: TestSMTPConfig_PortValidation/port_465_valid (0.00s)
- --- PASS: TestSMTPConfig_PortValidation/port_25_valid (0.00s)
-=== RUN TestSMTPConfig_EncryptionValidation
-=== RUN TestSMTPConfig_EncryptionValidation/empty_encryption_invalid
-=== RUN TestSMTPConfig_EncryptionValidation/invalid_encryption
-=== RUN TestSMTPConfig_EncryptionValidation/tls_lowercase_valid
-=== RUN TestSMTPConfig_EncryptionValidation/starttls_valid
-=== RUN TestSMTPConfig_EncryptionValidation/none_valid
---- PASS: TestSMTPConfig_EncryptionValidation (0.07s)
- --- PASS: TestSMTPConfig_EncryptionValidation/empty_encryption_invalid (0.00s)
- --- PASS: TestSMTPConfig_EncryptionValidation/invalid_encryption (0.00s)
- --- PASS: TestSMTPConfig_EncryptionValidation/tls_lowercase_valid (0.00s)
- --- PASS: TestSMTPConfig_EncryptionValidation/starttls_valid (0.00s)
- --- PASS: TestSMTPConfig_EncryptionValidation/none_valid (0.00s)
-=== RUN TestInviteUser_DuplicateEmailBlocked
---- PASS: TestInviteUser_DuplicateEmailBlocked (0.07s)
-=== RUN TestInviteUser_EmailCaseInsensitive
---- PASS: TestInviteUser_EmailCaseInsensitive (0.12s)
-=== RUN TestDeleteUser_CannotDeleteSelf
---- PASS: TestDeleteUser_CannotDeleteSelf (0.06s)
-=== RUN TestUpdatePermissions_ValidModes
-=== RUN TestUpdatePermissions_ValidModes/allow_all_valid
-=== RUN TestUpdatePermissions_ValidModes/deny_all_valid
-=== RUN TestUpdatePermissions_ValidModes/invalid_mode
-=== RUN TestUpdatePermissions_ValidModes/empty_mode
---- PASS: TestUpdatePermissions_ValidModes (0.07s)
- --- PASS: TestUpdatePermissions_ValidModes/allow_all_valid (0.00s)
- --- PASS: TestUpdatePermissions_ValidModes/deny_all_valid (0.00s)
- --- PASS: TestUpdatePermissions_ValidModes/invalid_mode (0.00s)
- --- PASS: TestUpdatePermissions_ValidModes/empty_mode (0.00s)
-=== RUN TestPublicEndpoints_NoAuthRequired
---- PASS: TestPublicEndpoints_NoAuthRequired (0.06s)
-PASS
-ok github.com/Wikid82/charon/backend/internal/api/tests (cached)
-=== RUN TestClient_Load_Success
---- PASS: TestClient_Load_Success (0.00s)
-=== RUN TestClient_Load_Failure
---- PASS: TestClient_Load_Failure (0.00s)
-=== RUN TestClient_GetConfig_Success
---- PASS: TestClient_GetConfig_Success (0.00s)
-=== RUN TestClient_Ping_Success
---- PASS: TestClient_Ping_Success (0.00s)
-=== RUN TestClient_Ping_Unreachable
---- PASS: TestClient_Ping_Unreachable (0.00s)
-=== RUN TestClient_Load_CreateRequestFailure
---- PASS: TestClient_Load_CreateRequestFailure (0.00s)
-=== RUN TestClient_Ping_CreateRequestFailure
---- PASS: TestClient_Ping_CreateRequestFailure (0.00s)
-=== RUN TestClient_GetConfig_Failure
---- PASS: TestClient_GetConfig_Failure (0.00s)
-=== RUN TestClient_GetConfig_InvalidJSON
---- PASS: TestClient_GetConfig_InvalidJSON (0.00s)
-=== RUN TestClient_Ping_Failure
---- PASS: TestClient_Ping_Failure (0.00s)
-=== RUN TestClient_RequestCreationErrors
---- PASS: TestClient_RequestCreationErrors (0.00s)
-=== RUN TestClient_NetworkErrors
---- PASS: TestClient_NetworkErrors (0.00s)
-=== RUN TestClient_Load_MarshalFailure
---- PASS: TestClient_Load_MarshalFailure (0.00s)
-=== RUN TestClient_Ping_TransportError
---- PASS: TestClient_Ping_TransportError (0.00s)
-=== RUN TestBuildACLHandler_GeoBlacklist
---- PASS: TestBuildACLHandler_GeoBlacklist (0.00s)
-=== RUN TestBuildACLHandler_UnknownTypeReturnsNil
---- PASS: TestBuildACLHandler_UnknownTypeReturnsNil (0.00s)
-=== RUN TestBuildACLHandler_GeoWhitelist
---- PASS: TestBuildACLHandler_GeoWhitelist (0.00s)
-=== RUN TestBuildACLHandler_LocalNetwork
---- PASS: TestBuildACLHandler_LocalNetwork (0.00s)
-=== RUN TestBuildACLHandler_IPRules
---- PASS: TestBuildACLHandler_IPRules (0.00s)
-=== RUN TestBuildACLHandler_InvalidIPJSON
---- PASS: TestBuildACLHandler_InvalidIPJSON (0.00s)
-=== RUN TestBuildACLHandler_NoIPRulesReturnsNil
---- PASS: TestBuildACLHandler_NoIPRulesReturnsNil (0.00s)
-=== RUN TestBuildACLHandler_Whitelist
---- PASS: TestBuildACLHandler_Whitelist (0.00s)
-=== RUN TestBuildCrowdSecHandler_Disabled
---- PASS: TestBuildCrowdSecHandler_Disabled (0.00s)
-=== RUN TestBuildCrowdSecHandler_EnabledWithoutConfig
---- PASS: TestBuildCrowdSecHandler_EnabledWithoutConfig (0.00s)
-=== RUN TestBuildCrowdSecHandler_EnabledWithEmptyAPIURL
---- PASS: TestBuildCrowdSecHandler_EnabledWithEmptyAPIURL (0.00s)
-=== RUN TestBuildCrowdSecHandler_EnabledWithCustomAPIURL
---- PASS: TestBuildCrowdSecHandler_EnabledWithCustomAPIURL (0.00s)
-=== RUN TestBuildCrowdSecHandler_JSONFormat
---- PASS: TestBuildCrowdSecHandler_JSONFormat (0.00s)
-=== RUN TestBuildCrowdSecHandler_WithHost
---- PASS: TestBuildCrowdSecHandler_WithHost (0.00s)
-=== RUN TestGenerateConfig_WithCrowdSec
---- PASS: TestGenerateConfig_WithCrowdSec (0.00s)
-=== RUN TestGenerateConfig_CrowdSecDisabled
---- PASS: TestGenerateConfig_CrowdSecDisabled (0.00s)
-=== RUN TestGenerateConfig_CatchAllFrontend
---- PASS: TestGenerateConfig_CatchAllFrontend (0.00s)
-=== RUN TestGenerateConfig_AdvancedInvalidJSON
-time="2025-12-12T19:01:40Z" level=warning msg="Failed to parse advanced_config for host" error="invalid character 'i' looking for beginning of object key string" host=adv1
---- PASS: TestGenerateConfig_AdvancedInvalidJSON (0.00s)
-=== RUN TestGenerateConfig_AdvancedArrayHandler
---- PASS: TestGenerateConfig_AdvancedArrayHandler (0.00s)
-=== RUN TestGenerateConfig_LowercaseDomains
---- PASS: TestGenerateConfig_LowercaseDomains (0.00s)
-=== RUN TestGenerateConfig_AdvancedObjectHandler
---- PASS: TestGenerateConfig_AdvancedObjectHandler (0.00s)
-=== RUN TestGenerateConfig_AdvancedHeadersStringToArray
---- PASS: TestGenerateConfig_AdvancedHeadersStringToArray (0.00s)
-=== RUN TestGenerateConfig_ACLWhitelistIncluded
---- PASS: TestGenerateConfig_ACLWhitelistIncluded (0.00s)
-=== RUN TestGenerateConfig_SkipsEmptyDomainEntries
---- PASS: TestGenerateConfig_SkipsEmptyDomainEntries (0.00s)
-=== RUN TestGenerateConfig_AdvancedNoHandlerKey
-time="2025-12-12T19:01:40Z" level=warning msg="advanced_config for host is not a handler object" host=adv3
---- PASS: TestGenerateConfig_AdvancedNoHandlerKey (0.00s)
-=== RUN TestGenerateConfig_AdvancedUnexpectedJSONStructure
-time="2025-12-12T19:01:40Z" level=warning msg="advanced_config for host has unexpected JSON structure" host=adv4
---- PASS: TestGenerateConfig_AdvancedUnexpectedJSONStructure (0.00s)
-=== RUN TestBuildACLHandler_UnknownIPTypeReturnsNil
---- PASS: TestBuildACLHandler_UnknownIPTypeReturnsNil (0.00s)
-=== RUN TestGenerateConfig_SecurityPipeline_Order
---- PASS: TestGenerateConfig_SecurityPipeline_Order (0.00s)
-=== RUN TestGenerateConfig_SecurityPipeline_OmitWhenDisabled
---- PASS: TestGenerateConfig_SecurityPipeline_OmitWhenDisabled (0.00s)
-=== RUN TestGenerateConfig_ZerosslAndBothProviders
---- PASS: TestGenerateConfig_ZerosslAndBothProviders (0.00s)
-=== RUN TestGenerateConfig_SecurityPipeline_Order_Locations
---- PASS: TestGenerateConfig_SecurityPipeline_Order_Locations (0.00s)
-=== RUN TestGenerateConfig_ACLLogWarning
---- PASS: TestGenerateConfig_ACLLogWarning (0.00s)
-=== RUN TestGenerateConfig_ACLHandlerIncluded
---- PASS: TestGenerateConfig_ACLHandlerIncluded (0.00s)
-=== RUN TestGenerateConfig_DecisionsBlockWithAdminExclusion
- config_generate_additional_test.go:147: handles: [
- {
- "handler": "subroute",
- "routes": [
- {
- "handle": [
- {
- "body": "Access denied: Blocked by security decision",
- "handler": "static_response",
- "status_code": 403
- }
- ],
- "match": [
- {
- "remote_ip": {
- "ranges": [
- "1.2.3.4"
- ]
- }
- },
- {
- "not": [
- {
- "remote_ip": {
- "ranges": [
- "10.0.0.1/32"
- ]
- }
- }
- ]
- }
- ],
- "terminal": true
- }
- ]
- },
- {
- "flush_interval": -1,
- "handler": "reverse_proxy",
- "upstreams": [
- {
- "dial": "app:8080"
- }
- ]
- }
- ]
---- PASS: TestGenerateConfig_DecisionsBlockWithAdminExclusion (0.00s)
-=== RUN TestGenerateConfig_WAFModeAndRulesetReference
---- PASS: TestGenerateConfig_WAFModeAndRulesetReference (0.00s)
-=== RUN TestGenerateConfig_WAFModeDisabledSkipsHandler
---- PASS: TestGenerateConfig_WAFModeDisabledSkipsHandler (0.00s)
-=== RUN TestGenerateConfig_WAFSelectedSetsContentAndMode
---- PASS: TestGenerateConfig_WAFSelectedSetsContentAndMode (0.00s)
-=== RUN TestGenerateConfig_DecisionAdminPartsEmpty
---- PASS: TestGenerateConfig_DecisionAdminPartsEmpty (0.00s)
-=== RUN TestNormalizeHeaderOps_PreserveStringArray
---- PASS: TestNormalizeHeaderOps_PreserveStringArray (0.00s)
-=== RUN TestGenerateConfig_WAFUsesRuleSet
---- PASS: TestGenerateConfig_WAFUsesRuleSet (0.00s)
-=== RUN TestGenerateConfig_WAFUsesRuleSetFromAdvancedConfig
---- PASS: TestGenerateConfig_WAFUsesRuleSetFromAdvancedConfig (0.00s)
-=== RUN TestGenerateConfig_WAFUsesRuleSetFromAdvancedConfig_Array
---- PASS: TestGenerateConfig_WAFUsesRuleSetFromAdvancedConfig_Array (0.00s)
-=== RUN TestGenerateConfig_WAFUsesRulesetFromSecCfgFallback
---- PASS: TestGenerateConfig_WAFUsesRulesetFromSecCfgFallback (0.00s)
-=== RUN TestGenerateConfig_RateLimitFromSecCfg
---- PASS: TestGenerateConfig_RateLimitFromSecCfg (0.00s)
-=== RUN TestGenerateConfig_CrowdSecHandlerFromSecCfg
---- PASS: TestGenerateConfig_CrowdSecHandlerFromSecCfg (0.00s)
-=== RUN TestGenerateConfig_EmptyHostsAndNoFrontend
---- PASS: TestGenerateConfig_EmptyHostsAndNoFrontend (0.00s)
-=== RUN TestGenerateConfig_SkipsInvalidCustomCert
---- PASS: TestGenerateConfig_SkipsInvalidCustomCert (0.00s)
-=== RUN TestGenerateConfig_SkipsDuplicateDomains
---- PASS: TestGenerateConfig_SkipsDuplicateDomains (0.00s)
-=== RUN TestGenerateConfig_LoadPEMSetsTLSWhenNoACME
---- PASS: TestGenerateConfig_LoadPEMSetsTLSWhenNoACME (0.00s)
-=== RUN TestGenerateConfig_DefaultAcmeStaging
---- PASS: TestGenerateConfig_DefaultAcmeStaging (0.00s)
-=== RUN TestGenerateConfig_ACLHandlerBuildError
---- PASS: TestGenerateConfig_ACLHandlerBuildError (0.00s)
-=== RUN TestGenerateConfig_SkipHostDomainEmptyAndDisabled
---- PASS: TestGenerateConfig_SkipHostDomainEmptyAndDisabled (0.00s)
-=== RUN TestGenerateConfig_CustomCertsAndTLS
---- PASS: TestGenerateConfig_CustomCertsAndTLS (0.00s)
-=== RUN TestGenerateConfig_Empty
---- PASS: TestGenerateConfig_Empty (0.00s)
-=== RUN TestGenerateConfig_SingleHost
---- PASS: TestGenerateConfig_SingleHost (0.00s)
-=== RUN TestGenerateConfig_MultipleHosts
---- PASS: TestGenerateConfig_MultipleHosts (0.00s)
-=== RUN TestGenerateConfig_WebSocketEnabled
---- PASS: TestGenerateConfig_WebSocketEnabled (0.00s)
-=== RUN TestGenerateConfig_EmptyDomain
---- PASS: TestGenerateConfig_EmptyDomain (0.00s)
-=== RUN TestGenerateConfig_Logging
---- PASS: TestGenerateConfig_Logging (0.00s)
-=== RUN TestGenerateConfig_IPHostsSkipAutoHTTPS
---- PASS: TestGenerateConfig_IPHostsSkipAutoHTTPS (0.00s)
-=== RUN TestGenerateConfig_Advanced
---- PASS: TestGenerateConfig_Advanced (0.00s)
-=== RUN TestGenerateConfig_ACMEStaging
---- PASS: TestGenerateConfig_ACMEStaging (0.00s)
-=== RUN TestBuildACLHandler_WhitelistAndBlacklistAdminMerge
---- PASS: TestBuildACLHandler_WhitelistAndBlacklistAdminMerge (0.00s)
-=== RUN TestBuildACLHandler_GeoAndLocalNetwork
---- PASS: TestBuildACLHandler_GeoAndLocalNetwork (0.00s)
-=== RUN TestBuildACLHandler_AdminWhitelistParsing
---- PASS: TestBuildACLHandler_AdminWhitelistParsing (0.00s)
-=== RUN TestBuildRateLimitHandler_Disabled
---- PASS: TestBuildRateLimitHandler_Disabled (0.00s)
-=== RUN TestBuildRateLimitHandler_InvalidValues
---- PASS: TestBuildRateLimitHandler_InvalidValues (0.00s)
-=== RUN TestBuildRateLimitHandler_ValidConfig
---- PASS: TestBuildRateLimitHandler_ValidConfig (0.00s)
-=== RUN TestBuildRateLimitHandler_JSONFormat
---- PASS: TestBuildRateLimitHandler_JSONFormat (0.00s)
-=== RUN TestGenerateConfig_WithRateLimiting
---- PASS: TestGenerateConfig_WithRateLimiting (0.00s)
-=== RUN TestBuildRateLimitHandler_UsesBurst
---- PASS: TestBuildRateLimitHandler_UsesBurst (0.00s)
-=== RUN TestBuildRateLimitHandler_DefaultBurst
---- PASS: TestBuildRateLimitHandler_DefaultBurst (0.00s)
-=== RUN TestBuildRateLimitHandler_BypassList
---- PASS: TestBuildRateLimitHandler_BypassList (0.00s)
-=== RUN TestBuildRateLimitHandler_BypassList_PlainIPs
---- PASS: TestBuildRateLimitHandler_BypassList_PlainIPs (0.00s)
-=== RUN TestBuildRateLimitHandler_BypassList_InvalidEntries
---- PASS: TestBuildRateLimitHandler_BypassList_InvalidEntries (0.00s)
-=== RUN TestBuildRateLimitHandler_BypassList_Empty
---- PASS: TestBuildRateLimitHandler_BypassList_Empty (0.00s)
-=== RUN TestBuildRateLimitHandler_BypassList_AllInvalid
---- PASS: TestBuildRateLimitHandler_BypassList_AllInvalid (0.00s)
-=== RUN TestParseBypassCIDRs
-=== RUN TestParseBypassCIDRs/empty
-=== RUN TestParseBypassCIDRs/single_cidr
-=== RUN TestParseBypassCIDRs/multiple_cidrs
-=== RUN TestParseBypassCIDRs/plain_ipv4
-=== RUN TestParseBypassCIDRs/plain_ipv6
-=== RUN TestParseBypassCIDRs/mixed
-=== RUN TestParseBypassCIDRs/with_spaces
-=== RUN TestParseBypassCIDRs/all_invalid
---- PASS: TestParseBypassCIDRs (0.00s)
- --- PASS: TestParseBypassCIDRs/empty (0.00s)
- --- PASS: TestParseBypassCIDRs/single_cidr (0.00s)
- --- PASS: TestParseBypassCIDRs/multiple_cidrs (0.00s)
- --- PASS: TestParseBypassCIDRs/plain_ipv4 (0.00s)
- --- PASS: TestParseBypassCIDRs/plain_ipv6 (0.00s)
- --- PASS: TestParseBypassCIDRs/mixed (0.00s)
- --- PASS: TestParseBypassCIDRs/with_spaces (0.00s)
- --- PASS: TestParseBypassCIDRs/all_invalid (0.00s)
-=== RUN TestBuildWAFHandler_ParanoiaLevel
-=== RUN TestBuildWAFHandler_ParanoiaLevel/level_1_default
-=== RUN TestBuildWAFHandler_ParanoiaLevel/level_1_explicit
-=== RUN TestBuildWAFHandler_ParanoiaLevel/level_2
-=== RUN TestBuildWAFHandler_ParanoiaLevel/level_3
-=== RUN TestBuildWAFHandler_ParanoiaLevel/level_4_max
-=== RUN TestBuildWAFHandler_ParanoiaLevel/level_invalid_high
-=== RUN TestBuildWAFHandler_ParanoiaLevel/level_invalid_neg
---- PASS: TestBuildWAFHandler_ParanoiaLevel (0.00s)
- --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_1_default (0.00s)
- --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_1_explicit (0.00s)
- --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_2 (0.00s)
- --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_3 (0.00s)
- --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_4_max (0.00s)
- --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_invalid_high (0.00s)
- --- PASS: TestBuildWAFHandler_ParanoiaLevel/level_invalid_neg (0.00s)
-=== RUN TestBuildWAFHandler_Exclusions
---- PASS: TestBuildWAFHandler_Exclusions (0.00s)
-=== RUN TestBuildWAFHandler_ExclusionsWithTarget
---- PASS: TestBuildWAFHandler_ExclusionsWithTarget (0.00s)
-=== RUN TestBuildWAFHandler_PerHostDisabled
---- PASS: TestBuildWAFHandler_PerHostDisabled (0.00s)
-=== RUN TestBuildWAFHandler_MonitorMode
---- PASS: TestBuildWAFHandler_MonitorMode (0.00s)
-=== RUN TestBuildWAFHandler_GlobalDisabled
---- PASS: TestBuildWAFHandler_GlobalDisabled (0.00s)
-=== RUN TestBuildWAFHandler_NoRuleset
---- PASS: TestBuildWAFHandler_NoRuleset (0.00s)
-=== RUN TestParseWAFExclusions
-=== RUN TestParseWAFExclusions/empty
-=== RUN TestParseWAFExclusions/single_exclusion
-=== RUN TestParseWAFExclusions/multiple_exclusions
-=== RUN TestParseWAFExclusions/invalid_json
---- PASS: TestParseWAFExclusions (0.00s)
- --- PASS: TestParseWAFExclusions/empty (0.00s)
- --- PASS: TestParseWAFExclusions/single_exclusion (0.00s)
- --- PASS: TestParseWAFExclusions/multiple_exclusions (0.00s)
- --- PASS: TestParseWAFExclusions/invalid_json (0.00s)
-=== RUN TestGenerateConfig_WithWAFPerHostDisabled
---- PASS: TestGenerateConfig_WithWAFPerHostDisabled (0.00s)
-=== RUN TestBuildWAFHandler_PathTraversalAttack
-=== RUN TestBuildWAFHandler_PathTraversalAttack/Path_traversal_in_ruleset_name
-=== RUN TestBuildWAFHandler_PathTraversalAttack/Null_byte_injection
-=== RUN TestBuildWAFHandler_PathTraversalAttack/URL_encoded_traversal
---- PASS: TestBuildWAFHandler_PathTraversalAttack (0.00s)
- --- PASS: TestBuildWAFHandler_PathTraversalAttack/Path_traversal_in_ruleset_name (0.00s)
- --- PASS: TestBuildWAFHandler_PathTraversalAttack/Null_byte_injection (0.00s)
- --- PASS: TestBuildWAFHandler_PathTraversalAttack/URL_encoded_traversal (0.00s)
-=== RUN TestBuildWAFHandler_SQLInjectionInRulesetName
-=== RUN TestBuildWAFHandler_SQLInjectionInRulesetName/';_DROP_TABLE_rulesets;_--
-=== RUN TestBuildWAFHandler_SQLInjectionInRulesetName/1'_OR_'1'='1
-=== RUN TestBuildWAFHandler_SQLInjectionInRulesetName/UNION_SELECT_*_FROM_users--
-=== RUN TestBuildWAFHandler_SQLInjectionInRulesetName/admin'/*
---- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName (0.00s)
- --- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName/';_DROP_TABLE_rulesets;_-- (0.00s)
- --- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName/1'_OR_'1'='1 (0.00s)
- --- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName/UNION_SELECT_*_FROM_users-- (0.00s)
- --- PASS: TestBuildWAFHandler_SQLInjectionInRulesetName/admin'/* (0.00s)
-=== RUN TestBuildWAFHandler_XSSInAdvancedConfig
-=== RUN TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":""}
-=== RUN TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":""}
-=== RUN TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"javascript:alert(1)"}
-=== RUN TestBuildWAFHandler_XSSInAdvancedConfig/{"ruleset_name":"