#!/bin/sh

# Install and set up Jitsi (mostly) per:
# https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart
# on Debian >= 10 host
# with direct Internet connectivity - no firewall or NAT/SNAT between
# host and The Internet
# and with letsencrypt certs and such already pre-populated in
# the customary locations:
# /etc/letsencrypt/live/"$DOMAIN"/{privkey,fullchain}.pem
# with customary links to applicable
# /etc/letsencrypt/archive/"$DOMAIN"/{privkey,fullchain}*.pem
# locations
# DOMAIN must already be set appropriately in the environment, e.g.
# DOMAIN=jitsi.example.com
# We also skip tuning/resource limits, so this configuration is
# more suitable for development or (very) small-scale testing.
# After base installation, we reconfigure to:
# reasonably secure from The Internet (unauthenticated can't create rooms)

# vi(1) :se tabstop=4

set -x
set -e

umask 022

[ -n "$DOMAIN" ]

[ 0 = "$(id -u)" ]

[ -f /etc/debian_version ]
expr match "$(cat /etc/debian_version)" '[1-9][0-9]*' >>/dev/null

apt-get -y update

my_have_pkg(){
	[ "$#" -eq 1 ]
	pkgre="$(echo "$1" | sed -e 's/\./\\&/g')"
	dpkg -l "$1" 2>>/dev/null |
	grep "^ii  *$pkgre " >>/dev/null
}

my_get_pkg(){
	[ "$#" -eq 1 ]
	my_have_pkg "$1" ||
	apt-get -y install "$1"
}

my_get_pkg gnupg2
my_get_pkg apt-transport-https
my_get_pkg nginx-full
my_get_pkg man-db
my_get_pkg psmisc
my_get_pkg rcs

hostnamectl set-hostname "$DOMAIN"

