How to install Prosody using Tiki for its userlist
Prosody is a lightweight and modular XMPP (Jabber) server.
This page describes how an instance of Prosody can be set up in such a way that it will make use of the Tiki database as its identity provider (IdP) for:
- Users
- Groups
- Authentication
It also shows how to expose anonymous chat for visitors (via Converse.js), and auto-join registered Tiki users to specific group chatrooms.
Note that this is a specialized setup, and comes with some challenges.
Preparation / Assumptions
- A working instance of Tiki is available. This guide assumes Tiki stores its own users, groups and permissions in its database (default). It has not been tested with setups using LDAP, Shibboleth, etc.
- Prosody is installed on GNU/Linux (Debian/Ubuntu recommended).
- Domains used in this guide:
-
xmpp.example.org→ registered users (authenticated via Tiki) -
guest.example.org→ anonymous visitors -
conference.example.org→ MUC component (group chatrooms)
-
- DNS (A/AAAA + SRV) and Let’s Encrypt certificates are set up for these hosts.
- An administrative account in Tiki is available.
1) Install Prosody
Obtain and install Prosody from your package manager or the official repository.
- Debian/Ubuntu:
sudo apt update sudo apt install prosody sudo systemctl enable --now prosody
Verify installation:
sudo prosodyctl check config sudo prosodyctl about
Always restart after editing:
sudo systemctl restart prosody sudo systemctl status prosody
1.1. Install community modules (for HTTP auth)
Prosody’s HTTP auth comes from the community module mod_auth_http (community modules repo).
# Common prerequisites (adjust to your distro): sudo apt install lua-sec mercurial -y # Clone community modules (place under /usr/local/lib/prosody) sudo mkdir -p /usr/local/lib/prosody cd /usr/local/lib/prosody sudo hg clone https://hg.prosody.im/prosody-modules/ modules # Alternative (git mirror) # sudo git clone https://github.com/bjc/prosody-modules /usr/local/lib/prosody/modules
In /etc/prosody/prosody.cfg.lua add:
plugin_paths = { "/usr/local/lib/prosody/modules" }
This enables authentication = "http" later.
2) TLS Certificates
Using Let’s Encrypt for production:
sudo apt install certbot -y sudo certbot certonly --standalone \ -d xmpp.example.org \ -d guest.example.org \ -d conference.example.org # Import certificates into Prosody’s cert store sudo prosodyctl --root cert import /etc/letsencrypt/live
If your Tiki site is already running under Apache, you can also request and install the certificate using the Apache plugin:
sudo apt update sudo apt install python3-certbot-apache -y sudo certbot --apache -d tiki.example.org -d www.tiki.example.org
Verify:
sudo prosodyctl check certs
Expected output:
- Certificate found for
xmpp.example.org - Certificate found for
guest.example.org - Certificate found for
conference.example.org
More details: Prosody Certificate Documentation
3) Enable required modules
In /etc/prosody/prosody.cfg.lua under modules_enabled add the useful modules:
-- Prosody Configuration File -- Complete working configuration with Tiki HTTP auth and Push notifications -- Last updated: 2026-02-13 plugin_paths = { "/usr/local/lib/prosody/modules" } admins = { "admin@xmpp.example.org" } modules_enabled = { -- Core "disco"; -- Service discovery "roster"; -- User rosters "saslauth"; -- Authentication "tls"; -- TLS support -- Essential "blocklist"; -- User blocklists "bookmarks"; -- Groupchat bookmarks "carbons"; -- Message carbons for multi-device "dialback"; -- S2S dialback "limits"; -- Bandwidth limiting "pep"; -- Personal Eventing Protocol "private"; -- Private XML storage "smacks"; -- Stream Management "vcard4"; -- vCard4 "vcard_legacy"; -- Legacy vCard -- Nice to have "csi_simple"; -- Client State Indication "invites"; -- Invites system "invites_adhoc"; -- Ad-hoc invites "invites_register"; -- Invite-based registration "ping"; -- XMPP Ping "time"; -- Entity Time "uptime"; -- Server uptime "version"; -- Server version "mam"; -- Message Archive Management -- HTTP "bosh"; -- BOSH "websocket"; -- WebSockets -- Admin "admin_adhoc"; -- Ad-hoc admin commands "admin_shell"; -- Shell admin -- PUSH NOTIFICATIONS (XEP-0357) - CRITICAL FOR MOBILE CLIENTS "push"; -- XEP-0357: Push Notifications "cloud_notify"; -- Modern push implementation for iOS/Android } modules_disabled = { -- "offline"; -- Uncomment if you want to disable offline storage -- "c2s"; -- Uncomment to disable client connections -- "s2s"; -- Uncomment to disable server-to-server } pidfile = "/run/prosody/prosody.pid" s2s_secure_auth = true limits = { c2s = { rate = "10kb/s" }; s2sin = { rate = "30kb/s" }; } archive_expires_after = "1w" -- 1 week message retention log = { debug = "/var/log/prosody/prosody.debug"; info = "/var/log/prosody/prosody.log"; error = "/var/log/prosody/prosody.err"; { levels = { "error" }; to = "syslog" }; } certificates = "/etc/prosody/certs" ----------- Network ----------- interfaces = { "0.0.0.0" } http_interfaces = { "0.0.0.0" } https_interfaces = { "0.0.0.0" } c2s_interfaces = { "0.0.0.0" } s2s_interfaces = { "0.0.0.0" } http_ports = { 5280 } https_ports = { 5281 } s2s_require_encryption = true consider_websocket_secure = true -- Global SSL https_ssl = { key = "/etc/letsencrypt/live/xmpp.example.org/privkey.pem"; certificate = "/etc/letsencrypt/live/xmpp.example.org/fullchain.pem"; } ----------- VirtualHost: Registered Users (Tiki HTTP Auth) ----------- VirtualHost "xmpp.example.org" ssl = { key = "/etc/letsencrypt/live/xmpp.example.org/privkey.pem"; certificate = "/etc/letsencrypt/live/xmpp.example.org/fullchain.pem"; } authentication = "http" http_auth_url = "https://tiki.example.org/tiki-xmpp-auth.php" http_auth_credentials = "prosody:REPLACE_WITH_YOUR_SECRET_HERE" c2s_require_encryption = true allow_unencrypted_plain_auth = false sasl_mech_list = { "PLAIN" } disco_items = { { "conference.example.org" } } -- PUSH NOTIFICATION SERVICE - REQUIRED FOR MONAL cloud_notify_push_service = "push.xmpp.example.org" ----------- VirtualHost: Anonymous Visitors ----------- VirtualHost "guest.example.org" authentication = "anonymous" ssl = { key = "/etc/letsencrypt/live/xmpp.example.org/privkey.pem"; certificate = "/etc/letsencrypt/live/xmpp.example.org/fullchain.pem"; } c2s_require_encryption = true allow_registration = false ----------- MUC Component ----------- Component "conference.example.org" "muc" ssl = { key = "/etc/letsencrypt/live/xmpp.example.org/privkey.pem"; certificate = "/etc/letsencrypt/live/xmpp.example.org/fullchain.pem"; } restrict_room_creation = false modules_enabled = { "muc_mam" } muc_room_default_persistent = true muc_room_default_public = true muc_room_default_members_only = false muc_room_default_allow_anonymous = true muc_room_default_history_length = 20 muc_max_history_messages = 100 muc_tombstones = true ----------- PUSH COMPONENT - CRITICAL FOR iOS/MONAL ----------- Component "push.xmpp.example.org" "cloud_notify" ssl = { key = "/etc/letsencrypt/live/xmpp.example.org/privkey.pem"; certificate = "/etc/letsencrypt/live/xmpp.example.org/fullchain.pem"; } -- CRITICAL: DO NOT USE CUSTOM APP ID -- Monal uses ITS OWN Apple Push Certificate -- The ONLY app_id that works with Monal is: app_id = "im.monal.monal" -- Optional: Add app_secret if required by your setup -- app_secret = "your-secret-here" ----------- Include additional configs ----------- Include "conf.d/*.cfg.lua"
⚠️ Note: muc and muc_mam are not enabled globally here — they must be loaded in a Component block.
4) VirtualHosts, MUC & Push Components
Prosody requires explicit VirtualHost and Component definitions for different roles:
| Role | Domain | Purpose |
| Registered users | xmpp.example.org | Tiki HTTP authentication |
| Anonymous visitors | guest.example.org | Converse.js anonymous chat |
| Group chat | conference.example.org | MUC rooms with history |
| Push notifications | push.xmpp.example.org | XEP-0357 for iOS/Monal |
FULL CONFIGURATION AVAILABLE IN SECTION 3
The complete configuration block above (section 3) contains ALL required elements:
- VirtualHost
xmpp.example.orgaveccloud_notify_push_service - VirtualHost
guest.example.orgpour anonymes - Component
conference.example.orgpour MUC - Component
push.xmpp.example.orgavecapp_id = "im.monal.monal"⚠️ CRITICAL
Validation :
sudo prosodyctl check config sudo systemctl restart prosody sudo prosodyctl mod_list xmpp.example.org # Doit afficher push, cloud_notify
Push verification :
sudo tail -f /var/log/prosody/prosody.log | grep -i push # Expected: component 'push.xmpp.example.org' loaded
5) Tiki HTTP auth endpoint
Tiki provides tiki-xmpp-auth.php, responding to /check_password and /user_exists for Prosody’s mod_auth_http.
5.1 Web server requirements (Apache)
Make sure Apache forwards the Authorization header to PHP (this is essential if you use HTTP Basic auth). Add these lines inside the <VirtualHost> or in the <Directory> that serves tiki-xmpp-auth.php:
sudo nano /etc/apache2/sites-enabled/example.org.conf
# Ensure Apache forwards the Authorization header to PHP SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 CGIPassAuth On <Directory /home/prosody/public_html> Options -Indexes +IncludesNOEXEC +SymLinksIfOwnerMatch Require all granted # Forward Authorization header SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 CGIPassAuth On </Directory>
Reload Apache:
sudo apache2ctl configtest && sudo systemctl reload apache2
5.2 Generate and install the shared secret (recommended secure method)
Generate a secure random secret and store it in /etc/prosody/xmpp_http_secret (Prosody and Tiki will use it). Example:
# Generate secret (40 chars, safe characters) and secure it sudo sh -c 'head -c32 /dev/urandom | base64 | tr -d /=+ | cut -c1-40 > /etc/prosody/xmpp_http_secret' sudo chown root:prosody /etc/prosody/xmpp_http_secret sudo chmod 640 /etc/prosody/xmpp_http_secret # Show the secret (as root) to copy it for Prosody config / Tiki settings: sudo cat /etc/prosody/xmpp_http_secret
Important: do not expose this secret in public logs or commit it to git.
5.3 Configure Prosody with that secret (preferred: Basic Auth header)
Set http_auth_credentials in Prosody to prosody:THESECRET (this makes Prosody send an Authorization: Basic ... header). Example:
-- replace REPLACE_WITH_SECRET with the secret content from /etc/prosody/xmpp_http_secret http_auth_credentials = "prosody:XXXXXYYYYYYZZZZ"
Restart Prosody:
sudo systemctl restart prosody
5.4 Configure Tiki (tiki-xmpp-auth.php)
The Tiki tiki-xmpp-auth.php script accepts either:
- HTTP Basic Auth (
Authorization: Basic ...) with usernameprosodyand password equal to the shared secret, or - the query/post parameter
secret=...(less preferred; avoids exposing secret in URLs when possible).
Make sure the Tiki site preference xmpp_shared_secret (if used) matches the file /etc/prosody/xmpp_http_secret, or rely on the file secret logic in the script.
5.5 Quick diagnostics (curl)
# Check endpoint reachable (without auth you may get 403) curl -I "https://tiki.example.org/tiki-xmpp-auth.php" # Using Basic auth (preferred) SECRET=$(sudo cat /etc/prosody/xmpp_http_secret) curl -v -u "prosody:${SECRET}" \ "https://tiki.example.org/tiki-xmpp-auth.php/check_password?user=admin&pass=THEPASSWORD" # Using ?secret= (less recommended) curl -v "https://tiki.example.org/tiki-xmpp-auth.php/check_password?user=admin&pass=THEPASSWORD&secret=${SECRET}"
Expected output for valid credentials: true (plain text) for the /check_password call.
If you see 403 or false, check:
- Apache
SetEnvIf Authorization+CGIPassAuthpresence - That Prosody is actually sending Basic auth (check Prosody logs)
- That the secret used by Prosody and Tiki matches exactly
6) Converse.js configuration (in Tiki)
Admin → XMPP → ConverseJS Extra Settings (example):
Minimal configuration example:
{ "discover_connection_methods": false, "keepalive": true, "persistent_store": "localStorage", "debug": true }
-
sessionStorageavoids harmless warnings about session restore during testing.
To allow anonymous visitors to automatically join chat rooms with auto-generated nicknames set muc_nickname_from_jid to true
{ "websocket_url": "wss://xmpp.example.org/xmpp-websocket", "persistent_store": "sessionStorage", }
Optional XEP-0156 discovery (useful if you let Converse discover endpoints):
# /var/www/xmpp/.well-known/host-meta <?xml version='1.0' encoding='utf-8'?> <XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'> <link rel="urn:xmpp:alt-connections:xbosh" href="https://xmpp.example.org:5281/http-bind" /> <link rel="urn:xmpp:alt-connections:websocket" href="wss://xmpp.example.org:5281/xmpp-websocket" /> </XRD>
Permissions :
sudo chown -R www-data:www-data /var/www/xmpp sudo chmod -R 755 /var/www/xmpp
Apache snippet (/etc/apache2/sites-enabled/olivierkango.com.conf) :
# Prevent reverse-proxy from eating .well-known ProxyPass /.well-known ! Alias /.well-known/ /var/www/xmpp/.well-known/ <Directory /var/www/xmpp/.well-known> Options -Indexes AllowOverride None Require all granted Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET, OPTIONS" Header set Access-Control-Allow-Headers "Content-Type" </Directory>
Required logs (for troubleshooting):
# real time access log sudo tail -f /var/log/virtualmin/example.org_access_log # real time prosody log sudo tail -f /var/log/prosody/prosody.log # real time apache error log sudo tail -f /home/prosody/logs/php_log # real time error log sudo tail -f /var/log/virtualmin/example.org_error_log # prosody infos log sudo journalctl -u prosody -f
7) Test endpoints
curl -vk https://xmpp.example.org:5281/http-bind curl -vk https://xmpp.example.org:5281/xmpp-websocket
Expected:
- BOSH: HTML page
Prosody BOSH endpoint – It works - WebSocket:
HTTP/1.1 101 Switching Protocols
8) XMPP rooms and Gajim
This section explains how chat rooms are created and used, based on real use cases.
Room creation model
Chat rooms are not created manually in advance.
Rooms are created automatically on first join by Prosody (MUC), based on:
- the room JID
- the configured MUC domain
- the auto-join logic from Tiki or the XMPP client
Defined rooms
- Community room (anonymous + registered users):
community@conference.example.com - Support room (anonymous support):
support@conference.example.com - Registered users room:
registered@conference.example.com - Translators room:
translators@conference.example.com
Registered users behaviour (Bob, Charlie, Dan)
- When a user logs into Tiki:
- he is authenticated to XMPP via HTTP auth
- he is auto-joined to rooms based on Tiki groups
Examples:
- Bob (group: Registered) → auto-joined to
registered@conference.example.com - Charlie (group: Translators) → auto-joined to
translators@conference.example.com - Dan (external XMPP account configured in Tiki profile) → joins the same rooms based on group mapping
Admin / support workflow (Eve)
Eve uses Gajim instead of the web interface. Add admin account in Gajim
JID: admin@xmpp.example.com Password: admin’s Tiki password Server override: Host: xmpp.example.com Port: 5222 Encryption: StartTLS (Require TLS) Auth method: PLAIN Verify server certificate: ON
How Eve creates or joins rooms
Rooms are created simply by joining them.
Gajim → + → Join Group Chat Room: support Server: conference.example.com
This creates (if not already created): support@conference.example.com
Eve stays online in this room to answer anonymous visitors.
Anonymous visitors behaviour (Alice)
- Alice visits the Tiki site
- Converse.js opens automatically
- Based on configuration:
- community use case → joins
community@conference.example.com - support use case → joins
support@conference.example.com
- community use case → joins
Eve receives messages in Gajim in real time.
Add registered account in Gajim (use admin, not Eve)
- JID: admin@xmpp.example.org - Password: (admin’s Tiki password OR the local prosody password if you created one) - Resource: optional (e.g. AdminLaptop) Server (override) - Host: xmpp.example.org - Port: 5222 - Encryption: StartTLS (Require TLS) - Auth method / SASL: PLAIN - Verify server certificate: ON (unless testing with self-signed cert) Notes: - If DNS SRV records are correct you can skip Host override and let the client use the domain. - Only use SASL PLAIN over an encrypted (TLS) connection.
Troubleshooting checklist (brief)
- Ensure Apache forwards Authorization header (SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 + CGIPassAuth On).
- Ensure Prosody virtualhost uses auth http and sends credentials (
http_auth_url+http_auth_credentialsorhttp_auth_user/http_auth_password). - Confirm certificate names match hostnames and client uses TLS.
- Check Prosody logs (
/var/log/prosody/prosody.log) and Tiki PHP log for the debug lines.
-- end of Gajim section (use admin@xmpp.example.org credentials)
9) Configure Tiki (Admin → XMPP)
| Section | Preference | Example value |
| Common (Openfire & Prosody) | XMPP MUC Domain | conference.example.org
|
| XMPP BOSH URL (http-bind) | https://xmpp.example.org:5281/http-bind/
| |
| XMPP WebSocket URL | wss://xmpp.example.org:5281/xmpp-websocket
| |
| Prosody (HTTP Auth) | XMPP domain for registered users | xmpp.example.org
|
| XMPP domain for anonymous visitors | guest.example.org
| |
| Anonymous visitor mode | Community room
| |
| Default anonymous chat room | community@conference.example.com
| |
| Anonymous support room | support@conference.example.com
| |
| Default registered chat room | registered@conference.example.org
| |
| Mapping Tiki groups to chat rooms | { "Registered": "registered@conference.example.org", "Translators": "translators@conference.example.org" }
| |
| Auto-join strategy | by-groups (recommended) | |
| XMPP shared secret (HTTP auth) | (same secret as in Prosody config or leave blank and use file `/etc/prosody/xmpp_http_secret`) | |
| CORS allowed origins (comma-separated) | https://tiki.example.org
| |
| ConverseJS options (common) | Always Load ConverseJS | Enable ✅ |
| ConverseJS Debug Mode | Enable only for debugging | |
| ConverseJS Extra Settings | {"discover_connection_methods": false, "keepalive": true, "persistent_store": "localStorage", "debug": true} |
Then, in the wiki page, add the XMPP plugin for the room you want to use (depending on the case):
{xmpp room="Support"} # or {xmpp room="Registered"} # or {GROUP(groups="Translators")} {xmpp room="Translators"} {GROUP}
Note: Anonymous users will always be automatically projected into the Support room, regardless of which plugin is configured on the page.
10) Pitfalls & troubleshooting
10.1 Firewall (firewalld / nftables) — COMMON BLOCKER
This is the #1 real-world cause of “No route to host” when Prosody is running correctly.
From a remote machine:
nc -vz xmpp.example.org 5222
Result: nc: connect to xmpp.example.org port 5222 failed: No route to host
Even though on the server: ss -lntp | grep 5222 Shows: LISTEN 0.0.0.0:5222
How to detect firewalld
Run on the server:
systemctl status firewalld
If you see: active (running) Then firewalld IS ACTIVE, even if ufw is not installed. You can also confirm with: nft list ruleset
If you see: table inet firewalld { firewalld is enforcing rules via nftables.
Default problem
By default, the public zone does NOT allow XMPP ports.
Typical allowed ports:
- 22 (SSH)
- 80 / 443 (HTTP/HTTPS)
- mail ports
x Missing:
- 5222 (XMPP client)
- 5269 (server-to-server)
- 5280 / 5281 (BOSH / WebSocket)
FIX — Open XMPP ports properly (RECOMMENDED)
Run one by one as root:
firewall-cmd --permanent --add-port=5222/tcp firewall-cmd --permanent --add-port=5269/tcp firewall-cmd --permanent --add-port=5280/tcp firewall-cmd --permanent --add-port=5281/tcp firewall-cmd --reload
Verify: firewall-cmd --list-ports Expected: 5222/tcp 5269/tcp 5280/tcp 5281/tcp
Mandatory verification (from another machine)
nc -vz xmpp.example.org 5222
Expected: Connection to xmpp.example.org 5222 port tcp/xmpp-client succeeded!
Only after this succeeds should you configure Gajim or Converse.js.
10.2 ⚠️ SSL certificate expired but still used by Prosody
Problem:
When connecting with Gajim, an SSL error appears:
The certificate has expired
Clicking on View Certificate crashes Gajim with:
AttributeError: 'NoneType' object has no attribute 'connect'
Cause:
- Important: Let's Encrypt certificates expire every 90 days.
- The server was presenting an expired certificate
- A new certificate was generated by Let's Encrypt
- Prosody was still using the old one (loaded in memory)
Diagnosis:
# 1. Check certificate on disk sudo openssl x509 -in /etc/letsencrypt/live/xmpp.example.org/fullchain.pem -noout -dates # 2. Try to renew (shows if renewal is possible) sudo certbot renew # 3. Check what the server actually sends echo | openssl s_client -connect xmpp.example.org:5222 -starttls xmpp -servername xmpp.example.org 2>/dev/null | openssl x509 -noout -dates # 4. Compare results: # - If disk certificate is valid but server sends expired → Prosody needs restart # - If both are expired → renew certificate first
Fix:
Force Prosody to reload the new certificate:
sudo systemctl stop prosody sudo systemctl start prosody
Prevention :
To avoid this issue in the future, create a Certbot deploy hook that automatically imports certificates into Prosody after each renewal. This is the method recommended by the official Prosody documentation: https://prosody.im/doc/letsencrypt
sudo nano /etc/letsencrypt/renewal-hooks/deploy/prosody.sh
Content:
#!/bin/sh /usr/bin/prosodyctl --root cert import /etc/letsencrypt/live
Make it executable:
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/prosody.sh
11) Simple and Reliable Solution (XMPP SEO Blocking)
Objective
Permanently block the xmpp. and guest. subdomains at the server (Apache) level to prevent any SEO indexing.
- Step 1 — Open the terminal__ Via: - Virtualmin → Terminal or - SSH
- Step 2 — Create the blocking VirtualHost Run exactly:
sudo nano /etc/apache2/sites-available/blocked-subdomains.conf - Step 3 — Paste the following content (important)
<VirtualHost *:80> ServerName xmpp.example.org ServerAlias guest.example.org DocumentRoot /var/www/empty <Directory /var/www/empty> Require all granted </Directory> Header set X-Robots-Tag "noindex, nofollow" </VirtualHost>
Save the file: - CTRL + O → Enter, CTRL + X
- Step 4 — Create the empty directory
sudo mkdir -p /var/www/empty
sudo chown -R www-data:www-data /var/www/empty
- Step 5 — Enable Apache headers module (if needed):
sudo a2enmod headers - Step 6 — Enable the site and reload Apache
sudo a2ensite blocked-subdomains.conf sudo systemctl reload apache2
Immediate test (critical)
Open in your browser:
Expected result
- Empty page or default Apache page
- No Tiki content
- No indexable content
If this is the case, the SEO issue is resolved at ~90%.
Others Pitfalls & troubleshooting
- 🔐 Firewall: open 5222, 5269, 5280, 5281 as needed.
- 📜 Certificates mismatch: point all vhosts/components to a valid cert pair.
- 🚫 Room creation restricted: set restrict_room_creation = false (or handle via admin).
- 👻 Duplicate anonymous nicknames: expected on reload; let Converse generate unique nicks.
- ❗ Apache drops Authorization: add SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1 and CGIPassAuth On in the vhost.
- 🔒 Do not pass secret in URL in production: prefer Basic auth so secret is sent in Authorization header and not logged in server logs.
- ⚠️ SASL warning (PLAIN forbidden on insecure): enable c2s_require_encryption = true and connect via HTTPS BOSH/WebSocket.
- 🧹 Converse “_restore: no restoreable session”: benign; clear cache or use sessionStorage.
- 🛂 Admin not-authorized in logs: ensure the XMPP Admin in Tiki is a real Tiki user and the password matches; do not rely on prosodyctl register for HTTP-auth vhosts.
User Stories
- Alice (anonymous visitor): She is not registered. She sees the Converse.js pop up and she asks a question.
- Bob (registered user): Is automatically added to the Registered group and the associated chatroom.
- Charlie (translator): Is also added to the Translators chatroom in addition to the Registered one.
- Dan (geek): Uses his own external XMPP JID while still joining group chatrooms.
- Eve (administrator): Uses Gajim (desktop XMPP client) to answer queries from anonymous visitors.
At this point:
- Converse.js can connect via BOSH or WebSocket
- Anonymous visitors (guest.example.org) can chat
- Registered users (xmpp.example.org) can join
- Group chats are served by conference.example.org with message history