Software /
code /
prosody
Changeset
13721:8170dd8f370c
Merge 13.0->trunk
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sun, 16 Feb 2025 13:44:23 +0000 |
parents | 13716:953108962cd0 (current diff) 13720:c3c4281c1339 (diff) |
children | 13724:650f3869de82 |
files | |
diffstat | 7 files changed, 130 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGES Sun Feb 16 11:57:18 2025 +0100 +++ b/CHANGES Sun Feb 16 13:44:23 2025 +0000 @@ -62,6 +62,7 @@ - Method for retrieving integer settings from config - It is now easy for modules to expose a Prosody shell command, by adding a shell-command item - Modules can now implement a module.ready method which will be called after server initialization +- module:depends() now accepts a second parameter 'soft' to enable soft dependencies ### Configuration @@ -84,6 +85,7 @@ - Support for systemd socket activation in server_epoll - mod_invites_adhoc gained a command for creating password resets - mod_cloud_notify imported from community modules for push notification support +- mod_http_altconnect imported from community modules, simplifying web clients ## Removed
--- a/core/features.lua Sun Feb 16 11:57:18 2025 +0100 +++ b/core/features.lua Sun Feb 16 13:44:23 2025 +0000 @@ -12,6 +12,8 @@ "mod_cloud_notify"; -- mod_muc has built-in vcard support "muc_vcard"; + -- mod_http_altconnect bundled + "http_altconnect"; -- Roles, module.may and per-session authz "permissions"; -- prosody.* namespace
--- a/core/moduleapi.lua Sun Feb 16 11:57:18 2025 +0100 +++ b/core/moduleapi.lua Sun Feb 16 13:44:23 2025 +0000 @@ -136,10 +136,14 @@ return f(); end -function api:depends(name) +function api:depends(name, soft) local modulemanager = require"prosody.core.modulemanager"; if self:get_option_inherited_set("modules_disabled", {}):contains(name) then - error("Dependency on disabled module mod_"..name); + if not soft then + error("Dependency on disabled module mod_"..name); + end + self:log("debug", "Not loading disabled soft dependency mod_%s", name); + return nil, "disabled"; end if not self.dependencies then self.dependencies = {};
--- a/plugins/mod_bosh.lua Sun Feb 16 11:57:18 2025 +0100 +++ b/plugins/mod_bosh.lua Sun Feb 16 13:44:23 2025 +0000 @@ -557,6 +557,8 @@ ["POST /"] = handle_POST; }; }); + + module:depends("http_altconnect", true); end if require"prosody.core.modulemanager".get_modules_for_host("*"):contains(module.name) then
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/mod_http_altconnect.lua Sun Feb 16 13:44:23 2025 +0000 @@ -0,0 +1,52 @@ +-- mod_http_altconnect +-- XEP-0156: Discovering Alternative XMPP Connection Methods + +module:depends"http"; + +local mm = require "prosody.core.modulemanager"; +local json = require"prosody.util.json"; +local st = require"prosody.util.stanza"; +local array = require"prosody.util.array"; + +local advertise_bosh = module:get_option_boolean("advertise_bosh", true); +local advertise_websocket = module:get_option_boolean("advertise_websocket", true); + +local function get_supported() + local uris = array(); + if advertise_bosh and (mm.is_loaded(module.host, "bosh") or mm.is_loaded("*", "bosh")) then + uris:push({ rel = "urn:xmpp:alt-connections:xbosh", href = module:http_url("bosh", "/http-bind") }); + end + if advertise_websocket and (mm.is_loaded(module.host, "websocket") or mm.is_loaded("*", "websocket")) then + uris:push({ rel = "urn:xmpp:alt-connections:websocket", href = module:http_url("websocket", "xmpp-websocket"):gsub("^http", "ws") }); + end + return uris; +end + + +local function GET_xml(event) + local response = event.response; + local xrd = st.stanza("XRD", { xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0' }); + local uris = get_supported(); + for _, method in ipairs(uris) do + xrd:tag("Link", method):up(); + end + response.headers.content_type = "application/xrd+xml" + response.headers.access_control_allow_origin = "*"; + return '<?xml version="1.0" encoding="UTF-8"?>' .. tostring(xrd); +end + +local function GET_json(event) + local response = event.response; + local jrd = { links = get_supported() }; + response.headers.content_type = "application/json" + response.headers.access_control_allow_origin = "*"; + return json.encode(jrd); +end; + +module:provides("http", { + default_path = "/.well-known"; + route = { + ["GET /host-meta"] = GET_xml; + ["GET /host-meta.json"] = GET_json; + }; +});
--- a/plugins/mod_websocket.lua Sun Feb 16 11:57:18 2025 +0100 +++ b/plugins/mod_websocket.lua Sun Feb 16 13:44:23 2025 +0000 @@ -367,6 +367,8 @@ }; }); + module:depends("http_altconnect", true); + module:hook("c2s-read-timeout", keepalive, -0.9); end
--- a/util/prosodyctl/check.lua Sun Feb 16 11:57:18 2025 +0100 +++ b/util/prosodyctl/check.lua Sun Feb 16 13:44:23 2025 +0000 @@ -1486,6 +1486,10 @@ muc = "groups"; }; + local recommended_component_modules = { + muc = { "muc_mam" }; + }; + local function print_feature_status(feature, host) if quiet then return; end print("", feature.ok and "OK" or "(!)", feature.name); @@ -1501,11 +1505,20 @@ table.sort(feature.lacking_components); for _, component_module in ipairs(feature.lacking_components) do local subdomain = common_subdomains[component_module]; + local recommended_mods = recommended_component_modules[component_module]; if subdomain then print("", "", "Suggested component:"); print(""); + print("", "", "", ("-- Documentation: https://prosody.im/doc/modules/mod_%s"):format(component_module)); print("", "", "", ("Component %q %q"):format(subdomain.."."..host, component_module)); - print("", "", "", ("-- Documentation: https://prosody.im/doc/modules/mod_%s"):format(component_module)); + if recommended_mods then + print("", "", "", " modules_enabled = {"); + table.sort(recommended_mods); + for _, mod in ipairs(recommended_mods) do + print("", "", "", (" %q;"):format(mod)); + end + print("", "", "", " }"); + end else print("", "", ("Suggested component: %s"):format(component_module)); end @@ -1514,6 +1527,30 @@ print("", "", "If you have already configured any these components, they may not be"); print("", "", "linked correctly to "..host..". For more info see https://prosody.im/doc/components"); end + if feature.lacking_component_modules then + table.sort(feature.lacking_component_modules, function (a, b) + return a.host < b.host; + end); + for _, problem in ipairs(feature.lacking_component_modules) do + local hostapi = api(problem.host); + local current_modules_enabled = hostapi:get_option_array("modules_enabled", {}); + print("", "", ("Component %q is missing the following modules: %s"):format(problem.host, table.concat(problem.missing_mods))); + print(""); + print("","", "Add the missing modules to your modules_enabled under the Component, like this:"); + print(""); + print(""); + print("", "", "", ("-- Documentation: https://prosody.im/doc/modules/mod_%s"):format(problem.component_module)); + print("", "", "", ("Component %q %q"):format(problem.host, problem.component_module)); + print("", "", "", (" modules_enabled = {")); + for _, mod in ipairs(current_modules_enabled) do + print("", "", "", (" %q;"):format(mod)); + end + for _, mod in ipairs(problem.missing_mods) do + print("", "", "", (" %q; -- Add this!"):format(mod)); + end + print("", "", "", (" }")); + end + end end print(""); end @@ -1572,8 +1609,27 @@ local function check_component(suggested, alternate, ...) local found; for _, component_module in ipairs({ suggested, alternate, ... }) do - found = #host_components[component_module] > 0; - if found then break; end + found = host_components[component_module][1]; + if found then + local enabled_component_modules = api(found):get_option_inherited_set("modules_enabled"); + local recommended_mods = recommended_component_modules[component_module]; + local missing_mods = {}; + for _, mod in ipairs(recommended_mods) do + if not enabled_component_modules:contains(mod) then + table.insert(missing_mods, mod); + end + end + if #missing_mods > 0 then + if not current_feature.lacking_component_modules then + current_feature.lacking_component_modules = {}; + end + table.insert(current_feature.lacking_component_modules, { + host = found; + component_module = component_module; + missing_mods = missing_mods; + }); + end + end end if not found then current_feature.lacking_components = current_feature.lacking_components or {}; @@ -1664,7 +1720,11 @@ for _, feature in ipairs(features) do current_feature = feature; feature.check(); - feature.ok = not feature.lacking_modules and not feature.lacking_components; + feature.ok = ( + not feature.lacking_modules and + not feature.lacking_components and + not feature.lacking_component_modules + ); -- For improved presentation, we group the (ok) and (not ok) features if feature.ok then print_feature_status(feature, host);