fix(auth): address code review feedback - accessibility, docstrings, portable test paths

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/51d9bb59-d4b5-4713-9a4a-8acfc599e2cc
This commit is contained in:
copilot-swe-agent[bot]
2026-03-22 12:47:15 +00:00
parent 0287a165cf
commit c17afe8c11
3 changed files with 44 additions and 6 deletions
+10 -1
View File
@@ -109,6 +109,15 @@ def _dropbox_userinfo_compliance_fix(client, user_cls, token, data):
Dropbox's /2/users/get_current_account returns a non-standard response
format. This compliance fix normalizes the response data — the HTTP
method (POST) is handled by authlib's compliance infrastructure.
Args:
client: The OAuth client instance (required by authlib compliance fix interface).
user_cls: The user class (required by authlib compliance fix interface).
token: The OAuth token dict.
data: The raw userinfo response dict from Dropbox.
Returns:
The normalized userinfo dict with ``sub`` and ``name`` fields.
"""
# Dropbox returns account_id instead of sub
if "account_id" in data and "sub" not in data:
@@ -435,7 +444,7 @@ async def login(request: Request):
show_oauth = OAUTH_CONFIGURED
# SSO Auto Login: redirect directly to SSO provider if configured
if show_oauth and getattr(settings, "sso_auto_login", False) is True and not error and not message:
if show_oauth and settings.sso_auto_login is True and not error and not message:
return RedirectResponse(url="/oauth-login", status_code=status.HTTP_302_FOUND)
return templates.TemplateResponse(
+33 -4
View File
@@ -104,10 +104,13 @@
</main>
<!-- Service Configuration Modal -->
<div id="service-modal" class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4 hidden" role="dialog" aria-modal="true" aria-labelledby="service-modal-title">
<div id="service-modal" class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4 hidden" role="dialog" aria-modal="true" aria-labelledby="service-modal-title" aria-describedby="service-modal-description">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-lg overflow-y-auto max-h-[90vh]" onclick="event.stopPropagation()">
<div class="px-6 pt-6 pb-2 flex items-center justify-between border-b border-gray-200 dark:border-gray-700">
<h2 id="service-modal-title" class="text-lg font-semibold text-gray-900 dark:text-white"></h2>
<div>
<h2 id="service-modal-title" class="text-lg font-semibold text-gray-900 dark:text-white"></h2>
<p id="service-modal-description" class="text-xs text-gray-500 dark:text-gray-400 mt-1">{{ _("connections.save_note") }}</p>
</div>
<button type="button" onclick="closeServiceModal()" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 rounded-md p-1" style="min-height:44px; min-width:44px" aria-label="Close">
<i class="fas fa-times text-xl" aria-hidden="true"></i>
</button>
@@ -129,6 +132,14 @@
</div>
</div>
<!-- Accessible notification banner -->
<div id="save-notification" class="fixed top-4 right-4 z-[60] hidden max-w-sm" role="alert" aria-live="assertive">
<div id="save-notification-inner" class="rounded-lg shadow-lg px-4 py-3 text-sm font-medium flex items-center gap-2">
<i id="save-notification-icon" class="fas" aria-hidden="true"></i>
<span id="save-notification-text"></span>
</div>
</div>
<script>
const serviceSettings = {{ service_settings | tojson }};
const settingMetadata = {};
@@ -269,12 +280,12 @@ function saveServiceSettings(event) {
closeServiceModal();
location.reload();
} else {
alert('Some settings failed to save. Please check the values and try again.');
showNotification('error', 'Some settings failed to save. Please check the values and try again.');
}
})
.catch(function(err) {
console.error('Error saving settings:', err);
alert('Failed to save settings. Please try again.');
showNotification('error', 'Failed to save settings. Please try again.');
});
}
@@ -301,5 +312,23 @@ document.addEventListener('keydown', function(e) {
document.getElementById('service-modal')?.addEventListener('click', function(e) {
if (e.target === this) closeServiceModal();
});
function showNotification(type, message) {
var el = document.getElementById('save-notification');
var inner = document.getElementById('save-notification-inner');
var icon = document.getElementById('save-notification-icon');
var text = document.getElementById('save-notification-text');
if (!el) return;
text.textContent = message;
if (type === 'error') {
inner.className = 'rounded-lg shadow-lg px-4 py-3 text-sm font-medium flex items-center gap-2 bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200';
icon.className = 'fas fa-exclamation-circle';
} else {
inner.className = 'rounded-lg shadow-lg px-4 py-3 text-sm font-medium flex items-center gap-2 bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200';
icon.className = 'fas fa-check-circle';
}
el.classList.remove('hidden');
setTimeout(function() { el.classList.add('hidden'); }, 5000);
}
</script>
{% endblock %}
+1 -1
View File
@@ -306,7 +306,7 @@ class TestTranslationKeys:
import json
from pathlib import Path
en_path = Path("/home/runner/work/DocuElevate/DocuElevate/frontend/translations/en.json")
en_path = Path(__file__).parents[1] / "frontend" / "translations" / "en.json"
translations = json.loads(en_path.read_text())
expected_keys = [