Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package prosody for openSUSE:Factory checked in at 2026-01-23 17:34:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/prosody (Old) and /work/SRC/openSUSE:Factory/.prosody.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "prosody" Fri Jan 23 17:34:38 2026 rev:41 rq:1328898 version:13.0.3 Changes: -------- --- /work/SRC/openSUSE:Factory/prosody/prosody.changes 2025-11-05 16:21:29.014096062 +0100 +++ /work/SRC/openSUSE:Factory/.prosody.new.1928/prosody.changes 2026-01-23 17:34:54.518508111 +0100 @@ -1,0 +2,98 @@ +Fri Jan 23 13:06:26 UTC 2026 - Michael Vetter <[email protected]> + +- Update to 13.0.3: + Fixes and improvements: + * mod_storage_sql: Set configurable wait time for locked SQLite3 database + * net.server_event: Port TLS 1.3 channel binding method to libevent backend + * mod_roster: Add command for cleaning out invalid contact JIDs + * migrator: Allow migrating between different configs of the same driver + * mod_admin_shell: Allow pinging any JID with xmpp:ping() + * mod_invites: Accept –admin flag as shortcut for –role prosody:admin + * mod_mam: Add send_legacy_offline_messages_to_mam_clients config option + * mod_limits: Allow configuration of general ‘s2s’ limit, and have s2sout inherit from s2sin + * mod_storage_internal: Return item-not-found for unknown before/after ids + * MUC: Fixes for room avatar caching + Minor changes: + * core.configmanager: Fix referencing previous config options #1950 + * MUC: Ensure allow MUC PM setting has valid value (fixes #1933: PM does not work on new MUCs) + * mod_storage_sql: Assert that serialization of archive:set() payload succeeds + * mod_smacks: Remove extra optional from sm element + * mod_s2s_auth_dane_in: Fix caching SHA2-512 hash + * MUC: Fix muc_room_default_presence_broadcast option not working + * util.sslconfig: Fix error when applying ssl={[port]=…} + * net.server_epoll: Restore idle checks after pause (e.g. rate limits) + * util.jid: Validate domainparts using IDNA or as IP literals (fixes #1903: Invalid JID in Roster) + * util.datamanager: Fix detection of index files created on different architectures + * util.startup: Inform process manager about failure to reload config + * mod_muc: Revert f4e16e6265e6 and invalidate avatar cache only on vcard change + * mod_http_file_share: Improve debug logging around unexpected file sizes + * mod_admin_shell: Ensure JIDs are normalized in xmpp:ping() + * mod_invites: Return error when generating password reset for non-existent account + * util.uuid: Update UUIDv7 to match RFC 9562 +- bsc#1254309: Fix starting prosody + Update prodody.service with content from https://hg.prosody.im/debian/file/default/prosody.service + +------------------------------------------------------------------- +Fri Jan 23 13:05:40 UTC 2026 - Michael Vetter <[email protected]> + +- Update to 13.0.2: + Fixes and improvements: + * mod_storage_internal: Fix queries with only start returning extra items + * mod_invites_register: Stricter validation of registration events + Minor changes: + * MUC: Ensure allow MUC PM setting has valid value (fixes #1933: PM does not work on new MUCs) + * mod_storage_sql: Delay showing SQL library error until attempted load + * mod_storage_sql: Handle failure to deploy new UNIQUE index + * mod_storage_sql: Add shell command to create tables and indices (again) + * mod_s2s: Fix log to use formatting instead of concatenation (fixes #1461: Logging issues uncovered by mod_log_json) + * modulemanager, util.pluginloader: Improve error message when load fails but some candidates were filtered + * prosodyctl check config: add recommendation to switch from admin_telnet to shell + * mod_storage_sql: Retrieve all indices to see if the new one exists + * prosodyctl check config: List modules which Prosody cannot successfully load + * net.http.files: Fix issue with caching + * util.jsonschema: Fix handling of false as schema + * mod_invites: Consider password reset a distinct type wrt invite page + * configmanager: Emit config warning when referencing non-existent value + * mod_admin_shell: Add role:list() and role:show() commands + * MUC: Fix nickname registration form error handling (#1930) + * MUC: Fix Error when join stanza sent without resource (#1934) + * MUC: Factor out identification of join stanza + * mod_invites_register: Don’t restrict username for roster invites (thanks lissine) + * mod_admin_shell: Fix matching logic in s2s:close (Thanks Menel) + * mod_authz_internal: Improve error message when invalid role specified + * mod_http_file_share: Add media-src ‘self’ to Content-Security-Policy header + * mod_admin_shell: Visual tweaks to the output of debug:cert_index() + * mod_http: Log problems parsing IP addresses in X-Forwarded-For (Thanks Boris) + * mod_http: Fix IP address normalization (Thanks Boris) + * util.prosodyctl.check: Improve reporting of DNS lookup problems + +------------------------------------------------------------------- +Fri Jan 23 13:05:01 UTC 2026 - Michael Vetter <[email protected]> + +- Update to 13.0.1: + Fixes and improvements: + * mod_admin_shell: Add debug:cert_index() command to aid debugging of automatic certificate selection + * mod_tls: Enable Prosody’s certificate checking for incoming s2s connections (fixes #1916: Impossible to override certificate verification policy in 13.0) + * portmanager: Multiple fixes to use correct certificates for direct TLS ports (fixes #1915) + * net.server_epoll: Use correct connection timeout when initiating Direct TLS + * mod_roster: Fix shell commands when a component is involved (fixes #1908: error in prosodyctl shell roster attempting to subscribe a component) + * mod_http_file_share: Explicitly reject all unsupported ranges + * mod_http_file_share: Fix off by one in Range response + * mod_admin_shell, prosodyctl shell: Report command failure when no password entered (fixes #1907: prosodyctl adduser: unexpected account creation on password mismatch) + Minor changes: + * mod_storage_sql: Drop legacy index without confirmation to ease upgrades + * util.adminstream: Fix traceback on double-close (fixes #1913: Prosody fails to completely stop while shell watch:log is active) + * certmanager: Improve logging for all cases where certs are skipped + * mod_tls: Collect full certificate chain validation information + * mod_s2s: Fix error detection with newer versions of OpenSSL + * portmanager: Add debug log message to state which certificate we end up using + * prosodyctl check certs: Use correct hostname in warning message about HTTPS + * prosodyctl check: Be more robust against invalid disco_items, and show warning + * spec/tls: Add TLS/certificate integration tests + * mod_http_file_share: Improve error reporting by using util.error more + * core.storagemanager: Fix tests by removing an assert that upset luarocks + * core.usermanager: Fix COMPAT layer for legacy is_admin() function + * certmanager: Remove obsolete and verbose index log (replaced by shell command) + * doap: Add XEP-0333, XEP-0334, XEP-0156 and mod_http_altconnect + +------------------------------------------------------------------- Old: ---- prosody-13.0.2.tar.gz prosody-13.0.2.tar.gz.asc New: ---- prosody-13.0.3.tar.gz prosody-13.0.3.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ prosody.spec ++++++ --- /var/tmp/diff_new_pack.QsNnBD/_old 2026-01-23 17:34:55.150535002 +0100 +++ /var/tmp/diff_new_pack.QsNnBD/_new 2026-01-23 17:34:55.150535002 +0100 @@ -18,7 +18,7 @@ %define _piddir /run Name: prosody -Version: 13.0.2 +Version: 13.0.3 Release: 0 Summary: Communications server for Jabber/XMPP License: MIT @@ -119,7 +119,7 @@ %service_del_postun %{name}.service %files -%config(noreplace) %attr(-,root,prosody) %{_sysconfdir}/prosody/ +%config(noreplace) %attr(-,prosody,prosody) %{_sysconfdir}/prosody/ %{_bindir}/prosody %{_bindir}/prosodyctl %dir %{_libdir}/prosody ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.QsNnBD/_old 2026-01-23 17:34:55.190536704 +0100 +++ /var/tmp/diff_new_pack.QsNnBD/_new 2026-01-23 17:34:55.194536874 +0100 @@ -1,6 +1,6 @@ -mtime: 1749099187 -commit: 8b088f7c4c922497f156ca88ef7331db5edc246f908aee301bb454731c2ea514 +mtime: 1769175718 +commit: 3d59fd6654890f517cb585f698a258954ef17c3adfa33955795e239a9a162709 url: https://src.opensuse.org/lua/prosody.git -revision: 8b088f7c4c922497f156ca88ef7331db5edc246f908aee301bb454731c2ea514 +revision: 3d59fd6654890f517cb585f698a258954ef17c3adfa33955795e239a9a162709 projectscmsync: https://src.opensuse.org/lua/_ObsPrj.git ++++++ build.specials.obscpio ++++++ ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-01-23 14:42:41.000000000 +0100 @@ -0,0 +1 @@ +.osc ++++++ prosody-13.0.2.tar.gz -> prosody-13.0.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/.hg_archival.txt new/prosody-13.0.3/.hg_archival.txt --- old/prosody-13.0.2/.hg_archival.txt 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/.hg_archival.txt 2026-01-05 13:34:45.144840830 +0100 @@ -1,4 +1,4 @@ repo: 3e3171b59028ee70122cfec6ecf98f518f946b59 -node: 0dd82a8f19131ed6615cd5287be422e6eb0742bb +node: f65302ea37b071c3c4bf5fa31f3e4ffd4b4922d1 branch: 13.0 -tag: 13.0.2 +tag: 13.0.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/core/configmanager.lua new/prosody-13.0.3/core/configmanager.lua --- old/prosody-13.0.2/core/configmanager.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/core/configmanager.lua 2026-01-05 13:34:45.144840830 +0100 @@ -7,8 +7,8 @@ -- local _G = _G; -local setmetatable, rawget, rawset, io, os, error, dofile, type, pairs, ipairs = - setmetatable, rawget, rawset, io, os, error, dofile, type, pairs, ipairs; +local getmetatable, setmetatable, rawget, rawset, io, os, error, dofile, type, pairs, ipairs = + getmetatable, setmetatable, rawget, rawset, io, os, error, dofile, type, pairs, ipairs; local format, math_max, t_insert = string.format, math.max, table.insert; local envload = require"prosody.util.envload".envload; @@ -169,6 +169,9 @@ error("Invalid syntax - missing '=' perhaps?", 2); end; }; + local function is_config_option_proxy(v) + return getmetatable(v) == config_option_proxy_mt; + end -- For reading config values out of files. local function filereader(basepath, defaultmode) @@ -262,6 +265,9 @@ t_insert(warnings, ("%s:%d: Duplicate option '%s'"):format(config_file, get_line_number(config_file), k)); end set_options[option_path] = true; + if is_config_option_proxy(v) then + setmetatable(v, nil); + end set(config_table, env.__currenthost or "*", k, v); end }); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/doc/doap.xml new/prosody-13.0.3/doc/doap.xml --- old/prosody-13.0.2/doc/doap.xml 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/doc/doap.xml 2026-01-05 13:34:45.144840830 +0100 @@ -65,6 +65,7 @@ <implements rdf:resource="https://www.rfc-editor.org/info/rfc8305"/> <implements rdf:resource="https://www.rfc-editor.org/info/rfc9266"/> <implements rdf:resource="https://www.rfc-editor.org/info/rfc9525"/> + <implements rdf:resource="https://www.rfc-editor.org/info/rfc9562"/> <implements rdf:resource="https://datatracker.ietf.org/doc/draft-cridland-xmpp-session/"> <!-- since=0.6.0 note=Added in hg:0bbbc9042361 --> </implements> @@ -518,7 +519,7 @@ <implements> <xmpp:SupportedXep> <xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0198.html"/> - <xmpp:version>1.6.2</xmpp:version> + <xmpp:version>1.6.3</xmpp:version> <xmpp:status>complete</xmpp:status> <xmpp:since>0.12.0</xmpp:since> <xmpp:note>mod_smacks</xmpp:note> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/net/server_epoll.lua new/prosody-13.0.3/net/server_epoll.lua --- old/prosody-13.0.2/net/server_epoll.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/net/server_epoll.lua 2026-01-05 13:34:45.144840830 +0100 @@ -966,6 +966,8 @@ if self.conn and self.conn:dirty() then self:noise("Have buffered incoming data to process"); self:onreadable(); + else + self:setreadtimeout(); end end); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/net/server_event.lua new/prosody-13.0.3/net/server_event.lua --- old/prosody-13.0.2/net/server_event.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/net/server_event.lua 2026-01-05 13:34:45.144840830 +0100 @@ -304,6 +304,14 @@ return sock:getpeerfinished(); end +function interface_mt:ssl_exportkeyingmaterial(label, len, context) + local sock = self.conn; + if not sock then return nil, "not-connected" end + if sock.exportkeyingmaterial then + return sock:exportkeyingmaterial(label, len, context); + end +end + function interface_mt:resume() self:_lock(self.nointerface, false, self.nowriting); if self.readcallback and not self.eventread then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_admin_shell.lua new/prosody-13.0.3/plugins/mod_admin_shell.lua --- old/prosody-13.0.2/plugins/mod_admin_shell.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_admin_shell.lua 2026-01-05 13:34:45.144840830 +0100 @@ -2051,22 +2051,22 @@ def_env.xmpp = new_section("Commands for sending XMPP stanzas"); -describe_command [[xmpp:ping(localhost, remotehost) - Sends a ping to a remote XMPP server and reports the response]] +describe_command [[xmpp:ping(localjid, remotejid) - Sends a ping to an XMPP entity and reports the response]] local new_id = require "prosody.util.id".medium; -function def_env.xmpp:ping(localhost, remotehost, timeout) - localhost = select(2, jid_split(localhost)); - remotehost = select(2, jid_split(remotehost)); +function def_env.xmpp:ping(localjid, remotejid, timeout) + local localnode, localhost, localresource = jid_split(localjid); + local remotenode, remotehost, remoteresource = jid_split(remotejid); if not localhost then - return nil, "Invalid sender hostname"; + return nil, "Invalid sender JID"; elseif not prosody.hosts[localhost] then return nil, "No such local host"; + elseif localresource then + return nil, "Server can't send ping from local resource"; -- Would require creating a temporary session with bound resource and everything end if not remotehost then - return nil, "Invalid destination hostname"; - elseif prosody.hosts[remotehost] then - return nil, "Both hosts are local"; + return nil, "Invalid destination JID"; end - local iq = st.iq{ from=localhost, to=remotehost, type="get", id=new_id()} + local iq = st.iq { from = jid_join(localnode, localhost); to = jid_join(remotenode, remotehost, remoteresource); type = "get"; id = new_id() } :tag("ping", {xmlns="urn:xmpp:ping"}); local time_start = time.now(); local print = self.session.print; @@ -2083,6 +2083,12 @@ end end end + if localhost == remotehost or prosody.hosts[remotehost] then + -- No s2s connections will be triggered + return module:context(localhost):send_iq(iq, nil, timeout):next(function(pong) + return ("pong from %s in %gs"):format(pong.stanza.attr.from, time.now() - time_start); + end); + end local onconnected = onchange("connected"); local onauthenticated = onchange("authenticated"); local onestablished = onchange("established"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_http_file_share.lua new/prosody-13.0.3/plugins/mod_http_file_share.lua --- old/prosody-13.0.2/plugins/mod_http_file_share.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_http_file_share.lua 2026-01-05 13:34:45.144840830 +0100 @@ -66,7 +66,7 @@ code = 413; type = "modify"; condition = "not-acceptable"; - text = "File too large"; + text = "File too large"; -- also used if file is too small extra = { tag = st.stanza("file-too-large", { xmlns = namespace }):tag("max-file-size"):text(tostring(file_size_limit)); }; @@ -293,6 +293,7 @@ return upload_errors.new("unauthz", { request = request }); end if request.headers.content_length and tonumber(request.headers.content_length) ~= authed_upload_info.filesize then + module:log("debug", "Unexpected Content-Length %q, expected %s", request.headers.content_length, B(authed_upload_info.filesize)); return upload_errors.new("filesize", { request = request }); -- Note: We don't know the size if the upload is streamed in chunked encoding, -- so we also check the final file size on completion. @@ -351,6 +352,8 @@ local uploaded, err = errors.coerce(request.body_sink:close()); if final_size ~= upload_info.filesize then -- Could be too short as well, but we say the same thing + module:log("debug", "Final file size is %s but expected %s (%s difference)", + B(final_size), B(upload_info.filesize), B(upload_info.filesize - final_size)); uploaded, err = false, upload_errors.new("filesize", { request = request }); end if uploaded then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_invites.lua new/prosody-13.0.3/plugins/mod_invites.lua --- old/prosody-13.0.2/plugins/mod_invites.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_invites.lua 2026-01-05 13:34:45.144840830 +0100 @@ -1,5 +1,6 @@ local id = require "prosody.util.id"; local it = require "prosody.util.iterators"; +local usermanager = require "prosody.core.usermanager"; local url = require "socket.url"; local jid_node = require "prosody.util.jid".node; local jid_split = require "prosody.util.jid".split; @@ -260,6 +261,7 @@ flags = { array_params = { role = true, group = have_group_invites }; value_params = { expires_after = true }; + kv_params = { admin = true }; }; handler = function (self, user_jid, opts) --luacheck: ignore 212/self @@ -301,10 +303,13 @@ }; handler = function (self, user_jid, opts) --luacheck: ignore 212/self - local username = jid_split(user_jid); + local username, host = jid_split(user_jid); if not username then return nil, "Supply the JID of the account you want to generate a password reset for"; end + if not usermanager.user_exists(username, host) then + return nil, "The specified user account does not exist: " .. username; + end local duration_sec = require "prosody.util.human.io".parse_duration(opts and opts.expires_after or "1d"); if not duration_sec then return nil, "Unable to parse duration: "..opts.expires_after; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_limits.lua new/prosody-13.0.3/plugins/mod_limits.lua --- old/prosody-13.0.2/plugins/mod_limits.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_limits.lua 2026-01-05 13:34:45.144840830 +0100 @@ -44,7 +44,7 @@ bytes_per_second = 10 * 1024; burst_seconds = 2; }; - s2sin = { + s2s = { bytes_per_second = 30 * 1024; burst_seconds = 2; }; @@ -57,6 +57,13 @@ }; end +if not limits.s2sin and limits.s2s then + limits.s2sin = limits.s2s; +end +if not limits.s2sout then + limits.s2sout = limits.s2s or limits.s2sin; +end + local default_filter_set = {}; function default_filter_set.bytes_in(bytes, session) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_mam/mod_mam.lua new/prosody-13.0.3/plugins/mod_mam/mod_mam.lua --- old/prosody-13.0.2/plugins/mod_mam/mod_mam.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_mam/mod_mam.lua 2026-01-05 13:34:45.144840830 +0100 @@ -39,6 +39,7 @@ local timestamp, datestamp = import( "util.datetime", "datetime", "date"); local default_max_items, max_max_items = 20, module:get_option_integer("max_archive_query_results", 50, 0); local strip_tags = module:get_option_set("dont_archive_namespaces", { "http://jabber.org/protocol/chatstates" }); +local send_legacy_offline_to_mam_clients = module:get_option_boolean("send_legacy_offline_messages_to_mam_clients", false); local archive_store = module:get_option_string("archive_store", "archive"); local archive = module:open_store(archive_store, "archive"); @@ -495,12 +496,14 @@ end end, -2); --- Don't broadcast offline messages to clients that have queried the archive. -module:hook("message/offline/broadcast", function (event) - if event.origin.mam_requested then - return true; - end -end); +if not send_legacy_offline_to_mam_clients then + -- Don't broadcast offline messages to clients that have queried the archive. + module:hook("message/offline/broadcast", function (event) + if event.origin.mam_requested then + return true; + end + end); +end if cleanup_after ~= math.huge then local cleanup_storage = module:open_store("archive_cleanup"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_roster.lua new/prosody-13.0.3/plugins/mod_roster.lua --- old/prosody-13.0.2/plugins/mod_roster.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_roster.lua 2026-01-05 13:34:45.144840830 +0100 @@ -313,3 +313,36 @@ end; }); +module:add_item("shell-command", { + section = "roster"; + section_desc = "View and manage user rosters (contact lists)"; + name = "clean"; + desc = "Remove invalid JIDs from roster"; + args = { + { name = "jid", type = "string" }; + }; + host_selector = "jid"; + handler = function(self, jid) -- luacheck: ignore 212/self + local function iter(user, host) + if user then return pairs({ [user] = true }); end + local users = require"prosody.core.usermanager".users; + return users(host); + end + + local user, host = jid_split(jid); + local removed = 0; + for user_ in iter(user, host) do + local roster = assert(rm_load_roster(user_, host)); + for contact in pairs(roster) do + if type(contact) == "string" then + if not jid_prep(contact) or jid_resource(contact) then + roster[contact] = nil; + removed = removed + 1; + end + end + end + end + return true, ("%d invalid roster entrie(s) removed"):format(removed); + end; +}); + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_s2s_auth_dane_in.lua new/prosody-13.0.3/plugins/mod_s2s_auth_dane_in.lua --- old/prosody-13.0.2/plugins/mod_s2s_auth_dane_in.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_s2s_auth_dane_in.lua 2026-01-05 13:34:45.144840830 +0100 @@ -51,7 +51,7 @@ return h; elseif i == 2 then local h = sha512(t[0]); - t[1] = h; + t[2] = h; return h; end end; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_smacks.lua new/prosody-13.0.3/plugins/mod_smacks.lua --- old/prosody-13.0.2/plugins/mod_smacks.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_smacks.lua 2026-01-05 13:34:45.144840830 +0100 @@ -152,16 +152,16 @@ module:hook("stream-features", function (event) if can_do_smacks(event.origin, true) then - event.features:tag("sm", sm2_attr):tag("optional"):up():up(); - event.features:tag("sm", sm3_attr):tag("optional"):up():up(); + event.features:tag("sm", sm2_attr):up(); + event.features:tag("sm", sm3_attr):up(); end end); module:hook("s2s-stream-features", function (event) if can_do_smacks(event.origin, true) then - event.features:tag("sm", sm2_attr):tag("optional"):up():up(); - event.features:tag("sm", sm3_attr):tag("optional"):up():up(); + event.features:tag("sm", sm2_attr):up(); + event.features:tag("sm", sm3_attr):up(); end end); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_storage_internal.lua new/prosody-13.0.3/plugins/mod_storage_internal.lua --- old/prosody-13.0.2/plugins/mod_storage_internal.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_storage_internal.lua 2026-01-05 13:34:45.144840830 +0100 @@ -173,6 +173,7 @@ return list[i] end + local after_found; if query then if query.reverse then i = #list + 1 @@ -231,12 +232,23 @@ iter = it.filter(function(item) local found_after = found; if item.key == query.after then + after_found = true; found = true end return found_after; end, iter); end if query.before then + local before_key, before_found = query.before; + for idx = 1, #list do + if list[idx].key == before_key then + before_found = true; + break; + end + end + if not before_found then + return nil, "item-not-found"; + end local found = false; iter = it.filter(function(item) if item.key == query.before then @@ -250,8 +262,18 @@ end end + local first_item = iter(); + if first_item == nil and query and query.after and not after_found then + return nil, "item-not-found"; + end + return function() - local item = iter(); + local item; + if first_item then + item, first_item = first_item, nil; + else + item = iter(); + end if item == nil then if list.close then list:close(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/mod_storage_sql.lua new/prosody-13.0.3/plugins/mod_storage_sql.lua --- old/prosody-13.0.2/plugins/mod_storage_sql.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/mod_storage_sql.lua 2026-01-05 13:34:45.144840830 +0100 @@ -556,7 +556,7 @@ if new_value then table.insert(setf, '"type" = ?') table.insert(setf, '"value" = ?') - local t, value = serialize(new_value); + local t, value = assert(serialize(new_value)); table.insert(args, 1, t); table.insert(args, 2, value); end @@ -995,6 +995,8 @@ engine:execute("PRAGMA fullfsync=1;") end + engine:execute(("PRAGMA busy_timeout=%d;"):format(module:get_option_integer("sqlite_busy_timeout_ms", 1000, 0))); + for row in engine:select[[PRAGMA journal_mode;]] do journal_mode = row[1]; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/muc/mod_muc.lua new/prosody-13.0.3/plugins/muc/mod_muc.lua --- old/prosody-13.0.2/plugins/muc/mod_muc.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/muc/mod_muc.lua 2026-01-05 13:34:45.144840830 +0100 @@ -302,8 +302,7 @@ room:set_changesubject(module:get_option_boolean("muc_room_default_change_subject", room:get_changesubject())); room:set_historylength(module:get_option_integer("muc_room_default_history_length", room:get_historylength(), 0)); room:set_language(lang or module:get_option_string("muc_room_default_language")); - room:set_presence_broadcast(module:get_option_enum("muc_room_default_presence_broadcast", room:get_presence_broadcast(), "visitor", "participant", - "moderator")); + room:set_presence_broadcast(module:get_option("muc_room_default_presence_broadcast", room:get_presence_broadcast())); room:set_allow_pm(module:get_option_enum("muc_room_default_allow_pm", room:get_allow_pm(), "visitor", "participant", "moderator")); room:set_allow_modpm(module:get_option_boolean("muc_room_default_always_allow_moderator_pms", room:get_allow_modpm())); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/plugins/muc/vcard.lib.lua new/prosody-13.0.3/plugins/muc/vcard.lib.lua --- old/prosody-13.0.2/plugins/muc/vcard.lib.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/plugins/muc/vcard.lib.lua 2026-01-05 13:34:45.144840830 +0100 @@ -62,11 +62,12 @@ end, 10); if advertise_hashes ~= "none" then - module:hook("muc-occupant-joined", function (event) + module:hook("muc-occupant-session-new", function (event) send_avatar_hash(event.room, event.stanza.attr.from); end); module:hook("vcard-updated", function (event) local room = get_room_from_jid(event.stanza.attr.to); + room.avatar_hash = nil; send_avatar_hash(room, nil); end); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/prosody.release new/prosody-13.0.3/prosody.release --- old/prosody-13.0.2/prosody.release 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/prosody.release 2026-01-05 13:34:45.144840830 +0100 @@ -1 +1 @@ -13.0.2 +13.0.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/spec/core_storagemanager_spec.lua new/prosody-13.0.3/spec/core_storagemanager_spec.lua --- old/prosody-13.0.2/spec/core_storagemanager_spec.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/spec/core_storagemanager_spec.lua 2026-01-05 13:34:45.144840830 +0100 @@ -621,7 +621,44 @@ assert.equal(2, count); end); + it("for non-existent after id returning error", function () + do + local data, err = archive:find("user", { + ["after"] = "non-existent-id"; + }); + assert.is_falsy(data); + assert.is_equal("item-not-found", err); + end + + do + local data, err = archive:find("user", { + ["after"] = "non-existent-id"; + ["reverse"] = true; + }); + assert.is_falsy(data); + assert.is_equal("item-not-found", err); + end + end); + + it("for non-existent before id returning error", function () + do + local data, err = archive:find("user", { + ["before"] = "non-existent-id"; + }); + assert.is_falsy(data); + assert.is_equal("item-not-found", err); + end + do + local data, err = archive:find("user", { + ["before"] = "non-existent-id"; + ["reverse"] = true; + }); + assert.is_falsy(data); + assert.is_equal("item-not-found", err); + end + + end); end); @@ -791,3 +828,4 @@ end); end end); + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/spec/util_jid_spec.lua new/prosody-13.0.3/spec/util_jid_spec.lua --- old/prosody-13.0.2/spec/util_jid_spec.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/spec/util_jid_spec.lua 2026-01-05 13:34:45.144840830 +0100 @@ -64,6 +64,8 @@ test("server/resource", nil, "server", "resource" ); test("server/resource@foo", nil, "server", "resource@foo" ); test("server/resource@foo/bar", nil, "server", "resource@foo/bar"); + test("[email protected]", "node", "203.0.113.80", nil); + test("node@[2001:db8::50:726f:736f:6479]/foo", "node", "[2001:db8::50:726f:736f:6479]", "foo") -- Always invalid JIDs test(nil, nil, nil, nil); @@ -74,6 +76,9 @@ test("@server/", nil, nil, nil); test("server/", nil, nil, nil); test("/resource", nil, nil, nil); + test("xmpp:[email protected]", nil, nil, nil); + test("xmpp:example.com", nil, nil, nil); + test("[email protected])", nil, nil, nil); end); it("should reject invalid arguments", function () assert.has_error(function () jid.prepped_split(false) end) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/spec/util_roles_spec.lua new/prosody-13.0.3/spec/util_roles_spec.lua --- old/prosody-13.0.2/spec/util_roles_spec.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/spec/util_roles_spec.lua 2026-01-05 13:34:45.144840830 +0100 @@ -80,8 +80,8 @@ assert.truthy(grandchild_role:may("inherited-permission")); end); describe("supports ordered inheritance from multiple roles", function () - local parent_role = roles.new(); - local final_role = roles.new({ + local parent_role = roles and roles.new(); + local final_role = roles and roles.new({ -- Yes, the names are getting confusing. -- btw, test_role is inherited through child_role. inherits = { parent_role, child_role }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/tools/migration/prosody-migrator.lua new/prosody-13.0.3/tools/migration/prosody-migrator.lua --- old/prosody-13.0.2/tools/migration/prosody-migrator.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/tools/migration/prosody-migrator.lua 2026-01-05 13:34:45.144840830 +0100 @@ -149,6 +149,7 @@ local cm = require "prosody.core.configmanager"; local hm = require "prosody.core.hostmanager"; +local mm = require "prosody.core.modulemanager"; local sm = require "prosody.core.storagemanager"; local um = require "prosody.core.usermanager"; @@ -177,6 +178,7 @@ local function get_driver(host, conf) prepare_config(host, conf); + mm.unload(host, "storage_" .. conf.type); return assert(sm.load_driver(host, conf.type)); end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/util/datamanager.lua new/prosody-13.0.3/util/datamanager.lua --- old/prosody-13.0.2/util/datamanager.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/util/datamanager.lua 2026-01-05 13:34:45.144840830 +0100 @@ -274,7 +274,7 @@ if string.packsize then index_fmt = "T"; -- offset to the end of the item, length can be derived from two index items index_item_size = string.packsize(index_fmt); - index_magic = string.pack(index_fmt, 7767639 + 1); -- Magic string: T9 for "prosody", version number + index_magic = string.pack(index_fmt, 7767639 + 2 + index_item_size); -- Magic string: T9 for "prosody", version number end local function list_append(username, host, datastore, data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/util/jid.lua new/prosody-13.0.3/util/jid.lua --- old/prosody-13.0.2/util/jid.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/util/jid.lua 2026-01-05 13:34:45.144840830 +0100 @@ -13,6 +13,8 @@ local nodeprep = require "prosody.util.encodings".stringprep.nodeprep; local nameprep = require "prosody.util.encodings".stringprep.nameprep; local resourceprep = require "prosody.util.encodings".stringprep.resourceprep; +local idna_to_ascii = require "prosody.util.encodings".idna.to_ascii; +local net = require "prosody.util.net"; local escapes = { [" "] = "\\20"; ['"'] = "\\22"; @@ -48,6 +50,11 @@ return host; end +local function valid_ip(ip) + local v6 = match(ip, "^%[([%x:.]+)%]$"); + return net.pton(v6 or ip); +end + local function prepped_split(jid, strict) local node, host, resource = split(jid); if host ~= nil and host ~= "." then @@ -56,6 +63,7 @@ end host = nameprep(host, strict); if host == nil then return; end + if not (valid_ip(host) or idna_to_ascii(host)) then return; end if node ~= nil then node = nodeprep(node, strict); if node == nil then return; end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/util/sslconfig.lua new/prosody-13.0.3/util/sslconfig.lua --- old/prosody-13.0.2/util/sslconfig.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/util/sslconfig.lua 2026-01-05 13:34:45.144840830 +0100 @@ -120,7 +120,7 @@ if type(new) == "table" then for field, value in pairs(new) do -- exclude keys which are internal to the config builder - if field:sub(1, 1) ~= "_" then + if type(field) == "string" and field:sub(1, 1) ~= "_" then (handlers[field] or rawset)(config, field, value); end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/util/startup.lua new/prosody-13.0.3/util/startup.lua --- old/prosody-13.0.2/util/startup.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/util/startup.lua 2026-01-05 13:34:45.144840830 +0100 @@ -347,6 +347,10 @@ elseif level == "file" then log("error", "Couldn't read the config file when trying to reload: %s", err); end + prosody.events.fire_event("config-reload-failed", { + filename = prosody.config_file; + level = level; error = err; + }); else prosody.events.fire_event("config-reloaded", { filename = prosody.config_file, @@ -859,6 +863,15 @@ prosody.events.add_handler("reloading-config", function() notify_socket:send(string.format("RELOADING=1\nMONOTONIC_USEC=%d", math.floor(time.monotonic() * 1000000))); end); + prosody.events.add_handler("config-reload-failed", function(event) + if event and event.level == "parser" then + notify_socket:send(string.format("READY=1\nSTATUS=Error parsing configuration file: %s", tostring(event.error))); + elseif event and event.level == "file" then + notify_socket:send(string.format("READY=1\nSTATUS=Could not read configuration file: %s", tostring(event.error))); + else + notify_socket:send("READY=1\nSTATUS=Could not read configuration file"); + end + end); prosody.events.add_handler("config-reloaded", function() notify_socket:send("READY=1"); end); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/prosody-13.0.2/util/uuid.lua new/prosody-13.0.3/util/uuid.lua --- old/prosody-13.0.2/util/uuid.lua 2025-05-29 17:42:58.718566327 +0200 +++ new/prosody-13.0.3/util/uuid.lua 2026-01-05 13:34:45.144840830 +0100 @@ -28,15 +28,11 @@ local function generate_v7() -- Sortable based on time and random - -- https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-01#section-4.4 - local t = time.now(); - local unixts = m_floor(t); - local unixts_a = m_floor(unixts / 16); - local unixts_b = m_floor(unixts % 16); - local subsec = t % 1; - local subsec_a = m_floor(subsec * 0x1000); - local subsec_b = m_floor(subsec * 0x1000000) % 0x1000; - return ("%08x-%x%03x-7%03x-%4s-%12s"):format(unixts_a, unixts_b, subsec_a, subsec_b, get_twobits() .. get_nibbles(3), get_nibbles(12)); + -- https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-7 + local unix_ts_ms = m_floor(time.now()*1000); + local unix_ts_ms_a = m_floor(unix_ts_ms / 0x10000); + local unix_ts_ms_b = unix_ts_ms % 0x10000; + return ("%08x-%4x-7%3s-%1s%3s-%12s"):format(unix_ts_ms_a, unix_ts_ms_b, get_nibbles(3), get_twobits(), get_nibbles(3), get_nibbles(12)); end return { ++++++ prosody.service ++++++ --- /var/tmp/diff_new_pack.QsNnBD/_old 2026-01-23 17:34:55.770561382 +0100 +++ /var/tmp/diff_new_pack.QsNnBD/_new 2026-01-23 17:34:55.774561552 +0100 @@ -1,6 +1,9 @@ [Unit] -Description=Jabber/XMPP Server -After=network-online.target mysql.service +Description=Prosody XMPP Server +Documentation=https://prosody.im/doc + +Requires=network-online.target +After=network-online.target network.target mariadb.service mysql.service postgresql.service [Service] # added automatically, for details please see @@ -16,12 +19,37 @@ ProtectControlGroups=true RestrictRealtime=true # end of automatic additions -Type=forking -PIDFile=/run/prosody/prosody.pid -ExecStart=/usr/bin/prosodyctl start -ExecStop=/usr/bin/prosodyctl stop +Type=notify + +# Start by executing the main executable +ExecStart=/usr/bin/prosody -F +ExecReload=/bin/kill -HUP $MAINPID +Restart=on-abnormal + +User=prosody +Group=prosody +UMask=0027 + +RuntimeDirectory=prosody +ConfigurationDirectory=prosody +StateDirectory=prosody +StateDirectoryMode=0750 +LogsDirectory=prosody +WorkingDirectory=~ + +# Set stdin to /dev/null since Prosody does not need it +StandardInput=null + +# Direct stdout/-err to journald for use with log = "*stdout" +StandardOutput=journal +StandardError=inherit + +# Allow binding low ports +AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target Alias=org.prosody.service +# vim: filetype=systemd +
