- Offline reason modes: offline reasons gained a mode field ("Offline Mode" by default, "Online mode"), so an operator can pick a reason such as "Training" and stay online instead of going offline. Selecting an online mode reason keeps hide_online = 0, stores the reason on the operator and, when the operator was offline, creates a new online record in lh_users_online_session; the reason is stored in the new online_reason_id column so the offline reason value is not overwritten, and online hours statistics show both the offline and the online reason. Switching reason while the operator is already online also starts a new online record, but the previous record is closed exactly at the new record start so online hours shows no bogus "sync timeout" gap (and a zero length gap is not rendered at all). Switching back to plain online clears the reason. The status control and the "Set online status" modal list the available reasons with their mode.
- Reason enforced restrictions: reasons gained "Disable auto assigned" and "Disable transferring chats/mails to me manually if I am in this mode"; both apply only to "Online mode" reasons (an offline reason already keeps the operator out of the online assignment). While an operator is online with such a reason his exclude_autoasign / exclude_autoasign_mails flags are set on the department assignments so the chat and mail auto assignment workflows skip him, and the operator's own preference is restored when he switches away; "Disable transferring..." blocks manual chat/mail transfer and owner change to that operator.
- Private group chats: messages and history of a private group chat are now accepted only from its own members.
- Chat e-mail hardening: the chat e-mail is now escaped inside the mailto: link of the operator information row, so a value stored by an earlier version can no longer break out of the attribute; an invalid e-mail submitted while the pre-chat form "E-mail" field is optional is no longer persisted, the value stays empty until a valid address is provided, and the offline request path only copies the e-mail into the chat after FILTER_VALIDATE_EMAIL accepts it.
- Demo chat endpoint access: the publicly reachable chat/demo endpoint is now gated behind a logged in operator holding the lhchat/use permission or an anonymous request presenting an e2e_secret parameter matching the E2E_SECRET environment variable (compared with hash_equals to avoid timing leaks); unauthenticated visitors are redirected to the login page and logged in users without the permission get the no-permission page, preserving the previous behaviour.
- Widget: fixed the mobile widget message input and send button being covered by the Firefox for Android 132+ toolbar and keyboard - while the full screen mobile widget is open interactive-widget=resizes-content is appended to the host page viewport meta (pages that set interactive-widget themselves are left untouched) and the original value is restored when the widget is closed (wrapper version 279); the initial scroll position is now applied before the messages become visible, so the visitor no longer briefly sees the messages at the top, and scrolling is done instantly inside the widget's own messages container instead of scrolling the parent page (React app version 428).
- Notifications: replaced the dead VAPID key generator link in the notification settings (web-push-codelab.glitch.me now returns 410 Gone) with pwastack.com/tools/vapid-key-generator.
- Miscellaneous: updated install scripts, structure.json and db.dbml for the three new lh_abstract_offline_reason columns and the lh_users_online_session.online_reason_id column; bumped version to 4.96v.
Summary
- This release adds operator "online mode" offline reasons: an operator can pick a reason such as "Training" and stay online instead of going offline, the reason is recorded in the new online_reason_id column and shown together with the offline reason in online hours statistics, and a reason can disable auto assignment and manual chat/mail transfer to that operator while it is active.
- Security and input hardening: the chat e-mail is escaped in the operator mailto: link and invalid e-mail input is rejected, the public demo endpoint requires an operator or the E2E secret, and private group chat messages and history are limited to their members.
- Widget and UX fixes: the mobile widget works with the Firefox for Android keyboard, opens at the correct scroll position without scrolling the parent page, and the notification settings point to a working VAPID key generator.
For update just follow standard update procedure. For manual update it's update_361.sql
**Full Changelog**: https://github.com/LiveHelperChat/livehelperchat/compare/4.95v...4.96v