# HG changeset patch # User Matthew Wild # Date 1602242386 -3600 # Node ID 9127fa98ee1e798679b9ba58aab0cd381c6815e8 # Parent ad9ce675088095cdbb558721301c33c0ae368357 mod_welcome_page: New module to provide a friendly entrypoint to invite-based setups diff -r ad9ce6750880 -r 9127fa98ee1e mod_welcome_page/README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_welcome_page/README.markdown Fri Oct 09 12:19:46 2020 +0100 @@ -0,0 +1,47 @@ +--- +labels: +- 'Stage-Beta' +summary: 'Serve a welcome page to users' +rockspec: + dependencies: + - mod_invites + build: + copy_directories: + - html +... + +Introduction +============ + +This module serves a welcome page to users, and allows them to create an +account invite via the web on invite-only servers. + +The page template and policy of when to allow account creation are both +possible to override. + +This module is part of the suite of modules that implement invite-based +account registration for Prosody. The other modules are: + +- mod_invites +- mod_invites_adhoc +- mod_invites_page +- mod_invites_register +- mod_invites_register_web +- mod_register_apps + +For details and a full overview, start with the mod_invites documentation. + +Configuration +======= + +`welcome_page_template_path` +: The path to a directory containing the page templates and assets. See + the module source for the example template. + +`welcome_page_variables` +: Optional variables to pass to the template, available as `{var.name}` + +`welcome_page_open_registration` +: Whether to allow account creation in the absence of any other plugin + overriding the policy. Defaults to `false` unless `registration_invite_only` + is set to `false`. diff -r ad9ce6750880 -r 9127fa98ee1e mod_welcome_page/html/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_welcome_page/html/index.html Fri Oct 09 12:19:46 2020 +0100 @@ -0,0 +1,57 @@ + + + + + + {site_name} + + + + + + + + + + + +
+ +
+

{site_name}

+

Welcome to our chat service

+
+

{site_name} is an XMPP chat service.

+ + {message&} + +
+ +
+ + {var.links&{var.links# + {item.text} + }} + + {var.webchat&

Already have an account here? Log in via the web chat

} +
+ + + + + diff -r ad9ce6750880 -r 9127fa98ee1e mod_welcome_page/mod_welcome_page.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_welcome_page/mod_welcome_page.lua Fri Oct 09 12:19:46 2020 +0100 @@ -0,0 +1,71 @@ +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 template_path = module:get_option_string("welcome_page_template_path", module:get_directory().."/html"); +local user_vars = module:get_option("welcome_page_variables", {}); +local site_name = module:get_option("site_name", module.host); +local invite_only = module:get_option_boolean("registration_invite_only", true); +local open_registration = module:get_option_boolean("welcome_page_open_registration", not invite_only); + +module:depends("http"); +local invites = module:depends("invites"); + +local function load_template(path) + local template_file, err = io.open(path); + if not template_file then + error("Unable to load template file: "..tostring(err)); + end + local template = template_file:read("*a"); + template_file:close(); + return template; +end + +local template = load_template(template_path.."/index.html"); + +local function serve_page(event) + event.response.headers["Content-Type"] = "text/html; charset=utf-8"; + return render_html_template(template, { + site_name = site_name; + request = event.request; + var = user_vars; + }); +end + +local function handle_submit(event) + local submission = { allowed = open_registration, request = event.request }; + module:fire_event("mod_welcome_page/submission", submission); + if not submission.allowed then + event.response.headers["Content-Type"] = "text/html; charset=utf-8"; + return render_html_template(template, { + site_name = site_name; + request = event.request; + var = user_vars; + message = { + class = "alert-danger"; + text = submission.reason or "Account creation is not possible at this time"; + }; + }); + end + + local invite = invites.create_account(nil, { source = module.name }); + if not invite then + return 500; + end + + event.response.headers.Location = invite.landing_page or invite.uri; + + return 303; +end + +local http_files = module:depends("http_files"); + +module:provides("http", { + route = { + ["GET"] = serve_page; + ["GET /*"] = http_files.serve({ path = template_path }); + ["POST"] = handle_submit; + }; +});