User idle warning modal and auto logout (clear session) after configurable timeout value is hit#800
Conversation
…ow horizontal scroll in response window while preserving access to drop down menus.
…s out of oig chat and clears app session after certain time of inactivity.
Merge Deveopment into feedback-user-timeout
…on/off and fixed some bugs.
…safe_int a util function.
… more intelligent.
…nt for extreme edge case.
…der to follow pattern.
|
@microsoft-github-policy-service agree |
1 similar comment
|
@microsoft-github-policy-service agree |
Bionic711
left a comment
There was a problem hiding this comment.
Update the defaults to False.
… added default values to admin settings and moved global config variables to config.py file.
…nute timeout and allow warning dialog to be disabled.
There was a problem hiding this comment.
Pull request overview
Adds an idle-session timeout feature (with a warning modal + configurable admin settings) and fixes settings deep-merge persistence so newly added default keys get upserted back to Cosmos and cache stays consistent.
Changes:
- Add server-side idle timeout enforcement +
/api/session/heartbeatand a client-side warning/countdown + local logout flow. - Add admin settings UI + route parsing for idle timeout/warning/message configuration.
- Fix
get_settings()deep-merge persistence logic by makingdeep_merge_dicts()return a “changed” flag and upserting on change; add functional tests + docs/release notes.
Reviewed changes
Copilot reviewed 20 out of 22 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| functional_tests/test_settings_deep_merge_persistence_fix.py | Functional regression test for deep-merge persistence wiring. |
| functional_tests/test_idle_logout_timeout.py | Functional wiring checks for idle timeout backend/frontend/admin settings integration. |
| functional_tests/test_admin_settings_safe_int_fallback_fix.py | Functional coverage for extracted safe-int parsing and route wiring. |
| docs/explanation/release_notes.md | Release notes entry for new idle timeout feature and merge persistence fix. |
| docs/explanation/fixes/v0.239.012/SETTINGS_DEEP_MERGE_PERSISTENCE_FIX.md | Fix documentation for merge persistence change. |
| docs/explanation/fixes/v0.239.012/IDLE_SESSION_API_ACTIVITY_SEED_FIX.md | Fix documentation for API activity timestamp seeding. |
| docs/explanation/fixes/v0.239.012/IDLE_HEARTBEAT_REAUTH_HANDLING_FIX.md | Fix documentation for heartbeat reauth handling. |
| docs/explanation/fixes/v0.239.012/IDLE_HEARTBEAT_INTERVAL_FIX.md | Fix documentation for heartbeat interval scaling. |
| docs/explanation/fixes/v0.239.012/ADMIN_SETTINGS_SAFE_INT_FALLBACK_FIX.md | Fix documentation for safe-int fallback hardening. |
| application/single_app/templates/base.html | Injects idle-timeout config + warning modal markup and loads idle warning JS for signed-in users. |
| application/single_app/templates/admin_settings.html | Adds idle timeout settings fields + toggle section in admin UI. |
| application/single_app/static/js/idle-logout-warning.js | Implements client-side timers, warning modal, countdown, and heartbeat-driven session refresh/logout behavior. |
| application/single_app/static/js/admin/admin_settings.js | Toggles the idle-timeout settings section visibility based on the switch. |
| application/single_app/static/images/custom_logo_dark.png | Adds/updates image asset. |
| application/single_app/static/images/custom_logo.png | Adds/updates image asset. |
| application/single_app/static/css/chats.css | Adjusts .message-content overflow comment (and preserves overflow behavior). |
| application/single_app/route_frontend_authentication.py | Adds local logout route and initializes/clears last_activity_epoch during auth flows. |
| application/single_app/route_frontend_admin_settings.py | Parses and persists idle timeout settings; introduces structured int parsing via helper. |
| application/single_app/functions_settings.py | Adds idle timeout defaults; fixes deep-merge change detection/persistence and adds settings-source logging + cache update on upsert. |
| application/single_app/config.py | Bumps VERSION; introduces idle-timeout exempt path/prefix lists; minor indentation fix. |
| application/single_app/app.py | Adds request-scoped settings helper, settings-source logging, idle timeout enforcement, and heartbeat endpoint; injects idle timeout vars into templates. |
| application/single_app/admin_settings_int_utils.py | New helper module for robust int parsing with source reporting. |
docs/explanation/fixes/v0.240.002/SETTINGS_DEEP_MERGE_PERSISTENCE_FIX.md
Show resolved
Hide resolved
There was a problem hiding this comment.
Need to undelete these files. Not sure why running it locally sometimes deletes these.
There was a problem hiding this comment.
Files undeleted and added fix to prevent local deletion in the future.
There was a problem hiding this comment.
Need to undelete these files. Not sure why running it locally sometimes deletes these.
There was a problem hiding this comment.
Files undeleted and added fix to prevent local deletion in the future.
| logout_url += f"&logout_hint={quote(user_email)}" | ||
|
|
||
| print(f"{user_name} logged out. Redirecting to Azure AD logout.") | ||
| # print(f"{user_name} logged out. Redirecting to Azure AD logout.") |
There was a problem hiding this comment.
Either remove this or convert to using log_event from function_appinsights.py and adding an activity log that the user signed out (or was forced signed out).
There was a problem hiding this comment.
Converted to debug_print to match style in rest of file. Can convert to log_event if desired more than file consistency.
| # print(f"Front Door enabled: {settings.get('enable_front_door', False)}") | ||
| # print(f"Front Door URL: {settings.get('front_door_url')}") | ||
| # print(f"Logout redirect URI: {logout_uri}") |
There was a problem hiding this comment.
Either remove this or convert to using log_event from function_appinsights.py and adding an activity log that the user signed out (or was forced signed out).
There was a problem hiding this comment.
Converted to debug_print to match style in rest of file. Can convert to log_event if desired more than file consistency.
| # print( | ||
| # "Warning: Failed to get settings from cache, read from Cosmos DB instead. " | ||
| # f"Called from {caller_file}:{caller_line} in {caller_func}()." | ||
| # ) |
| # print( | ||
| # "Warning: Failed to get settings from cache, " | ||
| # "read from Cosmos DB instead. (no caller frame)" | ||
| # ) |
| except Exception as e: | ||
| print(f"Error retrieving settings: {str(e)}") | ||
| return None | ||
| # print(f"Error retrieving settings: {str(e)}") |
| cosmos_settings_container.create_item(body=default_settings) | ||
| print("Default settings created in Cosmos and returned.") | ||
| return default_settings | ||
| # print("Default settings created in Cosmos and returned.") |
There was a problem hiding this comment.
Couple more changes being requested. Small removals of dead code mostly and a restoration of the two logo files (you may need to grab them from a different copy of the repo). It happens when running the code locally.
Lastly, if you could pull a copy of Development, and merge into your branch to resolve any conflicts.
a6d5c7d to
79d3e18
Compare
@Bionic711 I restored the logos, added a fix to prevent future deletion of logos, fixed merge conflicts, and converted /deleted commented out print statements. |
This pull requests adds 1 new feature and 1 bug fix.
(NOTE: The code went through a lot of iterations implementing copilot's suggestions. The code iterations are documented in the docs/explanations/fixes section so you can see the reasoning behind the iterations.)
New warning modal window:

Updated admin section:
