fix: merge main, address code review feedback for security fix PR #816

- Merge origin/main into branch (resolve conflict in integrations_dashboard.html)
- Add defensive JSON parsing with try/except for integration.config
- Wrap tester() call in try/except to prevent 500 errors from bad config
- Add i18n key integrations.connection_test_failed_fallback in en.json
- Reference i18n key in template JS fallback message
- Update SECURITY_AUDIT.md: add fix date (2026-03-23), update doc date
- Remove accidental revert.sh file
- Fix missing MagicMock/patch imports in test file
- Add tests for invalid JSON config and tester exception error paths

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/daebb70e-059a-4601-8864-88eef49f99cf
This commit is contained in:
copilot-swe-agent[bot]
2026-03-23 16:21:09 +00:00
parent 41d6f682c0
commit 1a195a96bd
359 changed files with 139902 additions and 2252 deletions
+50 -4
View File
@@ -21,16 +21,45 @@
<!-- Alpine.js moved to head for earlier loading -->
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
{% block head_css %}
<!-- Tailwind CSS and other CSS -->
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- flag-icons: SVG/CSS flag sprites that render correctly on all platforms including Windows -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flag-icons@7.3.2/css/flag-icons.min.css"
crossorigin="anonymous" referrerpolicy="no-referrer" />
{% endblock %}
{% block head_extra %}{% endblock %}
<!-- CSRF token for AJAX/fetch requests -->
<meta name="csrf-token" content="{{ csrf_token | default('', true) }}">
{# ── Sentry Browser SDK ─────────────────────────────────────────────────
Loaded only when SENTRY_DSN is configured. The DSN is a *public*
Sentry key and is intentionally embedded in client-side code.
Update the version pin at browser.sentry-cdn.com/releases when
upgrading the SDK.
──────────────────────────────────────────────────────────────────────── #}
{% if sentry_dsn %}
<script src="https://browser.sentry-cdn.com/10.45.0/bundle.tracing.replay.feedback.logs.metrics.min.js"
integrity="sha384-TCY3xw5Ej940LIWfS6PwhCCBl7lvEsxBpHy+BirF+EycSQUvXbfZsgsLi0oU18yZ"
crossorigin="anonymous"
></script>
<script>
if (window.Sentry) {
Sentry.init({
dsn: {{ sentry_dsn | tojson }},
environment: {{ sentry_environment | default("production") | tojson }},
release: {{ version | default(None) | tojson }},
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration(),
],
tracesSampleRate: {{ sentry_js_traces_sample_rate | default(0.0) }},
replaysSessionSampleRate: {{ sentry_js_replay_session_sample_rate | default(0.0) }},
replaysOnErrorSampleRate: {{ sentry_js_replay_on_error_sample_rate | default(0.1) }},
});
}
</script>
{% endif %}
</head>
<body class="bg-gray-50 min-h-screen flex flex-col"
@@ -152,6 +181,9 @@
<a href="/admin/credentials" role="menuitem" class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<i class="fas fa-key w-4 mr-2 text-yellow-500" aria-hidden="true"></i> {{ _("nav.credentials") }}
</a>
<a href="/admin/connections" role="menuitem" class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<i class="fas fa-plug w-4 mr-2 text-purple-500" aria-hidden="true"></i> {{ _("nav.connections") }}
</a>
<a href="/admin/files" role="menuitem" class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<i class="fas fa-folder-open w-4 mr-2 text-gray-500" aria-hidden="true"></i> {{ _("nav.file_manager") }}
</a>
@@ -174,6 +206,11 @@
<a href="/admin/backup" role="menuitem" class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<i class="fas fa-database w-4 mr-2 text-green-600" aria-hidden="true"></i> {{ _("nav.backup_restore") }}
</a>
{% if enable_factory_reset %}
<a href="/admin/system-reset" role="menuitem" class="flex items-center px-4 py-2 text-sm text-red-600 hover:bg-red-50">
<i class="fas fa-skull-crossbones w-4 mr-2 text-red-500" aria-hidden="true"></i> {{ _("nav.system_reset") }}
</a>
{% endif %}
<a href="/admin/audit-logs" role="menuitem" class="flex items-center px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<i class="fas fa-shield-halved w-4 mr-2 text-indigo-500" aria-hidden="true"></i> Audit Logs
</a>
@@ -250,7 +287,7 @@
>
<span class="text-base leading-none" aria-hidden="true">
{% set cur_lang = suggested_languages | selectattr("code", "equalto", current_locale) | list %}
{% if cur_lang %}{{ cur_lang[0].flag }}{% else %}🌐{% endif %}
{% if cur_lang %}<span class="fi fi-{{ cur_lang[0].flag }}"></span>{% else %}<i class="fas fa-globe"></i>{% endif %}
</span>
</button>
<div
@@ -290,7 +327,7 @@
class="flex items-center w-full px-4 py-2 text-sm text-left hover:bg-gray-100 dark:hover:bg-gray-700"
:onclick="`setLanguage('${lang.code}')`"
>
<span class="mr-2 text-base" x-text="lang.flag"></span>
<span class="fi mr-2" :class="`fi-${lang.flag}`" aria-hidden="true"></span>
<span x-text="lang.native"></span>
<i x-show="lang.code === '{{ current_locale }}'" class="fas fa-check ml-auto text-blue-500" aria-hidden="true"></i>
</button>
@@ -421,6 +458,9 @@
<a href="/admin/credentials" class="block px-3 py-3 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50">
<i class="fas fa-key mr-2 text-yellow-400" aria-hidden="true"></i> {{ _("nav.credentials") }}
</a>
<a href="/admin/connections" class="block px-3 py-3 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50">
<i class="fas fa-plug mr-2 text-purple-400" aria-hidden="true"></i> {{ _("nav.connections") }}
</a>
<a href="/admin/files" class="block px-3 py-3 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50">
<i class="fas fa-folder-open mr-2 text-gray-400" aria-hidden="true"></i> {{ _("nav.file_manager") }}
</a>
@@ -442,6 +482,11 @@
<a href="/admin/backup" class="block px-3 py-3 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50">
<i class="fas fa-database mr-2 text-green-500" aria-hidden="true"></i> {{ _("nav.backup_restore") }}
</a>
{% if enable_factory_reset %}
<a href="/admin/system-reset" class="block px-3 py-3 rounded-md text-base font-medium text-red-600 hover:text-red-800 hover:bg-red-50">
<i class="fas fa-skull-crossbones mr-2 text-red-500" aria-hidden="true"></i> {{ _("nav.system_reset") }}
</a>
{% endif %}
<a href="/status" class="block px-3 py-3 rounded-md text-base font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-50"
{% if request and request.url.path == '/status' %}aria-current="page"{% endif %}>
<i class="fas fa-circle-dot mr-2 text-gray-400" aria-hidden="true"></i> {{ _("nav.status") }}
@@ -557,6 +602,7 @@
profileSettings: {{ _("nav.profile_settings") | tojson }},
mySubscription: {{ _("nav.my_subscription") | tojson }},
apiTokens: {{ _("nav.api_tokens") | tojson }},
devices: {{ _("nav.devices") | tojson }},
sharedLinks: {{ _("nav.shared_links") | tojson }},
signOut: {{ _("nav.sign_out") | tojson }},
logIn: {{ _("nav.login") | tojson }},