Software /
code /
verse
Changeset
506:3610196c5e83 default tip
Merge with Zash.
author | Trần H. Trung <xmpp:trần.h.trung@trung.fun> |
---|---|
date | Sat, 08 Jul 2023 02:17:52 +0700 |
parents | 505:289c866d7fb0 (diff) 494:04c216ac429a (current diff) |
children | |
files | |
diffstat | 8 files changed, 31 insertions(+), 429 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Fri Jul 07 17:23:09 2023 +0700 +++ b/Makefile Sat Jul 08 02:17:52 2023 +0700 @@ -22,9 +22,6 @@ mkdir -p "$(@D)" wget "$(PROSODY_URL)$@" -O "$@" -rsm.lib.lua: - wget https://hg.prosody.im/prosody-0.10/raw-file/0.10.1/util/rsm.lua -O rsm.lib.lua - release: $(MISSING_FILES) rm config.unix
--- a/init.lua Fri Jul 07 17:23:09 2023 +0700 +++ b/init.lua Sat Jul 08 02:17:52 2023 +0700 @@ -152,10 +152,8 @@ verse.log("error", "Attempt to close disconnected connection - possibly a bug"); return; end - local on_disconnect = self.conn.disconnect(); self:event("shutdown"); self.conn:close(); - on_disconnect(self.conn, reason); end -- Logging functions
--- a/plugins/adhoc.lua Fri Jul 07 17:23:09 2023 +0700 +++ b/plugins/adhoc.lua Sat Jul 08 02:17:52 2023 +0700 @@ -1,5 +1,5 @@ local verse = require "verse"; -local adhoc = require "verse.lib.adhoc"; +local adhoc = require "verse.util.adhoc"; local xmlns_commands = "http://jabber.org/protocol/commands"; local xmlns_data = "jabber:x:data";
--- a/plugins/vcard.lua Fri Jul 07 17:23:09 2023 +0700 +++ b/plugins/vcard.lua Sat Jul 08 02:17:52 2023 +0700 @@ -1,5 +1,5 @@ local verse = require "verse"; -local vcard = require "prosody.util.vcard"; +local vcard = require "verse.util.vcard"; local xmlns_vcard = "vcard-temp";
--- a/squishy Fri Jul 07 17:23:09 2023 +0700 +++ b/squishy Sat Jul 08 02:17:52 2023 +0700 @@ -1,17 +1,14 @@ Output "verse.lua" -local VerseModule = Module +local function VerseModule(s) + return Module("verse."..s); +end local function ProsodyModule(s) - return VerseModule("prosody." .. s) + return Module("prosody." .. s) end function ProsodyModules() local Module = ProsodyModule; - -- Verse-specific versions of libraries - Module "util.encodings" "libs/encodings.lua" - Module "util.hashes" "libs/hashes.lua" - Module "lib.adhoc" "libs/adhoc.lib.lua" - Module "util.table" "libs/table.lua" -- Prosody libraries if not GetOption("prosody") then @@ -21,7 +18,8 @@ end Module "util.sha1" "util/sha1.lua" - Module "util.bit" "libs/bit.lua" + Module "util.bitcompat" "libs/bitcompat.lua" + Module "util.bit53" "libs/bit53.lua" Module "util.stanza" "util/stanza.lua" Module "util.timer" "util/timer.lua" @@ -44,7 +42,6 @@ Module "util.events" "util/events.lua" Module "util.dataforms" "util/dataforms.lua" Module "util.caps" "util/caps.lua" - Module "util.vcard" "util/vcard.lua" Module "util.logger" "util/logger.lua" Module "util.datetime" "util/datetime.lua" Module "util.json" "util/json.lua" @@ -65,9 +62,6 @@ Module "net.http" "net/http.lua" Module "util.x509" "util/x509.lua" - if GetOption "internal-bit-module" then - Module "bit" "libs/bit.lua" - end end ProsodyModules() @@ -118,20 +112,31 @@ } for _, plugin in ipairs(plugins) do - VerseModule("verse.plugins." .. plugin)("plugins/" .. plugin .. ".lua") + VerseModule("plugins." .. plugin)("plugins/" .. plugin .. ".lua") end -VerseModule "verse.server" "server.lua" +-- Verse-specific versions of libraries +VerseModule "util.adhoc" "libs/adhoc.lib.lua" +VerseModule "util.encodings" "libs/encodings.lua" +VerseModule "util.hashes" "libs/hashes.lua" +VerseModule "util.table" "libs/table.lua" +VerseModule "util.vcard" "util/vcard.lua" + +VerseModule "server" "server.lua" -- SASL client mechanisms -VerseModule "verse.util.sasl.scram" "util/sasl/scram.lua" -VerseModule "verse.util.sasl.plain" "util/sasl/plain.lua" -VerseModule "verse.util.sasl.anonymous" "util/sasl/anonymous.lua" -VerseModule "verse.util.sasl.oauthbearer" "util/sasl/oauthbearer.lua" +VerseModule "util.sasl.scram" "util/sasl/scram.lua" +VerseModule "util.sasl.plain" "util/sasl/plain.lua" +VerseModule "util.sasl.anonymous" "util/sasl/anonymous.lua" +VerseModule "util.sasl.oauthbearer" "util/sasl/oauthbearer.lua" -VerseModule "verse.client" "client.lua" -VerseModule "verse.component" "component.lua" -VerseModule "verse.bosh" "bosh.lua" +VerseModule "client" "client.lua" +VerseModule "component" "component.lua" +VerseModule "bosh" "bosh.lua" + +if GetOption "internal-bit-module" then + Module "bit" "libs/bit.lua" +end -- Main verse file Main "init.lua"
--- a/util/dataforms.lua Fri Jul 07 17:23:09 2023 +0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,398 +0,0 @@ --- Prosody IM --- Copyright (C) 2008-2010 Matthew Wild --- Copyright (C) 2008-2010 Waqas Hussain --- --- This project is MIT/X11 licensed. Please see the --- COPYING file in the source package for more information. --- - -local setmetatable = setmetatable; -local ipairs = ipairs; -local type, next = type, next; -local tonumber = tonumber; -local tostring = tostring; -local t_concat = table.concat; -local st = require "prosody.util.stanza"; -local jid_prep = require "prosody.util.jid".prep; - -local _ENV = nil; --- luacheck: std none - -local xmlns_forms = 'jabber:x:data'; -local xmlns_validate = 'http://jabber.org/protocol/xdata-validate'; - -local form_t = {}; -local form_mt = { __index = form_t }; - -local function new(layout) - return setmetatable(layout, form_mt); -end - -local function from_stanza(stanza) - local layout = { - title = stanza:get_child_text("title"); - instructions = stanza:get_child_text("instructions"); - }; - for tag in stanza:childtags("field") do - local field = { - name = tag.attr.var; - label = tag.attr.label; - type = tag.attr.type; - required = tag:get_child("required") and true or nil; - value = tag:get_child_text("value"); - }; - layout[#layout+1] = field; - if field.type then - local value = {}; - if field.type:match"list%-" then - for tag in tag:childtags("option") do - value[#value+1] = { label = tag.attr.label, value = tag:get_child_text("value") }; - end - for tag in tag:childtags("value") do - value[#value+1] = { label = tag.attr.label, value = tag:get_text(), default = true }; - end - elseif field.type:match"%-multi" then - for tag in tag:childtags("value") do - value[#value+1] = tag.attr.label and { label = tag.attr.label, value = tag:get_text() } or tag:get_text(); - end - if field.type == "text-multi" then - field.value = t_concat(value, "\n"); - else - field.value = value; - end - end - end - local datatype_tag = tag:get_child("validate", xmlns_validate); - if datatype_tag then - field.datatype = datatype.attr.datatype; - local range_tag = datatype_tag:get_child("range"); - if range_tag then - field.range_min = tonumber(range_tag.attr.min); - field.range_max = tonumber(range_tag.attr.max); - end - end - - end - return new(layout); -end - -function form_t.form(layout, data, formtype) - if not formtype then formtype = "form" end - local form = st.stanza("x", { xmlns = xmlns_forms, type = formtype }); - if formtype == "cancel" then - return form; - end - if formtype ~= "submit" then - if layout.title then - form:tag("title"):text(layout.title):up(); - end - if layout.instructions then - form:tag("instructions"):text(layout.instructions):up(); - end - end - for _, field in ipairs(layout) do - local field_type = field.type or "text-single"; - -- Add field tag - form:tag("field", { type = field_type, var = field.var or field.name, label = formtype ~= "submit" and field.label or nil }); - - if formtype ~= "submit" then - if field.desc then - form:text_tag("desc", field.desc); - end - end - - if formtype == "form" and field.datatype then - form:tag("validate", { xmlns = xmlns_validate, datatype = field.datatype }); - if field.range_min or field.range_max then - form:tag("range", { - min = field.range_min and tostring(field.range_min), - max = field.range_max and tostring(field.range_max), - }):up(); - end - -- <basic/> assumed - form:up(); - end - - - local value = field.value; - local options = field.options; - - if data and data[field.name] ~= nil then - value = data[field.name]; - - if formtype == "form" and type(value) == "table" - and (field_type == "list-single" or field_type == "list-multi") then - -- Allow passing dynamically generated options as values - options, value = value, nil; - end - end - - if formtype == "form" and options then - local defaults = {}; - for _, val in ipairs(options) do - if type(val) == "table" then - form:tag("option", { label = val.label }):tag("value"):text(val.value):up():up(); - if val.default then - defaults[#defaults+1] = val.value; - end - else - form:tag("option", { label= val }):tag("value"):text(val):up():up(); - end - end - if not value then - if field_type == "list-single" then - value = defaults[1]; - elseif field_type == "list-multi" then - value = defaults; - end - end - end - - if value ~= nil then - if type(value) == "number" then - -- TODO validate that this is ok somehow, eg check field.datatype - value = ("%g"):format(value); - end - -- Add value, depending on type - if field_type == "hidden" then - if type(value) == "table" then - -- Assume an XML snippet - form:tag("value") - :add_child(value) - :up(); - else - form:tag("value"):text(value):up(); - end - elseif field_type == "boolean" then - form:tag("value"):text((value and "1") or "0"):up(); - elseif field_type == "fixed" then - form:tag("value"):text(value):up(); - elseif field_type == "jid-multi" then - for _, jid in ipairs(value) do - form:tag("value"):text(jid):up(); - end - elseif field_type == "jid-single" then - form:tag("value"):text(value):up(); - elseif field_type == "text-single" or field_type == "text-private" then - form:tag("value"):text(value):up(); - elseif field_type == "text-multi" then - -- Split into multiple <value> tags, one for each line - for line in value:gmatch("([^\r\n]+)\r?\n*") do - form:tag("value"):text(line):up(); - end - elseif field_type == "list-single" then - form:tag("value"):text(value):up(); - elseif field_type == "list-multi" then - for _, val in ipairs(value) do - form:tag("value"):text(val):up(); - end - end - end - - local media = field.media; - if media then - form:tag("media", { xmlns = "urn:xmpp:media-element", height = ("%g"):format(media.height), width = ("%g"):format(media.width) }); - for _, val in ipairs(media) do - form:tag("uri", { type = val.type }):text(val.uri):up() - end - form:up(); - end - - if formtype == "form" and field.required then - form:tag("required"):up(); - end - - -- Jump back up to list of fields - form:up(); - end - return form; -end - -local field_readers = {}; -local data_validators = {}; - -function form_t.data(layout, stanza, current) - local data = {}; - local errors = {}; - local present = {}; - - for _, field in ipairs(layout) do - local tag; - for field_tag in stanza:childtags("field") do - if (field.var or field.name) == field_tag.attr.var then - tag = field_tag; - break; - end - end - - if not tag then - if current and current[field.name] ~= nil then - data[field.name] = current[field.name]; - elseif field.required then - errors[field.name] = "Required value missing"; - end - elseif field.name then - present[field.name] = true; - local reader = field_readers[field.type]; - if reader then - local value, err = reader(tag, field.required); - local validator = field.datatype and data_validators[field.datatype]; - if value ~= nil and validator then - local valid, ret = validator(value, field); - if valid then - value = ret; - else - value, err = nil, ret or ("Invalid value for data of type " .. field.datatype); - end - end - data[field.name], errors[field.name] = value, err; - end - end - end - if next(errors) then - return data, errors, present; - end - return data, nil, present; -end - -local function simple_text(field_tag, required) - local data = field_tag:get_child_text("value"); - -- XEP-0004 does not say if an empty string is acceptable for a required value - -- so we will follow HTML5 which says that empty string means missing - if required and (data == nil or data == "") then - return nil, "Required value missing"; - end - return data; -- Return whatever get_child_text returned, even if empty string -end - -field_readers["text-single"] = simple_text; - -field_readers["text-private"] = simple_text; - -field_readers["jid-single"] = - function (field_tag, required) - local raw_data, err = simple_text(field_tag, required); - if not raw_data then return raw_data, err; end - local data = jid_prep(raw_data); - if not data then - return nil, "Invalid JID: " .. raw_data; - end - return data; - end - -field_readers["jid-multi"] = - function (field_tag, required) - local result = {}; - local err = {}; - for value_tag in field_tag:childtags("value") do - local raw_value = value_tag:get_text(); - local value = jid_prep(raw_value); - result[#result+1] = value; - if raw_value and not value then - err[#err+1] = ("Invalid JID: " .. raw_value); - end - end - if #result > 0 then - return result, (#err > 0 and t_concat(err, "\n") or nil); - elseif required then - return nil, "Required value missing"; - end - end - -field_readers["list-multi"] = - function (field_tag, required) - local result = {}; - for value in field_tag:childtags("value") do - result[#result+1] = value:get_text(); - end - if #result > 0 then - return result; - elseif required then - return nil, "Required value missing"; - end - end - -field_readers["text-multi"] = - function (field_tag, required) - local data, err = field_readers["list-multi"](field_tag, required); - if data then - data = t_concat(data, "\n"); - end - return data, err; - end - -field_readers["list-single"] = simple_text; - -local boolean_values = { - ["1"] = true, ["true"] = true, - ["0"] = false, ["false"] = false, -}; - -field_readers["boolean"] = - function (field_tag, required) - local raw_value, err = simple_text(field_tag, required); - if not raw_value then return raw_value, err; end - local value = boolean_values[raw_value]; - if value == nil then - return nil, "Invalid boolean representation:" .. raw_value; - end - return value; - end - -field_readers["hidden"] = - function (field_tag) - return field_tag:get_child_text("value"); - end - -data_validators["xs:integer"] = - function (data, field) - local n = tonumber(data); - if not n then - return false, "not a number"; - elseif n % 1 ~= 0 then - return false, "not an integer"; - end - if field.range_max and n > field.range_max then - return false, "out of bounds"; - elseif field.range_min and n < field.range_min then - return false, "out of bounds"; - end - return true, n; - end - - -local function get_form_type(form) - if not st.is_stanza(form) then - return nil, "not a stanza object"; - elseif form.attr.xmlns ~= "jabber:x:data" or form.name ~= "x" then - return nil, "not a dataform element"; - end - for field in form:childtags("field") do - if field.attr.var == "FORM_TYPE" then - return field:get_child_text("value"); - end - end - return ""; -end - -return { - new = new; - from_stanza = from_stanza; - get_type = get_form_type; -}; - - ---[=[ - -Layout: -{ - - title = "MUC Configuration", - instructions = [[Use this form to configure options for this MUC room.]], - - { name = "FORM_TYPE", type = "hidden", required = true }; - { name = "field-name", type = "field-type", required = false }; -} - - ---]=]
--- a/util/sasl/oauthbearer.lua Fri Jul 07 17:23:09 2023 +0700 +++ b/util/sasl/oauthbearer.lua Sat Jul 08 02:17:52 2023 +0700 @@ -1,9 +1,9 @@ return function (stream, name) - if name == "OAUTHBEARER" and stream.username then + if name == "OAUTHBEARER" then return function (stream) local auth = stream.bearer_token and ("Bearer "..stream.bearer_token) or ""; - local message, data = coroutine.yield("n,a="..stream.username.."@"..stream.host..",\001auth="..auth.."\001"); + local message, data = coroutine.yield("n,,\001auth="..auth.."\001\001"); if message == "success" then return true; elseif message == "challenge" then
--- a/util/sha1.lua Fri Jul 07 17:23:09 2023 +0700 +++ b/util/sha1.lua Sat Jul 08 02:17:52 2023 +0700 @@ -13,7 +13,7 @@ local strbyte = string.byte local strsub = string.sub local floor = math.floor -local bit = bit32 or require "prosody.util.bit" +local bit = require "prosody.util.bitcompat" local bnot = bit.bnot local band = bit.band local bor = bit.bor