-
Notifications
You must be signed in to change notification settings - Fork 7
Frontend/auto logout #1203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Frontend/auto logout #1203
Conversation
WalkthroughAdds an inactivity-based auto-logout feature: new config, Vue AutoLogout component with modal and focus-trap, Vuex state/mutations/actions and tests, App integration, styles, and localization entries. All pieces implement role-based timers, a 30s grace period, and a stay-signed-in flow. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant App as App Component
participant Auto as AutoLogout
participant Store as Vuex Store
participant Router
Note over App,Store: After user logs in
App->>Auto: mount
Auto->>Store: check isLoggedIn & startAutoLogoutInactivityTimer()
Auto->>Auto: attach debounced activity listeners
User->>Auto: activity events (mousemove/click/keypress/scroll)
Auto->>Store: startAutoLogoutInactivityTimer()
Store->>Store: clearAutoLogoutTimeout() -> setAutoLogoutTimeout(role-based)
Note over Store,Auto: inactivity timeout fires
Store->>Store: updateAutoLogoutWarning(true)
Store->>Auto: isAutoLogoutWarning = true (modal shown)
Auto->>Auto: startAutoLogoutGracePeriodTimer()
alt User clicks "Stay Signed In"
User->>Auto: staySignedIn()
Auto->>Store: updateAutoLogoutWarning(false)
Auto->>Store: clearAutoLogoutTimeout()
Auto->>Auto: startAutoLogoutInactivityTimer()
else Grace period expires
Auto->>Store: updateAutoLogoutWarning(false)
Auto->>Router: navigate to /logout
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
webroot/src/components/AutoLogout/AutoLogout.spec.ts (1)
12-19: Consider expanding test coverage for timer and event handling logic.The current tests verify basic component mounting, which aligns with the team's testing approach. However, given the AutoLogout component's complexity (timer management, event listeners, grace period handling, cleanup on unmount), additional tests covering these behaviors could help catch edge cases:
- Timer initialization and cleanup on mount/unmount
- Event listener attachment and removal
- Grace period warning flow
- Interaction between store state and component behavior
The store-level tests in user.spec.ts do cover the action/mutation layer, which is good.
Based on learnings
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
webroot/src/app.config.ts(2 hunks)webroot/src/components/App/App.ts(2 hunks)webroot/src/components/App/App.vue(1 hunks)webroot/src/components/AutoLogout/AutoLogout.less(1 hunks)webroot/src/components/AutoLogout/AutoLogout.spec.ts(1 hunks)webroot/src/components/AutoLogout/AutoLogout.ts(1 hunks)webroot/src/components/AutoLogout/AutoLogout.vue(1 hunks)webroot/src/locales/en.json(1 hunks)webroot/src/locales/es.json(1 hunks)webroot/src/store/user/user.actions.ts(2 hunks)webroot/src/store/user/user.mutations.ts(3 hunks)webroot/src/store/user/user.spec.ts(2 hunks)webroot/src/store/user/user.state.ts(2 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 1058
File: webroot/src/store/user/user.actions.ts:231-231
Timestamp: 2025-09-04T17:58:32.677Z
Learning: In webroot/src/store/user/user.actions.ts, the token refresh timer is set to run 1 minute before token expiry. With 5-minute access tokens, this means refresh happens at 4 minutes, which avoids browser background timer throttling that typically begins after 5 minutes of tab inactivity. This timing has been tested locally and works effectively.
📚 Learning: 2025-09-04T17:58:32.677Z
Learnt from: landonshumway-ia
Repo: csg-org/CompactConnect PR: 1058
File: webroot/src/store/user/user.actions.ts:231-231
Timestamp: 2025-09-04T17:58:32.677Z
Learning: In webroot/src/store/user/user.actions.ts, the token refresh timer is set to run 1 minute before token expiry. With 5-minute access tokens, this means refresh happens at 4 minutes, which avoids browser background timer throttling that typically begins after 5 minutes of tab inactivity. This timing has been tested locally and works effectively.
Applied to files:
webroot/src/app.config.tswebroot/src/store/user/user.spec.tswebroot/src/store/user/user.actions.tswebroot/src/store/user/user.mutations.ts
📚 Learning: 2025-07-03T15:35:57.893Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 905
File: webroot/src/components/UpdateHomeJurisdiction/UpdateHomeJurisdiction.vue:32-41
Timestamp: 2025-07-03T15:35:57.893Z
Learning: In the CompactConnect frontend codebase, the team prefers to keep non-dynamic text directly in Vue templates rather than moving it to computed properties in TypeScript modules, as this approach prevents cluttering the TS files with template labels.
Applied to files:
webroot/src/components/App/App.tswebroot/src/components/AutoLogout/AutoLogout.vue
📚 Learning: 2025-08-29T18:44:53.901Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/pages/PublicDashboard/PublicDashboard.spec.ts:39-45
Timestamp: 2025-08-29T18:44:53.901Z
Learning: In webroot/src/pages/PublicDashboard/PublicDashboard.spec.ts, the test intentionally calls getCognitoConfig() without arguments to test runtime fallback behavior and improve code coverage, even though this causes a TypeScript error. This is a valid testing pattern for verifying that functions handle invalid arguments gracefully.
Applied to files:
webroot/src/components/AutoLogout/AutoLogout.spec.ts
📚 Learning: 2025-05-28T16:09:12.906Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/components/Forms/InputEmailList/InputEmailList.spec.ts:12-19
Timestamp: 2025-05-28T16:09:12.906Z
Learning: The CompactConnect application uses mount testing as the general component testing strategy. They focus their testing efforts on the data layer (models and store) rather than extensive component testing, and mount tests meet their coverage needs.
Applied to files:
webroot/src/components/AutoLogout/AutoLogout.spec.ts
📚 Learning: 2025-05-28T16:09:24.547Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 822
File: webroot/src/components/StateSettingsConfig/StateSettingsConfig.spec.ts:12-19
Timestamp: 2025-05-28T16:09:24.547Z
Learning: The CompactConnect app uses mount testing as their general component testing strategy, focusing more on testing the data layer (models and store) rather than comprehensive component testing. This meets their test coverage needs and is their preferred approach.
Applied to files:
webroot/src/components/AutoLogout/AutoLogout.spec.ts
📚 Learning: 2025-09-09T19:28:53.260Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1071
File: webroot/tests/helpers/setup.ts:153-155
Timestamp: 2025-09-09T19:28:53.260Z
Learning: In the CompactConnect project, component tests are kept minimal and focus primarily on basic functionality. The main testing effort is concentrated on the data layer (models, store, etc.). For component tests, API stub methods only need to exist to prevent runtime errors - they don't need to return specific mock data since components aren't being tested for full API integration scenarios.
Applied to files:
webroot/src/components/AutoLogout/AutoLogout.spec.ts
📚 Learning: 2025-08-29T18:22:23.275Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/pages/MfaResetConfirmLicensee/MfaResetConfirmLicensee.spec.ts:12-12
Timestamp: 2025-08-29T18:22:23.275Z
Learning: In the CompactConnect frontend codebase, async describe blocks are widely used and supported in their version of Mocha. The pattern `describe('Test Suite', async () => {` is an accepted and working approach throughout their test files, so suggestions to remove the async keyword from describe blocks should not be made for this codebase.
Applied to files:
webroot/src/components/AutoLogout/AutoLogout.spec.ts
📚 Learning: 2025-08-29T17:54:57.683Z
Learnt from: jsandoval81
Repo: csg-org/CompactConnect PR: 1042
File: webroot/src/locales/es.json:958-958
Timestamp: 2025-08-29T17:54:57.683Z
Learning: Spanish translations in webroot/src/locales/es.json are currently generated using Google Translate and are considered nice-to-have. The team plans to use professional translation services if formal Spanish support is needed in the future. Don't spend time on nuanced translation quality issues for Spanish locale files.
Applied to files:
webroot/src/locales/es.json
🧬 Code graph analysis (5)
webroot/src/components/AutoLogout/AutoLogout.spec.ts (1)
webroot/tests/helpers/setup.ts (1)
mountShallow(265-265)
webroot/src/store/user/user.spec.ts (1)
webroot/src/store/user/user.state.ts (1)
state(36-51)
webroot/src/store/user/user.actions.ts (2)
webroot/src/store/user/user.state.ts (1)
state(36-51)webroot/src/app.config.ts (1)
autoLogoutConfig(122-134)
webroot/src/components/AutoLogout/AutoLogout.ts (1)
webroot/src/app.config.ts (1)
autoLogoutConfig(122-134)
webroot/src/store/user/user.mutations.ts (1)
webroot/src/store/user/user.state.ts (1)
state(36-51)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: CheckWebroot
🔇 Additional comments (14)
webroot/src/locales/es.json (1)
978-981: LGTM!The Spanish localization keys for the auto-logout feature are properly structured and placed. Based on learnings, Spanish translations are generated via Google Translate and translation quality review is not required.
webroot/src/components/App/App.ts (1)
24-24: LGTM!The AutoLogout component is correctly imported and registered following the existing component registration pattern.
Also applies to: 33-33
webroot/src/locales/en.json (1)
994-997: LGTM!The English localization strings for the auto-logout warning modal are clear, user-friendly, and appropriately convey the security-focused nature of the feature.
webroot/src/components/App/App.vue (1)
37-37: LGTM!The AutoLogout component is appropriately placed at the app level after the Modal component, which makes sense for a global auto-logout feature that needs to be active throughout the application.
webroot/src/store/user/user.state.ts (1)
29-30: LGTM!The new state properties for auto-logout tracking are properly typed and initialized with sensible defaults. The pattern follows the existing
refreshTokenTimeoutIdconvention.Also applies to: 46-47
webroot/src/components/AutoLogout/AutoLogout.less (1)
1-65: LGTM!The stylesheet provides appropriate responsive styling for the auto-logout modal with:
- Proper use of Vue 3's
:deep()selector for modal customization- Mobile-first responsive design using flexbox
- Sensible breakpoints and spacing adjustments for tablet and desktop
webroot/src/store/user/user.spec.ts (1)
255-270: LGTM! Consider browser timer throttling for long inactivity periods.The tests properly cover the new auto-logout mutations and actions:
- Mutation tests verify state updates for
autoLogoutTimeoutIdandisAutoLogoutWarning- Action tests verify correct dispatch sequences (clear → set pattern)
- Both staff and licensee authentication types are covered
Based on learnings, browser background timer throttling typically begins after 5 minutes of tab inactivity. Since the config sets inactivity timeout to ~10 minutes, if the user's tab is backgrounded during inactivity, timer behavior may be affected by browser throttling. However, this may be acceptable since the user is already inactive - just worth noting for awareness.
Based on learnings
Also applies to: 793-829
webroot/src/components/AutoLogout/AutoLogout.vue (1)
8-36: LGTM! Well-structured accessible modal.The template correctly implements the auto-logout warning modal with proper ARIA attributes, keyboard handling, and i18n integration. The conditional rendering logic and event handlers align well with the TypeScript implementation.
webroot/src/app.config.ts (1)
119-134: LGTM! Clean configuration structure.The autoLogoutConfig provides a centralized, flexible configuration for auto-logout timers. Having separate constants for different user roles allows for easy differentiation in the future, even though they currently share the same 10-minute value. The LOG helper toggle is useful for testing.
webroot/src/store/user/user.mutations.ts (1)
40-41: LGTM! Mutations follow established patterns.The new mutations for auto-logout state management are well-integrated with the existing mutation structure. The reset logic properly clears the new state properties, and the handlers correctly update the corresponding state fields.
Also applies to: 165-166, 186-191
webroot/src/store/user/user.actions.ts (2)
288-307: Verify timer behavior with browser throttling.The 10-minute inactivity timer may be affected by browser background tab throttling. Based on learnings, browsers typically throttle timers after 5 minutes of tab inactivity, which is why the token refresh timer runs at 4 minutes. The auto-logout timer at 10 minutes could fire late or unpredictably in backgrounded tabs, potentially degrading the user experience.
Consider verifying this behavior during testing, especially when the tab is inactive or in the background.
Based on learnings.
279-321: Well-structured auto-logout actions.The new actions integrate cleanly with the existing store structure. The role-based timer selection logic is correct, and the flow from inactivity detection → warning → logout is well-organized. The logging integration helps with debugging during development.
webroot/src/components/AutoLogout/AutoLogout.ts (2)
70-95: Verify event listener re-establishment pattern.The event listeners use
once: true, meaning they automatically remove themselves after firing. The event handler then recursively callsstartAutoLogoutInactivityTimerto re-establish the listeners. While this pattern appears intentional, the combination of debouncing + recursive re-establishment +once: truecreates a complex flow.Consider verifying during testing that:
- Event listeners are correctly re-established after firing
- The debounce prevents excessive timer resets during rapid user activity
- No memory leaks occur from the recursive pattern
26-182: Well-architected auto-logout component.The component effectively manages the inactivity detection and grace period workflows. Key strengths:
- Clean lifecycle management with proper event listener cleanup using AbortController
- Debouncing prevents excessive timer resets during active use
- The
gracePeriodExtendEnabledflag prevents UI flicker during logout navigation- Watchers appropriately respond to login state and warning state changes
- Proper focus management for accessibility
- Update to submit button
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
webroot/src/components/AutoLogout/AutoLogout.vue (1)
24-32: Consider adding a countdown timer for better UX.The modal currently shows a static warning message without indicating how much time remains in the grace period. Consider enhancing the user experience by displaying a countdown (e.g., "You will be logged out in 25 seconds") to create urgency and help users understand when action is needed.
Example enhancement in AutoLogout.ts:
// Add a computed property for remaining seconds private remainingSeconds = 30; // Update via interval in AutoLogout.ts // Add to template data formData = { stayLoggedIn: { /* ... */ }, remainingSeconds: () => this.remainingSeconds };Then update the template:
<div class="description-container"> {{ $t('account.autoLogoutWarningDescription', { seconds: formData.remainingSeconds() }) }} </div>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
webroot/src/components/AutoLogout/AutoLogout.ts(1 hunks)webroot/src/components/AutoLogout/AutoLogout.vue(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- webroot/src/components/AutoLogout/AutoLogout.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-03T15:35:57.893Z
Learnt from: rmolinares
Repo: csg-org/CompactConnect PR: 905
File: webroot/src/components/UpdateHomeJurisdiction/UpdateHomeJurisdiction.vue:32-41
Timestamp: 2025-07-03T15:35:57.893Z
Learning: In the CompactConnect frontend codebase, the team prefers to keep non-dynamic text directly in Vue templates rather than moving it to computed properties in TypeScript modules, as this approach prevents cluttering the TS files with template labels.
Applied to files:
webroot/src/components/AutoLogout/AutoLogout.vue
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: CheckWebroot
🔇 Additional comments (3)
webroot/src/components/AutoLogout/AutoLogout.vue (3)
19-23: Good accessibility implementation.The use of
aria-live="assertive"androle="status"properly announces the modal to screen readers as an urgent status update. This ensures users with assistive technology are immediately aware of the impending logout.
39-40: LGTM!Standard Vue SFC pattern for importing external TypeScript logic and scoped Less styles. The scoped attribute properly isolates styles to this component.
9-17: Initial focus management is properly implemented—no changes needed.The modal correctly focuses the "Stay Signed In" button when the warning appears. With only one interactive element, both
firstTabIndexandlastTabIndexcorrectly reference the same element, properly trapping focus within the modal. The focus trap and keyboard navigation meet WCAG standards for modal dialogs.
ChiefStief
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
@jlkravitz This is ready for your review. FYI The PR for the investigation info FE should be prioritized before this one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Two comments/questions.
Update: Going to run locally to test briefly soon, too, so may be back with a couple of other items.
Update: local testing looks good :)
jlkravitz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isabeleliassen Good to merge!

Requirements List
Description List
app.configwith initial timer durationsTesting List
yarn test:unit:allshould run without errors or warningsyarn serveshould run without errors or warningsyarn buildshould run without errors or warningsapp.configyou can adjust theautoLogoutConfigvalues to be durations that are much shorter. E.g.LOGfunction inautoLogoutConfigto enable helper logging in the console. E.g.Closes #1155
Summary by CodeRabbit
New Features
Style
Tests
Documentation