# HG changeset patch # User Trần H. Trung # Date 1740566174 -25200 # Node ID 05125c29fd673a109ee0f76cf6459687b724e2eb # Parent abd1bbe5006e6cf20051a5ea2a35b20681a4d83f mod_invites_webgen: initial release diff -r abd1bbe5006e -r 05125c29fd67 mod_invites_webgen/README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_invites_webgen/README.markdown Wed Feb 26 17:36:14 2025 +0700 @@ -0,0 +1,61 @@ +--- +labels: +- 'Stage-Alpha' +summary: 'Enable create invitations via the web' +... + +Introduction +============ + +Not every client would implement the create invitation feature. Thus, this +module allows users to create new invites from the server's website. + +Details +======= + +The invitation will create account-and-contact invites (the "add to roster" +kind of invite). Once user have sucessfully enter their credential, the module +redirect them to the invite page. + +It depends on these module and their purpose: + +- [mod_http]: for obvious reason :). +- [mod_invites][doc:modules:mod_invites]: generate the actual invite. +- [mod_invites_register_web][doc:modules:mod_invites_register]: serve the + invite page. + +Configuration +============= + +The configuration utilizes the same `allow_user_invites` and +`allow_contact_invites` as [mod_invites_adhoc]. + +If you specify a `site_name`, it will uses that else it will fallback to the +`VirtualHost` that it was loaded onto. + +You can use your own html templates with `invites_template_html`. Names of the +files MUST match the default. More over, you can offer multiple (human) +languages by adding the `&l=` to the URL. Meaning this module will serve +`register.html` for your default URL: +``` + + https://prosody.example.net/?=aowiefjoaij + +``` + +And if you have a `register.en.html` in the directory you have specified in +your config file, it will be served at: +``` + + https://prosody.example.net/?=aowiefjoaij&l=en + +``` + +So in your `register.html`, you can point to the English version by using an +`` tag like this: +``` + + English + +``` + diff -r abd1bbe5006e -r 05125c29fd67 mod_invites_webgen/html/webgen.en.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_invites_webgen/html/webgen.en.html Wed Feb 26 17:36:14 2025 +0700 @@ -0,0 +1,119 @@ + + + + + +Register + + + + + + + + + + + +
+ +
+
+ +

Register

+ +

« tiếng Việt »

+ +

To register for a account +@{site_name}, you need an invite.

+ +

To generate an invite with your account, you can authenticate below:

+ +
+ + + + + ++++ + + + + + + + + + + + + + + +
…{message&{message}!}
UsernamePassword
+

@{site_name} +

+

+

+

+ +

+
+ +
+ +

If you're new to XMPP and yet to know anybody, contact me.

+ +

~*~

+ +
+
+ +
+ + + + diff -r abd1bbe5006e -r 05125c29fd67 mod_invites_webgen/html/webgen.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_invites_webgen/html/webgen.html Wed Feb 26 17:36:14 2025 +0700 @@ -0,0 +1,121 @@ + + + + + +Đăng Ký + + + + + + + + + + + +
+ +
+
+ +

Đăng Ký

+ +

« English »

+ +

Để đăng ký tài khoản +@{site_name}, bạn cần có lời mời.

+ +

Để tạo lời mời với tài khoản của mình, bạn có thể xác danh dưới đây:

+ +
+ + + + + ++++ + + + + + + + + + + + + + + + +
…{message&{message}!}
Tên Đăng NhậpMật Khẩu
+

@{site_name} +

+

+

+

+ +

+
+ +
+ +

Nếu XMPP còn mới và bạn chưa quen ai, hãy liên lạc.

+ +

~*~

+ +
+
+ + +
+ + + + diff -r abd1bbe5006e -r 05125c29fd67 mod_invites_webgen/mod_invites_webgen.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_invites_webgen/mod_invites_webgen.lua Wed Feb 26 17:36:14 2025 +0700 @@ -0,0 +1,94 @@ +local http_formdecode = require "net.http".formdecode; +local usermanager = require "core.usermanager"; +local nodeprep = require "util.encodings".stringprep.nodeprep; +local st = require "util.stanza"; +local url_escape = require "util.http".urlencode; +local render_html_template = require "util.interpolation".new("%b{}", st.xml_escape, { + urlescape = url_escape; +}); + +local site_name = module:get_option_string("site_name", module.host); + +local invites = module:depends("invites"); +--local template_get = module:depends("invites_page").template_get; + +local templatePath = module:get_option_string("invites_template_html", "html"); +function template_get(filename, lang) + local template = lang and templatePath.."/"..filename.."."..lang..".html" + or templatePath.."/"..filename..".html"; + return assert(module:load_resource(template):read("*a")); +end + + +module:depends("http"); + +local default_path, lang; + +local function serve_webgen(event) + local query_params = event.request.url.query and http_formdecode(event.request.url.query); + lang = query_params and query_params.l; + + local webgen_template = template_get("webgen", lang); + event.response.headers["Content-Type"] = "text/html; charset=utf-8"; + + local webgen = render_html_template(webgen_template, { + site_name = site_name; + }); + return webgen; +end + +module:depends("invites_register_web"); + +local function handle_webgen(event) + local request, response = event.request, event.response; + local form_data = http_formdecode(request.body); + local username, password = form_data["username"], form_data["password"]; + + event.response.headers["Content-Type"] = "text/html; charset=utf-8"; + + local webgen_template = template_get("webgen", lang); + local htmlPath = module:http_url("webgen", "/webgen"); + + if not username or #username == 0 or not password or #password == 0 then + return render_html_template(webgen_template, { + site_name = site_name; + path = htmlPath; + msg_class = "alert-warning"; + message = "Please fill in all fields."; + }); + end + + local prepped_username = nodeprep(username); + local exists = usermanager.user_exists(prepped_username, module.host); + local pass = usermanager.test_password(prepped_username, module.host, password); + local allow_user = module:get_option_boolean("allow_user_invites", false); + local allow_contact = module:get_option_boolean("allow_contact_invites", false); + + local invite; + if exists and pass and allow_user and allow_contact then + invite = invites.create_contact(username, true, { source = "webgen" }); + else + return render_html_template(webgen_template, { + site_name = site_name; + path = htmlPath; + username = username; + msg_class = "alert-warning"; + message = "Invalid input!"; + }); + end + + if not invite then + return 500; + else + event.response.headers.Location = invite.landing_page or invite.uri; + return 303; + end +end + +module:provides("http", { + default_path = "webgen"; + route = { + ["GET"] = serve_webgen; + ["POST"] = handle_webgen; + }; +});