summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Lionel <lionel@les-miquelots.net>2021-05-31 21:06:34 +0100
committerMiquel Lionel <lionel@les-miquelots.net>2021-05-31 21:06:34 +0100
commit805b1c983dd62d53b1be88dc957768e77bb0ba33 (patch)
treed157988aa0e3d42cb4165f5bc8d06f2dd2994e97
parente0e590be90f1fba904ee0de997a5cf7f72c5a29c (diff)
downloadxmpp_guide_files-805b1c983dd62d53b1be88dc957768e77bb0ba33.tar.gz
xmpp_guide_files-805b1c983dd62d53b1be88dc957768e77bb0ba33.zip
add html files for offline readingHEADmaster
-rwxr-xr-xindex.fr.html932
-rwxr-xr-xindex.html855
-rwxr-xr-xstyles.css192
3 files changed, 1979 insertions, 0 deletions
diff --git a/index.fr.html b/index.fr.html
new file mode 100755
index 0000000..f0e62dc
--- /dev/null
+++ b/index.fr.html
@@ -0,0 +1,932 @@
+<!DOCTYPE html>
+<html lang="fr">
+<head>
+<title>Mise en place d'un client web XMPP avec liens de création de compte (conversejs+prosody)</title>
+<link rel='stylesheet' type='text/css' href='styles.css'>
+<meta charset='utf-8'/>
+</head>
+<body>
+<h1>Mise en place d'un client web XMPP avec liens de création de compte (conversejs+prosody)</h1>
+<small>[<a href='partage.les-miquelots.net/blog/2021/index.html#mise-en-place-dun-client-web-xmpp-avec-liens-de-creation-de-compte-conversejsprosody'>lien</a>&mdash;<a href='index.fr.html'>billet seul</a>]</small>
+<p><b>maj 28/05/2021</b>: corrections des iptables (r&eacute;gles dupliqu&eacute;s), ajout de liens de
+documentation, ajout d'une entrée de DNS pour websocket. <samp>http_altconnect</samp> rajouté en module prosody
+pour éviter les erreurs dans la console du navigateur
+<p><b>maj 22/05/2021</b>: OMEMO par pas d&eacute;faut au final, on laisse le choix &agrave;
+l'utilisateur de l'activer dans ses discussions, et c'est mieux niveau historique des messages
+sur plusieurs appareils. On am&eacute;liore aussi la commande apt (-y --no-install-recommends). <br><br>
+<p>Bonjour &agrave; tous, <br><br>
+<p>Aujourd'hui je vais vous montrer comment mettre en place un serveur XMPP avec un
+client Web sur la m&ecirc;me machine, avec la
+possibilit&eacute;
+d'envoyer des liens d'invitations de cr&eacute;ation de comptes ou d'ajout
+en contact pour faciliter l'embarquement de vos proches et amis.
+Je ne fais pas de pr&eacute;sentation du protocole XMPP, c'est hors de la
+port&eacute;e de ce guide et des gens l'explique mieux que moi, je pense
+surtout &agrave; <a
+href="https://www.goffi.org/b/S%C3%A0T_DOTCLEAR_IMPORT_BLOG_default_goffi_99%3A2015%2F06%2F24%2FParlons-XMPP-%C3%A9pisode-1-les-bases">cette
+ suite d'articles de chez goffi.org</a>.<br>
+<b>pav&eacute; c&eacute;sar g&eacute;palu lol</b>: c'est un protocole
+compos&eacute; d'une myriade de standards permettant
+la construction de r&eacute;seaux de messagerie instantan&eacute;e
+d&eacute;centralis&eacute;s et s&eacute;curis&eacute;s. Possibilit&eacute; d'avoir
+des salons publics et priv&eacute;s.
+<br><br>
+
+<p><div id="guide-sommaire">
+ <u>Sommaire:</u>
+ <ol>
+ <li><a href="#xmpp-guide-prereq">Pr&eacute;requis</a></li>
+ <li><a href="#xmpp-guide-dnszone">Configuration zone DNS</a></li>
+ <li><a href="#xmpp-guide-iptables">Configuration pare-feu</a></li>
+ <li><a href="#xmpp-guide-pkgs">Installation des
+ paquets</a></li>
+ <li><a href="#xmpp-guide-certs">Installation des
+ certificats</a></li>
+ <li><a href="#xmpp-guide-confpkgs">Configuration des
+ paquets</a></li>
+ <li><a href="#xmpp-guide-con">Connexion &agrave; l'interface web</a></li>
+ <li><a href="#xmpp-guide-genlinks">G&eacute;n&eacute;ration des liens d'invitation</a></li>
+
+ <li><a href="#xmpp-guide-remarks">Remarques</a></li>
+ <li><a href="#xmpp-guide-docs">Documentations</a></li>
+ <li><a href="#xmpp-guide-thanks">Remerciements</a></li>
+ </ol>
+ </div>
+ <br><br>
+
+<h3 id="xmpp-guide-prereq"><a href="#xmpp-guide-prereq">1.
+Pr&eacute;requis</a></h3>
+
+<p>Tr&ecirc;ve de bavardages, voici ce que l'on va devoir installer:
+<ul>
+ <li><samp>certbot</samp>: g&eacute;n&eacute;ration des certificats
+ pour renforcer la s&eacute;curit&eacute; de la communication
+ client=&gt;serveur et serveur&lt;=&gt;serveur.</li>
+ <li><samp>prosody</samp>: le serveur XMPP, la pi&egrave;ce maîtresse.</li>
+ <li><samp>nginx</samp>: le proxy invers&eacute; qui g&eacute;rera les
+ connexions &agrave; l'interface web et les connexions <span
+ style="color:green"><b>HTTPS</b></span>.</li>
+ <li><samp>conversejs</samp>: l'interface web pour notre serveur XMPP.</li>
+ <li><samp>libjs-bootstrap4 libjs-jquery</samp>: le module
+ <samp><a
+ href="https://modules.prosody.im/mod_invites.html#external-dependencies"
+ target="_blank" rel="noopener" >mod_invites</a></samp> de Prosody a
+ besoin de ces biblioth&egrave;ques pour le CSS et bouts de JavaScript.
+ <li><samp>hg</samp>: pour cloner le d&eacute;pôt des modules de
+ <samp>prosody</samp> et les maintenir &agrave; jour.</li>
+</ul><br>
+
+
+<p>Mettez-vous d'accord sur votre nom de domaine: vous remplacerez les
+occurences de <samp>exemple.fr</samp> dans ce guide par votre
+nom de domaine. On va aussi utiliser un sous-domaine pour
+l'interface web, <samp>chat.exemple.fr</samp>, un qui contiendra les
+salons publics et priv&eacute;s, <samp>salons.exemple.fr</samp> et un
+autre pour le serveur d'envoi de fichiers,
+<samp>f.exemple.fr</samp>.<br>
+N'oubliez pas de rajouter des entr&eacute;es DNS type A pour ces
+sous-domaines.
+<br><br>
+
+<h3 id="xmpp-guide-dnszone"><a href="#xmpp-guide-dnszone">2. Configuration zone DNS</a></h3>
+<p>Tout d'abord, rendez-vous dans la zone DNS de votre nom de domaine, on va
+rajouter quelques entr&eacute;es de type SRV et TXT pour faciliter la
+communication des clients et serveurs XMPP avec nous (plus de
+d&eacute;tails en anglais <a
+href="https://wiki.xmpp.org/web/SRV_Records">par l&agrave;</a> ou <a
+href="https://prosody.im/doc/dns">encore ici</a>):
+<pre>
+_xmpp-client._tcp.exemple.fr 86400 SRV 1 1 5222 exemple.fr.
+_xmpps-client._tcp.exemple.fr 86400 SRV 1 1 5223 exemple.fr.
+_xmpp-server._tcp.exemple.fr 86400 SRV 1 1 5269 exemple.fr.
+_xmppconnect.exemple.fr TXT _xmpp-client-xbosh=https://chat.exemple.fr/http-bind
+_xmppconnect.exemple.fr TXT _xmpp-client-websocket=wss://chat.example.fr/xmpp-websocket
+</pre>
+
+<p><b>À noter:</b> le <samp>exemple.fr</samp> &agrave; de gauche
+repr&eacute;nte le domaine XMPP, celui de droite est le serveur qui
+r&eacute;pondra aux requ&ecirc;tes et une entr&eacute;e DNS de type A
+doit exister pour celui-ci, pas de raccourci type CNAME autoris&eacute;.
+C'est pratique quand vous voulez des adresses utilisateurs "propres" tel
+que <u>vous@exemple.fr</u> mais que le serveur est en fait sur le
+sous-domaine <samp>xmpp.exemple.fr</samp>. Si c'est le cas, changez
+alors le <samp>exemple.fr</samp> de droite par
+<samp>xmpp.exemple.fr</samp>.<br><br>
+
+
+<h3 id="xmpp-guide-iptables"><a href="#xmpp-guide-iptables">3. Configuration pare-feu</a></h3>
+<p><b><u>IMPORTANT</u>:Connectez-vous en tant que root avant d'ex&eacute;cutez les
+commandes contenues dans
+ce tutoriel</b>. On va ensuite configurer des r&egrave;gles
+<samp>iptables</samp> pour &eacute;viter de se mordre les doigts
+de rage par la suite. Je pars du principe que vous avez d&eacute;j&agrave;
+ configur&eacute; quelques r&egrave;gles vous permettant de SSH tranquillou.
+
+<pre>
+iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT # on accepte les connexions client &agrave; serveur
+iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT # pareil que le dessus mais celles qui sont chiffr&eacute;s.
+iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT # connexions serveur &agrave; serveur.
+iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # HTTP pour l'interface web
+iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS
+iptables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT # pour envoyer des requ&ecirc;te DNS
+iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT # en output aussi si des serveurs utilisant l'HTTP upload pour les pjs
+iptables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
+
+iptables-save &gt; /etc/iptables/iptables.rules
+
+
+# pareil pour l'ipv6
+ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT
+ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT
+ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT
+ip6tables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # HTTP pour l'interface web
+ip6tables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS
+ip6tables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT # pour envoyer des requ&ecirc;te DNS
+ip6tables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT # en output aussi si des serveurs utilise l'HTTP upload pour les pjs
+ip6tables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
+
+ip6tables-save &gt; /etc/iptables/ip6tables.rules
+systemctl enable --now iptables # activation du service iptables si pas
+# d&eacute;j&agrave; fait pour garder la config du pare-feu apr&egrave;s reboot.
+</pre><br>
+
+<h3 id="xmpp-guide-pkgs"><a href="#xmpp-guide-pkgs">4. Installation des paquets</a></h3>
+
+<p>Apr&egrave;s ceci, installez <samp>prosody</samp> depuis <a
+href="https://prosody.im/doc/installing_from_source">les sources</a> ou
+votre <a href="https://prosody.im/download/start">installeur de
+paquets</a>. On en profitera pour installer les autres composants requis
+&agrave; ce guide. Sur un Debian classique cel&agrave; donnera:<br>
+<pre>sudo apt-get install -y --no-install-recommends prosody nginx-full \
+certbot python3-certbot-nginx \
+mercurial libjs-bootstrap4 libjs-jquery</pre><br>
+
+<p>On va maintenant cloner les <samp>prosody-modules</samp> depuis la
+source. Il n'est pas toujours &agrave; jour dans les d&eacute;p&ocirc;ts de
+paquets:
+<pre>
+hg clone https://hg.prosody.im/prosody-modules/ /usr/lib/prosody/modules/
+</pre>
+<p>On pr&eacute;pare en m&ecirc;me temps un script pour mettre
+&agrave; automatiquement via la crontab. Cr&eacute;ez le fichier
+<samp>/usr/local/sbin/maj_prosodymods.sh</samp> avec le contenu suivant:
+<pre>
+#!/bin/sh
+MODDIR="/usr/lib/prosody/modules/"
+
+if test -d $MODDIR; then
+ cd $MODDIR
+ hg pull --update
+else
+ mkdir -p /usr/lib/prosody
+ hg clone https://hg.prosody.im/prosody-modules/ $MODDIR
+fi
+</pre>
+<p>N'oubliez pas de faire un coup de <samp>chmod +x</samp> dessus...
+<br><br>
+
+<p>On va ensuite t&eacute;l&eacute;charger <samp>conversejs</samp>.
+&Agrave; ce jour sur Debian Buster, il n'y a pas de paquet &agrave; jour
+officiel pour <samp>conversejs</samp>, donc on va faire un script qu'on
+int&eacute;grera dans notre crontab.<br>
+Ins&eacute;rez le contenu suivant
+dans le fichier <samp>/usr/local/sbin/update_conversejs.sh</samp> puis
+rendez-le ex&eacute;cutable:
+<pre>
+#!/bin/sh
+TEMPDIR="$(mktemp -d)"
+LOG=/var/log/update_conversejs.log
+WWWDIR='/var/www/chat.exemple.fr'
+WWWUSER='www-data' # cette valeur sera s&ucirc;rement diff&eacute;rente
+ # si vous n'&ecirc;tes pas sur Debian avec nginx.
+ # par ex. &ccedil;a sera 'http' sous Arch avec nginx.
+
+mkdir -p $WWWDIR/dist
+cd $TEMPDIR
+printf "\n\n$(date) - INFO - Starting updating conversejs..." | tee -a $LOG
+CURL_ERR=$(curl -s \
+ https://api.github.com/repos/conversejs/converse.js/releases/latest | \
+ grep -o "https://.*\.tgz" | \
+ grep converse\.js- | \
+ xargs curl -fsOJL) || \
+ (printf "\n$(date) - ERR - Updating conversejs failed." | tee -a $LOG &amp;&amp; exit)
+
+# on installe libsignal pour pouvoir utiliser OMEMO
+# dans le client web
+if test -e "$WWWDIR/dist/libsignal-protocol.min.js"; then
+ printf "\n$(date) - TOK - Libsignal already installed, skipping." | tee -a $LOG
+else
+ curl -fsOJL \
+ https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js || \
+ (printf "\n$(date) - ERR - Updating libsignal-protocol-javascript failed." | \
+ tee -a $LOG)
+ cp libsignal*.js $WWWDIR/dist/
+fi
+
+tar xzf *.tgz
+cp -rf package/dist $WWWDIR/
+sed "s/fullscreen\.html/index\.html/g" package/manifest.json &gt; $WWWDIR/manifest.json
+chown $WWWUSER:$WWWUSER -R $WWWDIR/
+chmod 755 -R $WWWDIR/
+rm -rf $TEMPDIR
+printf "\n$(date) - TOK - Done." | tee -a $LOG
+</pre>
+<p>Ex&eacute;cutez ce fichier pour gagner du temps dans l'<a
+href="#xmpp-guide-confpkgs">&eacute;tape 6</a>, vous n'aurez pas &agrave;
+cr&eacute;er le <samp>$WWWDIR</samp>.
+
+<h3 id="xmpp-guide-certs"><a href="#xmpp-guide-certs">5. Installation des
+certificats</a></h3>
+
+
+<p>On va ensuite lancer certbot pour g&eacute;n&eacute;rer des certificats.
+Je pars du principe que vous avez configur&eacute; les entr&eacute;es de
+type A pour <samp>exemple.fr</samp>, <samp>chat.exemple.fr</samp>
+et <samp>f.exemple.fr</samp> dans votre zone DNS:
+<pre>certbot certonly --agree-tos --nginx --deploy-hook "prosodyctl --root cert import /etc/letsencrypt/live" -d chat.exemple.fr -d exemple.fr -d f.exemple.fr -d salons.exemple.fr </pre>
+<p>Une fois que cette commande s'ex&eacute;cute avec succ&eacute;s, des
+dossiers correspondants aux domaines demand&eacute;s devrait
+appara&icirc;tre dans <samp>/etc/letsencrypt/live/</samp>.
+<br><br>
+
+<h3 id="xmpp-guide-confpkgs"><a href="#xmpp-guide-confpkgs">6. Configuration des
+paquets</a></h3>
+
+<p>Le moment est venu! On va t&acirc;ter &acirc; prosody et sa
+configuration.<br>
+Ouvrez le fichier <samp>/usr/lib/prosody/net/http/server.lua</samp>, on va simplifier la
+connexion entre l'interface HTTP de prosody (BOSH) et nginx.<br>
+Dans le
+fichier, trouver la ligne suivante:
+<pre>
+headers = { date = date_header, connection = response_conn_header };
+</pre>
+<p>et rempla&ccedil;ez la par:
+<pre>
+headers = { date = date_header, connection = response_conn_header,
+ access_control_allow_origin = "exemple.fr" };
+-- si 'exemple.fr' ne r&eacute;sout pas le soucis de connexion, mettez
+-- un '*' &agrave; la place. Pour rappel, c'est l'adresse du serveur XMPP
+-- qui faut mettre, et non celle du domaine.
+</pre><br>
+
+<p>Ensuite, on va s'occuper du script qui permettra d'envoyer des fichiers
+&agrave; d'autres utilisateurs. Ex&eacute;cutez ceci:
+<pre>
+mkdir -p /var/www/upload
+chown www-data:www-data /var/www/upload # l'utilisateur de nginx peut
+ # diff&eacute;rer selon la distrib, faites gaffe
+mkdir -p /usr/local/lib/perl
+wget -O /usr/local/lib/perl/upload.pm https://raw.githubusercontent.com/weiss/ngx_http_upload/master/upload.pm
+</pre>
+<p>Ouvrez le fichier <samp>upload.pm</samp>, cherchez un bout de texte
+ressemblant &agrave; <samp>my $external_secret = 'it-is-secret';</samp>
+et changez le <samp>it-is-secret</samp> par un mot de passe fort, de
+pr&eacute;f&egrave;rence sans apostrophe ou antislash pour &eacute;viter
+que le programme en Perl plantouille quand on va tout d&eacute;marrer.<br>
+Notez-vous ce mot de passe sur un bout de papier, on va en avoir besoin
+derechef.<br><br>
+
+<p>Passons &agrave; la configuration de prosody: &eacute;ditez le fichier
+ <samp>/etc/prosody/prosody.cfg.lua</samp> avec les informations
+suivantes:
+<pre>
+admins = { "vous@exemple.fr" }
+
+-- For more information see: https://prosody.im/doc/libevent
+-- use_libevent = true
+
+plugin_paths = { "/usr/lib/prosody/modules" }
+
+modules_enabled = {
+
+ -- Generally required
+ "roster"; -- Allow users to have a roster. Recommended ;)
+ "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
+ "tls"; -- Add support for secure TLS on c2s/s2s connections
+ "dialback"; -- s2s dialback support
+ "disco"; -- Service discovery
+
+ -- Not essential, but recommended
+ "carbons"; -- Keep multiple clients in sync
+ "carbons_copies";
+ "carbons_copies_adhoc";
+ "pep"; -- Enables users to publish their avatar, mood, activity, playing music and more
+ "private"; -- Private XML storage (for room bookmarks, etc.)
+ "blocklist"; -- Allow users to block communications with other users
+ "vcard4"; -- User profiles (stored in PEP)
+ "vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard
+ "smacks";
+ "bookmarks"; -- vieux module mais compatible avec la
+ -- majorit&eacute; des clients XMPP contrairement
+ -- &agrave; bookmarks2
+ --"bookmarks2";
+ "presence"; -- voir l'&eacute;tat de l'utilisateur (en ligne, hors
+ -- ligne, etc...)
+ "offline";
+
+ -- Nice to have
+ "version"; -- Replies to server version requests
+ "uptime"; -- Report how long server has been running
+ "time"; -- Let others know the time here on this server
+ "ping"; -- Replies to XMPP pings with pongs
+ "register"; -- Allow users to register on this server using a client and change passwords
+ "mam"; -- Store messages in an archive and allow users to access it
+ "csi";
+ "csi_simple"; -- Simple Mobile optimizations
+ "csi_battery_saver";
+ "vjud"; -- recherche d'utilisateurs dans les salons
+
+ -- Admin interfaces
+ "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
+
+ -- HTTP modules
+ "bosh"; -- Enable BOSH clients, aka "Jabber over HTTP"
+ "websocket"; -- XMPP over WebSockets
+ "http_altconnect";
+
+ -- Other specific functionality
+ "posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
+ "limits"; -- Enable bandwidth limiting for XMPP connections
+ "groups"; -- Shared roster support
+ "server_contact_info"; -- Publish contact information for this service
+ "announce"; -- Send announcement to all online users
+ "welcome"; -- Welcome users who register accounts
+ "watchregistrations"; -- Alert admins of registrations
+ "motd"; -- Send a message to users when they log in
+ --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots.
+ --"proxy65"; -- Enables a file transfer proxy service which clients behind NAT can use
+}
+
+-- These modules are auto-loaded, but should you want
+-- to disable them then uncomment them here:
+modules_disabled = {
+ -- "offline"; -- Store offline messages
+ -- "c2s"; -- Handle client connections
+ -- "s2s"; -- Handle server-to-server connections
+}
+
+motd_text = [[Bonjour &agrave; tous ! Bienvenue sur mon serveur XMPP. Clavardez heureux !]]
+welcome_message = "C'est ta premi&egrave;re connexion, $username. Bienvenue &agrave; toi."
+
+daemonize = false;
+pidfile = "/run/prosody/prosody.pid";
+trusted_proxies = { "127.0.0.1", "::1" }
+
+-- Force certificate authentication for server-to-server connections
+c2s_require_encryption = true -- chiffrement requis pour connexion client &agrave; serveur
+s2s_require_encryption = true -- chiffrement requis pour connexion entre serveurs
+s2s_secure_auth = true
+authentication = "internal_hashed"
+
+-- mam settings
+archive_expires_after = "never" -- historique permanent des chats
+
+log = {
+ -- Log files (change 'info' to 'debug' for debug logs):
+ info = "/var/log/prosody/prosody.log";
+ error = "/var/log/prosody/prosody.err";
+ -- Syslog:
+ { levels = { "error" }; to = "syslog"; };
+}
+
+-- http and certificate shenanigans
+certificates = "certs"
+
+-- Include "conf.d/*.cfg.lua"
+
+legacy_ssl_ports = { 5223 }
+-- http_ports = { 5280 }
+-- http_interface = { "*" }
+-- https_ports = { 5281 }
+-- https_interfaces { "*" }
+
+
+cross_domain_bosh = { "https://chat.exemple.fr" }
+cross_domain_websocket = { "https://chat.exemple.fr" }
+consider_bosh_secure = true
+consider_websocket_secure = true
+allow_registration = true -- n&eacute;cessaire pour mod_invites
+registration_invite_only = true -- inscription autoris&eacute; seulement avec les invitations
+vjud_mode = "opt-in" -- l'utilisateur doit consentir pour que la recherche vjud
+ -- le fasse remonter dans les r&eacute;sultats.
+
+-- https://prosody.im/security/advisory_20210512/
+gc = {
+ speed = 500;
+}
+c2s_stanza_size_limit = 256 * 1024
+s2s_stanza_size_limit = 512 * 1024
+
+limits = {
+ c2s = {
+ rate = "10kb/s";
+ };
+ s2sin = {
+ rate = "3kb/s";
+ };
+}
+-- https://prosody.im/security/advisory_20210512/
+
+ssl = {
+ key = "certs/exemple.fr.key";
+ certificate = "certs/exemple.fr.crt";
+}
+
+VirtualHost "exemple.fr"
+ invites_page = "https://chat.exemple.fr/invite?{invite.token}"
+ webchat_url = "https://chat.exemple.fr/"
+ http_external_url = "https://chat.exemple.fr/"
+ invite_expiry = 86400 * 7 -- 7 jours avant qu'un lien d'invitation expire
+ http_paths = {
+ invites_page = "/invite";
+ invites_register_web = "/register";
+ }
+
+ modules_enabled = {
+ "invites";
+ "invites_adhoc";
+ "invites_page";
+ "invites_register";
+ "invites_register_web";
+ "http_libjs";
+ }
+
+ contact_info = {
+ abuse = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" };
+ admin = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" };
+ security = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" };
+ support = { "mailto:vous@exemple.fr", "xmpp:vous@exemple.fr" };
+ };
+
+ https_certificate = "certs/exemple.fr.crt";
+ ssl = {
+ key = "certs/exemple.fr.key";
+ certificate = "certs/exemple.fr.crt";
+ }
+
+ Component "f.exemple.fr" "http_upload_external"
+ http_upload_external_base_url = "https://f.exemple.fr/"
+ http_upload_external_secret = "its-a-secret"
+ http_upload_external_file_size_limit = 104857600 -- limite de &agrave; 100Mo pour les envois de pjs
+ ssl = {
+ key = "certs/f.exemple.fr.key";
+ certificate = "certs/f.exemple.fr.crt";
+ }
+
+ Component "salons.exemple.fr" "muc"
+ name = "Salons (chatrooms) chez exemple.fr"
+ modules_enabled = { "muc_mam", "vcard_muc" }
+ muc_room_default_language = "fr"
+ muc_log_expires_after = "never" -- histo permanent des groupes de
+ -- chats
+ log_all_rooms = true
+ muc_log_by_default = true
+ muc_log_presences = false
+ restrict_room_creation = "admin" -- seul l'admin peut cr&eacute;er des salons
+ ssl = {
+ key = "certs/salons.exemple.fr.key";
+ certificate = "certs/salons.exemple.fr.crt";
+ }
+</pre>
+<p>Oui, il faut rempla&ccedil;er <u><samp>its-a-secret</samp></u> par le
+mot de passe que vous avez not&eacute; tout &agrave; l'heure.<br>
+Certains auront aussi remarqu&eacute; qu'on a d&eacute;fini un utilisateur
+administrateur au d&eacute;but du fichier de config,
+<u>vous@exemple.fr</u>. On va donc cr&eacute;er l'utilisateur avec la
+commande:
+<pre>
+prosodyctl check # &ccedil;a va v&eacute;rifier si y'a des soucis dans la configuration
+prosodyctl adduser vous@exemple.fr
+</pre><br>
+
+<p>Cr&eacute;ez le fichier
+<samp>/var/www/chat.exemple.fr/index.html</samp> avec le texte suivant:
+<pre>
+&lt;!DOCTYPE html&gt;
+&lt;html class="no-js" lang="en"&gt;
+ &lt;head&gt;
+ &lt;title&gt;Converse&lt;/title&gt;
+ &lt;meta charset="utf-8"/&gt;
+ &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"/&gt;
+ &lt;meta name="description" content="Converse XMPP/Jabber Chat"/&gt;
+ &lt;meta name="keywords" content="xmpp chat webchat converse.js" /&gt;
+ &lt;link rel="manifest" href="/manifest.json"&gt;
+ &lt;link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" /&gt;
+ &lt;script src="/dist/libsignal-protocol.min.js"&gt;&lt;/script&gt;
+ &lt;script src="/dist/converse.min.js"&gt;&lt;/script&gt;
+ &lt;/head&gt;
+ &lt;body class="converse-fullscreen"&gt;
+ &lt;noscript&gt;You need to enable JavaScript to run the Converse.js chat app.&lt;/noscript&gt;
+ &lt;div id="conversejs-bg"&gt;&lt;/div&gt;
+ &lt;script&gt;
+ /*
+ @licstart
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ For more information, please refer to &lt;http://unlicense.org/&gt;
+ @licend
+ */
+ converse.initialize({
+ auto_away: 300, //absent au bout de 5minutes
+ auto_list_rooms: true,
+ auto_reconnect: true,
+ auto_xa: 600, //absence prolong&eacute;e au bout de 10minutes
+ bosh_service_url: 'https://chat.exemple.fr/http-bind/',
+ csi_waiting_time: 60,
+ enable_smacks: true,
+ i18n: 'fr', // pour avoir l'interface en fran&ccedil;ais
+ locked_domain: exemple.fr, // on verouille le domaine autoris&eacute;&agrave; se connecter
+ message_archiving: 'always',
+ persistent_store: 'IndexedDB', // jcbrand a dit qu'en 8.0.0
+ play_sounds: true,
+ // ça va aller plus vite avec l'IndexedDB
+ theme: 'concord',
+ view_mode: 'fullscreen',
+ websocket_url: 'wss://chat.exemple.fr/xmpp-websocket',
+ });
+ &lt;/script&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre><br>
+
+<p>C'est presque la fin de ce guide ! On va maintenant cr&eacute;er les
+fichiers de configuration nginx. <br>
+Cr&eacute;ons <samp>/etc/nginx/sites-enabled/exemple.fr.conf</samp> pour
+commencer:
+<pre>
+server {
+ listen 80;
+ server_name exemple.fr;
+
+ location / {
+ return 301 https://$host$uri;
+ }
+}
+
+server {
+ listen 443 ssl;
+ server_nam exemple.fr;
+ ssl_certificate /etc/letsencrypt/live/exemple.fr/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/exemple.fr/privkey.pem;
+
+ # this block is for the prosody's http_altconnect module
+ location ~* host-(meta|meta\.json) {
+ proxy_pass http://example.com:5280$uri;
+ proxy_http_version 1.1;
+ }
+}
+</pre><br>
+
+<p>Ensuite, cr&eacute;ez
+<samp>/etc/nginx/sites-enabled/f.exemple.fr.conf</samp>, ce sera pour le
+composant
+qui g&eacute;rera les pi&egrave;ces jointes:
+<pre>
+perl_modules /usr/local/lib/perl; # Path to upload.pm.
+perl_require upload.pm;
+
+server {
+ listen 80;
+ server_name f.exemple.fr;
+ location / {
+ return 301 https://$host$request_uri;
+ }
+}
+
+server {
+ # Specify directives such as "listen", "server_name", and TLS-related
+ # settings for the "server" that handles the uploads.
+ listen 443 ssl http2;
+ server_name f.exemple.fr;
+
+ ssl_certificate /etc/letsencrypt/live/f.exemple.fr/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/f.exemple.fr/privkey.pem;
+ # Uploaded files will be stored below the "root" directory. To minimize
+ # disk I/O, make sure the specified path is on the same file system as
+ # the directory used by Nginx to store temporary files holding request
+ # bodies ("client_body_temp_path", often some directory below /var).
+ root /var/www/upload;
+ index index.html;
+ # Specify this "location" block (if you don't use "/", see below):
+ location / {
+ perl upload::handle;
+ }
+
+ # Upload file size limit (default: 1m), also specified in your XMPP
+ # server's upload module configuration (see below):
+ client_max_body_size 100m;
+}
+</pre>
+<p>Ex&eacute;cutez <samp>nginx -t</samp> pour tester la configuration. Si
+aucune erreur n'est d&eacute;tect&eacute;e, cr&eacute;er le fichier
+<samp>/etc/nginx/sites-enabled/chat.exemple.fr.conf</samp>:
+<pre>
+server {
+ listen 80;
+ server_name chat.exemple.fr;
+
+ location / {
+ return 301 https://$host$uri;
+ }
+}
+
+server {
+ listen 443 ssl http2;
+ ssl_certificate /etc/letsencrypt/live/chat.exemple.fr/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/chat.exemple.fr/privkey.pem;
+ root /var/www/chat.exemple.fr;
+ index index.html;
+
+ # XMPP BOSH
+ location ^~ /http-bind {
+ proxy_pass https://exemple.fr:5281/http-bind;
+ proxy_http_version 1.1;
+ proxy_set_header Host exemple.fr;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # XMPP HTTP-Upload
+ location ^~ /upload {
+ proxy_pass https://f.exemple.fr; proxy_http_version 1.1;
+ proxy_set_header Host exemple.fr;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # XMPP Websockets
+ location /xmpp-websocket {
+ proxy_pass http://exemple.fr:5280/xmpp-websocket;
+ proxy_http_version 1.1;
+ proxy_buffering off;
+ proxy_set_header Connection "Upgrade";
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_read_timeout 900s;
+ }
+
+ # XMPP Account invite
+ location ^~ /invite {
+ proxy_pass https://exemple.fr:5281/invite;
+ proxy_http_version 1.1;
+ proxy_set_header Host exemple.fr;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # XMPP account register
+ location ^~ /register {
+ proxy_pass https://exemple.fr:5281/register;
+ proxy_http_version 1.1;
+ proxy_set_header Host exemple.fr;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # sur mon vps debian j'ai eu besoin de &ccedil;a pour
+ # que les pages d'invitation soit bien
+ # format&eacute;es
+ location = /share/bootstrap4/css/bootstrap.min.css {
+ alias /usr/lib/nodejs/bootstrap/dist/css/bootstrap.min.css;
+ }
+
+ location = /share/jquery/jquery.min.js {
+ alias /usr/lib/nodejs/jquery/dist/jquery.min.js;
+ }
+
+ location = /share/bootstrap4/js/bootstrap.min.js {
+ alias /usr/lib/nodejs/bootstrap/dist/js/bootstrap.min.js;
+ }
+
+}
+</pre>
+<p>Ex&eacute;cutez de nouveau <samp>nginx -t</samp> pour d&eacute;tecter
+d'&eacute;ventuels probl&egrave;mes de configuration. Une fois que tout
+est OK, ajoutez la ligne <samp>127.0.0.1 exemple.fr</samp>
+dans le fichier <samp>/etc/hosts</samp>.<br>
+Red&eacute;marrez le serveur Prosody et Nginx:
+<pre>
+systemctl start prosody nginx
+# ou
+prosodyctl start &amp;&amp; nginx -s reload
+</pre><br>
+
+<h3 id="xmpp-guide-con"><a
+href="#xmpp-guide-con">7. Connexion &agrave; l'interface web:</a></h3>
+<p>Rendez-vous maintenant sur la page web du chat: pour notre
+guide &ccedil;a serait <a
+href="https://chat.exemple.fr">https://chat.exemple.fr</a>
+, adaptez avec ce que vous avez.<br>
+Vous devriez voir quelque chose comme &ccedil;a:<br>
+<a href="img/conversejs_login.png"><img
+src="img/conversejs_login.png"></a>
+
+<p><b>Petite astuce</b>: si vous voulez vous connecter avec l'utilisateur
+<u><samp>vous@exemple.fr</samp></u> vous pouvez omettre la partie droite
+de votre adresse, comme ceci:<br>
+<a href="img/conversejs_logintrick.png"><img
+src="img/conversejs_logintrick.png"></a>
+
+<p>C'est gr&acirc;ce &agrave; la configuration de
+<samp><a
+href="https://conversejs.org/docs/html/configuration.html?highlight=locked_domain#locked-domain"
+target="_blank" rel="noopener">locked_domain</a></samp> lors de l'initialisation de Converse.js.<br>
+Une fois connect&eacute;, l'interface ressemblera a ceci:<br>
+<a href="img/conversejs_main.png"><img
+src="img/conversejs_main.png"></a>
+
+<p>Vous pouvez alors commencer &agrave; utiliser XMPP et rejoindre ou
+cr&eacute;er des salons, ajouter des contacts et bien s&ucirc;r discuter depuis
+cette interface web !<br><br>
+
+<h3 id="xmpp-guide-genlinks"><a href="#xmpp-guide-genlinks">8.
+G&eacute;n&eacute;ration des liens d'invitation</a></h3>
+
+<p>La chose qui nous int&eacute;resse surtout c'est la cr&eacute;ation
+de liens d'invitation accessible depuis le Web.<br>
+Pour ce faire, cliquez gauche sur la roue dent&eacute;e en haut &agrave; gauche
+&agrave; c&ocirc;t&eacute; de votre nom, cliquez sur <u>Commandes</u>.
+Dans le champ <u>"Sur quelle entit&eacute; voulez-vous lancer des
+commandes ?"</u> rentrez le nom de votre serveur XMPP, puis cliquez sur
+<u>"Lister les commandes disponibles"</u>. Vous devez avoir quelque chose
+de similaire &agrave; ceci:<br>
+<a href="img/conversejs_adhoc1.png"><img
+src="img/conversejs_adhoc1.png"></a><br>
+
+<p>Descendez un peu jusqu'&agrave; voir <u>"Create new contact invite"</u>
+et cliquez dessus:<br>
+<a href="img/conversejs_adhoc2.png"><img
+src="img/conversejs_adhoc2.png"></a><br>
+Une invitation s'est cr&eacute;&eacute;e ! Vous pouvez alors copier le texte
+contenu dans <u>"Invite web page"</u> et l'envoyer &agrave; l'un de vos amis,
+proches, etc...<br>
+Une fois ouvert, le lien am&egrave;ne sur une page de ce type:<br>
+<a href="img/conversejs_invitepage.png"><img
+src="img/conversejs_invitepage.png"></a><br>
+<p>La page d&eacute;tecte automatiquement votre plateforme et vous propose
+des applications XMPP natives en fonction. Dans le cas ou la plateforme
+est un smartphone, &ccedil;a am&eacute;nera sur la page de
+t&eacute;l&eacute;chargement de l'application puis ouvrira celle-ci tout
+en continuant l'inscription.<br>
+Le lien entour&eacute; de rouge
+en bas avec le texte <u>"register an account manually"</u> permet de
+s'inscrire via un formulaire web. Pratique pour juste cr&eacute;er le
+compte et le tester plus tard. Voici &agrave; quoi &ccedil;a
+ressemble:<br>
+<a href="img/conversejs_register1.png"><img
+src="img/conversejs_register1.png"></a><br>
+<p>Vous pouvez voir que j'ai commenc&eacute; a remplir le formulaire: une
+fois l'inscription envoy&eacute;e en cliquant sur le bouton
+<u>"Submit"</u>, vous serez accueilli par l'&eacute;cran
+suivant:<br>
+<a href="img/conversejs_register2.png"><img
+src="img/conversejs_register2.png"></a><br>
+<p>Une page vous confirmant votre inscription s'affiche, avec la
+possibilit&eacute; de montrer de nouveau le mot de passe saisie lors de
+l'inscription ou cas o&ugrave; (le bouton <u>"Show"</u>).<br>
+Le bouton ento&ucirc;r&eacute; de rouge, <u>"Log in via web"</u>,
+permettra
+&agrave; l'utilisateur inscrit de se connecter &agrave; l'interface web
+configur&eacute;e pendant ce tutoriel, et il vous aura en tant que
+contact.<br>
+<a href="img/conversejs_chatting.png"><img
+src="img/conversejs_chatting.png"></a><br>
+
+<h3 id="xmpp-guide-remarks"><a href="#xmpp-guide-remarks">9. Remarques</a></h3>
+<p>Le guide se finit ici! Je reviendrais pour corriger quelques fautes,
+&eacute;tourderies et oublis si j'en aper&ccedil;ois.
+J'ai des remarques &agrave; faire sur le logiciel:
+<ul style="list-style:disclosure-closed">
+ <li>Les messages chiffr&eacute;s OMEMO ne semblent pas lisibles entres
+ clients Converse.js. L'envoyeur peut lire son message OMEMO, mais si
+ le destinataire utilise uniquement converse.js, il y a de fortes
+ chances qu'il voit un message du type <u>"Ceci est un message chiffr&eacute;
+ avec OMEMO, que votre client ne semble pas prendre en charge..."</u>.
+ Des clients tel que Gajim ou Dino n'ont pas de soucis de ce
+ c&ocirc;t&eacute; l&agrave; d'apr&eacute;s mon exp&eacute;rience. J'ai
+ peut-&ecirc;tre aussi une erreur de configuration...</li>
+ <li>Je vous conseille d'utilisateur un seul navigateur pour
+ Converse.js si vous aimez avoir un historique des messages consistant.</li>
+ <li>Le chiffrement des pi&egrave;ces jointes n'est pas encore
+ impl&eacute;ment&eacute; (source: @jcbrand dans le salon
+ discuss@conference.conversejs.org).</li>
+ <li>Si vous voulez traduire en fran&ccedil;ais les pages
+ d'inscriptions, je vous invite &agrave; regarder le code source des
+ modules <samp>mod_invites_pages</samp>, <samp>mod_register_web</samp>
+ et <samp>mod_register_apps</samp>.
+</ul>
+
+<h3 id="xmpp-guide-docs"><a href="#xmpp-guide-docs">10.
+Documentations</a></h3>
+<p>Ces liens m'ont bien aid&eacute;:
+ <ul style="list-style:square">
+ <li><b>Converse.js</b>: <a
+ href="https://conversejs.org/docs/html/index.html" target="_blank"
+ rel="noopener">G&eacute;n&eacute;ral</a>, <a
+ href="https://conversejs.org/docs/html/configuration.html#configuration-settings"
+ target="_blank"
+ rel="noopener">param&eacute;trage et initialisation</a>, lire le code source HTML de la page <a
+ href="https://inverse.chat" target="_blank" rel="noopener">https://inverse.chat</a>
+
+ </li>
+ <li><b>Prosody</b>: <a
+ href="https://prosody.im/doc" target="_blank" rel="noopener">G&eacute;n&eacute;ral</a>, <a
+ href="https://prosody.im/doc/setting_up_bosh" target="_blank"
+ rel="noopener">BOSH+Nginx</a>,
+ <a href="https://prosody.im/doc/websocket" target="_blank"
+ rel="noopener">Websockets+Nginx</a>,
+ <a href="https://modules.prosody.im/xeps.html" target="_blank"
+ rel="noopener">Liens XEPs &lt;=&gt;
+ modules</a>, le <a
+ href="https://modules.prosody.im/mod_invites.html" target="_blank"
+ rel="noopener">module d'inscription via invitation</a>, le <a
+ href="https://modules.prosody.im/mod_http_upload_external.html"
+ target="_blank" rel="noopener">module d'envoi de fichiers via
+ script externe</a> et l'impl&eacute;mentation d'Holger (<a
+ href="https://github.com/weiss/ngx_http_upload" target="_blank"
+ rel="noopener">upload.pm</a>).</li>
+
+ <li><b>XMPP</b>: <a href="https://wiki.xmpp.org/">le wiki officiel</a>, <a href="https://compliance.conversations.im/">
+ tests de compliance des serveurs</a>.
+ </ul>
+
+<h3 id="xmpp-guide-thanks"><a href="#xmpp-guide-thanks">11.
+Remerciements</a></h3>
+<p>Tout ceci n'aurait pas &eacute;t&eacute; possible sans les logiciels
+libres et leurs collaborateurs. Merci &agrave; vous.<br>
+Plus sp&eacute;cifiquement:
+<ol style="list-style:square">
+ <li><a href="https://blog.laxu.de">laxu.de</a>, l'auteur de <a
+ href="https://blog.laxu.de/2018/09/08/conversejs-prosody/">
+ https://blog.laxu.de/2018/09/08/conversejs-prosody/</a>, pour le patch de
+ <samp>net/http/server.lua</samp> et les bouts de configuration nginx</li>
+ <li><a href="https://qorg11.net/">qorg</a> pour son guide sur XMPP, plus
+ particuli&egrave;rement l'"HTTP upload"
+ (<a
+ href="https://kill-9.xyz/guides/xmpp_server" target="_blank"
+ rel="noopener">https://kill-9.xyz/guides/xmpp_server</a>)</li>
+ <li> <a
+ href="https://wiki.xmpp.org/web/Jan-Carel_Brand_Application_2021"
+ target="_blank" rel="noopener">jcbrand</a>, l'auteur et
+ d&eacute;veloppeur principal de <a
+ href="https://conversejs.org/" target="_blank"
+ rel="noopener">Converse.js</a>. Tr&egrave;s r&eacute;actif aux
+ questions concernant XMPP et Converse.js dans le salon <a
+ href="xmpp:discuss@conference.conversejs.org?join">discuss@conference.conversejs.org</a>.</li>
+ <li><a href="xmpp:holger@jabber.fu-berlin.de?message">Holger Weiß</a>,
+ d&eacute;veloppeur travaillant sur le serveur XMPP ejabberd et admin du salon
+ <a
+ href="xmpp:ejabberd@conference.process-one.net?join">ejabberd@conference.process-one.net</a>
+ qui a pris de son temps pour me d&eacute;panner (<a
+ href="https://partage.les-miquelots.net/blog/un-rappel-lorsque-vous-mettez-en-place-un-serveur-xmpp-avec-prosody.html">le
+ probl&egrave;me en question</a>).</li>
+</ol><br>
+
+<p>&Agrave; bient&ocirc;t, passez une excellente journ&eacute;e et si vous
+avez des questions, remarques, suggestions ou am&eacute;liorations
+&agrave; me faire part, n'h&eacute;sitez pas &agrave; me contacter via
+mail ou XMPP &agrave; l'adresse <u>lionel ( @ ) les-miquelots ( . )
+net</u>.
+<footer>par <strong><a href='http://partage.les-miquelots.net/'>Miquel Lionel</a></strong></footer>
+</body>
+
+</html>
diff --git a/index.html b/index.html
new file mode 100755
index 0000000..ab6b6e2
--- /dev/null
+++ b/index.html
@@ -0,0 +1,855 @@
+<!DOCTYPE html>
+<html
+ lang="en">
+<head>
+<title>Setting up a XMPP server with a web client (converse.js+nginx+prosody on Debian)</title>
+<link rel='stylesheet'
+ type='text/css' href='styles.css'>
+<meta
+ charset='utf-8'/>
+</head>
+<body>
+<h1>Setting up a XMPP server with a web client (converse.js+nginx+prosody on Debian)</h1>
+<small>[<a
+ href='partage.les-miquelots.net/blog/2021/index.html#setting-up-a-xmpp-server-with-a-web-client-conversejsnginxprosody-on-debian'>link</a>&mdash;<a href='index.html'>standalone</a>]</small>
+<p><b>27/05/2021</b>: add the <samp>http_altconnect</samp> module to prosody config to avoid errors whining about <samp>/.well-known/host-meta</samp> not being present<br>
+<p><b>22/05/2021</b>: don't enable OMEMO by default, we let the users make its own choices and it can be better
+for multi-device history. I improved the apt command too (with <samp>-y --no-install-recommends</samp>).<br><br>
+
+<p>Hi everyone,<br><br>
+<p>Today we're going to install a XMPP server with a web client that is capable to
+send invites links to ease the onboarding of your friends and family.<br>
+I won't explain what is XMPP in great details, because it's outside the scope of this
+guide and some people will explain <i>faaar</i> better than me. I'm thinking about <a
+href="https://www.goffi.org/b/S%C3%A0T_DOTCLEAR_IMPORT_BLOG_default_goffi_99%3A2015%2F06%2F24%2FParlons-XMPP-%C3%A9pisode-1-les-bases">these
+articles on goffi.org (french blog)</a>. For english readers, the <a href="https://wiki.xmpp.org/web/Technology_overview" target="_blank" rel="noopener">official wiki</a> is a good start.<br>
+<b>tl;dr</b>: it's a protocol made of various standards and it's possible to build
+ secure decentralized instant messaging networks with it. There are possibilities
+ to create public and private rooms too, like any popular modern instant messaging software.
+<br><br>
+
+<p><div id="guide-sommaire">
+ <u>Table of matters:</u>
+ <ol>
+ <li><a href="#xmpp-guide-prereq">Prerequisites</a></li>
+ <li><a href="#xmpp-guide-dnszone">DNS zone configuration</a></li>
+ <li><a href="#xmpp-guide-iptables">Firewall configuration</a></li>
+ <li><a href="#xmpp-guide-pkgs">Packages setup</a></li>
+ <li><a href="#xmpp-guide-certs">Certificates setup</a></li>
+ <li><a href="#xmpp-guide-confpkgs">Packages configuration</a></li>
+ <li><a href="#xmpp-guide-con">Discovering the webclient</a></li>
+ <li><a href="#xmpp-guide-genlinks">Invite links generation</a></li>
+
+ <li><a href="#xmpp-guide-remarks">Remarks</a></li>
+ <li><a href="#xmpp-guide-docs">Documentations</a></li>
+ <li><a href="#xmpp-guide-thanks">Thanks</a></li>
+
+
+ </ol>
+ </div>
+ <br><br>
+
+<h3 id="xmpp-guide-prereq"><a href="#xmpp-guide-prereq">1.
+Prerequisites</a></h3>
+
+<p>Enough talking, this is what we're going to install:
+<ul>
+ <li><samp>certbot</samp>: to generate certificates to secure client=&gt;server and server&lt;=&gt;server communication.</li>
+ <li><samp>prosody</samp>: the XMPP server and the most important piece.</li>
+ <li><samp>nginx</samp>: reverse proxy that'll handle <span
+ style="color:green"><b>HTTPS</b></span> and connecting to the XMPP web client.</li>
+ <li><samp>conversejs</samp>: the web client for our XMPP server.</li>
+ <li><samp>libjs-bootstrap4 libjs-jquery</samp>: the
+ <samp><a
+ href="https://modules.prosody.im/mod_invites.html#external-dependencies"
+ target="_blank" rel="noopener" >mod_invites</a></samp> module for Prosody needs
+ these CSS and Javascript libraries for UI.
+ <li><samp>hg</samp>: thanks to it we'll clone the prosody module repo and keep it updated .</li>
+</ul><br>
+
+<p>Agree on a domain name: you'll replace mentions of <samp>example.com</samp> in this
+guide by your chosen domain name. You'll also need subdomains: one for the web client, <samp>chat.example.com</samp>
+, one for groups chats, <samp>salons.example.com</samp>, and finally another for uploading files <samp>f.example.com</samp>.<br>
+Don't forget to add type A records for these subdomains too.
+<br><br>
+
+<h3 id="xmpp-guide-dnszone"><a href="#xmpp-guide-dnszone">2. DNS zone configuration</a></h3>
+<p>First, stay on the DNS zone configuration of your registrar, we'll add some SRV and TXT type entries
+to ease XMPP clients and servers communications with us (more details about this
+<a href="https://wiki.xmpp.org/web/SRV_Records">on the XMPP wiki</a> or <a
+href="https://prosody.im/doc/dns">prosody docs</a>):
+<pre>
+_xmpp-client._tcp.example.com 86400 SRV 1 1 5222 example.com.
+_xmpps-client._tcp.example.com 86400 SRV 1 1 5223 example.com.
+_xmpp-server._tcp.example.com 86400 SRV 1 1 5269 example.com.
+_xmppconnect.example.com TXT _xmpp-client-xbosh=https://chat.example.com/http-bind
+_xmppconnect.example.com TXT _xmpp-client-websocket=wss://chat.example.com/xmpp-websocket
+</pre>
+
+<p><b>NB:</b> the left <samp>example.com</samp> is the XMPP <i>domain</i>, the one
+on the right is the <i>server</i> that'll actually answer requests and you'll need a
+type A record for it, not a CNAME. These records can come in handy when you want
+"clean" users adresses like <u>you@example.com</u> but <samp>example.com</samp> is used for something
+else, for example a website or mailserver, and the XMPP server is set up on <samp>xmpp.example.com</samp> .<br>
+If that's the case, change the <samp>example.com</samp> on the right to <samp>xmpp.example.com</samp>.<br><br>
+
+
+<h3 id="xmpp-guide-iptables"><a href="#xmpp-guide-iptables">3. Firewall configuration</a></h3>
+<p><b><u>IMPORTANT</u>:Log in as root before running the commands in this tutorial.</b>
+We'll then configure the <samp>iptables</samp> rules to avoid eating our fingers
+in rage and confusion later. I'm assuming your default <samp>iptables</samp> policy is set to
+<samp>DROP</samp> and you have some rules set allowing you to SSH into your server:
+<pre>
+iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT # client&lt;=&gt;server comms
+iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT # same as above but for encrypted ones
+iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT # server&lt;=&gt;servers comms
+iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT # for access to webclient
+iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT # HTTPS
+iptables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT # DNS requests
+iptables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT # useful for updating packages and letsencrypt
+iptables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT # same as above but we HTTPS
+
+iptables-save &gt; /etc/iptables/iptables.rules
+
+
+# pareil pour l'ipv6
+ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222 -j ACCEPT
+ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5223 -j ACCEPT
+ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT
+ip6tables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
+ip6tables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
+ip6tables -A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
+ip6tables -A OUTPUT -p tcp -m tcp --dport 80 -j ACCEPT
+ip6tables -A OUTPUT -p tcp -m tcp --dport 443 -j ACCEPT
+
+ip6tables-save &gt; /etc/iptables/ip6tables.rules
+systemctl enable --now iptables # enable iptables services so rules persists after reboots
+</pre><br>
+
+<h3 id="xmpp-guide-pkgs"><a href="#xmpp-guide-pkgs">4. Packages setup</a></h3>
+
+<p>Next, install <samp>prosody</samp> from
+ <a href="https://prosody.im/doc/installing_from_source">sources</a> or
+<a href="https://prosody.im/download/start">your package manager</a>.
+Two birds one stone, we'll install other needed packages too:
+<pre>sudo apt-get install -y --no-install-recommends prosody nginx-full \
+certbot python3-certbot-nginx \
+mercurial libjs-bootstrap4 libjs-jquery</pre><br>
+
+<p>We'll now clone the <samp>prosody-modules</samp> repo from source. Some distro package managers haven't always this one up to date (looking at you, Debian, stable branch). Execute the following:
+<pre>
+hg clone https://hg.prosody.im/prosody-modules/ /usr/lib/prosody/modules/
+</pre>
+<p>And here below is an updating script that you can put on your <samp>/etc/cron.daily/</samp> folder if it exists, or root crontab. On my server, I created the following file at <samp>/usr/local/sbin/maj_prosodymods.sh</samp>:
+<pre>
+#!/bin/sh
+MODDIR="/usr/lib/prosody/modules/"
+
+if test -d $MODDIR; then
+ cd $MODDIR
+ hg pull --update
+else
+ mkdir -p /usr/lib/prosody
+ hg clone https://hg.prosody.im/prosody-modules/ $MODDIR
+fi
+</pre>
+<p>Don't forget to flip the executable bit with <samp>chmod +x</samp>...
+<br><br>
+
+<p>Then, we'll download <samp>converse.js</samp>.
+On Debian Buster as of 23-05-2021 there isn't an official
+package for it, so we'll whip up another script that we can
+put in a crontab. On my server, I created the file <samp>/usr/local/sbin/update_conversejs.sh</samp> with the following:
+<pre>
+#!/bin/sh
+TEMPDIR="$(mktemp -d)"
+LOG=/var/log/update_conversejs.log # update log path
+WWWDIR='/var/www/chat.example.com' # where static and js files will be downloaded
+WWWUSER='www-data' # this value will differ on the
+ # distro you're using: it'll be 'http' for
+ # Arch Linux nginx for example.
+
+mkdir -p $WWWDIR/dist
+cd $TEMPDIR
+printf "\n\n$(date) - INFO - Starting updating conversejs..." | tee -a $LOG
+CURL_ERR=$(curl -s \ # get latest release tarball
+ https://api.github.com/repos/conversejs/converse.js/releases/latest | \
+ grep -o "https://.*\.tgz" | \
+ grep converse\.js- | \
+ xargs curl -fsOJL) || \
+ (printf "\n$(date) - ERR - Updating conversejs failed." | tee -a $LOG &amp;&amp; exit)
+
+# download libsignal for OMEMO support in conversejs webclient
+if test -e "$WWWDIR/dist/libsignal-protocol.min.js"; then
+ printf "\n$(date) - TOK - Libsignal already installed, skipping." | tee -a $LOG
+else
+ curl -fsOJL \
+ https://cdn.conversejs.org/3rdparty/libsignal-protocol.min.js || \
+ (printf "\n$(date) - ERR - Updating libsignal-protocol-javascript failed." | \
+ tee -a $LOG)
+ cp libsignal*.js $WWWDIR/dist/
+fi
+
+tar xzf *.tgz
+cp -rf package/dist $WWWDIR/
+sed "s/fullscreen\.html/index\.html/g" package/manifest.json &gt; $WWWDIR/manifest.json
+chown $WWWUSER:$WWWUSER -R $WWWDIR/
+chmod 755 -R $WWWDIR/
+rm -rf $TEMPDIR
+printf "\n$(date) - TOK - Done." | tee -a $LOG
+</pre>
+<p>Execute this script after fitting it to your taste, it'll make you
+save time for <a href="#xmpp-guide-confpkgs">step 6</a> because you won't have to create the <samp>$WWWDIR</samp>
+
+<h3 id="xmpp-guide-certs"><a href="#xmpp-guide-certs">5. Certificates setup</a></h3>
+
+<p>It's time to launch certbot to get our certificates.
+I'm assuming and I hope that you already have set up A records for
+the main domain <samp>example.com</samp> and subdomains too (<samp>chat.example.com</samp>, <samp>f.example.com</samp> and <samp>salons.example.com</samp>) in your registrar DNS zone:
+<pre>certbot certonly --agree-tos --nginx --deploy-hook "prosodyctl --root cert import /etc/letsencrypt/live" -d chat.example.com -d example.com -d f.example.com -d salons.example.com </pre>
+<p>Once it executes successfully, the certificates should be in
+<samp>/etc/letsencrypt/live</samp>.
+<br><br>
+
+
+<h3 id="xmpp-guide-confpkgs"><a href="#xmpp-guide-confpkgs">6. Packages configuration</a></h3>
+
+<p>It's time we dive into <samp>prosody</samp> config files.<br>
+Open the file <samp>/usr/lib/prosody/net/http/server.lua</samp>, we'll modify it
+in order to ease connecting nginx with the http interface of prosody (BOSH). In the
+file, find the following line:
+<pre>
+headers = { date = date_header, connection = response_conn_header };
+</pre>
+<p>and replace it by:
+<pre>
+headers = { date = date_header, connection = response_conn_header,
+ access_control_allow_origin = "example.com" };
+-- if 'example.com' dont fix it, replace it by '*'. Remember that your
+-- XMPP server domain name goes here.
+</pre><br>
+
+<p>Then, we'll configure the script that'll allow us to send files to others.
+Execute this:
+<pre>
+mkdir -p /var/www/upload
+chown www-data:www-data /var/www/upload # l'utilisateur de nginx peut
+ # diff&eacute;rer selon la distrib, faites gaffe
+mkdir -p /usr/local/lib/perl
+wget -O /usr/local/lib/perl/upload.pm https://raw.githubusercontent.com/weiss/ngx_http_upload/master/upload.pm
+</pre>
+<p>Open the downloaded file <samp>upload.pm</samp> and search for
+a line like this: <samp>my $external_secret = 'it-is-secret'</samp>.
+Replace <samp>it-is-secret</samp> by a strong passphrase without backslashes
+or quotes to avoid crashing the script due to syntax error later.<br>
+Save or write it down somewhere, it'll be useful very soon.
+<br><br>
+
+<p>Let's now get to write the <samp>prosody</samp> configuration file
+<samp>/etc/prosody/prosody.cfg.lua</samp> with the following:
+<pre>
+admins = { "you@example.com" }
+
+-- For more information see: https://prosody.im/doc/libevent
+-- use_libevent = true
+
+plugin_paths = { "/usr/lib/prosody/modules" }
+
+modules_enabled = {
+
+ -- Generally required
+ "roster"; -- Allow users to have a roster. Recommended ;)
+ "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
+ "tls"; -- Add support for secure TLS on c2s/s2s connections
+ "dialback"; -- s2s dialback support
+ "disco"; -- Service discovery
+
+ -- Not essential, but recommended
+ "carbons"; -- Keep multiple clients in sync
+ "carbons_copies";
+ "carbons_copies_adhoc";
+ "pep"; -- Enables users to publish their avatar, mood, activity, playing music and more
+ "private"; -- Private XML storage (for room bookmarks, etc.)
+ "blocklist"; -- Allow users to block communications with other users
+ "vcard4"; -- User profiles (stored in PEP)
+ "vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard
+ "smacks";
+ "bookmarks"; -- old module but compatible with most clients
+ --"bookmarks2";
+ "presence"; -- see user status (online, offline, etc)
+ "offline";
+
+ -- Nice to have
+ "version"; -- Replies to server version requests
+ "uptime"; -- Report how long server has been running
+ "time"; -- Let others know the time here on this server
+ "ping"; -- Replies to XMPP pings with pongs
+ "register"; -- Allow users to register on this server using a client and change passwords
+ "mam"; -- Store messages in an archive and allow users to access it
+ "csi";
+ "csi_simple"; -- Simple Mobile optimizations
+ "csi_battery_saver";
+ "vjud"; -- recherche d'utilisateurs dans les salons
+
+ -- Admin interfaces
+ "admin_adhoc"; -- Allows administration via an XMPP client that supports ad-hoc commands
+
+ -- HTTP modules
+ "bosh"; -- Enable BOSH clients, aka "Jabber over HTTP"
+ "websocket"; -- XMPP over WebSockets
+ "http_altconnect"; -- BOSH and WebSocket connection endpoints discoverable via HTTP
+
+ -- Other specific functionality
+ "posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
+ "limits"; -- Enable bandwidth limiting for XMPP connections
+ "groups"; -- Shared roster support
+ "server_contact_info"; -- Publish contact information for this service
+ "announce"; -- Send announcement to all online users
+ "welcome"; -- Welcome users who register accounts
+ "watchregistrations"; -- Alert admins of registrations
+ "motd"; -- Send a message to users when they log in
+ --"legacyauth"; -- Legacy authentication. Only used by some old clients and bots.
+ --"proxy65"; -- Enables a file transfer proxy service which clients behind NAT can use
+}
+
+-- These modules are auto-loaded, but should you want
+-- to disable them then uncomment them here:
+modules_disabled = {
+ -- "offline"; -- Store offline messages
+ -- "c2s"; -- Handle client connections
+ -- "s2s"; -- Handle server-to-server connections
+}
+
+motd_text = [[Hi everyone ! Welcome to my XMPP server. Have an happy chat !]]
+welcome_message = "It seems it's your first logging in, $username. Welcome and enjoy your stay at $host."
+
+daemonize = false;
+pidfile = "/run/prosody/prosody.pid";
+trusted_proxies = { "127.0.0.1", "::1" }
+
+-- Force certificate authentication for server-to-server connections
+c2s_require_encryption = true -- client to server require encryption
+s2s_require_encryption = true -- server to server require encryption
+s2s_secure_auth = true
+authentication = "internal_hashed"
+
+-- mam settings
+archive_expires_after = "never" -- permanent message history
+
+log = {
+ -- Log files (change 'info' to 'debug' for debug logs):
+ info = "/var/log/prosody/prosody.log";
+ error = "/var/log/prosody/prosody.err";
+ -- Syslog:
+ { levels = { "error" }; to = "syslog"; };
+}
+
+-- http and certificate shenanigans
+certificates = "certs"
+
+-- Include "conf.d/*.cfg.lua"
+
+legacy_ssl_ports = { 5223 }
+-- http_ports = { 5280 }
+-- http_interface = { "*" }
+-- https_ports = { 5281 }
+-- https_interfaces { "*" }
+
+
+cross_domain_bosh = { "https://chat.example.com" }
+cross_domain_websocket = { "https://chat.example.com" }
+consider_bosh_secure = true
+consider_websocket_secure = true
+allow_registration = true -- needed for mod_invites
+registration_invite_only = true -- registration is only permitted through invites
+vjud_mode = "opt-in" -- public search is opt-in
+
+-- https://prosody.im/security/advisory_20210512/
+gc = {
+ speed = 500;
+}
+c2s_stanza_size_limit = 256 * 1024
+s2s_stanza_size_limit = 512 * 1024
+
+limits = {
+ c2s = {
+ rate = "10kb/s";
+ };
+ s2sin = {
+ rate = "3kb/s";
+ };
+}
+-- https://prosody.im/security/advisory_20210512/
+
+ssl = {
+ key = "certs/example.com.key";
+ certificate = "certs/example.com.crt";
+}
+
+VirtualHost "example.com"
+ invites_page = "https://chat.example.com/invite?{invite.token}"
+ webchat_url = "https://chat.example.com/"
+ http_external_url = "https://chat.example.com/"
+ invite_expiry = 86400 * 7
+ http_paths = {
+ invites_page = "/invite";
+ invites_register_web = "/register";
+ }
+
+ modules_enabled = {
+ "invites";
+ "invites_adhoc";
+ "invites_page";
+ "invites_register";
+ "invites_register_web";
+ "http_libjs";
+ }
+
+ contact_info = {
+ abuse = { "mailto:you@example.com", "xmpp:you@example.com" };
+ admin = { "mailto:you@example.com", "xmpp:you@example.com" };
+ security = { "mailto:you@example.com", "xmpp:you@example.com" };
+ support = { "mailto:you@example.com", "xmpp:you@example.com" };
+ };
+
+ https_certificate = "certs/example.com.crt";
+ ssl = {
+ key = "certs/example.com.key";
+ certificate = "certs/example.com.crt";
+ }
+
+ Component "f.example.com" "http_upload_external"
+ http_upload_external_base_url = "https://f.example.com/"
+ http_upload_external_secret = "its-a-secret"
+ http_upload_external_file_size_limit = 104857600 -- limite de &agrave; 100Mo pour les envois de pjs
+ ssl = {
+ key = "certs/f.example.com.key";
+ certificate = "certs/f.example.com.crt";
+ }
+
+ Component "salons.example.com" "muc"
+ name = "Salons (chatrooms) chez example.com"
+ modules_enabled = { "muc_mam", "vcard_muc" }
+ muc_room_default_language = "fr"
+ muc_log_expires_after = "never" -- perm hist for gcs
+ log_all_rooms = true
+ muc_log_by_default = true
+ muc_log_presences = false
+ restrict_room_creation = "admin" -- only admin can create gcs
+ ssl = {
+ key = "certs/salons.example.com.key";
+ certificate = "certs/salons.example.com.crt";
+ }
+</pre>
+<p>As you can guess the <samp>its-a-secret</samp> value there must be replaced
+by the passphrase you wrote down earlier.<br>
+Some of you probably have noticed that the user <u>you@example.com</u>
+was listed as an admin, so let's create him with the following command line:
+<pre>
+prosodyctl check # checks config file
+prosodyctl adduser you@example.com # adapt to your username@domain
+</pre><br>
+
+<p>We'll now start to configure our web client, <samp>converse.js</samp>. Create
+ <samp>/var/www/chat.example.com/index.html</samp> with the following text:
+<pre>
+&lt;!DOCTYPE html&gt;
+&lt;html class="no-js" lang="en"&gt;
+ &lt;head&gt;
+ &lt;title&gt;Converse&lt;/title&gt;
+ &lt;meta charset="utf-8"/&gt;
+ &lt;meta name="viewport" content="width=device-width, initial-scale=1.0"/&gt;
+ &lt;meta name="description" content="Converse XMPP/Jabber Chat"/&gt;
+ &lt;meta name="keywords" content="xmpp chat webchat converse.js" /&gt;
+ &lt;link rel="manifest" href="/manifest.json"&gt;
+ &lt;link type="text/css" rel="stylesheet" media="screen" href="/dist/converse.min.css" /&gt;
+ &lt;script src="/dist/libsignal-protocol.min.js"&gt;&lt;/script&gt;
+ &lt;script src="/dist/converse.min.js"&gt;&lt;/script&gt;
+ &lt;/head&gt;
+ &lt;body class="converse-fullscreen"&gt;
+ &lt;noscript&gt;You need to enable JavaScript to run the Converse.js chat app.&lt;/noscript&gt;
+ &lt;div id="conversejs-bg"&gt;&lt;/div&gt;
+ &lt;script&gt;
+ /*
+ @licstart
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+ For more information, please refer to &lt;http://unlicense.org/&gt;
+ @licend
+ */
+ converse.initialize({
+ auto_away: 300, // in seconds
+ auto_list_rooms: true,
+ auto_reconnect: true,
+ auto_xa: 600, // extended away, in seconds
+ bosh_service_url: 'https://chat.example.com/http-bind/',
+ csi_waiting_time: 60, // smartphone battery optimizations
+ enable_smacks: true,
+ locked_domain: example.com, // xmpp server that the client will only be allowed to connect to
+ message_archiving: 'always',
+ persistent_store: 'IndexedDB', // jcbrand said it'll be fast in 8.0.0 and better than localStorage
+ play_sounds: true,
+ theme: 'concord', // dark theme
+ view_mode: 'fullscreen',
+ websocket_url: 'wss://chat.example.com/xmpp-websocket', // can be unstable, if you got problems
+ // don't hesitate to comment it
+ });
+ &lt;/script&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre><br>
+
+<p>This guide is almost done ! We now need to do the nginx config files.<br>
+Let's start with <samp>/etc/nginx/sites-enabled/example.com.conf</samp>:
+<pre>
+server {
+ listen 80;
+ server_name example.com;
+
+ location / {
+ return 301 https://$host$uri;
+ }
+}
+
+server {
+ listen 443 ssl;
+ server_nam example.com;
+ ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
+
+ proxy_set_header Access-Control-Allow-Origin 'chat.example.com';
+
+ # this block is for the prosody's http_altconnect module
+ location ~* host-(meta|meta\.json) {
+ proxy_pass http://example.com:5280$uri;
+ proxy_http_version 1.1;
+ }
+}
+</pre><br>
+
+<p>Next, let's continue with
+ <samp>/etc/nginx/sites-enabled/f.example.com.conf</samp>, it's the config file for
+ uploading files:
+<pre>
+perl_modules /usr/local/lib/perl; # Path to upload.pm.
+perl_require upload.pm;
+
+server {
+ listen 80;
+ server_name f.example.com;
+ location / {
+ return 301 https://$host$request_uri;
+ }
+}
+
+server {
+ # Specify directives such as "listen", "server_name", and TLS-related
+ # settings for the "server" that handles the uploads.
+ listen 443 ssl http2;
+ server_name f.example.com;
+
+ ssl_certificate /etc/letsencrypt/live/f.example.com/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/f.example.com/privkey.pem;
+ # Uploaded files will be stored below the "root" directory. To minimize
+ # disk I/O, make sure the specified path is on the same file system as
+ # the directory used by Nginx to store temporary files holding request
+ # bodies ("client_body_temp_path", often some directory below /var).
+ root /var/www/upload;
+ index index.html;
+ # Specify this "location" block (if you don't use "/", see below):
+ location / {
+ perl upload::handle;
+ }
+
+ # Upload file size limit (default: 1m), also specified in your XMPP
+ # server's upload module configuration (see below):
+ client_max_body_size 100m;
+}
+</pre>
+
+<p>Execute <samp>nginx -t</samp> to test the config files created so far.
+Once no errors are detected create
+ <samp>/etc/nginx/sites-enabled/chat.example.com.conf</samp>:
+<pre>
+server {
+ listen 80;
+ server_name chat.example.com;
+
+ location / {
+ return 301 https://$host$uri;
+ }
+}
+
+server {
+ listen 443 ssl http2;
+ ssl_certificate /etc/letsencrypt/live/chat.example.com/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/chat.example.com/privkey.pem;
+ root /var/www/chat.example.com;
+ index index.html;
+
+ # XMPP BOSH
+ location ^~ /http-bind {
+ proxy_pass https://example.com:5281/http-bind;
+ proxy_http_version 1.1;
+ proxy_set_header Host example.com;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # XMPP HTTP-Upload
+ location ^~ /upload {
+ proxy_pass https://f.example.com; proxy_http_version 1.1;
+ proxy_set_header Host example.com;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # XMPP Websockets
+ location /xmpp-websocket {
+ proxy_pass http://example.com:5280/xmpp-websocket;
+ proxy_http_version 1.1;
+ proxy_buffering off;
+ proxy_set_header Connection "Upgrade";
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_read_timeout 900s;
+ }
+
+ # XMPP Account invite
+ location ^~ /invite {
+ proxy_pass https://example.com:5281/invite;
+ proxy_http_version 1.1;
+ proxy_set_header Host example.com;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # XMPP account register
+ location ^~ /register {
+ proxy_pass https://example.com:5281/register;
+ proxy_http_version 1.1;
+ proxy_set_header Host example.com;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_buffering off;
+ tcp_nodelay on;
+ }
+
+ # sur mon vps debian j'ai eu besoin de &ccedil;a pour
+ # que les pages d'invitation soit bien
+ # format&eacute;es
+ location = /share/bootstrap4/css/bootstrap.min.css {
+ alias /usr/lib/nodejs/bootstrap/dist/css/bootstrap.min.css;
+ }
+
+ location = /share/jquery/jquery.min.js {
+ alias /usr/lib/nodejs/jquery/dist/jquery.min.js;
+ }
+
+ location = /share/bootstrap4/js/bootstrap.min.js {
+ alias /usr/lib/nodejs/bootstrap/dist/js/bootstrap.min.js;
+ }
+
+}
+</pre>
+<p>Execute again <samp>nginx -t</samp> to spot any troubles with your
+config files. Once all is OK, add the line
+<pre>
+# XMPP server domain name here, i.e it
+# could be xmpp.example.com in your case
+127.0.0.1 example.com
+</pre>
+
+<p>in your <samp>/etc/hosts</samp>.<br>
+Restart <samp>nginx</samp> and <samp>prosody</samp>:
+<pre>
+systemctl start prosody nginx
+# or
+prosodyctl start &amp;&amp; nginx -s reload
+</pre><br>
+
+<h3 id="xmpp-guide-con"><a
+href="#xmpp-guide-con">7. Discovering the webclient</a></h3>
+
+<p>Let's see the results of our work! Open a web browser and navigate
+to <a href="https://chat.example.com">https://chat.example.com</a>, YMMV.
+You should see something like this:
+<a href="img/0conversejs_login.png"><img
+src="img/0conversejs_login.png"></a>
+
+<p><b>Small trick</b>: if you want to login as
+<u><samp>you@example.com</samp></u>, you can omit the right part of your adress like
+this:<br>
+<a href="img/0conversejs_logintrick.png"><img
+src="img/0conversejs_logintrick.png"></a>
+<p>It's thanks to the
+<samp><a
+href="https://conversejs.org/docs/html/configuration.html?highlight=locked_domain#locked-domain"
+target="_blank" rel="noopener">locked_domain</a></samp> parameter.<br>
+
+Once logged in your view should be like this:<br>
+<a href="img/0conversejs_main.png"><img
+src="img/0conversejs_main.png"></a>
+
+<p>You can then start to use XMPP and join or create group chats, add friends and chat
+with them from there !<br><br>
+
+<h3 id="xmpp-guide-genlinks"><a href="#xmpp-guide-genlinks">8. Invite links generation</a></h3>
+
+<p>The really interesting thing is that we can create invite links from
+Converse.js thanks to the <samp>admin_adhoc</samp> module.<br>
+To do so, left click on the gear icon on the top left next to your
+username, then click <u>Commands</u>.
+In the <u>'On which entity do you want to run commands?'</u> field, type
+in your XMPP server domain name and left click <u>'List available commands'</u>.
+You should have something similar to this:<br>
+<a href="img/0conversejs_adhoc1.png"><img
+src="img/0conversejs_adhoc1.png"></a><br>
+
+<p>Scroll down a bit and left click on <u>"Create new contact invite"</u>:<br>
+<a href="img/0conversejs_adhoc2.png"><img
+src="img/0conversejs_adhoc2.png"></a><br>
+
+<p>An invite link has been created ! You can now copy and send it to your
+friends, family, etc...<br>
+Once opened, the link will lead to this kind of page:
+<a href="img/0conversejs_invitepage.png"><img
+src="img/0conversejs_invitepage.png"></a><br>
+<p>The web page auto-detects your OS platform and will
+suggest you compatible XMPP software to download. In the
+case you're on a smartphone, the links will download the apps
+on their respective stores and continue the registration
+after opening thanks to the <u>Invite URI</u>.<br>
+The text squared in red in the bottom left, <u>'register an account manually'</u>,
+allows you to register via the web browser. It's handy when you want to create
+an account and test it later. Here how it looks:<br>
+<a href="img/0conversejs_register1.png"><img
+src="img/0conversejs_register1.png"></a><br>
+
+<p>As you can see I started to fill in the form: once submitted succesfully,
+ you'll be greeted with this:
+<a href="img/0conversejs_register2.png"><img
+src="img/0conversejs_register2.png"></a><br>
+
+<p>A page confirming your registration is shown, with the possibility to view your chat adress and password again to
+write them down somewhere. The user can then log in with
+Converse.js by clicking on the <u>"Log in via web"</u> button.
+Once logged in, you will be added to his roster (because we did a <i>contact</i> invite) and he can start to chat with you.<br>
+<a href="img/0conversejs_chatting.png"><img
+src="img/0conversejs_chatting.png"></a><br>
+
+<h3 id="xmpp-guide-remarks"><a href="#xmpp-guide-remarks">9. Remarks</a></h3>
+<p>The guide ends there! I'll get back from time to time to fix some typos and inconstencies when I spot them.
+I've got some notes and remarks:
+<ul style="list-style:disclosure-closed">
+ <li>OMEMO encrypted chats don't seem readable between converse.js clients.
+ The sender can read it fine, but if the recipient only uses converse.js, there's
+ an high probability he sees the dreaded <u>I sent you an OMEMO encrypted message but your client doesn't seem to support that...</u> message.
+ From my experience, Dino and Gajim can decrypt these chats just fine. I've maybe
+ misconfigured something ?</li>
+ <li>Due to reliance on the browser cache to display last messages, I recommend
+ to dedicate a browser (and maybe ideally a browser <i>profile</i>) to your converse.js
+ client if you like having a consistent messaging history.</li>
+ <li>File encryption via OMEMO isn't implemented yet (source: @jcbrand in <a href="xmpp:discuss@conference.conversejs.org?join">discuss@conference.conversejs.org</a>).
+ <li>If you want to translate the invites pages in your language,
+ look into the source code of <samp>mod_invites_pages</samp>,
+ <samp>mod_register_web</samp> and <samp>mod_register_apps</samp>.</li>
+</ul>
+
+
+<h3 id="xmpp-guide-docs"><a href="#xmpp-guide-docs">10. Documentations</a></h3>
+
+<p>Those links greatly helped me:
+ <ul style="list-style:square">
+ <li><b>Converse.js</b>: <a
+ href="https://conversejs.org/docs/html/index.html" target="_blank"
+ rel="noopener">General</a>, <a
+ href="https://conversejs.org/docs/html/configuration.html#configuration-settings"
+ target="_blank"
+ rel="noopener">config and initilization</a><br>
+ Reading the HTML source code of<a
+ href="https://inverse.chat" target="_blank" rel="noopener">https://inverse.chat</a>
+
+ </li>
+ <li><b>Prosody</b>: <a
+ href="https://prosody.im/doc" target="_blank" rel="noopener">General</a>, <a
+ href="https://prosody.im/doc/setting_up_bosh" target="_blank"
+ rel="noopener">BOSH+Nginx</a>,
+ <a href="https://prosody.im/doc/websocket" target="_blank"
+ rel="noopener">Websockets+Nginx</a>,
+ <a href="https://modules.prosody.im/xeps.html" target="_blank"
+ rel="noopener">Links between XEPs and modules</a>, <a
+ href="https://modules.prosody.im/mod_invites.html" target="_blank"
+ rel="noopener">mod_invites docs</a>, <a
+ href="https://modules.prosody.im/mod_http_upload_external.html"
+ target="_blank" rel="noopener">mod_http_upload_external docs</a> and Holger's implementation ,<a
+ href="https://github.com/weiss/ngx_http_upload" target="_blank"
+ rel="noopener">upload.pm</a>.</li>
+ <li><b>XMPP</b>: <a href="https://wiki.xmpp.org/web/Main_Page" target="_blank" rel="noopener">the Wiki</a>, <a href="https://compliance.conversations.im/" target="_blank" rel="noopener">compliance tester</a>.
+ </ul>
+
+
+<h3 id="xmpp-guide-thanks"><a href="#xmpp-guide-thanks">11.
+Thanks</a></h3>
+
+<p>This wouldn't have been possible without free software and their contributors. Thanks you so much.<br>
+To be more specific:
+<ol style="list-style:square">
+ <li><a href="https://blog.laxu.de">laxu.de</a>, author of
+ <a href="https://blog.laxu.de/2018/09/08/conversejs-prosody/">
+ https://blog.laxu.de/2018/09/08/conversejs-prosody/</a> which walks through the patching of <samp>net/http/server.lua</samp> and gives some related nginx configuration snippets</li>
+ <li><a href="https://qorg11.net/">qorg</a> for <a href="https://kill-9.xyz/guides/xmpp_server" target="_blank" rel="noopener">his XMPP guide</a>, in particular the part dealing about <samp>mod_http_upload_external</samp>
+ <li> <a
+ href="https://wiki.xmpp.org/web/Jan-Carel_Brand_Application_2021"
+ target="_blank" rel="noopener">jcbrand</a>, creator and main developer of <a
+ href="https://conversejs.org/" target="_blank"
+ rel="noopener">Converse.js</a>. Very quick to respond to questions
+ relating to XMPP and Converse.js in <a href="xmpp:discuss@conference.conversejs.org?join">discuss@conference.conversejs.org</a>.</li>
+ <li><a href="xmpp:holger@jabber.fu-berlin.de?message">Holger Weiß</a>,
+ a developer working on the ejabberd XMPP server and admin of
+ <a
+ href="xmpp:ejabberd@conference.process-one.net?join">ejabberd@conference.process-one.net</a> who took his time
+ to help me (<a href="https://partage.les-miquelots.net/engver/blog/reminder-when-setting-up-a-xmpp-server-with-prosody.html">problem and fix here</a>).</li>
+</ol><br>
+
+<p>See you soon and have a great day ! If you have any questions, remarks, suggestions or improvements to point out, don't hesitate to message me via XMPP or email at <u>lionel ( @ ) les-miquelots ( . ) net</u>.
+<footer>by <strong><a href='http://partage.les-miquelots.net/'>Miquel Lionel</a></strong></footer>
+</body>
+
+</html>
diff --git a/styles.css b/styles.css
new file mode 100755
index 0000000..4ca9777
--- /dev/null
+++ b/styles.css
@@ -0,0 +1,192 @@
+*{
+ line-height:24px;
+}
+
+img{
+ padding:10px;
+ height:60%;
+ width:70%;
+}
+
+#spinthonk{
+ padding:1px;
+ height:50px;
+ width:50px;
+}
+
+#gitimg, #rssimg, #rssimg2 {
+ height:24px;
+ width:24px;
+ padding:2px;
+
+}
+
+.pagetoplink {
+ position: fixed;
+ width: 20%;
+ bottom: 0;
+ left: 0;
+ padding: 0.5em;
+}
+
+
+#omemo_fpts {
+margin-left:17%;
+}
+
+#guide-sommaire{
+ padding:5px;
+ border:1px solid black;
+}
+
+body{
+ background-color:beige;
+ color:#222222;
+ font-family: Sans-Serif;
+ font-style: normal;
+ font-weight: 375;
+ font-size:12pt;
+}
+
+h1,h2,h3{
+ line-height:30px;
+ text-align:center;
+ margin:auto;
+ width:70%;
+}
+
+h2,h3{
+ text-align:left;
+ margin-top:2.5%;
+}
+
+p,table,pre,ol,ul,#guide-sommaire{
+ color: #222222;
+ width:70%;
+ margin:auto;
+}
+
+p{
+text-indent:3%;
+
+}
+
+#footnotes {
+ font-size:0.85em;
+}
+
+pre{
+ overflow:auto;
+ padding:10px;
+ border-radius:10px;
+ border:1px solid grey;
+ line-height:15px;
+ color:white;
+ background-color:#222236;
+ font-size:0.9em;
+}
+
+pre, code{
+ font-family:monospace;
+}
+
+pre a {
+ color:cyan;
+}
+
+table{
+ width:85%;
+ padding:5px;
+}
+
+td,tr{
+ width:25%;
+ text-align:center;
+ padding:5px;
+}
+
+td,th{
+ border-bottom:1px solid black;
+}
+
+th{
+ border:2px solid #222222;
+ border-width:2px;
+}
+
+li{
+ width:90%;
+ margin:auto;
+}
+
+a{
+ color:teal;
+ text-decoration:none;
+}
+
+a:hover{
+ text-decoration:underline;
+}
+
+.blogentry{
+ width:65%;
+ margin:auto;
+}
+
+.blogentry h2, .blogentry p{
+ width:100%;
+}
+
+footer{
+ width:70%;
+ margin:auto;
+ padding-top:15px;
+}
+
+.blogentry small, body small{
+ width:100%;
+ display:block;
+ text-align:center;
+}
+
+
+blockquote{
+ width:65%;
+ margin:auto;
+ padding:10px;
+ margin-top:10px;
+ margin-bottom:10px;
+ border-left:3px solid grey;
+ text-align:none;
+}
+
+blockquote small{
+ text-align:inherit;
+}
+
+/*ripped from mozilla MDN, thx lol*/
+kbd {
+ background-color: #eee;
+ border-radius: 3px;
+ border: 1px solid #b4b4b4;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .2), 0 2px 0 0 rgba(255,
+ 255, 255, .7) inset;
+ color: #333;
+ display: inline-block;
+ font-size: .85em;
+ font-weight: 700;
+ line-height: 1;
+ padding: 2px 4px;
+ white-space: nowrap;
+}
+figcaption {
+ text-align: center;
+ font-style: italic;
+ font-size: 90%;
+}
+
+@media screen and (max-width: 740px) {
+ #omemo_fpts {
+ margin-left:25%;
+ }
+}