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
+304 -54
View File
@@ -41,6 +41,53 @@
"about.story_heading": "Our Story",
"about.story_p1": "DocuElevate was created with one goal in mind: to simplify and streamline document management for everyone, whether youre a small startup or a large enterprise.",
"about.story_p2": "We harness the power of pluggable AI providers (OpenAI, Anthropic Claude, Google Gemini, Ollama, OpenRouter, Portkey, and more) for metadata extraction and text refinement, integrate seamlessly with Dropbox, Nextcloud, and Paperless NGX for storage and indexing, leverage Azure Document Intelligence for OCR, and even use Gotenberg for file-to-PDF conversions.",
"admin_files.admin_only_badge": "Admin Only",
"admin_files.aria_breadcrumb": "Breadcrumb",
"admin_files.badge_delta_detected": "Delta detected",
"admin_files.badge_duplicate": "dup",
"admin_files.badge_in_db": "in DB",
"admin_files.badge_on_disk": "on disk",
"admin_files.breadcrumb_workdir": "workdir",
"admin_files.btn_download": "Download",
"admin_files.col_actions": "Actions",
"admin_files.col_db": "DB",
"admin_files.col_health": "Health",
"admin_files.col_id": "ID",
"admin_files.col_ingested": "Ingested",
"admin_files.col_local_filename": "local_filename",
"admin_files.col_missing_paths": "Missing paths",
"admin_files.col_modified": "Modified",
"admin_files.col_name": "Name",
"admin_files.col_original_file_path": "original_file_path",
"admin_files.col_original_filename": "Original Filename",
"admin_files.col_path_relative": "Path (relative to workdir)",
"admin_files.col_processed_file_path": "processed_file_path",
"admin_files.col_size": "Size",
"admin_files.delta_detected_detail": "Found {orphan_count} orphan file(s) on disk with no DB record, and {ghost_count} DB record(s) with missing files on disk.",
"admin_files.delta_detected_title": "Delta detected.",
"admin_files.empty_database": "No file records found in the database.",
"admin_files.empty_directory": "This directory is empty.",
"admin_files.ghost_records_desc": "(in DB, file(s) missing on disk)",
"admin_files.ghost_records_heading": "Ghost records",
"admin_files.heading": "File Manager",
"admin_files.health_missing": "Missing",
"admin_files.health_ok": "OK",
"admin_files.legend_file_exists": "File exists on disk",
"admin_files.legend_file_missing": "File missing from disk",
"admin_files.legend_found_in_db": "Found in DB",
"admin_files.legend_not_in_db": "Not in DB (orphan)",
"admin_files.legend_path_not_set": "Path not set",
"admin_files.no_delta": "No delta found — filesystem and database are in sync.",
"admin_files.no_ghost_records": "No ghost records found.",
"admin_files.no_orphan_files": "No orphan files found.",
"admin_files.orphan_files_desc": "(on disk, no DB record)",
"admin_files.orphan_files_heading": "Orphan files",
"admin_files.page_title": "File Manager Admin",
"admin_files.status_in_db": "In DB",
"admin_files.status_orphan": "Orphan",
"admin_files.tab_database": "Database Records",
"admin_files.tab_filesystem": "Filesystem",
"admin_files.tab_reconcile": "Reconcile",
"admin_plans.aria_delete_plan": "Delete {name}",
"admin_plans.aria_edit_plan": "Edit {name}",
"admin_plans.aria_feature_n": "Feature {n}",
@@ -55,10 +102,10 @@
"admin_plans.btn_edit": "Edit",
"admin_plans.btn_restore_defaults": "Restore Defaults",
"admin_plans.btn_restore_defaults_title": "Restore all four default plans (only if no plans exist yet)",
"admin_plans.btn_restoring": "Restoring\u2026",
"admin_plans.btn_restoring": "Restoring",
"admin_plans.btn_save_changes": "Save Changes",
"admin_plans.btn_save_order": "Save Order",
"admin_plans.btn_saving": "Saving\u2026",
"admin_plans.btn_saving": "Saving",
"admin_plans.btn_stripe_setup": "Stripe Setup",
"admin_plans.btn_stripe_setup_title": "Open the Stripe Setup Wizard to configure API keys and sync plans",
"admin_plans.col_actions": "Actions",
@@ -113,7 +160,7 @@
"admin_plans.js_seed_failed": "Seed failed",
"admin_plans.js_yearly_enter": "Enter yearly price to show savings",
"admin_plans.js_yearly_save": "Save {pct}% vs monthly",
"admin_plans.loading": "Loading plans\u2026",
"admin_plans.loading": "Loading plans",
"admin_plans.modal_close_aria": "Close modal",
"admin_plans.modal_create_title": "Add Plan",
"admin_plans.modal_edit_title_prefix": "Edit Plan: ",
@@ -122,17 +169,17 @@
"admin_plans.overage_0pct": "0% (exact)",
"admin_plans.overage_100pct": "100%",
"admin_plans.overage_50pct": "50%",
"admin_plans.overage_announce": "\u2192 announce",
"admin_plans.overage_announce": " announce",
"admin_plans.overage_buffer_body_prefix": "The overage buffer is",
"admin_plans.overage_buffer_body_suffix": "We advertise X docs/month but only enforce at",
"admin_plans.overage_buffer_formula": "X \u00d7 (1 + buffer%)",
"admin_plans.overage_buffer_formula": "X × (1 + buffer%)",
"admin_plans.overage_buffer_invisible": "invisible to users",
"admin_plans.overage_buffer_tail": "docs. For example, a 150-doc/month plan with a 20% buffer enforces at 180 docs. This prevents hard cutoffs at the exact announced limit, giving users a graceful soft landing.",
"admin_plans.overage_buffer_title": "About the Overage Buffer",
"admin_plans.overage_docs": "docs,",
"admin_plans.overage_docs_end": "docs",
"admin_plans.overage_enforce_at": "enforce at",
"admin_plans.page_title": "Plan Designer \u2014 DocuElevate Admin",
"admin_plans.page_title": "Plan Designer DocuElevate Admin",
"admin_plans.section_basic_info": "Basic Info",
"admin_plans.section_display": "Display",
"admin_plans.section_features": "Features List",
@@ -149,53 +196,6 @@
"admin_plans.stripe_wizard_text": "Stripe Setup Wizard",
"admin_plans.subheading": "Manage subscription plans shown on the public pricing page.",
"admin_plans.table_aria_label": "Subscription plans",
"admin_files.admin_only_badge": "Admin Only",
"admin_files.aria_breadcrumb": "Breadcrumb",
"admin_files.badge_delta_detected": "Delta detected",
"admin_files.badge_duplicate": "dup",
"admin_files.badge_in_db": "in DB",
"admin_files.badge_on_disk": "on disk",
"admin_files.breadcrumb_workdir": "workdir",
"admin_files.btn_download": "Download",
"admin_files.col_actions": "Actions",
"admin_files.col_db": "DB",
"admin_files.col_health": "Health",
"admin_files.col_id": "ID",
"admin_files.col_ingested": "Ingested",
"admin_files.col_local_filename": "local_filename",
"admin_files.col_missing_paths": "Missing paths",
"admin_files.col_modified": "Modified",
"admin_files.col_name": "Name",
"admin_files.col_original_file_path": "original_file_path",
"admin_files.col_original_filename": "Original Filename",
"admin_files.col_path_relative": "Path (relative to workdir)",
"admin_files.col_processed_file_path": "processed_file_path",
"admin_files.col_size": "Size",
"admin_files.delta_detected_detail": "Found {orphan_count} orphan file(s) on disk with no DB record, and {ghost_count} DB record(s) with missing files on disk.",
"admin_files.delta_detected_title": "Delta detected.",
"admin_files.empty_database": "No file records found in the database.",
"admin_files.empty_directory": "This directory is empty.",
"admin_files.ghost_records_desc": "(in DB, file(s) missing on disk)",
"admin_files.ghost_records_heading": "Ghost records",
"admin_files.heading": "File Manager",
"admin_files.health_missing": "Missing",
"admin_files.health_ok": "OK",
"admin_files.legend_file_exists": "File exists on disk",
"admin_files.legend_file_missing": "File missing from disk",
"admin_files.legend_found_in_db": "Found in DB",
"admin_files.legend_not_in_db": "Not in DB (orphan)",
"admin_files.legend_path_not_set": "Path not set",
"admin_files.no_delta": "No delta found \u2014 filesystem and database are in sync.",
"admin_files.no_ghost_records": "No ghost records found.",
"admin_files.no_orphan_files": "No orphan files found.",
"admin_files.orphan_files_desc": "(on disk, no DB record)",
"admin_files.orphan_files_heading": "Orphan files",
"admin_files.page_title": "File Manager \u2013 Admin",
"admin_files.status_in_db": "In DB",
"admin_files.status_orphan": "Orphan",
"admin_files.tab_database": "Database Records",
"admin_files.tab_filesystem": "Filesystem",
"admin_files.tab_reconcile": "Reconcile",
"admin_users.add_user_profile_btn": "Add User Profile",
"admin_users.admin_only_badge": "Admin Only",
"admin_users.btn_password": "Password",
@@ -315,7 +315,23 @@
"admin_users.total_count_users": "{count} users",
"admin_users.total_no_users": "No users",
"admin_users.total_one_user": "1 user",
"annotations.add": "Add annotation",
"annotations.color": "Color",
"annotations.content_placeholder": "Write an annotation...",
"annotations.delete_confirm": "Are you sure you want to delete this annotation?",
"annotations.deleted": "Annotation deleted",
"annotations.empty": "No annotations yet",
"annotations.go_to_page": "Go to page",
"annotations.heading": "Annotations",
"annotations.page": "Page",
"annotations.save": "Save",
"annotations.type_highlight": "Highlight",
"annotations.type_note": "Note",
"annotations.type_strikethrough": "Strikethrough",
"annotations.type_underline": "Underline",
"annotations.updated": "Annotation updated",
"api_tokens.col_created": "Created",
"api_tokens.col_expires": "Expires",
"api_tokens.col_last_ip": "Last IP",
"api_tokens.col_last_used": "Last Used",
"api_tokens.col_name": "Name",
@@ -327,6 +343,14 @@
"api_tokens.create_heading": "Create New Token",
"api_tokens.create_token": "Create Token",
"api_tokens.creating": "Creating…",
"api_tokens.delete": "Delete",
"api_tokens.delete_confirm": "Permanently delete this revoked token? This cannot be undone.",
"api_tokens.delete_prefix": "Permanently delete token",
"api_tokens.expires_at_label": "Expires (optional)",
"api_tokens.expires_at_placeholder": "e.g. 30, 90, 365 days",
"api_tokens.expires_in_days_label": "Token lifetime (days)",
"api_tokens.expires_never": "Never",
"api_tokens.expires_on": "Expires",
"api_tokens.heading": "API Tokens",
"api_tokens.intro": "Create personal API tokens to interact with the DocuElevate API programmatically. Use tokens for webhook uploads, CI/CD pipelines, or any script that needs to upload or retrieve documents.",
"api_tokens.loading_tokens": "Loading tokens…",
@@ -334,9 +358,13 @@
"api_tokens.no_tokens_heading": "No API tokens yet",
"api_tokens.no_tokens_help": "Create your first token above to get started.",
"api_tokens.page_title": "API Tokens DocuElevate",
"api_tokens.reactivate": "Reactivate",
"api_tokens.reactivate_confirm": "Reactivate this token? It will be usable again immediately.",
"api_tokens.reactivate_prefix": "Reactivate token",
"api_tokens.revoke": "Revoke",
"api_tokens.revoke_prefix": "Revoke token",
"api_tokens.status_active": "Active",
"api_tokens.status_expired": "Expired",
"api_tokens.status_revoked": "Revoked",
"api_tokens.table_aria": "API Tokens",
"api_tokens.token_created": "Token created successfully!",
@@ -471,6 +499,21 @@
"billing.success_heading": "You're all set!",
"billing.success_message": "Your subscription has been activated. Thank you for choosing DocuElevate!",
"billing.success_page_title": "DocuElevate - Subscription Activated",
"comments.add_comment": "Add comment",
"comments.add_reply": "Reply",
"comments.body_placeholder": "Write a comment... Use @username to mention someone",
"comments.delete_confirm": "Are you sure you want to delete this comment?",
"comments.deleted": "Comment deleted",
"comments.edit": "Edit",
"comments.empty": "No comments yet",
"comments.heading": "Comments",
"comments.mention_users": "Mention users",
"comments.reply_placeholder": "Write a reply...",
"comments.resolve": "Resolve",
"comments.resolved": "Resolved",
"comments.save": "Save",
"comments.unresolve": "Reopen",
"comments.updated": "Comment updated",
"common.actions": "Actions",
"common.active": "Active",
"common.all": "All",
@@ -505,6 +548,7 @@
"common.next_page": "Next page",
"common.no": "No",
"common.none": "None",
"common.not_available": "N/A",
"common.page": "Page",
"common.paused": "Paused",
"common.pending": "Pending",
@@ -574,6 +618,22 @@
"cookie_policy.s5_p3_pre": "This Cookie Policy is part of and incorporated into our",
"cookie_policy.s5_privacy_link": "Privacy Notice",
"cookie_policy.s5_terms_link": "Terms of Service",
"connections.configure": "Configure",
"connections.configured": "Connected",
"connections.description": "Configure external authentication providers like OAuth2 and SAML.",
"connections.frontend_url_note": "Note: Requires Frontend URL to be configured. Configure in System Settings.",
"connections.linked": "Linked",
"connections.mobile_upload_description": "Allow users to upload files from mobile devices by scanning a QR code.",
"connections.mobile_upload_title": "Mobile Phone Upload",
"connections.qr_code_enabled": "Enable QR Code Upload",
"connections.save_note": "Changes to authentication providers require a restart to take effect.",
"connections.sso_auto_login": "Enable SSO Auto Login",
"connections.sso_auto_login_description": "Automatically redirect to SSO login when authentication is required.",
"connections.sso_auto_login_title": "SSO Auto Login",
"connections.title": "Connections",
"connections.unconfigure": "Disconnect",
"connections.unlinked": "Unlinked",
"connections.unlinked_services": "Services",
"credentials.col_action": "Action",
"credentials.col_credential": "Credential",
"credentials.col_source": "Source",
@@ -607,6 +667,46 @@
"dashboard.title": "Dashboard",
"dashboard.total_files": "Total Files",
"dashboard.welcome": "Welcome to DocuElevate",
"devices.col_created": "Connected",
"devices.col_device": "Device",
"devices.col_last_ip": "Last IP",
"devices.col_last_seen": "Last Seen",
"devices.col_last_used": "Last Used",
"devices.col_platform": "Platform",
"devices.col_push_token": "Push Token",
"devices.col_status": "Status",
"devices.col_token_prefix": "Token Prefix",
"devices.confirm_deactivate_device": "Remove this device? It will stop receiving push notifications.",
"devices.confirm_revoke_token": "Revoke access for this device? It will need to log in again.",
"devices.deactivate_device": "Remove",
"devices.delete_device": "Delete",
"devices.delete_device_confirm": "Permanently delete this inactive device? This cannot be undone.",
"devices.delete_token": "Delete",
"devices.delete_token_confirm": "Permanently delete this revoked token? This cannot be undone.",
"devices.device_deleted_success": "Device permanently deleted.",
"devices.device_removed_success": "Device removed successfully.",
"devices.heading": "Mobile Devices",
"devices.intro": "Manage your mobile app connections and registered devices. You can revoke access for individual devices here.",
"devices.loading": "Loading devices…",
"devices.mobile_tokens_description": "These tokens were created when you logged in via the mobile app or scanned a QR code. Revoking a token will sign the device out.",
"devices.mobile_tokens_heading": "Mobile App Tokens",
"devices.no_devices": "No registered devices",
"devices.no_devices_help": "Install the DocuElevate mobile app and log in to register a device for push notifications.",
"devices.no_mobile_tokens": "No mobile app tokens",
"devices.no_mobile_tokens_help": "Log in via the mobile app or scan a QR code to create a mobile token.",
"devices.page_title": "Devices DocuElevate",
"devices.qr_login_cta": "Connect a new device via QR code",
"devices.reactivate_token": "Reactivate",
"devices.reactivate_token_confirm": "Reactivate this token? The device will be able to use it again immediately.",
"devices.registered_devices_description": "Devices registered for push notifications from the DocuElevate mobile app.",
"devices.registered_devices_heading": "Registered Devices",
"devices.revoke_token": "Revoke",
"devices.status_active": "Active",
"devices.status_inactive": "Inactive",
"devices.status_revoked": "Revoked",
"devices.token_deleted_success": "Token permanently deleted.",
"devices.token_reactivated_success": "Token reactivated successfully.",
"devices.token_revoked_success": "Device token revoked successfully.",
"duplicates.file_id_label": "File ID",
"duplicates.file_id_placeholder": "e.g. 42",
"duplicates.find_btn": "Find",
@@ -668,6 +768,7 @@
"files.drop_overlay_hint": "Supports PDF, Office docs, images, HTML, Markdown, and more folders are processed recursively",
"files.drop_overlay_title": "Drop files or folders anywhere to upload",
"files.error_hint": "This might be due to a configuration or import issue. Please check the server logs.",
"files.file_actions_aria": "File actions",
"files.file_size": "File Size",
"files.filename": "Filename",
"files.files_selected": "files selected",
@@ -695,6 +796,50 @@
"files.filter_tags_placeholder": "e.g. invoice,amazon",
"files.fulltext_search_label": "Full-Text Search (OCR text, metadata, tags)",
"files.fulltext_search_placeholder": "Search document content, sender, tags, type...",
"files.js_confirm_cloud_ocr": "Are you sure you want to re-run Cloud OCR on {count} file(s)?",
"files.js_confirm_delete_files": "Are you sure you want to delete {count} file(s)?",
"files.js_confirm_reprocess_files": "Are you sure you want to reprocess {count} file(s)?",
"files.js_delete_saved_search_aria": "Delete saved search {name}",
"files.js_delete_saved_search_confirm": "Delete this saved search?",
"files.js_download": "Download",
"files.js_download_file_aria": "Download file",
"files.js_enter_search_name": "Enter a name for this saved search:",
"files.js_error_deleting_file": "Error deleting file: {error}",
"files.js_error_deleting_files": "Error deleting files: {error}",
"files.js_error_downloading_files": "Error downloading files: {error}",
"files.js_error_queuing_cloud_ocr": "Error queuing Cloud OCR: {error}",
"files.js_error_reprocessing_files": "Error reprocessing files: {error}",
"files.js_failed_create_zip": "Failed to create ZIP download",
"files.js_failed_delete_file": "Failed to delete file",
"files.js_failed_delete_files": "Failed to delete files",
"files.js_failed_load_file": "Failed to load file",
"files.js_failed_load_pdf": "Failed to load PDF",
"files.js_failed_queue_cloud_ocr": "Failed to queue Cloud OCR",
"files.js_failed_reprocess_files": "Failed to reprocess files",
"files.js_full_view": "Full view",
"files.js_load_saved_searches_error": "Could not load saved searches",
"files.js_loading": "Loading…",
"files.js_next_page": "Next »",
"files.js_no_filters_to_save": "No filters to save. Please apply at least one filter (search, date, status, tags, etc.) before saving.",
"files.js_no_results": "No results found.",
"files.js_no_saved_searches": "No saved searches yet",
"files.js_open_full_view_aria": "Open full view",
"files.js_page_info": "Page {page} / {pages}",
"files.js_pdf_page_info": "Page {page} of {total}",
"files.js_prev_page": "« Prev",
"files.js_preview_fallback": "Preview",
"files.js_reset_zoom": "Reset zoom",
"files.js_search_results_count": "{total} result(s) for \"{query}\"",
"files.js_search_unavailable": "Search unavailable: {error}",
"files.js_searching": "Searching…",
"files.js_select_files_cloud_ocr": "Please select files to re-run Cloud OCR on",
"files.js_select_files_delete": "Please select files to delete",
"files.js_select_files_download": "Please select files to download",
"files.js_select_files_reprocess": "Please select files to reprocess",
"files.js_untitled": "(untitled)",
"files.js_view_file": "View file",
"files.js_zoom_in": "Zoom in",
"files.js_zoom_out": "Zoom out",
"files.no_files": "No files found",
"files.ocr_status": "OCR Status",
"files.page_title": "File Records",
@@ -962,6 +1107,7 @@
"integrations.connected": "Connected",
"integrations.connection_failed": "Connection failed",
"integrations.connection_success": "Connection successful",
"integrations.connection_test_failed_fallback": "Connection test failed.",
"integrations.delete_confirm_are_you_sure": "Are you sure you want to delete",
"integrations.delete_confirm_title": "Delete Integration?",
"integrations.delete_confirm_undone": "This action cannot be undone.",
@@ -1102,10 +1248,12 @@
"nav.api_docs": "API Docs",
"nav.api_tokens": "API Tokens",
"nav.backup_restore": "Backup & Restore",
"nav.connections": "Connections",
"nav.credentials": "Credentials",
"nav.dark_mode": "Dark Mode",
"nav.dashboard": "Dashboard",
"nav.developer_docs": "Developer Docs",
"nav.devices": "Devices",
"nav.duplicates": "Duplicates",
"nav.file_manager": "File Manager",
"nav.files": "Files",
@@ -1138,6 +1286,7 @@
"nav.skip_to_content": "Skip to main content",
"nav.status": "Status",
"nav.subscription": "Subscription",
"nav.system_reset": "System Reset",
"nav.toggle_dark_mode": "Toggle dark mode",
"nav.toggle_nav": "Toggle navigation menu",
"nav.upload": "Upload",
@@ -1377,6 +1526,9 @@
"profile.contact_email_label": "Contact / Notification E-mail",
"profile.contact_email_placeholder": "you@example.com",
"profile.current_password": "Current Password",
"profile.default_document_language_auto": "Use system default",
"profile.default_document_language_hint": "Documents in other languages are automatically translated into this language. Leave blank to use the system default (English).",
"profile.default_document_language_label": "Default Document Language",
"profile.dismiss": "Dismiss",
"profile.display_name_hint": "Leave blank to use your account username or email.",
"profile.display_name_label": "Display Name",
@@ -1402,6 +1554,20 @@
"profile.theme_system": "System Default",
"profile.update_password": "Update Password",
"profile.updating": "Updating…",
"qr_login.claimed_device": "Device: {device_name}",
"qr_login.claimed_message": "QR code login successful! Your mobile device is now connected.",
"qr_login.description": "Scan this QR code with the DocuElevate mobile app to log in instantly.",
"qr_login.expired_message": "This QR code has expired. Please generate a new one.",
"qr_login.generate_new": "Generate New QR Code",
"qr_login.heading": "Mobile App QR Login",
"qr_login.how_it_works": "How it works",
"qr_login.page_title": "QR Code Login DocuElevate",
"qr_login.pending_message": "Waiting for mobile app to scan…",
"qr_login.step_1": "Open the DocuElevate app on your phone",
"qr_login.step_2": "Tap \"Scan QR Code\" on the login screen",
"qr_login.step_3": "Point your camera at this QR code",
"qr_login.subtitle": "Log in to the mobile app by scanning a QR code from this page.",
"qr_login.time_remaining": "Expires in {seconds} seconds",
"queue.active_tasks": "Active Tasks",
"queue.auto_refresh_1": "Auto-refreshes every",
"queue.auto_refresh_2": "seconds",
@@ -1463,6 +1629,25 @@
"search.saved_label": "Saved Searches",
"search.saved_loading": "Loading...",
"search.title": "Search Documents",
"sessions.active_sessions": "Active Sessions",
"sessions.confirm_revoke_all": "This will log you out of all other devices and browsers, and revoke all API tokens. Continue?",
"sessions.confirm_revoke_one": "Are you sure you want to end this session?",
"sessions.current_session": "This device",
"sessions.device_info": "Device",
"sessions.expires": "Expires",
"sessions.ip_address": "IP Address",
"sessions.last_active": "Last active",
"sessions.log_off_everywhere": "Log Off All Other Sessions",
"sessions.log_off_everywhere_desc": "End all other browser sessions and revoke all API tokens. Your current session will remain active.",
"sessions.no_other_sessions": "No other active sessions found.",
"sessions.qr_login_link": "Log in on mobile via QR code",
"sessions.revoke": "End Session",
"sessions.revoked_all_success": "All other sessions have been ended.",
"sessions.revoked_success": "Session ended successfully.",
"sessions.security_heading": "Security & Sessions",
"sessions.security_subtitle": "Manage your active sessions across devices and browsers.",
"sessions.session_lifetime": "Session lifetime: {days} days",
"sessions.started": "Started",
"settings.audit_log_btn": "Audit Log",
"settings.autocomplete_hint": "Type to search known values, or enter any custom value.",
"settings.autocomplete_no_matches": "No matches — you can still type a custom value",
@@ -1560,6 +1745,25 @@
"shared.table_aria": "Shared links",
"shared.unlimited_placeholder": "Unlimited",
"shared.your_links": "Your Shared Links",
"sharing.add_share": "Share",
"sharing.change_role": "Change role",
"sharing.error_empty_user": "Please enter a user ID to share with.",
"sharing.heading": "Share with Users",
"sharing.loading": "Loading shares…",
"sharing.no_shares": "Not shared with anyone yet.",
"sharing.revoke": "Revoke access",
"sharing.revoke_confirm": "Remove this user's access to the file?",
"sharing.role_editor": "Editor",
"sharing.role_label": "Role",
"sharing.role_viewer": "Viewer",
"sharing.user_id_label": "User ID or email",
"sharing.user_id_placeholder": "e.g. alice@example.com",
"file.owner_label": "Owner",
"file.owner_unowned": "Unowned",
"file.claim_ownership": "Claim Ownership",
"file.claim_ownership_confirm": "Claim this document as yours? You will become the owner and can manage sharing.",
"file.claim_ownership_success": "You are now the owner of this document.",
"file.claim_ownership_failed": "Could not claim ownership. The document may already have an owner.",
"similarity.backfill_auto": "The background task will compute them automatically every 5 minutes, or you can",
"similarity.files_missing_text": "file(s) have OCR text but no embedding yet.",
"similarity.find_pairs_btn": "Find Pairs",
@@ -1674,6 +1878,36 @@
"subscription.upgrade_info": "Upgrades take effect immediately. Downgrades are scheduled for the end of your current billing period.",
"subscription.upgrade_to_prefix": "Upgrade to",
"subscription.usage_heading": "Usage",
"system_reset.danger_desc": "The actions below will permanently destroy data. They cannot be undone. Application settings and configuration are preserved, but all documents, files, processing history, and audit logs will be deleted.",
"system_reset.danger_zone": "Danger Zone — Irreversible Actions",
"system_reset.full_reset_button": "Wipe All Data",
"system_reset.full_reset_desc": "Permanently deletes all user data from the database and removes all work files from disk. The application will be in its initial state after this operation.",
"system_reset.full_reset_item_cache": "All watch-folder caches and ingestion state",
"system_reset.full_reset_item_db": "All document records, processing logs, and audit history",
"system_reset.full_reset_item_files": "All original, processed, and temporary files on disk",
"system_reset.full_reset_item_settings_kept": "Application settings and configuration are preserved",
"system_reset.full_reset_subtitle": "Wipe everything and start fresh",
"system_reset.full_reset_title": "Full System Reset",
"system_reset.heading": "System Reset",
"system_reset.js_error_generic": "An error occurred. Please check the server logs for details.",
"system_reset.js_success_full": "System reset complete. All user data has been wiped.",
"system_reset.js_success_reimport": "Reset complete. Original files have been staged for re-import via the watch folder.",
"system_reset.page_title": "System Reset",
"system_reset.reimport_button": "Reset & Re-import",
"system_reset.reimport_desc": "Copies your original files to a special reimport folder, wipes everything, then lets the watch-folder mechanism re-process them as if they were freshly uploaded.",
"system_reset.reimport_note": "Re-imported files will go through the full processing pipeline with the same rate limits and backoff strategy as regular uploads.",
"system_reset.reimport_step_1": "Original files are copied to a dedicated reimport folder",
"system_reset.reimport_step_2": "All data (database + work files) is wiped clean",
"system_reset.reimport_step_3": "The reimport folder is configured as a watch folder for automatic re-ingestion",
"system_reset.reimport_subtitle": "Wipe and re-process all original files",
"system_reset.reimport_title": "Reset & Re-import",
"system_reset.startup_reset_active": "Factory Reset on Startup is ACTIVE",
"system_reset.startup_reset_desc": "FACTORY_RESET_ON_STARTUP is enabled. All user data is wiped every time the application starts.",
"system_reset.subtitle": "Reset DocuElevate to a clean, fresh state. All user data will be permanently deleted.",
"system_reset.type_delete": "Type DELETE to confirm",
"system_reset.type_delete_help": "You must type the word DELETE in capital letters to enable the reset button.",
"system_reset.type_reimport": "Type REIMPORT to confirm",
"system_reset.type_reimport_help": "You must type the word REIMPORT in capital letters to enable the button.",
"terms.cookie_link": "Cookie Policy",
"terms.heading": "Terms of Service",
"terms.last_updated": "Last Updated:",
@@ -1704,6 +1938,21 @@
"terms.s6_p3_mid": ". For licensing information, please refer to our",
"terms.s6_p3_post": ".",
"terms.s6_p3_pre": "For information about how we use cookies, please see our",
"translation.copied": "Copied!",
"translation.copy": "Copy",
"translation.default_language_version": "Default Language Version",
"translation.detected_language": "Detected language",
"translation.hide_text": "Hide text",
"translation.load_translation": "Load translation",
"translation.no_translation": "No translation available yet — it may still be processing",
"translation.select_language": "Select language…",
"translation.select_target": "Please select a target language.",
"translation.show_text": "Show text",
"translation.translate_btn": "Translate",
"translation.translate_to": "Translate to Another Language",
"translation.translated_to": "Translated to",
"translation.translating": "Translating…",
"translation.translation_failed": "Translation failed",
"upload.browse_button": "Browse Files",
"upload.button_processing": "Processing...",
"upload.camera_button": "Take Photo / Scan Document",
@@ -1731,5 +1980,6 @@
"upload.uploading": "Uploading...",
"upload.url_description": "Enter a direct link to a file (PDF, Office documents, or images)",
"upload.url_label": "File URL",
"upload.url_placeholder": "https://example.com/document.pdf"
"upload.url_placeholder": "https://example.com/document.pdf",
"annotations.type": "Type"
}