Authentication & Authorization
This page covers how authentication and authorization work in the admin panel, including login, token refresh, and permissions.
Authentication
The admin panel uses JWT-based authentication with the Tracker API. When a user logs in, the admin panel sends a request to the API's /api/v1/auth/login/json endpoint with the user's credentials. The API returns a JWT token, which the admin panel stores in local storage and includes in subsequent requests.
Login Process
- User enters their email and password in the login form
- The admin panel sends a POST request to
/api/v1/auth/login/jsonwith the credentials - If the credentials are valid, the API returns an access token and sets a refresh token as an HttpOnly cookie
- The admin panel stores the access token in localStorage and redirects to the dashboard
- Subsequent API requests include the access token in the Authorization header
Token Refresh Mechanism
The admin panel implements a robust automatic token refresh mechanism to maintain user sessions without requiring manual re-login. This mechanism works as follows:
- When a user logs in, the API returns an access token (valid for 30 minutes) and sets a refresh token as an HttpOnly cookie (valid for 7 days)
- The access token is stored in localStorage and used for API requests
- The admin panel refreshes the token through multiple strategies:
- Proactively refreshes the token 15 minutes before it expires
- Refreshes the token when a user returns to an inactive tab (using Page Visibility API)
- Refreshes the token after periods of user inactivity followed by new activity
- Refreshes the token if it's older than 15 minutes, regardless of expiration time
- If an API request returns a 401 Unauthorized error, the admin panel attempts to refresh the token
- If the token refresh succeeds, the failed request is retried automatically
- If the token is about to expire (within 2 minutes), a modal is shown to the user allowing them to refresh their session without losing their place
- If the token refresh fails, the user is logged out and redirected to the login page
This multi-layered approach ensures that users remain authenticated as long as their session is active, even if they leave the browser open for extended periods or if the browser puts tabs to sleep. The token refresh happens in the background without interrupting the user experience in most cases, and provides a graceful experience when manual intervention is needed.
The token refresh implementation includes:
- User activity tracking (mouse movements, clicks, keyboard input)
- Page visibility detection to handle browser tab sleeping
- A proactive refresh that triggers well before expiration
- A session expiration modal for graceful handling of expiring sessions
- Proper cleanup of timers and event listeners during logout to prevent memory leaks
- Error handling for failed refresh attempts
- Automatic retry of failed requests after successful token refresh
Login First Attempt Failure Fix
The admin panel includes a fix for an issue where the first login attempt might fail but subsequent attempts with the same credentials succeed. This was caused by token and cookie state not being properly cleared before login attempts. The fix includes:
- Clearing any existing tokens from localStorage before attempting login
- Adding a small delay to ensure cookies are properly cleared
- Improved error handling to provide better feedback
Authorization
The admin panel respects the authorization rules defined by the API. Users can only access resources they have permission to access, based on their roles and client access list.
User Roles
The admin panel supports the following user roles:
- Admin: Full access to all resources
- Manager: Access to resources associated with their assigned clients
- User: Limited access to resources associated with their assigned clients
Client Filtering
The admin panel respects the client filtering rules defined by the API. Users can only access resources associated with clients in their client_list. However, there are some special cases where client filtering is bypassed:
Direct ID Access for Resources
When accessing a resource directly by ID (for example, by clicking on a client chip in the user list, a production run chip in the brand list, or a production run link in the trackers list), the API bypasses client filtering for that specific resource if:
- The user is an admin, or
- The user has access to the resource through their client_list
This allows users to access specific resources they have permission to see, even if they don't have access to all resources. This is particularly useful for navigating between related resources, such as from a user to a specific client, from a brand to its production runs, or from a tracker to its production run.
The implementation includes:
- Frontend components that create direct links to filtered resource lists
- Backend logic that checks user permissions and bypasses client filtering when appropriate
- Proper error handling and logging for debugging access issues
- Special handling for ID filtering in the dataProvider
For example, when a user clicks on a client chip in the user list, the following happens:
- The frontend creates a URL with a filter parameter:
/#/clients?filter={"id":3} - The dataProvider converts this to an API request:
/api/v1/clients?skip=0&limit=10&id=3 - The backend API filters the clients to only include the one with the specified ID
- The frontend displays only the filtered client in the list
Permission Checking
The admin panel checks permissions for various actions:
- Read: Users can only view resources they have permission to access
- Create: Users can only create resources for clients they have permission to access
- Update: Users can only update resources they have permission to access
- Delete: Users can only delete resources they have permission to access
These permissions are enforced both in the frontend UI (by hiding buttons and forms) and in the backend API (by returning 403 Forbidden errors for unauthorized requests).