Skip to content

User idle warning modal and auto logout (clear session) after configurable timeout value is hit#800

Merged
Bionic711 merged 36 commits intomicrosoft:Developmentfrom
Xeelee33:feedback-user-timeout
Apr 1, 2026
Merged

User idle warning modal and auto logout (clear session) after configurable timeout value is hit#800
Bionic711 merged 36 commits intomicrosoft:Developmentfrom
Xeelee33:feedback-user-timeout

Conversation

@chadpalmer
Copy link
Copy Markdown
Contributor

@chadpalmer chadpalmer commented Mar 13, 2026

This pull requests adds 1 new feature and 1 bug fix.

  1. Added customizable app admin settings that set the amount of idle time before the app auto logs users out of chat.
  2. The auto logout clears the session in chat, but does not sign the users out of their SSO accounts.
  3. One of the admin settings sets how long before the auto logout the warning dialog appears letting the users know that they will logged out due to inactivity.
  4. You can set the auto logout for 2 minutes of inactivity and the warning dialog to 1 minute for easy testing in the local Docker setup, but the admin settings variables can (and should be) adjusted for production. (30 minute idle time and 28 minute warning dialog for example)
  5. The current setup allows the simple movement of the mouse pointer over the OIG Chat window to reset the idle timer and hide the warning dialog without the need to explicitly click the "Stay signed in" button.
  6. BUG FIX: Fixed bug where settings object was mutated in place and then compared to itself.

(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:
idle-warning-modal

Updated admin section:
admin-idle-timeout-settings

…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
@chadpalmer
Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

1 similar comment
@chadpalmer
Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

Copy link
Copy Markdown
Collaborator

@Bionic711 Bionic711 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the defaults to False.

… added default values to admin settings and moved global config variables to config.py file.
Copilot AI review requested due to automatic review settings March 16, 2026 21:34
Copilot AI review requested due to automatic review settings March 24, 2026 19:30
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/heartbeat and 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 making deep_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.

@paullizer paullizer self-requested a review March 27, 2026 01:17
@paullizer paullizer requested a review from Bionic711 March 27, 2026 09:43
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to undelete these files. Not sure why running it locally sometimes deletes these.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Files undeleted and added fix to prevent local deletion in the future.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to undelete these files. Not sure why running it locally sometimes deletes these.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converted to debug_print to match style in rest of file. Can convert to log_event if desired more than file consistency.

Comment on lines +276 to +278
# 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}")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Converted to debug_print to match style in rest of file. Can convert to log_event if desired more than file consistency.

Comment on lines +447 to +450
# print(
# "Warning: Failed to get settings from cache, read from Cosmos DB instead. "
# f"Called from {caller_file}:{caller_line} in {caller_func}()."
# )
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Comment on lines +462 to +465
# print(
# "Warning: Failed to get settings from cache, "
# "read from Cosmos DB instead. (no caller frame)"
# )
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

except Exception as e:
print(f"Error retrieving settings: {str(e)}")
return None
# print(f"Error retrieving settings: {str(e)}")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

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.")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Copy link
Copy Markdown
Collaborator

@Bionic711 Bionic711 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@chadpalmer chadpalmer force-pushed the feedback-user-timeout branch from a6d5c7d to 79d3e18 Compare March 31, 2026 21:55
@chadpalmer chadpalmer requested a review from Bionic711 April 1, 2026 19:27
@chadpalmer
Copy link
Copy Markdown
Contributor Author

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.

@Bionic711 I restored the logos, added a fix to prevent future deletion of logos, fixed merge conflicts, and converted /deleted commented out print statements.

@Bionic711 Bionic711 merged commit 0527e8d into microsoft:Development Apr 1, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants