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:
@@ -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 }},
|
||||
|
||||
Reference in New Issue
Block a user