# /etc/hosts
F="$(hostname -f)"
S="$(hostname -s)"
my_get_pkg dnsutils
#IPv6="$(dig @ns1.google.com. -6 o-o.myaddr.l.google.com. TXT +short | tr -d \")"
# this just does IPv4, also presumes host direct on The Internet
IPv4="$(dig @ns1.google.com. -4 o-o.myaddr.l.google.com. TXT +short | tr -d \")"
[ -n "$IPv4" ]
perl -i -e '
	$^W=1;
	use strict;

	my $IPv4='\'''"$IPv4"''\'';
	my $F='\'''"$F"''\'';
	my $S='\'''"$S"''\'';

	my $substituted=0;
	while(<>){
		chomp;
		local @_=split(/[ \t]+|(?=#)/,$_,-1);
		shift(@_) if $#_ >= 0 and $_[0] eq '\'''\'';
		if($#_ >= 0 and $_[0] eq '\'''"$IPv4"''\''){
			if($substituted){
			}else{
				print(
					'\'''"$IPv4"' '\'',
					'\'''"$F"' '\'',
					'\'''"$S"''\'',
					"\n",
				);
				$substituted=1;
			}
		}else{
			print "$_\n";
		};
		if(!$substituted and eof){
			print(
				'\'''"$IPv4"' '\'',
				'\'''"$F"' '\'',
				'\'''"$S"''\'',
				"\n",
			);
		};
	};
' /etc/hosts

ping -n -c 3 $(hostname)

my_get_pkg curl

curl -s https://download.jitsi.org/jitsi-key.gpg.key |
gpg --dearmor > /usr/share/keyrings/jitsi-keyring.gpg

echo 'deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/' >/etc/apt/sources.list.d/jitsi-stable.list

sudo apt-get -y update

if type ufw >>/dev/null 2>&1; then
	exit 1
else
	:
fi

[ -f /etc/letsencrypt/live/"$DOMAIN"/fullchain.pem ]
[ -f /etc/letsencrypt/live/"$DOMAIN"/privkey.pem ]

chown 0:0 /etc/letsencrypt/live/"$DOMAIN"/privkey.pem
chmod u=r,go= /etc/letsencrypt/live/"$DOMAIN"/privkey.pem

chown 0:0 /etc/letsencrypt/live/"$DOMAIN"/fullchain.pem
chmod a=r /etc/letsencrypt/live/"$DOMAIN"/fullchain.pem

chown 0:0 \
	/etc/letsencrypt \
	/etc/letsencrypt/archive \
	/etc/letsencrypt/archive/"$DOMAIN" \
	/etc/letsencrypt/live \
	/etc/letsencrypt/live/"$DOMAIN"
chmod u=rwx,go=rx \
	/etc/letsencrypt \
	/etc/letsencrypt/archive \
	/etc/letsencrypt/archive/"$DOMAIN" \
	/etc/letsencrypt/live \
	/etc/letsencrypt/live/"$DOMAIN"

set +x
echo enter/select these on the following:
echo DOMAIN: "$DOMAIN"
echo 'choose Generate a new self-signed certificate'
echo 'Press <RETURN> to continue: '; read x; unset x
set -x
apt-get -y install jitsi-meet

# /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
# To cover net of what the above and its reverse dependencies do
# at least for ssl cert installation, but not putting on cron entry
# to run certbot on periodic basis.  We'll also mostly utilized cert and
# such from its existing location under /etc/letsencrypt
cd /usr/local/sbin
CERT_KEY="/etc/letsencrypt/live/$DOMAIN/privkey.pem"
CERT_CRT="/etc/letsencrypt/live/$DOMAIN/fullchain.pem"
COTURN_CERT_DIR=/etc/coturn/certs
mkdir -p "$COTURN_CERT_DIR"
chown -R turnserver:turnserver /etc/coturn/
chmod -R 700 /etc/coturn/
TURN_CONFIG=/etc/turnserver.conf
umask 077
RENEWED_LINEAGE=/etc/letsencrypt/live/"$DOMAIN"
ln -sf "$RENEWED_LINEAGE/fullchain.pem" \
"$COTURN_CERT_DIR/$DOMAIN.fullchain.pem"
cp "$RENEWED_LINEAGE/privkey.pem" "$COTURN_CERT_DIR/$DOMAIN.privkey.pem"
chown turnserver "$COTURN_CERT_DIR/$DOMAIN.privkey.pem"
chmod 400 "$COTURN_CERT_DIR/$DOMAIN.privkey.pem"
sed -i "/^cert/c\cert=\/etc\/coturn\/certs\/$DOMAIN.fullchain.pem" \
"$TURN_CONFIG"
sed -i "/^pkey/c\pkey=\/etc\/coturn\/certs\/$DOMAIN.privkey.pem" \
"$TURN_CONFIG"
systemctl restart coturn.service
CONF_FILE="/etc/nginx/sites-available/$DOMAIN.conf"
CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\&/g;s/\//\\&/g')
sed -ne "s/ssl_certificate_key\ \/etc\/jitsi\/meet\/.*key/ssl_certificate_key\ $CERT_KEY_ESC/gp" \
"$CONF_FILE"
CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\&/g;s/\//\\&/g')
sed -ne "s/ssl_certificate\ \/etc\/jitsi\/meet\/.*crt/ssl_certificate\ $CERT_CRT_ESC/gp" \
"$CONF_FILE"
unset CERT_CRT CERT_CRT_ESC CERT_KEY CERT_KEY_ESC CONF_FILE \
	COTURN_CERT_DIR RENEWED_LINEAGE TURN_CONFIG
rm /etc/nginx/sites-enabled/default 2>>/dev/null || :
umask 022
cd
ln -sf /etc/letsencrypt/live/"$DOMAIN"/fullchain.pem /etc/jitsi/meet/"$DOMAIN".crt
ln -sf /etc/letsencrypt/live/"$DOMAIN"/privkey.pem /etc/jitsi/meet/"$DOMAIN".key
systemctl reload nginx.service

# That completes base Jitsi installation,
# however at this point it is unsecured,
# Jitsi open to any and all on The Internet,
# without any authentication - to both create and join rooms, etc.

# Let's start securing it, per:
# https://jitsi.github.io/handbook/docs/devops-guide/secure-domain

# require login (all users)
sed -i 's/^\([ 	]*authentication[ 	]*=[ 	]*"\)anonymous"[ 	]*$/\1internal_hashed"/' \
/etc/prosody/conf.avail/"$DOMAIN".cfg.lua
systemctl restart prosody.service #reload doesn't suffice, need restart

# Now let's proceed to allow unauthenticated to join existing room,
# but not create room - must authenticate to create room

cat << __EOT__ >> /etc/prosody/conf.avail/"$DOMAIN".cfg.lua

VirtualHost "guest.$DOMAIN"
    authentication = "anonymous"
    c2s_require_encryption = false
__EOT__
systemctl restart prosody.service

sed -i -e \
'
s/^\([ 	]*\)\/\/[ 	]*\(anonymousdomain:\).*$/\1\2 '\''guest.'"$DOMAIN"''\'',/
' \
/etc/jitsi/meet/"$DOMAIN"-config.js

cat << __EOT__ >> /etc/jitsi/jicofo/sip-communicator.properties
org.jitsi.jicofo.auth.URL=XMPP:$DOMAIN
__EOT__

set +x
echo 'enter usernames/passwords to (re)register:'
while :
do
	echo -n "username (^D if done): "
	read -r username || { :; break; }
	stty -echo
	echo -n "password: "
	read -r password
	stty echo
	echo
	stty -echo
	echo -n "password (again to confirm): "
	read -r p2
	stty echo
	echo
	[ x"$password" = x"$p2" ] || {
		echo "Passsords don't match, try again." 1>&2
		continue
	}
	prosodyctl deluser "$username" >>/dev/null 2>&1 || :
	prosodyctl register "$username" "$DOMAIN" "$password"
done
unset username password p2
echo
set -x

# We need to reload/restart some services here, for the preceeding auth
# changes to take effect.

# May be overkill, but this seems to cover reload/restart of the needed:
(umask 022 && cd / && set -x && { for d in prosody nginx jicofo coturn \
jitsi-videobridge2; do systemctl stop "$d" || break; done
for u in jitsi-videobridge2 coturn jicofo nginx prosody; do
systemctl start "$u" || break; done; })
