From 0b7b12eb4ce8bd370f9d4e11c322269cdd731a18 Mon Sep 17 00:00:00 2001 From: ff Date: Fri, 29 May 2026 14:38:55 -0400 Subject: [PATCH] fix: preserve DentaQuest cookies on startup so OTP trust survives restart DentaQuest stores its MFA trust as a persistent cookie, not in LocalStorage like DDMA/Azure B2C. Deleting the Cookies file on startup wiped that trust token, forcing OTP on every app restart. Now only the credentials tracking file is reset on startup; if credentials change, _force_logout() still calls delete_all_cookies() for a full reset. Covers both eligibility and claim flows (both share the same DentaQuestBrowserManager singleton). Co-Authored-By: Claude Sonnet 4.6 --- .../dentaquest_browser_manager.py | 41 +++++-------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/apps/SeleniumService/dentaquest_browser_manager.py b/apps/SeleniumService/dentaquest_browser_manager.py index d88a075a..2475493a 100644 --- a/apps/SeleniumService/dentaquest_browser_manager.py +++ b/apps/SeleniumService/dentaquest_browser_manager.py @@ -43,45 +43,26 @@ class DentaQuestBrowserManager: def clear_session_on_startup(self): """ - Clear only login cookies on startup to force credential re-entry after restart. - NEVER clears Local Storage or IndexedDB — those hold the DentaQuest device trust - token that allows the portal to skip OTP for recognised devices. + On startup, reset only the credentials tracking file so that credential-change + detection still works. Cookies are intentionally NOT deleted — DentaQuest stores + its MFA/OTP trust as a persistent cookie, so wiping cookies would force OTP on + every restart. If the session cookie is still valid the browser auto-logs in; if + it has expired the user re-enters credentials but OTP is skipped because the + MFA trust cookie is intact. Credential changes are handled by _force_logout() + which calls delete_all_cookies() explicitly. """ - print("[DentaQuest BrowserManager] Clearing login cookies on startup (preserving device trust)...") + print("[DentaQuest BrowserManager] Startup: preserving all cookies (OTP trust cookie must survive restart)...") try: - # Reset credentials tracking so the next login re-saves the hash if os.path.exists(self._credentials_file): os.remove(self._credentials_file) print("[DentaQuest BrowserManager] Cleared credentials tracking file") - # Only remove cookie / login-data files — these expire the session so the - # user must re-enter credentials, but the device trust token is untouched. - session_files = [ - "Cookies", - "Cookies-journal", - "Login Data", - "Login Data-journal", - ] - for filename in session_files: - for base in [os.path.join(self.profile_dir, "Default"), self.profile_dir]: - filepath = os.path.join(base, filename) - if os.path.exists(filepath): - try: - os.remove(filepath) - print(f"[DentaQuest BrowserManager] Removed {filename}") - except Exception as e: - print(f"[DentaQuest BrowserManager] Could not remove {filename}: {e}") - - # Local Storage, IndexedDB, and Session Storage are intentionally - # NOT cleared — they contain the DentaQuest device trust token that - # prevents OTP from being required on every login. - - self._needs_session_clear = True - print("[DentaQuest BrowserManager] Startup clear done — device trust preserved, OTP not required") + self._needs_session_clear = False + print("[DentaQuest BrowserManager] Startup done — cookies preserved, OTP trust intact") except Exception as e: - print(f"[DentaQuest BrowserManager] Error clearing session: {e}") + print(f"[DentaQuest BrowserManager] Error on startup: {e}") def _hash_credentials(self, username: str) -> str: """Create a hash of the username to track credential changes."""