prosody.events.fire_event is a plain function (event_name, event_data), not
a method. The colon form prosody.events:fire_event(name, data) passed the
events table as event_name, so the lookup found no handlers and the
vnc-fcm-invalidate-notify-cache / vcard-cache signals were silently lost.
mod_vnc_muc_fcm hooks these via module:hook_global (which registers under
the string event name), so its notify_cache was never invalidated cross-host.
A stale empty cache entry for an MUC affiliate (left by an earlier test
before the user had a token) then suppressed FCM pushes to that affiliate,
breaking test_muc_fcm_push_to_offline_member in the full suite.
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/11>
fcm_notify splits userName internally via jid_split, so callers were
double-splitting: passing jid_split(to) fed the bare node as userName
and shifted every subsequent argument by one (host→title, resource→body,
…), corrupting all notification payloads. Pass the full JID instead.
In mod_vnc_muc_fcm, replace event.stanza:clone() with st.clone() and
add the util.stanza import for robustness.
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/11>
mod_vnc_broadcast and mod_vnc_fcm accessed the deprecated
prosody.hosts[host].modules.muc.rooms[to] table, removed in Prosody 13,
triggering 'Attempt to read a non-existent global rooms' warnings and
silently breaking MUC affiliation fan-out for broadcasts and push.
Replace with a version-safe get_room_from_jid() helper (rawget fallback
to .rooms for older Prosody), matching the pattern already in
mod_vcard_muc. Guard _affiliations access behind a nil room check.
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/7>
Add a module-scoped util.cache LRU (lastactivity_cache_size default 5000,
lastactivity_cache_ttl default 300s) in front of the activity_store /
remote_activity_store fallback. Write-through on all set sites
(authentication-success, local last-session unavailable, remote
unavailable) and read-through in both IQ handlers (batch and standard
jabber:iq:last), so repeated last-activity queries for the same contacts
no longer hit the synchronous SQL driver, reducing event-loop blocking.
Also removes dead code (avatar-hash helpers, dumpTable, unused imports,
commented-out debug logging) and the unused remote avatar-update tracking.
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/5>
The store :set() calls go through mod_storage_sql (LuaDBI), a blocking C
client. These hooks fire on the presence/auth hot path, so inline writes
stall the event loop under presence storms. Buffer writes in memory and
flush every 5 seconds (configurable via vnc_lastactivity_flush_interval).
The IQ handlers already read from in-memory map/remote_act_cache first,
so read consistency is preserved. Final flush on server-stopping and
host-deactivating prevents data loss on graceful shutdown.
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
Neither _hin variant is enabled in the config (the active push modules
are mod_vnc_fcm for 1:1 and mod_vnc_muc_fcm for MUC). Drop the dead
files and update AGENTS.md to reference the active modules.
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
mod_vnc_e2ehints put the raw boolean returned by get_e2e() (false when
unset) into the disco#info roominfo formdata. muc#roominfo_e2e is a
text-single field, and util.dataforms/util.stanza cannot serialize a
boolean field value, so room:get_disco_info() raised an error and the
server silently dropped the disco#info reply for every existing room
(confirmed at the wire level: non-existent rooms returned item-not-found,
existing rooms returned nothing). Coerce the value to a string, matching
the working mod_vnc_muc_data pattern. get_e2e() itself is left returning a
boolean since the muc-config-form boolean field needs it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
Re-port all source patches onto 0.12.6; three are gone entirely:
moduleapi (the two vnc_muc_fcm modules call core.storagemanager
directly now), mod_admin_telnet and portmanager (replaced by
console_interfaces/http_interfaces config). The muc.lib fork keeps its
four functional changes including the externally consumed
muc-config-sub-mitted event; the operator-precedence hunk was fixed
upstream. mod_muc_mam shrinks to keep-archive-on-room-destroy since
muc_log_expires_after="never" disables cleanup upstream in 0.12.
Delete the bundled mod_smacks fork and the no-op mod_smacks_offline;
core 0.12 smacks supersedes them (options audited, dead smacks_max_old
corrected to smacks_max_old_sessions).
Config/startup: drop legacyauth, run_as_root, daemonize; bosh_ports ->
http_ports; cross_domain_* -> http_cors_override; randomize
component_secret at startup (env-overridable); export
log_slow_events_threshold fallback (latent render bug).
Found while smoke-testing: pin --idn-library=idn (0.12's ICU default
segfaults without ICU data in the image); http became a private
service in 0.12 so 5280 needs http_interfaces to stay public; the
telnet console now depends on mod_admin_socket, whose socket moves to
/var/log/prosody.
Verified: prosodyctl check config clean; boots against Postgres with
empty error log and same port bindings as 0.11; healthcheck green;
telnet console and SQL storage round-trip; 0.11->0.12 schema upgrade
rehearsed on a 0.11-created database with data intact.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>