Messio · Engineering case study
Balancing convenience and session security in Messio
Users reported having to sign in every day. I added an optional remembered session that renews for 15 days at a time, with a fixed 60-day limit and the existing 8-hour default.
- Project
- Messio
- Focus
- Remembered sign-in and session expiry
- Scope
- Local implementation and authentication tests
01 / Context
People return for short, everyday tasks
Messio supports the daily routines of a shared kitchen: planning meals, recording purchases, and checking balances. Users reported having to sign in every day, adding friction to those recurring tasks.
The request was to keep the existing 8-hour default while offering longer sign-in on a personal device. Remembering a browser would keep its session available between visits; it would not save the password or change which kitchen records the user could access.
02 / Problem
A short session could expire between visits
I traced the NextAuth configuration, session callbacks, and login redirects. The application explicitly used an 8-hour session lifetime. A successful client session refresh extended that lifetime, but a return after an overnight gap could arrive after expiry.
Increasing the timeout globally would also extend sessions on shared computers. Allowing renewal without a separate maximum lifetime could keep a session alive indefinitely. The implementation needed an opt-in policy that remained consistent across the browser cookie, encrypted token, and server-side access checks.
03 / Decisions
Offer persistence with a fixed stopping point
I kept the shorter default and made longer persistence a choice at password login. The security boundary depends on server-enforced expiry and account validation, rather than trusting a saved browser preference.
- 01
Make longer sign-in an explicit choice
Keep the existing 8-hour session by default. An unchecked Remember me checkbox lets a user opt into a 15-day renewable session for that browser.
The choice belongs to the authenticated session, so remembering a personal phone does not change the policy for a separate login on a shared computer.
Trade-off: Longer persistence reduces repeated password entry, but also extends access from an unattended device or a stolen session cookie. The checkbox does not make the browser inherently trustworthy.
- 02
Keep renewal separate from the maximum lifetime
A successful refresh can renew a remembered session for another 15 days, but never beyond 60 days from the original password login.
The original login time stays in the encrypted token. Near day 60, the renewal is shortened to the time remaining. An expired session cannot be revived by refreshing it.
Trade-off: An absolute limit prevents indefinite renewal, but regular users must eventually enter their password again. It does not prevent misuse of a stolen session before that limit.
- 03
Apply the policy at every session boundary
Use a shared policy for token encoding and decoding, request-specific cookie lifetimes, session responses, and page protection.
NextAuth's session maxAge is normally shared configuration. Per-session persistence needs request-local options so one login cannot change another browser's lifetime.
Trade-off: This adds more integration work than changing one timeout. The browser cookie, token expiry, and protected routes all need to agree about when access ends.
- 04
Preserve account revocation without adding device management
Continue checking the account's authVersion and existence when validating the session. Keep device listings and individual session revocation outside this change.
Password changes, password resets, global role changes, and account deletion must still invalidate existing access, including remembered sessions.
Trade-off: The current account-level mechanism can invalidate existing sessions together. Revoking one browser remotely will require individual session records in a later change.
04 / Implementation
Keep the original login time through every renewal
I added the Remember me checkbox and passed its value through the credentials flow. After successful authentication, the encrypted token records the choice and the original login timestamp. Profile updates cannot opt into the longer policy or reset that timestamp.
A shared session-policy helper calculates the remaining lifetime. For a remembered session, each renewal uses the smaller of 15 days and the time remaining before day 60. The auth route selects cookie lifetimes per request, and the proxy uses the same token decoder to reject expired sessions before protected pages are accessed.
01
Choose at login
A successful password login establishes either the 8-hour default or the remembered 15-day session.
02
Refresh before expiry
A remembered session can renew while it is still valid. Its original login time stays fixed.
03
Stop at day 60
The absolute limit ends the remembered session. A fresh password login is needed to start another.
The login and signup forms also lost their inactive Google sign-in buttons. The login form keeps a single Remember me choice alongside the existing email and password flow.
05 / Verification
Test the boundaries without waiting sixty days
The local Messio checks passed ESLint, TypeScript, the 48-test suite, and a production build. The authentication integration tests exercise the real NextAuth handlers with mocked account lookups, synthetic cookies, and a controlled clock; they do not query production data.
The tests check the 8-hour default, 15-day remembered cookies, independent browser policies, and renewal at the 60-day boundary. They also cover expired sessions, attempts to change the policy through session updates, token tampering, incorrect passwords, cross-origin login requests, and account revocation or deletion.
06 / Lessons
Persistent sign-in needs more than a longer cookie
The visible change is a checkbox, but the important work sits behind it: distinguishing rolling expiry from an absolute limit, keeping session configuration local to a request, and preserving the same policy across authentication and page protection.
The next steps are to verify the deployed behaviour, investigate the separate database-error logout path, and add device management when individual session revocation is needed. User feedback after release is still needed to assess whether the new policy improves daily use.