Overview
Meridian supports multi-device session management, allowing users to be logged in from multiple devices simultaneously. Each device maintains its own session with independent refresh tokens. This replaces the previous single-session model where only one device could be logged in at a time.Key Features
- Multi-Device Support: Users can be logged in from multiple devices simultaneously without invalidating other sessions
- Device Tracking: Each session tracks device information, IP address, and client type for security auditing
- Session Management: Users can view and revoke specific sessions from their account settings
- Automatic Expiration: Sessions automatically expire after 30 days and are cleaned up automatically
How It Works
Session Creation
When a user logs in (via email/password, Google OAuth, Apple Sign In, or SAML), a new session is created:- User provides credentials or completes OAuth flow
- System creates a new session record with:
- Unique refresh token
- Device information (device type, user agent)
- IP address
- Client type (web, mobile, ios, android)
- Expiration timestamp (30 days)
- Access token (1 minute) and refresh token (30 days) are set as HTTP-only cookies
- Session is stored in database, allowing multiple concurrent sessions per user
Session Validation
When refreshing tokens, the system validates against the session database:- Extract refresh token from HTTP-only cookie
- Verify JWT signature
- Look up session in database
- Check if session is expired
- Update last used timestamp
- Issue new access token
Session Deletion
When logging out, only the current session is deleted. Other devices remain logged in.API Endpoints
List Active Sessions
Get all active sessions for the current user. Endpoint:GET /sessions
Response:
sessions(array): Array of active sessions for the userid(string): Unique session identifierdeviceInfo(string): Human-readable device description (e.g., “iPhone”, “Chrome Browser”)clientType(string): Client type:web,mobile,ios, orandroidipAddress(string): IP address where session was createdlastUsed(string): ISO 8601 timestamp of last token refreshcreatedAt(string): ISO 8601 timestamp of session creationexpiresAt(string): ISO 8601 timestamp when session expiresisCurrent(boolean): Whether this is the current session making the request
Revoke Specific Session
Revoke a specific session by its ID. Only the session owner can revoke their own sessions. Endpoint:DELETE /sessions/:sessionId
Path Parameters:
sessionId(string, required): The ID of the session to revoke
Revoke All Other Sessions
Revoke all sessions except the current one. Useful for “logout from all devices” functionality. Endpoint:POST /sessions/revoke-all-others
Response:
Frontend Integration
Displaying Sessions
Show users their active sessions in account settings: React (Web):Examples
List All Sessions
Revoke a Session
Check Current Session
Security Considerations
Session Expiration
- Sessions expire after 30 days of inactivity
- Expired sessions are automatically cleaned up
- Users must re-authenticate after expiration
Device Tracking
Each session stores:- Device Information: Extracted from User-Agent header
- IP Address: For security auditing
- Client Type: web, mobile, ios, or android
- Last Used: Timestamp of last token refresh
Best Practices
- Session Monitoring: Regularly review active sessions and revoke suspicious sessions immediately
- User Education: Encourage users to review sessions and provide “logout from all devices” option
- Security Features: Use HTTP-only cookies, validate sessions on each refresh, clean up expired sessions periodically
Migration Notes
Backward Compatibility
TherefreshToken field remains in the User schema for backward compatibility but is no longer used. Existing users will need to log in again to create sessions.
Database Schema
The newSession model includes:
userId: Reference to UserrefreshToken: Unique refresh token for this sessiondeviceInfo: Human-readable device descriptionuserAgent: Full user agent stringipAddress: IP address at creationclientType: web, mobile, ios, or androidlastUsed: Last token refresh timestampexpiresAt: Session expiration timestamp
Cleanup Job
Consider adding a periodic job to clean up expired sessions:Troubleshooting
Session Not Found
Error:Session not found or you do not have permission to revoke it
Causes:
- Session was already revoked
- Session expired
- User doesn’t own the session
- Refresh the sessions list
- Check session expiration dates
- Verify user authentication
Multiple Sessions Not Working
Issue: New login invalidates previous session Causes:- Old code still using
refreshTokenfield on User model - Session creation not implemented in login endpoint
- Verify all login endpoints use
createSession() - Check that
refreshTokenfield is no longer updated on User model - Ensure Session model is registered in
getModelService.js
Sessions Not Expiring
Issue: Sessions remain active after expiration Causes:- Cleanup job not running
- Expiration check not implemented
- Implement periodic cleanup job
- Verify
expiresAtis set correctly on session creation - Check
validateSession()includes expiration check
Notes
- Sessions work independently across devices - logging out from one device doesn’t affect others
- Each session has its own refresh token stored securely in the database
- Session information is automatically tracked (device, IP, client type)
- Users can manage their sessions through the account settings page
- Expired sessions are automatically invalidated and cleaned up