fix: Chat initialization failing due to the JWT authenticated user doesn't exist in the DB yet.
fix: Always upsert custom attribues instead of replacing.
- Add widgetAuth middleware to handle JWT and inbox validation consistently
- Move authentication logic from request body to standard HTTP headers:
* JWT: Authorization: Bearer <token>
* Inbox ID: X-Libredesk-Inbox-ID: <id>
- Refactor all widget handlers to use middleware context instead of duplicate auth code
- Frontend now sends auth headers via HTTP interceptor for all widget requests
- Removed the widgetOrigin middleware as it would have same origin as the iFrame URL, changed this to use `Referrer` header on initial iFrame load.
- Feat(agent-view): Added external_user_id display in the conversation sidebar.
feat: Add HTTP utility functions for trusted origin checks
feat: Implement typing status broadcasting for live chat clients and agents.
feat: Add support for signed URLs in media manager
fix: Update database migration to handle duplicate visitors with same email address.
feat: Add conversation subscription and typing message models for WebSocket communication
feat: Implement conversation subscription management in WebSocket hub this is used for broadcasting typing indicator.
feat: Revamp widget JavaScript to improve mobile responsiveness and show unread messages if any.
- new vue app for serving live chat widget, created subdirectories inside frontend dir `main` and `widget`
- vite changes for both main app and widget app.
- new backend live chat channel
- apis for live chat widget
- Added endpoints to generate and revoke API keys for agents.
- Updated user model to include API key fields.
- Update authentication middleware to support API key validation.
- Modified database schema to accommodate API key fields.
- Updated frontend to manage API keys, including generation and revocation.
- Added localization strings for API key related messages.
- use cached agent in all middlewares
- fix: race in casbin that gave permission denied error.
- stop loading permissions into casbin on every `Enforce` function call instead cache user permissions in authz package and when permissions change only the load permission as policies atomically.
- sort permissions in get-agents to make the permissions slice comparsion using slices.Equal work