--- a/mod_server_info/README.md Fri Feb 23 13:02:33 2024 +0000
+++ b/mod_server_info/README.md Fri Feb 23 22:47:05 2024 +0000
@@ -14,37 +14,52 @@
Everything configured here is publicly visible to other XMPP entities.
+**Note:** This module was rewritten in February 2024, the configuration is not
+compatible with the previous version of the module.
+
## Configuration
-The `server_info` option accepts a list of dataforms. A dataform is an array
-of fields. A field has three required properties:
+The `server_info_extensions` option accepts a list of custom fields to include
+in the server info form.
+
+A field has three required properties:
- `type` - usually `text-single` or `list-multi`
-- `var` - the field name
+- `var` - the field name (see below)
- `value` the field value
Example configuration:
``` lua
server_info = {
-
- -- Our custom form
- {
- -- Conventionally XMPP dataforms have a 'FORM_TYPE' field to
- -- indicate what type of form it is
- { type = "hidden", var = "FORM_TYPE", value = "urn:example:foo" };
+ -- Advertise that our maximum speed is 88 mph
+ { type = "text-single", var = "speed", value = "88" };
- -- Advertise that our maximum speed is 88 mph
- { type = "text-single", var = "speed", value = "88" };
-
- -- Advertise that the time is 1:20 AM and zero seconds
- { type = "text-single", var = "time", value = "01:21:00" };
- };
-
+ -- Advertise that the time is 1:20 AM and zero seconds
+ { type = "text-single", var = "time", value = "01:21:00" };
}
```
+The `var` attribute is used to uniquely identify fields. Every `var` should be
+registered with the XSF [form registry](https://xmpp.org/registrar/formtypes.html#http:--jabber.org-network-serverinfo),
+or prefixed with a custom namespace using Clark notation, e.g. `{https://example.com}my-field-name`. This is to prevent
+collisions.
+
+## Developers
+
+Developers of other modules can add fields to the form at runtime:
+
+```lua
+module:depends("server_info");
+
+module:add_item("server-info-fields", {
+ { type = "text-single", var = "speed", value = "88" };
+ { type = "text-single", var = "time", value = "01:21:00" };
+});
+```
+
+Prosody will ensure they are removed if your module is unloaded.
+
## Compatibility
-This module should be compatible with Prosody 0.12, and possibly earlier
-versions.
+This module should be compatible with Prosody 0.12 and later.
--- a/mod_server_info/mod_server_info.lua Fri Feb 23 13:02:33 2024 +0000
+++ b/mod_server_info/mod_server_info.lua Fri Feb 23 22:47:05 2024 +0000
@@ -1,18 +1,60 @@
--- XEP-0128: Service Discovery Extensions (manual config)
---
--- Copyright (C) 2023 Matthew Wild
---
--- This project is MIT/X11 licensed. Please see the
--- COPYING file in the source package for more information.
---
+-- mod_server_info imported from Prosody commit 1ce18cb3e6cc for the benefit
+-- of 0.12 deployments. This community version of the module will not load in
+-- newer Prosody versions, which include their own copy of the module.
+--% conflicts: mod_server_info
+
+local dataforms = require "prosody.util.dataforms";
+
+local server_info_config = module:get_option("server_info", {});
+local server_info_custom_fields = module:get_option_array("server_info_extensions");
-local dataforms = require "util.dataforms";
-
-local config = module:get_option("server_info");
+-- Source: http://xmpp.org/registrar/formtypes.html#http:--jabber.org-network-serverinfo
+local form_layout = dataforms.new({
+ { var = "FORM_TYPE"; type = "hidden"; value = "http://jabber.org/network/serverinfo" };
+});
-if not config or next(config) == nil then return; end -- Nothing to do
-
-for _, form in ipairs(config) do
- module:add_extension(dataforms.new(form):form({}, "result"));
+if server_info_custom_fields then
+ for _, field in ipairs(server_info_custom_fields) do
+ table.insert(form_layout, field);
+ end
end
+local generated_form;
+
+function update_form()
+ local new_form = form_layout:form(server_info_config, "result");
+ if generated_form then
+ module:remove_item("extension", generated_form);
+ end
+ generated_form = new_form;
+ module:add_item("extension", generated_form);
+end
+
+function add_fields(event)
+ local fields = event.item;
+ for _, field in ipairs(fields) do
+ table.insert(form_layout, field);
+ end
+ update_form();
+end
+
+function remove_fields(event)
+ local removed_fields = event.item;
+ for _, removed_field in ipairs(removed_fields) do
+ local removed_var = removed_field.var or removed_field.name;
+ for i, field in ipairs(form_layout) do
+ local var = field.var or field.name
+ if var == removed_var then
+ table.remove(form_layout, i);
+ break;
+ end
+ end
+ end
+ update_form();
+end
+
+module:handle_items("server-info-fields", add_fields, remove_fields);
+
+function module.load()
+ update_form();
+end