Merge branch 'stretch' of https://github.com/bashrc/freedombone
This commit is contained in:
commit
c33f236ed5
|
@ -16,6 +16,10 @@
|
|||
</center>
|
||||
#+END_EXPORT
|
||||
|
||||
#+BEGIN_CENTER
|
||||
[[file:images/cryptpad.jpg]]
|
||||
#+END_CENTER
|
||||
|
||||
This is similar to [[./app_etherpad.html][EtherPad]] but with better security and more document types which can be collaboratively edited in real time. It includes not just text editing but also creating presentations, voting and editing source code.
|
||||
|
||||
For added security this system is only available via an onion address, so you and your collaborators will need to be using Tor compatible browsers.
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
#+TITLE:
|
||||
#+AUTHOR: Bob Mottram
|
||||
#+EMAIL: bob@freedombone.net
|
||||
#+KEYWORDS: freedombone, kanboard
|
||||
#+DESCRIPTION: How to use KanBoard
|
||||
#+OPTIONS: ^:nil toc:nil
|
||||
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="freedombone.css" />
|
||||
|
||||
#+BEGIN_CENTER
|
||||
[[file:images/logo.png]]
|
||||
#+END_CENTER
|
||||
|
||||
#+BEGIN_EXPORT html
|
||||
<center>
|
||||
<h1>KanBoard</h1>
|
||||
</center>
|
||||
#+END_EXPORT
|
||||
|
||||
Kanbans are one way of managing projects. They're traditionally used in businesses but can also be useful for personal TODO lists or within open source or DIY projects. If you have a list of things which need to be done and want to keep track of progress then this provides a way to do that.
|
||||
|
||||
* Installation
|
||||
Log into your system with:
|
||||
|
||||
#+begin_src bash
|
||||
ssh myusername@mydomain -p 2222
|
||||
#+end_src
|
||||
|
||||
Using cursor keys, space bar and Enter key select *Administrator controls* and type in your password.
|
||||
|
||||
Select *Add/Remove Apps* then *kanboard*. You will then be asked for a domain name and if you are using FreeDNS also the code for the domain which can be found under *Dynamic DNS* on the FreeDNS site (the random string from "/quick cron example/" which appears after /update.php?/ and before />>/). For more details on obtaining a domain and making it accessible via dynamic DNS see the [[./faq.html][FAQ]]. Typically the domain name you use will be a subdomain, such as /kanban.mydomainname.net/. It will need to be a domain which you have bought somewhere and own and not one of the FreeDNS subdomains, otherwise you won't be able to get a SSL/TLS certificate for it.
|
||||
|
||||
After the install has completed go to *Security settings* and select *Create a new Let's Encrypt certificate* and enter the domain name that you are using for KanBoard. If you're using the "onion only" version of the system then you don't need to do this. If the certificate is obtained successfully then you will see a congratulations message.
|
||||
|
||||
* Initial setup
|
||||
If you have just obtained a Lets Encrypt certificate as above then go to *About* on the administrator control panel and you should see your KanBoard domain listed there along with an onion address. You can then navigate to your site in a browser.
|
||||
|
||||
The default login is username "admin" and password "admin". Obviously the first thing you'll need to do is log in and change the password, which can be done by going to "My Profile" on the drop down list on the right hand side.
|
||||
|
||||
For more details of how to use KanBoard see the [[https://kanboard.net/documentation][documentation here]].
|
|
@ -75,6 +75,10 @@ Run your own IRC chat channel which can be secured with a password and accessibl
|
|||
* Jitsi Meet
|
||||
Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
|
||||
|
||||
* KanBoard
|
||||
A simple kanban system for managing projects or TODO lists.
|
||||
|
||||
[[./app_kanboard.html][How to use it]]
|
||||
* Koel
|
||||
Access your music collection from any internet connected device.
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
|
@ -37,7 +37,7 @@ SHOW_ICANN_ADDRESS_ON_ABOUT=0
|
|||
CRYPTPAD_ONION_PORT=8119
|
||||
CRYPTPAD_PORT=9003
|
||||
CRYPTPAD_REPO="https://github.com/xwiki-labs/cryptpad"
|
||||
CRYPTPAD_COMMIT='ed5b005216be9b9029c1ccd25a5fdc7908ed8730'
|
||||
CRYPTPAD_COMMIT='76e69f0ba85b0e3e21cad2c3eb0012c2429d4bb8'
|
||||
CRYPTPAD_DIR=/etc/cryptpad
|
||||
|
||||
cryptpad_variables=(ONION_ONLY)
|
||||
|
@ -89,6 +89,9 @@ function upgrade_cryptpad {
|
|||
set_repo_commit $CRYPTPAD_DIR "cryptpad commit" "$CRYPTPAD_COMMIT" $CRYPTPAD_REPO
|
||||
|
||||
cd $CRYPTPAD_DIR
|
||||
npm install
|
||||
chown -R cryptpad:cryptpad $CRYPTPAD_DIR
|
||||
su -c 'bower install' - cryptpad
|
||||
|
||||
systemctl start cryptpad
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ function gogs_create_database {
|
|||
fi
|
||||
|
||||
function_check create_database
|
||||
create_database gogs "$GOGS_ADMIN_PASSWORD"
|
||||
create_database gogs "$GIT_ADMIN_PASSWORD"
|
||||
}
|
||||
|
||||
function reconfigure_gogs {
|
||||
|
@ -302,7 +302,7 @@ function backup_remote_gogs {
|
|||
suspend_site ${GIT_DOMAIN_NAME}
|
||||
|
||||
function_check backup_database_to_friend
|
||||
backup_database_to_friend $GOGS_USERNAME
|
||||
backup_database_to_friend gogs
|
||||
|
||||
echo $"Obtaining Gogs settings backup"
|
||||
|
||||
|
|
|
@ -0,0 +1,579 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# .---. . .
|
||||
# | | |
|
||||
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
|
||||
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
|
||||
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
|
||||
#
|
||||
# Freedom in the Cloud
|
||||
#
|
||||
# kanboard kanban
|
||||
#
|
||||
# License
|
||||
# =======
|
||||
#
|
||||
# Copyright (C) 2017 Bob Mottram <bob@freedombone.net>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
VARIANTS='full full-vim social'
|
||||
|
||||
IN_DEFAULT_INSTALL=0
|
||||
SHOW_ON_ABOUT=1
|
||||
|
||||
KANBOARD_DOMAIN_NAME=
|
||||
KANBOARD_CODE=
|
||||
KANBOARD_ONION_PORT=8121
|
||||
KANBOARD_REPO="https://github.com/kanboard/kanboard"
|
||||
KANBOARD_COMMIT='7a6b1bc3da0af442e02b5a2dc430a4ded8e7c4ee'
|
||||
KANBOARD_ADMIN_PASSWORD=
|
||||
|
||||
|
||||
kanboard_variables=(ONION_ONLY
|
||||
KANBOARD_DOMAIN_NAME
|
||||
KANBOARD_CODE
|
||||
DDNS_PROVIDER
|
||||
MY_USERNAME)
|
||||
|
||||
function logging_on_kanboard {
|
||||
kanboard_configfile=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php
|
||||
sed -i "s|define('LOG_FILE'.*|define('LOG_FILE', DATA_DIR.DIRECTORY_SEPARATOR.'debug.log');|g" $kanboard_configfile
|
||||
}
|
||||
|
||||
function logging_off_kanboard {
|
||||
kanboard_configfile=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php
|
||||
sed -i "s|define('LOG_FILE'.*|define('LOG_FILE', '/dev/null');|g" $kanboard_configfile
|
||||
}
|
||||
|
||||
function remove_user_kanboard {
|
||||
remove_username="$1"
|
||||
|
||||
${PROJECT_NAME}-pass -u $remove_username --rmapp kanboard
|
||||
}
|
||||
|
||||
function add_user_kanboard {
|
||||
new_username="$1"
|
||||
new_user_password="$2"
|
||||
|
||||
${PROJECT_NAME}-pass -u $new_username -a kanboard -p "$new_user_password"
|
||||
echo '0'
|
||||
}
|
||||
|
||||
function install_interactive_kanboard {
|
||||
if [ ! $ONION_ONLY ]; then
|
||||
ONION_ONLY='no'
|
||||
fi
|
||||
|
||||
if [[ $ONION_ONLY != "no" ]]; then
|
||||
KANBOARD_DOMAIN_NAME='kanboard.local'
|
||||
else
|
||||
KANBOARD_DETAILS_COMPLETE=
|
||||
while [ ! $KANBOARD_DETAILS_COMPLETE ]
|
||||
do
|
||||
data=$(tempfile 2>/dev/null)
|
||||
trap "rm -f $data" 0 1 2 5 15
|
||||
if [[ $DDNS_PROVIDER == "default@freedns.afraid.org" ]]; then
|
||||
dialog --backtitle $"Freedombone Configuration" \
|
||||
--title $"KanBoard Configuration" \
|
||||
--form $"\nPlease enter your KanBoard details.\n\nIMPORTANT: This should be a domain name which is supported by Let's Encrypt." 13 55 2 \
|
||||
$"Domain:" 1 1 "$(grep 'KANBOARD_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 15 33 40 \
|
||||
$"Code:" 2 1 "$(grep 'KANBOARD_CODE' temp.cfg | awk -F '=' '{print $2}')" 2 15 33 255 \
|
||||
2> $data
|
||||
else
|
||||
dialog --backtitle $"Freedombone Configuration" \
|
||||
--title $"KanBoard Configuration" \
|
||||
--form $"\nPlease enter your KanBoard details.\n\nIMPORTANT: This should be a domain name which is supported by Let's Encrypt." 13 55 2 \
|
||||
$"Domain:" 1 1 "$(grep 'KANBOARD_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 15 33 40 \
|
||||
2> $data
|
||||
fi
|
||||
sel=$?
|
||||
case $sel in
|
||||
1) exit 1;;
|
||||
255) exit 1;;
|
||||
esac
|
||||
KANBOARD_DOMAIN_NAME=$(cat $data | sed -n 1p)
|
||||
if [ $KANBOARD_DOMAIN_NAME ]; then
|
||||
if [[ $KANBOARD_DOMAIN_NAME == "$HUBZILLA_DOMAIN_NAME" ]]; then
|
||||
KANBOARD_DOMAIN_NAME=""
|
||||
fi
|
||||
TEST_DOMAIN_NAME=$KANBOARD_DOMAIN_NAME
|
||||
validate_domain_name
|
||||
if [[ $TEST_DOMAIN_NAME != $KANBOARD_DOMAIN_NAME ]]; then
|
||||
KANBOARD_DOMAIN_NAME=
|
||||
dialog --title $"Domain name validation" --msgbox "$TEST_DOMAIN_NAME" 15 50
|
||||
else
|
||||
if [[ $DDNS_PROVIDER == "default@freedns.afraid.org" ]]; then
|
||||
KANBOARD_CODE=$(cat $data | sed -n 2p)
|
||||
validate_freedns_code "$KANBOARD_CODE"
|
||||
if [ ! $VALID_CODE ]; then
|
||||
KANBOARD_DOMAIN_NAME=
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ $KANBOARD_DOMAIN_NAME ]; then
|
||||
KANBOARD_DETAILS_COMPLETE="yes"
|
||||
fi
|
||||
done
|
||||
|
||||
# save the results in the config file
|
||||
write_config_param "KANBOARD_CODE" "$KANBOARD_CODE"
|
||||
fi
|
||||
write_config_param "KANBOARD_DOMAIN_NAME" "$KANBOARD_DOMAIN_NAME"
|
||||
APP_INSTALLED=1
|
||||
}
|
||||
|
||||
function change_password_kanboard {
|
||||
curr_username="$1"
|
||||
new_user_password="$2"
|
||||
|
||||
read_config_param 'KANBOARD_DOMAIN_NAME'
|
||||
|
||||
${PROJECT_NAME}-pass -u "$curr_username" -a kanboard -p "$new_user_password"
|
||||
}
|
||||
|
||||
function kanboard_create_database {
|
||||
if [ -f $IMAGE_PASSWORD_FILE ]; then
|
||||
KANBOARD_ADMIN_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
|
||||
else
|
||||
if [ ! $KANBOARD_ADMIN_PASSWORD ]; then
|
||||
KANBOARD_ADMIN_PASSWORD="$(create_password ${MINIMUM_PASSWORD_LENGTH})"
|
||||
fi
|
||||
fi
|
||||
if [ ! $KANBOARD_ADMIN_PASSWORD ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
function_check create_database
|
||||
create_database kanboard "$KANBOARD_ADMIN_PASSWORD" $MY_USERNAME
|
||||
}
|
||||
|
||||
function reconfigure_kanboard {
|
||||
echo -n ''
|
||||
}
|
||||
|
||||
function upgrade_kanboard {
|
||||
CURR_KANBOARD_COMMIT=$(get_completion_param "kanboard commit")
|
||||
if [[ "$CURR_KANBOARD_COMMIT" == "$KANBOARD_COMMIT" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if grep -q "kanboard domain" $COMPLETION_FILE; then
|
||||
KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
|
||||
fi
|
||||
|
||||
# update to the next commit
|
||||
function_check set_repo_commit
|
||||
set_repo_commit /var/www/$KANBOARD_DOMAIN_NAME/htdocs "kanboard commit" "$KANBOARD_COMMIT" $KANBOARD_REPO
|
||||
|
||||
chown -R www-data:www-data /var/www/${KANBOARD_DOMAIN_NAME}/htdocs
|
||||
}
|
||||
|
||||
|
||||
function backup_local_kanboard {
|
||||
KANBOARD_DOMAIN_NAME='kanboard'
|
||||
if grep -q "kanboard domain" $COMPLETION_FILE; then
|
||||
KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
|
||||
fi
|
||||
|
||||
source_directory=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/backup
|
||||
if [ ! -d $source_directory ]; then
|
||||
mkdir $source_directory
|
||||
fi
|
||||
cp -p /var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php $source_directory
|
||||
|
||||
function_check suspend_site
|
||||
suspend_site ${KANBOARD_DOMAIN_NAME}
|
||||
|
||||
function_check backup_directory_to_usb
|
||||
dest_directory=kanboardconfig
|
||||
backup_directory_to_usb $source_directory $dest_directory
|
||||
|
||||
source_directory=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/data
|
||||
dest_directory=kanboardfile
|
||||
backup_directory_to_usb $source_directory $dest_directory
|
||||
|
||||
function_check backup_database_to_usb
|
||||
backup_database_to_usb kanboard
|
||||
|
||||
function_check restart_site
|
||||
restart_site
|
||||
}
|
||||
|
||||
function restore_local_kanboard {
|
||||
if ! grep -q "kanboard domain" $COMPLETION_FILE; then
|
||||
return
|
||||
fi
|
||||
KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
|
||||
if [ $KANBOARD_DOMAIN_NAME ]; then
|
||||
echo $"Restoring kanboard"
|
||||
temp_restore_dir=/root/tempkanboard
|
||||
kanboard_dir=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs
|
||||
|
||||
function_check kanboard_create_database
|
||||
kanboard_create_database
|
||||
|
||||
restore_database kanboard
|
||||
if [ -d $temp_restore_dir ]; then
|
||||
rm -rf $temp_restore_dir
|
||||
fi
|
||||
|
||||
function_check restore_directory_from_usb
|
||||
restore_directory_from_usb $temp_restore_dir kanboardconfig
|
||||
if [ -d $temp_restore_dir ]; then
|
||||
cp $temp_restore_dir$kanboard_dir/backup/config.php $kanboard_dir/
|
||||
chown www-data:www-data $kanboard_dir/config.php
|
||||
rm -rf $temp_restore_dir
|
||||
fi
|
||||
|
||||
restore_directory_from_usb $temp_restore_dir kanboardfile
|
||||
if [ -d $temp_restore_dir ]; then
|
||||
cp -rp $temp_restore_dir$kanboard_dir/data $kanboard_dir/
|
||||
chown -R www-data:www-data $kanboard_dir/data
|
||||
rm -rf $temp_restore_dir
|
||||
fi
|
||||
|
||||
kanboard_update_after_restore kanboard ${KANBOARD_DOMAIN_NAME}
|
||||
|
||||
echo $"Restore of kanboard complete"
|
||||
fi
|
||||
}
|
||||
|
||||
function backup_remote_kanboard {
|
||||
KANBOARD_DOMAIN_NAME='kanboard'
|
||||
if grep -q "kanboard domain" $COMPLETION_FILE; then
|
||||
KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
|
||||
fi
|
||||
|
||||
source_directory=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/backup
|
||||
if [ ! -d $source_directory ]; then
|
||||
mkdir $source_directory
|
||||
fi
|
||||
cp -p /var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php $source_directory
|
||||
|
||||
function_check suspend_site
|
||||
suspend_site ${KANBOARD_DOMAIN_NAME}
|
||||
|
||||
function_check backup_directory_to_friend
|
||||
dest_directory=kanboardconfig
|
||||
backup_directory_to_friend $source_directory $dest_directory
|
||||
|
||||
source_directory=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/data
|
||||
dest_directory=kanboardfile
|
||||
backup_directory_to_friend $source_directory $dest_directory
|
||||
|
||||
function_check backup_database_to_friend
|
||||
backup_database_to_friend kanboard
|
||||
|
||||
function_check restart_site
|
||||
restart_site
|
||||
}
|
||||
|
||||
function restore_remote_kanboard {
|
||||
if ! grep -q "kanboard domain" $COMPLETION_FILE; then
|
||||
return
|
||||
fi
|
||||
KANBOARD_DOMAIN_NAME=$(get_completion_param "kanboard domain")
|
||||
if [ $KANBOARD_DOMAIN_NAME ]; then
|
||||
echo $"Restoring kanboard"
|
||||
temp_restore_dir=/root/tempkanboard
|
||||
kanboard_dir=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs
|
||||
|
||||
function_check kanboard_create_database
|
||||
kanboard_create_database
|
||||
|
||||
function_check restore_database_from_friend
|
||||
restore_database_from_friend kanboard
|
||||
if [ -d $temp_restore_dir ]; then
|
||||
rm -rf $temp_restore_dir
|
||||
fi
|
||||
|
||||
function_check restore_directory_from_friend
|
||||
restore_directory_from_friend $temp_restore_dir kanboardconfig
|
||||
if [ -d $temp_restore_dir ]; then
|
||||
cp $temp_restore_dir$kanboard_dir/backup/config.php $kanboard_dir/
|
||||
chown www-data:www-data $kanboard_dir/config.php
|
||||
rm -rf $temp_restore_dir
|
||||
fi
|
||||
|
||||
restore_directory_from_friend $temp_restore_dir kanboardfile
|
||||
if [ -d $temp_restore_dir ]; then
|
||||
cp -rp $temp_restore_dir$kanboard_dir/data $kanboard_dir/
|
||||
chown -R www-data:www-data $kanboard_dir/data
|
||||
rm -rf $temp_restore_dir
|
||||
fi
|
||||
|
||||
kanboard_update_after_restore kanboard ${KANBOARD_DOMAIN_NAME}
|
||||
|
||||
echo $"Restore of kanboard complete"
|
||||
fi
|
||||
}
|
||||
|
||||
function remove_kanboard {
|
||||
if [ ${#KANBOARD_DOMAIN_NAME} -eq 0 ]; then
|
||||
return
|
||||
fi
|
||||
read_config_param "KANBOARD_DOMAIN_NAME"
|
||||
read_config_param "MY_USERNAME"
|
||||
echo "Removing $KANBOARD_DOMAIN_NAME"
|
||||
nginx_dissite $KANBOARD_DOMAIN_NAME
|
||||
remove_certs $KANBOARD_DOMAIN_NAME
|
||||
|
||||
if [ -d /var/www/$KANBOARD_DOMAIN_NAME ]; then
|
||||
rm -rf /var/www/$KANBOARD_DOMAIN_NAME
|
||||
fi
|
||||
if [ -f /etc/nginx/sites-available/$KANBOARD_DOMAIN_NAME ]; then
|
||||
rm /etc/nginx/sites-available/$KANBOARD_DOMAIN_NAME
|
||||
fi
|
||||
function_check drop_database
|
||||
drop_database kanboard
|
||||
function_check remove_onion_service
|
||||
remove_onion_service kanboard ${KANBOARD_ONION_PORT}
|
||||
remove_app kanboard
|
||||
remove_completion_param install_kanboard
|
||||
sed -i '/kanboard/d' $COMPLETION_FILE
|
||||
remove_backup_database_local kanboard
|
||||
|
||||
function_check remove_ddns_domain
|
||||
remove_ddns_domain $KANBOARD_DOMAIN_NAME
|
||||
}
|
||||
|
||||
function install_kanboard {
|
||||
if [ ! $ONION_ONLY ]; then
|
||||
ONION_ONLY='no'
|
||||
fi
|
||||
|
||||
if [ ! $KANBOARD_DOMAIN_NAME ]; then
|
||||
echo $'No domain name was given for kanboard'
|
||||
exit 73478
|
||||
fi
|
||||
|
||||
kanboard_hourly_script kanboard $KANBOARD_DOMAIN_NAME
|
||||
|
||||
function_check install_mariadb
|
||||
install_mariadb
|
||||
|
||||
function_check get_mariadb_password
|
||||
get_mariadb_password
|
||||
|
||||
function_check repair_databases_script
|
||||
repair_databases_script
|
||||
|
||||
apt-get -yq install php-gettext php-curl php-gd php-mysql git curl
|
||||
apt-get -yq install memcached php-memcached php-intl exiftool libfcgi0ldbl
|
||||
|
||||
if [ ! -d /var/www/$KANBOARD_DOMAIN_NAME ]; then
|
||||
mkdir /var/www/$KANBOARD_DOMAIN_NAME
|
||||
fi
|
||||
if [ ! -d /var/www/$KANBOARD_DOMAIN_NAME/htdocs ]; then
|
||||
|
||||
if [ -d /repos/kanboard ]; then
|
||||
mkdir /var/www/$KANBOARD_DOMAIN_NAME/htdocs
|
||||
cp -r -p /repos/kanboard/. /var/www/$KANBOARD_DOMAIN_NAME/htdocs
|
||||
cd /var/www/$KANBOARD_DOMAIN_NAME/htdocs
|
||||
git pull
|
||||
else
|
||||
function_check git_clone
|
||||
git_clone $KANBOARD_REPO /var/www/$KANBOARD_DOMAIN_NAME/htdocs
|
||||
fi
|
||||
|
||||
if [ ! -d /var/www/$KANBOARD_DOMAIN_NAME/htdocs ]; then
|
||||
echo $'Unable to clone kanboard repo'
|
||||
exit 89365
|
||||
fi
|
||||
fi
|
||||
|
||||
cd /var/www/$KANBOARD_DOMAIN_NAME/htdocs
|
||||
git checkout $KANBOARD_COMMIT -b $KANBOARD_COMMIT
|
||||
set_completion_param "kanboard commit" "$KANBOARD_COMMIT"
|
||||
|
||||
chmod g+w /var/www/$KANBOARD_DOMAIN_NAME/htdocs
|
||||
chmod a+w /var/www/$KANBOARD_DOMAIN_NAME/htdocs/data
|
||||
chown -R www-data:www-data /var/www/$KANBOARD_DOMAIN_NAME/htdocs
|
||||
|
||||
function_check kanboard_create_database
|
||||
kanboard_create_database
|
||||
|
||||
if [ ! -f "/etc/aliases" ]; then
|
||||
touch /etc/aliases
|
||||
fi
|
||||
if ! grep -q "www-data: root" /etc/aliases; then
|
||||
echo 'www-data: root' >> /etc/aliases
|
||||
fi
|
||||
|
||||
function_check add_ddns_domain
|
||||
add_ddns_domain $KANBOARD_DOMAIN_NAME
|
||||
|
||||
KANBOARD_ONION_HOSTNAME=$(add_onion_service kanboard 80 ${KANBOARD_ONION_PORT})
|
||||
|
||||
kanboard_nginx_site=/etc/nginx/sites-available/$KANBOARD_DOMAIN_NAME
|
||||
if [[ $ONION_ONLY == "no" ]]; then
|
||||
function_check nginx_http_redirect
|
||||
nginx_http_redirect $KANBOARD_DOMAIN_NAME "index index.php"
|
||||
echo 'server {' >> $kanboard_nginx_site
|
||||
echo ' listen 443 ssl;' >> $kanboard_nginx_site
|
||||
echo ' listen [::]:443 ssl;' >> $kanboard_nginx_site
|
||||
echo " server_name $KANBOARD_DOMAIN_NAME;" >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
function_check nginx_compress
|
||||
nginx_compress $KANBOARD_DOMAIN_NAME
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Security' >> $kanboard_nginx_site
|
||||
function_check nginx_ssl
|
||||
nginx_ssl $KANBOARD_DOMAIN_NAME
|
||||
|
||||
function_check nginx_disable_sniffing
|
||||
nginx_disable_sniffing $KANBOARD_DOMAIN_NAME
|
||||
|
||||
echo ' add_header Strict-Transport-Security max-age=15768000;' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Logs' >> $kanboard_nginx_site
|
||||
echo ' access_log /dev/null;' >> $kanboard_nginx_site
|
||||
echo ' error_log /dev/null;' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Root' >> $kanboard_nginx_site
|
||||
echo " root /var/www/$KANBOARD_DOMAIN_NAME/htdocs;" >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Index' >> $kanboard_nginx_site
|
||||
echo ' index index.php;' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # PHP' >> $kanboard_nginx_site
|
||||
echo ' location ~ \.php {' >> $kanboard_nginx_site
|
||||
echo ' include snippets/fastcgi-php.conf;' >> $kanboard_nginx_site
|
||||
echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> $kanboard_nginx_site
|
||||
echo ' fastcgi_read_timeout 30;' >> $kanboard_nginx_site
|
||||
echo ' }' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Location' >> $kanboard_nginx_site
|
||||
echo ' location / {' >> $kanboard_nginx_site
|
||||
function_check nginx_limits
|
||||
nginx_limits $KANBOARD_DOMAIN_NAME '15m'
|
||||
echo ' try_files $uri $uri/ @kanboard;' >> $kanboard_nginx_site
|
||||
echo ' }' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Fancy URLs' >> $kanboard_nginx_site
|
||||
echo ' location @kanboard {' >> $kanboard_nginx_site
|
||||
echo ' rewrite ^(.*)$ /index.php?p=$1 last;' >> $kanboard_nginx_site
|
||||
echo ' }' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Restrict access that is unnecessary anyway' >> $kanboard_nginx_site
|
||||
echo ' location ~ /\.(ht|git) {' >> $kanboard_nginx_site
|
||||
echo ' deny all;' >> $kanboard_nginx_site
|
||||
echo ' }' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
# DO NOT ENABLE KEYBASE. kanboard really doesn't like having a .well-known directory
|
||||
echo '}' >> $kanboard_nginx_site
|
||||
else
|
||||
echo -n '' > $kanboard_nginx_site
|
||||
fi
|
||||
echo 'server {' >> $kanboard_nginx_site
|
||||
echo " listen 127.0.0.1:$KANBOARD_ONION_PORT default_server;" >> $kanboard_nginx_site
|
||||
echo " server_name $KANBOARD_ONION_HOSTNAME;" >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
function_check nginx_compress
|
||||
nginx_compress $KANBOARD_DOMAIN_NAME
|
||||
echo '' >> $kanboard_nginx_site
|
||||
function_check nginx_disable_sniffing
|
||||
nginx_disable_sniffing $KANBOARD_DOMAIN_NAME
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Logs' >> $kanboard_nginx_site
|
||||
echo ' access_log /dev/null;' >> $kanboard_nginx_site
|
||||
echo ' error_log /dev/null;' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Root' >> $kanboard_nginx_site
|
||||
echo " root /var/www/$KANBOARD_DOMAIN_NAME/htdocs;" >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Index' >> $kanboard_nginx_site
|
||||
echo ' index index.php;' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # PHP' >> $kanboard_nginx_site
|
||||
echo ' location ~ \.php {' >> $kanboard_nginx_site
|
||||
echo ' include snippets/fastcgi-php.conf;' >> $kanboard_nginx_site
|
||||
echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> $kanboard_nginx_site
|
||||
echo ' fastcgi_read_timeout 30;' >> $kanboard_nginx_site
|
||||
echo ' }' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Location' >> $kanboard_nginx_site
|
||||
echo ' location / {' >> $kanboard_nginx_site
|
||||
function_check nginx_limits
|
||||
nginx_limits $KANBOARD_DOMAIN_NAME '15m'
|
||||
echo ' try_files $uri $uri/ @kanboard;' >> $kanboard_nginx_site
|
||||
echo ' }' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Fancy URLs' >> $kanboard_nginx_site
|
||||
echo ' location @kanboard {' >> $kanboard_nginx_site
|
||||
echo ' rewrite ^(.*)$ /index.php?p=$1 last;' >> $kanboard_nginx_site
|
||||
echo ' }' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
echo ' # Restrict access that is unnecessary anyway' >> $kanboard_nginx_site
|
||||
echo ' location ~ /\.(ht|git) {' >> $kanboard_nginx_site
|
||||
echo ' deny all;' >> $kanboard_nginx_site
|
||||
echo ' }' >> $kanboard_nginx_site
|
||||
echo '' >> $kanboard_nginx_site
|
||||
# DO NOT ENABLE KEYBASE. kanboard really doesn't like having a .well-known directory
|
||||
echo '}' >> $kanboard_nginx_site
|
||||
|
||||
function_check configure_php
|
||||
configure_php
|
||||
|
||||
function_check create_site_certificate
|
||||
create_site_certificate $KANBOARD_DOMAIN_NAME 'yes'
|
||||
|
||||
# Ensure that the database gets backed up locally, if remote
|
||||
# backups are not being used
|
||||
function_check backup_databases_script_header
|
||||
backup_databases_script_header
|
||||
|
||||
function_check backup_database_local
|
||||
backup_database_local kanboard
|
||||
|
||||
function_check nginx_ensite
|
||||
nginx_ensite $KANBOARD_DOMAIN_NAME
|
||||
|
||||
KANBOARD_SERVER=${KANBOARD_DOMAIN_NAME}
|
||||
if [[ $ONION_ONLY != 'no' ]]; then
|
||||
KANBOARD_SERVER=${KANBOARD_ONION_HOSTNAME}
|
||||
fi
|
||||
|
||||
# Create the configuration
|
||||
kanboard_configfile=/var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.php
|
||||
cp /var/www/${KANBOARD_DOMAIN_NAME}/htdocs/config.default.php $kanboard_configfile
|
||||
sed -i "s|define('MAIL_FROM'.*|define('MAIL_FROM', '$MY_EMAIL_ADDRESS');|g" $kanboard_configfile
|
||||
sed -i "s|define('DB_DRIVER'.*|define('DB_DRIVER', 'mysql');|g" $kanboard_configfile
|
||||
sed -i "s|define('DB_USERNAME'.*|define('DB_USERNAME', 'root');|g" $kanboard_configfile
|
||||
sed -i "s|define('DB_PASSWORD'.*|define('DB_PASSWORD', '$MARIADB_PASSWORD');|g" $kanboard_configfile
|
||||
sed -i "s|define('DB_HOSTNAME'.*|define('DB_HOSTNAME', 'localhost');|g" $kanboard_configfile
|
||||
sed -i "s|define('DB_NAME'.*|define('DB_NAME', 'kanboard');|g" $kanboard_configfile
|
||||
sed -i "s|define('DB_PORT'.*|define('DB_PORT', null);|g" $kanboard_configfile
|
||||
logging_off_kanboard
|
||||
|
||||
initialise_database kanboard /var/www/${KANBOARD_DOMAIN_NAME}/htdocs/app/Schema/Sql/mysql.sql
|
||||
chown -R www-data:www-data /var/www/${KANBOARD_DOMAIN_NAME}/htdocs
|
||||
|
||||
cd /var/www/${KANBOARD_DOMAIN_NAME}/htdocs
|
||||
install_composer
|
||||
|
||||
systemctl restart mariadb
|
||||
systemctl restart php7.0-fpm
|
||||
systemctl restart nginx
|
||||
|
||||
${PROJECT_NAME}-pass -u $MY_USERNAME -a kanboard -p "$KANBOARD_ADMIN_PASSWORD"
|
||||
|
||||
set_completion_param "kanboard domain" "$KANBOARD_DOMAIN_NAME"
|
||||
|
||||
APP_INSTALLED=1
|
||||
}
|
||||
|
||||
# NOTE: deliberately there is no "exit 0"
|
|
@ -715,21 +715,9 @@ function install_koel {
|
|||
install_koel_main
|
||||
|
||||
cd /var/www/$KOEL_DOMAIN_NAME/htdocs
|
||||
install_composer
|
||||
|
||||
# curl -sS https://getcomposer.org/installer | php
|
||||
if [ -f ~/freedombone/image_build/composer_install ]; then
|
||||
cat ~/freedombone/image_build/composer_install | php
|
||||
else
|
||||
if [ -f /home/$MY_USERNAME/freedombone/image_build/composer_install ]; then
|
||||
cat /home/$MY_USERNAME/freedombone/image_build/composer_install | php
|
||||
fi
|
||||
fi
|
||||
npm install -g yarn
|
||||
php composer.phar install
|
||||
if [ ! "$?" = "0" ]; then
|
||||
echo $'Unable to run composer install'
|
||||
exit 7252198
|
||||
fi
|
||||
npm install
|
||||
|
||||
function_check get_mariadb_password
|
||||
|
|
|
@ -383,15 +383,8 @@ function install_movim {
|
|||
# Fix typo
|
||||
sed -i 's|weksocket|websocket|g' app/widgets/AdminTest/admintest.js
|
||||
|
||||
# curl -sS https://getcomposer.org/installer | php
|
||||
if [ -f ~/freedombone/image_build/composer_install ]; then
|
||||
cat ~/freedombone/image_build/composer_install | php
|
||||
else
|
||||
if [ -f /home/$MY_USERNAME/freedombone/image_build/composer_install ]; then
|
||||
cat /home/$MY_USERNAME/freedombone/image_build/composer_install | php
|
||||
fi
|
||||
fi
|
||||
php composer.phar install
|
||||
cd /var/www/$MOVIM_DOMAIN_NAME/htdocs
|
||||
install_composer
|
||||
|
||||
cd /var/www/$MOVIM_DOMAIN_NAME/htdocs/config
|
||||
cp db.example.inc.php db.inc.php
|
||||
|
|
|
@ -34,13 +34,13 @@ IN_DEFAULT_INSTALL=0
|
|||
SHOW_ON_ABOUT=1
|
||||
|
||||
LIBMESODE_REPO="https://github.com/boothj5/libmesode"
|
||||
LIBMESODE_COMMIT='e3db0e9bfba61b2d82193874343a94a88f910800'
|
||||
LIBMESODE_COMMIT='b91872cf7e7ed4d2443ab5c622f4cdb395d64dbe'
|
||||
|
||||
PROFANITY_REPO="https://github.com/boothj5/profanity"
|
||||
PROFANITY_COMMIT='2fafaec8a7dc9bc01ee894d83214590598b32914'
|
||||
PROFANITY_COMMIT='f8b855b09f2c4e9b461b0b7854afabbecf6d5b4a'
|
||||
|
||||
PROFANITY_OMEMO_PLUGIN_REPO="https://github.com/ReneVolution/profanity-omemo-plugin"
|
||||
PROFANITY_OMEMO_PLUGIN_COMMIT='3ec8ec173656bed9761b740b086123e07c749548'
|
||||
PROFANITY_OMEMO_PLUGIN_COMMIT='78be0c8367c6379829986755c0d1da287c031234'
|
||||
|
||||
xmpp_variables=(ONION_ONLY
|
||||
INSTALLED_WITHIN_DOCKER
|
||||
|
@ -285,7 +285,11 @@ function install_profanity {
|
|||
echo 'enabled=true' >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "jid=${MY_USERNAME}@${DEFAULT_DOMAIN_NAME}" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "server=$XMPP_ONION_HOSTNAME" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "pgp.keyid=$MY_GPG_PUBLIC_KEY_ID" >> $XMPP_CLIENT_ACCOUNTS
|
||||
# There is a bug where profanity doesn't refresh the screen
|
||||
# after gpg-agent has asked for a password, so for now
|
||||
# don't set the gpg key by default
|
||||
#echo "pgp.keyid=$MY_GPG_PUBLIC_KEY_ID" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "pgp.keyid=" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo 'resource=profanity' >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "muc.service=chat.${DEFAULT_DOMAIN_NAME}" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "muc.nick=${MY_USERNAME}" >> $XMPP_CLIENT_ACCOUNTS
|
||||
|
@ -310,7 +314,11 @@ function install_profanity {
|
|||
fi
|
||||
echo "jid=${MY_USERNAME}@${XMPP_ONION_HOSTNAME}" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "server=$XMPP_ONION_HOSTNAME" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "pgp.keyid=$MY_GPG_PUBLIC_KEY_ID" >> $XMPP_CLIENT_ACCOUNTS
|
||||
# There is a bug where profanity doesn't refresh the screen
|
||||
# after gpg-agent has asked for a password, so for now
|
||||
# don't set the gpg key by default
|
||||
#echo "pgp.keyid=$MY_GPG_PUBLIC_KEY_ID" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "pgp.keyid=" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo 'resource=profanity' >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "muc.service=${XMPP_ONION_HOSTNAME}" >> $XMPP_CLIENT_ACCOUNTS
|
||||
echo "muc.nick=${MY_USERNAME}" >> $XMPP_CLIENT_ACCOUNTS
|
||||
|
|
|
@ -0,0 +1,494 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# .---. . .
|
||||
# | | |
|
||||
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
|
||||
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
|
||||
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
|
||||
#
|
||||
# Freedom in the Cloud
|
||||
#
|
||||
# Wekan kanban
|
||||
#
|
||||
# License
|
||||
# =======
|
||||
#
|
||||
# Copyright (C) 2017 Bob Mottram <bob@freedombone.net>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
VARIANTS=''
|
||||
|
||||
IN_DEFAULT_INSTALL=0
|
||||
SHOW_ON_ABOUT=0
|
||||
|
||||
WEKAN_DOMAIN_NAME=
|
||||
WEKAN_CODE=
|
||||
WEKAN_PORT=8081
|
||||
WEKAN_ONION_PORT=8120
|
||||
WEKAN_REPO="https://github.com/wekan/wekan"
|
||||
WEKAN_COMMIT='dc547c38d1f5ca72729f6d8f81eb03671ca15934'
|
||||
FLOW_ROUTER_REPO="git://github.com/wekan/flow-router.git"
|
||||
FLOW_ROUTER_COMMIT='0c1f6423ed9b68eb00cfb1a19492438917a38956'
|
||||
WEKAN_DIR=/etc/wekan
|
||||
|
||||
wekan_variables=(ONION_ONLY
|
||||
WEKAN_DOMAIN_NAME
|
||||
WEKAN_CODE
|
||||
DDNS_PROVIDER
|
||||
MY_USERNAME)
|
||||
|
||||
function logging_on_wekan {
|
||||
echo -n ''
|
||||
}
|
||||
|
||||
function logging_off_wekan {
|
||||
echo -n ''
|
||||
}
|
||||
|
||||
function remove_user_wekan {
|
||||
remove_username="$1"
|
||||
}
|
||||
|
||||
function add_user_wekan {
|
||||
new_username="$1"
|
||||
new_user_password="$2"
|
||||
echo '0'
|
||||
}
|
||||
|
||||
function install_interactive_wekan {
|
||||
if [[ $ONION_ONLY != "no" ]]; then
|
||||
GIT_DOMAIN_NAME='wekan.local'
|
||||
write_config_param "WEKAN_DOMAIN_NAME" "$WEKAN_DOMAIN_NAME"
|
||||
else
|
||||
function_check interactive_site_details
|
||||
interactive_site_details wekan
|
||||
fi
|
||||
APP_INSTALLED=1
|
||||
}
|
||||
|
||||
function change_password_wekan {
|
||||
curr_username="$1"
|
||||
new_user_password="$2"
|
||||
}
|
||||
|
||||
function reconfigure_wekan {
|
||||
echo -n ''
|
||||
}
|
||||
|
||||
function upgrade_wekan {
|
||||
CURR_WEKAN_COMMIT=$(get_completion_param "wekan commit")
|
||||
if [[ "$CURR_WEKAN_COMMIT" == "$WEKAN_COMMIT" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
systemctl stop wekan
|
||||
|
||||
# update to the next commit
|
||||
function_check set_repo_commit
|
||||
set_repo_commit $WEKAN_DIR "wekan commit" "$WEKAN_COMMIT" $WEKAN_REPO
|
||||
|
||||
systemctl start wekan
|
||||
}
|
||||
|
||||
function backup_local_wekan {
|
||||
source_directory=$WEKAN_DIR/data
|
||||
if [ -d $source_directory ]; then
|
||||
systemctl stop wekan
|
||||
|
||||
dest_directory=wekan
|
||||
function_check suspend_site
|
||||
suspend_site wekan
|
||||
|
||||
function_check backup_database_to_usb
|
||||
backup_database_to_usb wekan
|
||||
|
||||
function_check backup_directory_to_usb
|
||||
backup_directory_to_usb $source_directory $dest_directory
|
||||
|
||||
function_check restart_site
|
||||
restart_site
|
||||
|
||||
systemctl start wekan
|
||||
fi
|
||||
}
|
||||
|
||||
function restore_local_wekan {
|
||||
if [ -d $WEKAN_DIR ]; then
|
||||
systemctl stop wekan
|
||||
|
||||
function_check restore_database
|
||||
restore_database gogs ${WEKAN_DOMAIN_NAME}
|
||||
|
||||
temp_restore_dir=/root/tempwekan
|
||||
function_check restore_directory_from_usb
|
||||
restore_directory_from_usb $temp_restore_dir wekan
|
||||
cp -r $temp_restore_dir$WEKAN_DIR/data/* $WEKAN_DIR/data/
|
||||
|
||||
systemctl start wekan
|
||||
fi
|
||||
}
|
||||
|
||||
function backup_remote_wekan {
|
||||
if grep -q "wekan domain" $COMPLETION_FILE; then
|
||||
temp_backup_dir=$WEKAN_DIR/data
|
||||
if [ -d $temp_backup_dir ]; then
|
||||
systemctl stop wekan
|
||||
|
||||
function_check suspend_site
|
||||
suspend_site wekan
|
||||
|
||||
echo $"Backing up Wekan installation"
|
||||
|
||||
function_check backup_database_to_friend
|
||||
backup_database_to_friend wekan
|
||||
|
||||
function_check backup_directory_to_friend
|
||||
backup_directory_to_friend $temp_backup_dir wekan
|
||||
|
||||
function_check restart_site
|
||||
restart_site
|
||||
|
||||
systemctl start wekan
|
||||
else
|
||||
echo $"wekan domain specified but not found in ${temp_backup_dir}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function restore_remote_wekan {
|
||||
if [ -d $WEKAN_DIR ]; then
|
||||
systemctl stop wekan
|
||||
|
||||
function_check restore_database_from_friend
|
||||
restore_database_from_friend wekan
|
||||
|
||||
temp_restore_dir=/root/tempwekan
|
||||
function_check restore_directory_from_usb
|
||||
restore_directory_from_friend $temp_restore_dir wekan
|
||||
cp -r $temp_restore_dir$WEKAN_DIR/data/* $WEKAN_DIR/data/
|
||||
|
||||
systemctl start wekan
|
||||
fi
|
||||
}
|
||||
|
||||
function remove_wekan {
|
||||
systemctl stop wekan
|
||||
systemctl disable wekan
|
||||
if [ -f /etc/systemd/system/wekan.service ]; then
|
||||
rm /etc/systemd/system/wekan.service
|
||||
fi
|
||||
systemctl daemon-reload
|
||||
|
||||
function_check remove_nodejs
|
||||
remove_nodejs wekan
|
||||
|
||||
nginx_dissite wekan
|
||||
|
||||
if [ -d $WEKAN_DIR ]; then
|
||||
rm -rf $WEKAN_DIR
|
||||
fi
|
||||
if [ -f /etc/nginx/sites-available/wekan ]; then
|
||||
rm /etc/nginx/sites-available/wekan
|
||||
fi
|
||||
function_check drop_database
|
||||
drop_database wekan
|
||||
function_check remove_onion_service
|
||||
remove_onion_service wekan ${WEKAN_ONION_PORT}
|
||||
remove_app wekan
|
||||
remove_completion_param install_wekan
|
||||
sed -i '/wekan/d' $COMPLETION_FILE
|
||||
|
||||
groupdel -f gogs
|
||||
userdel -r wekan
|
||||
remove_meteor
|
||||
}
|
||||
|
||||
function wekan_create_database {
|
||||
if [ -f ${IMAGE_PASSWORD_FILE} ]; then
|
||||
WEKAN_ADMIN_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
|
||||
else
|
||||
if [ ! ${GIT_ADMIN_PASSWORD} ]; then
|
||||
WEKAN_ADMIN_PASSWORD="$(create_password ${MINIMUM_PASSWORD_LENGTH})"
|
||||
fi
|
||||
fi
|
||||
if [ ! $WEKAN_ADMIN_PASSWORD ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
function_check create_database
|
||||
create_database gogs "$WEKAN_ADMIN_PASSWORD"
|
||||
}
|
||||
|
||||
function install_wekan_main {
|
||||
if [[ $(app_is_installed wekan_main) == "1" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if [ ! -d /var/www/wekan ]; then
|
||||
mkdir /var/www/wekan
|
||||
fi
|
||||
if [ -d $WEKAN_DIR ]; then
|
||||
rm -rf $WEKAN_DIR
|
||||
fi
|
||||
|
||||
if [ -d /repos/wekan ]; then
|
||||
mkdir -p $WEKAN_DIR
|
||||
cp -r -p /repos/wekan/. $WEKAN_DIR
|
||||
cd $WEKAN_DIR
|
||||
git pull
|
||||
else
|
||||
function_check git_clone
|
||||
git_clone $WEKAN_REPO $WEKAN_DIR
|
||||
fi
|
||||
|
||||
if [ ! -d $WEKAN_DIR ]; then
|
||||
echo $'Unable to clone wekan repo'
|
||||
exit 783251
|
||||
fi
|
||||
|
||||
# an unprivileged user to run as
|
||||
useradd -d $WEKAN_DIR/ wekan
|
||||
groupadd wekan
|
||||
|
||||
cd $WEKAN_DIR
|
||||
git checkout $WEKAN_COMMIT -b $WEKAN_COMMIT
|
||||
set_completion_param "wekan commit" "$WEKAN_COMMIT"
|
||||
|
||||
chown -R wekan:wekan $WEKAN_DIR
|
||||
|
||||
WEKAN_ONION_HOSTNAME=$(add_onion_service wekan 80 ${WEKAN_ONION_PORT})
|
||||
set_completion_param "wekan onion domain" "$WEKAN_ONION_HOSTNAME"
|
||||
|
||||
wekan_nginx_site=/etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
if [[ ${ONION_ONLY} == "no" ]]; then
|
||||
function_check nginx_http_redirect
|
||||
nginx_http_redirect ${WEKAN_DOMAIN_NAME}
|
||||
echo 'server {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' listen 443 ssl;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' listen [::]:443 ssl;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo " root /var/www/${WEKAN_DOMAIN_NAME}/htdocs;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo " server_name ${WEKAN_DOMAIN_NAME};" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' access_log /dev/null;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo " error_log /dev/null;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
function_check nginx_ssl
|
||||
nginx_ssl ${WEKAN_DOMAIN_NAME}
|
||||
function_check nginx_disable_sniffing
|
||||
nginx_disable_sniffing ${WEKAN_DOMAIN_NAME}
|
||||
echo ' add_header Strict-Transport-Security max-age=0;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' location / {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
function_check nginx_limits
|
||||
nginx_limits ${WEKAN_DOMAIN_NAME} '15m'
|
||||
echo " proxy_pass http://localhost:$WEKAN_PORT;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' }' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' fastcgi_buffers 64 4K;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' error_page 403 /core/templates/403.php;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' error_page 404 /core/templates/404.php;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' location = /robots.txt {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' allow all;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' log_not_found off;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' access_log /dev/null;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' }' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
nginx_keybase ${WEKAN_DOMAIN_NAME}
|
||||
echo '}' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
else
|
||||
echo -n '' > /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
fi
|
||||
echo 'server {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo " listen 127.0.0.1:${WEKAN_ONION_PORT} default_server;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo " root /var/www/$WEKAN_DOMAIN_NAME/htdocs;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo " server_name $WEKAN_DOMAIN_NAME;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' access_log /dev/null;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo " error_log /dev/null;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
function_check nginx_disable_sniffing
|
||||
nginx_disable_sniffing ${WEKAN_DOMAIN_NAME}
|
||||
echo ' add_header Strict-Transport-Security max-age=0;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' location / {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
function_check nginx_limits
|
||||
nginx_limits ${WEKAN_DOMAIN_NAME} '15m'
|
||||
echo " proxy_pass http://localhost:$WEKAN_PORT;" >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' }' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' fastcgi_buffers 64 4K;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' error_page 403 /core/templates/403.php;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' error_page 404 /core/templates/404.php;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' location = /robots.txt {' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' allow all;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' log_not_found off;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' access_log /dev/null;' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo ' }' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
echo '' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
nginx_keybase ${WEKAN_DOMAIN_NAME}
|
||||
echo '}' >> /etc/nginx/sites-available/${WEKAN_DOMAIN_NAME}
|
||||
|
||||
function_check nginx_ensite
|
||||
nginx_ensite wekan
|
||||
|
||||
install_completed wekan_main
|
||||
}
|
||||
|
||||
function install_wekan {
|
||||
apt-get -qy install build-essential c++ capnproto curl
|
||||
|
||||
function_check install_nodejs
|
||||
install_nodejs wekan
|
||||
|
||||
install_wekan_main
|
||||
install_meteor
|
||||
|
||||
cd $WEKAN_DIR
|
||||
|
||||
su -c 'npm install babel-runtime' - wekan
|
||||
su -c 'npm install node-gyp' - wekan
|
||||
su -c 'npm install node-pre-gyp' - wekan
|
||||
su -c 'npm install fibers' - wekan
|
||||
su -c 'npm install bcrypt' - wekan
|
||||
su -c 'npm install bson' - wekan
|
||||
su -c 'npm install es6-promise' - wekan
|
||||
su -c 'npm install meteor-node-stubs' - wekan
|
||||
su -c 'npm install winston' - wekan
|
||||
su -c 'npm install winston-zulip' - wekan
|
||||
su -c 'npm install xss' - wekan
|
||||
|
||||
# Remove any directories from previous installs
|
||||
if [ -d $WEKAN_DIR/.meteor ]; then
|
||||
rm -rf $WEKAN_DIR/.meteor
|
||||
fi
|
||||
if [ -d $WEKAN_DIR/app ]; then
|
||||
rm -rf $WEKAN_DIR/app
|
||||
fi
|
||||
if [ -d $WEKAN_DIR/app_build ]; then
|
||||
rm -rf $WEKAN_DIR/app_build
|
||||
fi
|
||||
|
||||
# Get additional packages
|
||||
mkdir -p $WEKAN_DIR/.meteor/packages
|
||||
chown wekan:wekan --recursive $WEKAN_DIR/.meteor
|
||||
cd $WEKAN_DIR/.meteor/packages
|
||||
if [ ! -d /repos/flowrouter ]; then
|
||||
su -c "git clone --depth 1 -b master $FLOW_ROUTER_REPO kadira-flow-router" - wekan
|
||||
else
|
||||
mkdir kadira-flow-router
|
||||
cp -r -p /repos/flowrouter/. kadira-flow-router
|
||||
cd kadira-flow-router
|
||||
git pull
|
||||
cd ..
|
||||
fi
|
||||
cd kadira-flow-router
|
||||
git checkout $FLOW_ROUTER_COMMIT -b $FLOW_ROUTER_COMMIT
|
||||
cd ..
|
||||
if [ ! -d /repos/meteoruseraccounts ]; then
|
||||
su -c "git clone --depth 1 -b master $METEOR_USERACCOUNTS_REPO meteor-useraccounts-core" - wekan
|
||||
else
|
||||
mkdir meteor-useraccounts-core
|
||||
cp -r -p /repos/meteoruseraccounts/. meteor-useraccounts-core
|
||||
cd meteor-useraccounts-core
|
||||
git pull
|
||||
cd ..
|
||||
fi
|
||||
cd meteor-useraccounts-core
|
||||
git checkout $METEOR_USERACCOUNTS_COMMIT -b $METEOR_USERACCOUNTS_COMMIT
|
||||
cd ..
|
||||
if [ ! -f $WEKAN_DIR/.meteor/packages/meteor-useraccounts-core/package.js ]; then
|
||||
echo $"File not found: $WEKAN_DIR/.meteor/packages/meteor-useraccounts-core/package.js"
|
||||
exit 7289529
|
||||
fi
|
||||
sed -i 's/api\.versionsFrom/\/\/api.versionsFrom/' $WEKAN_DIR/.meteor/packages/meteor-useraccounts-core/package.js
|
||||
cd $WEKAN_DIR/.meteor
|
||||
su -c "$WEKAN_DIR/.meteor/meteor -- help" - wekan
|
||||
|
||||
# Build app
|
||||
if [ ! -d $WEKAN_DIR/app ]; then
|
||||
echo $'No app subdirectory found'
|
||||
exit 294569
|
||||
fi
|
||||
cd $WEKAN_DIR/app
|
||||
su -c "$WEKAN_DIR/.meteor/meteor add standard-minifier-js" - wekan
|
||||
su -c "$WEKAN_DIR/.meteor/meteor npm install" - wekan
|
||||
su -c "$WEKAN_DIR/.meteor/meteor build --directory $WEKAN_DIR/app_build" - wekan
|
||||
cp $WEKAN_DIR/app/fix-download-unicode/cfs_access-point.txt $WEKAN_DIR/app_build/bundle/programs/server/packages/cfs_access-point.js
|
||||
chown wekan:wekan $WEKAN_DIR/app_build/bundle/programs/server/packages/cfs_access-point.js
|
||||
sed -i "s|build\/Release\/bson|browser_build\/bson|g" $WEKAN_DIR/app_build/bundle/programs/server/npm/node_modules/meteor/cfs_gridfs/node_modules/mongodb/node_modules/bson/ext/index.js
|
||||
if [ ! -d $WEKAN_DIR/app_build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt ]; then
|
||||
echo $"No subdirectory found: $WEKAN_DIR/app_build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt"
|
||||
exit 479832
|
||||
fi
|
||||
cd $WEKAN_DIR/app_build/bundle/programs/server/npm/node_modules/meteor/npm-bcrypt
|
||||
su -c 'rm -rf node_modules/bcrypt' - wekan
|
||||
su -c 'npm install bcrypt' - wekan
|
||||
cd $WEKAN_DIR/app_build/bundle/programs/server/
|
||||
su -c 'npm install' - wekan
|
||||
mv $WEKAN_DIR/app_build/bundle ../build
|
||||
|
||||
if [ ! -f $WEKAN_DIR/build/main.js ]; then
|
||||
echo $'main.js not found'
|
||||
exit 7828252
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
rm -R $WEKAN_DIR/.meteor
|
||||
rm -R $WEKAN_DIR/app
|
||||
rm -R $WEKAN_DIR/app_build
|
||||
|
||||
chown -R wekan:wekan $WEKAN_DIR
|
||||
|
||||
function_check install_mariadb
|
||||
install_mariadb
|
||||
|
||||
function_check get_mariadb_password
|
||||
get_mariadb_password
|
||||
|
||||
function_check wekan_create_database
|
||||
wekan_create_database
|
||||
|
||||
# daemon
|
||||
echo '[Unit]' > /etc/systemd/system/wekan.service
|
||||
echo 'Description=Wekan' >> /etc/systemd/system/wekan.service
|
||||
echo 'After=syslog.target' >> /etc/systemd/system/wekan.service
|
||||
echo 'After=network.target' >> /etc/systemd/system/wekan.service
|
||||
echo '' >> /etc/systemd/system/wekan.service
|
||||
echo '[Service]' >> /etc/systemd/system/wekan.service
|
||||
echo 'User=wekan' >> /etc/systemd/system/wekan.service
|
||||
echo 'Group=wekan' >> /etc/systemd/system/wekan.service
|
||||
echo "WorkingDirectory=$WEKAN_DIR" >> /etc/systemd/system/wekan.service
|
||||
echo "ExecStart=/usr/local/bin/node $WEKAN_DIR/build/main.js" >> /etc/systemd/system/wekan.service
|
||||
echo 'Environment=PATH=/usr/bin:/usr/local/bin' >> /etc/systemd/system/wekan.service
|
||||
echo 'Environment=NODE_ENV=production' >> /etc/systemd/system/wekan.service
|
||||
echo 'Restart=on-failure' >> /etc/systemd/system/wekan.service
|
||||
echo '' >> /etc/systemd/system/wekan.service
|
||||
echo '[Install]' >> /etc/systemd/system/wekan.service
|
||||
echo 'WantedBy=multi-user.target' >> /etc/systemd/system/wekan.service
|
||||
systemctl enable wekan.service
|
||||
systemctl daemon-reload
|
||||
systemctl start wekan.service
|
||||
|
||||
systemctl restart nginx
|
||||
|
||||
set_completion_param "wekan domain" "$WEKAN_DOMAIN_NAME"
|
||||
|
||||
APP_INSTALLED=1
|
||||
}
|
||||
|
||||
# NOTE: deliberately there is no "exit 0"
|
|
@ -1274,6 +1274,11 @@ function image_preinstall_repos {
|
|||
git clone $TOXID_REPO $rootdir/repos/toxid
|
||||
git clone $TOXIC_REPO $rootdir/repos/toxic
|
||||
git clone $TURTL_REPO $rootdir/repos/turtl
|
||||
git clone $KANBOARD_REPO $rootdir/repos/kanboard
|
||||
#git clone $WEKAN_REPO $rootdir/repos/wekan
|
||||
#git clone $FLOW_ROUTER_REPO $rootdir/repos/flowrouter
|
||||
#git clone $METEOR_USERACCOUNTS_REPO $rootdir/repos/meteoruseraccounts
|
||||
#git clone $METEOR_REPO $rootdir/repos/meteor
|
||||
#git clone $ZERONET_REPO $rootdir/repos/zeronet
|
||||
#git clone $QTOX_REPO $rootdir/repos/qtox
|
||||
}
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# .---. . .
|
||||
# | | |
|
||||
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
|
||||
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
|
||||
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
|
||||
#
|
||||
# Freedom in the Cloud
|
||||
#
|
||||
# Functions for installing meteor
|
||||
# See meteor.com
|
||||
#
|
||||
# License
|
||||
# =======
|
||||
#
|
||||
# Copyright (C) 2017 Bob Mottram <bob@freedombone.net>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
METEOR_RELEASE='1.4.4.1'
|
||||
METEOR_REPO="https://github.com/meteor/meteor"
|
||||
METEOR_COMMIT='b52c6587d7542c0f27481a3bee8c65be06068ac1'
|
||||
METEOR_USERACCOUNTS_REPO="git://github.com/meteor-useraccounts/core.git"
|
||||
METEOR_USERACCOUNTS_COMMIT='2e8986813b51f321f908d2f6211f6f81f76cd627'
|
||||
|
||||
function meteor_cleanUp {
|
||||
rm -rf "$TARBALL_FILE"
|
||||
rm -rf "$INSTALL_TMPDIR"
|
||||
}
|
||||
|
||||
function install_meteor_script {
|
||||
meteor_dir=$1
|
||||
|
||||
if [ ! $meteor_dir ]; then
|
||||
echo $'No meteor install directory specified'
|
||||
exit 692025
|
||||
fi
|
||||
|
||||
if [ ! -d $meteor_dir ]; then
|
||||
echo $'Meteor install directory not found'
|
||||
exit 845382
|
||||
fi
|
||||
|
||||
if [[ "$(arch)" == "arm"* ]]; then
|
||||
echo 'meteor does not support ARM'
|
||||
exit 8362952
|
||||
fi
|
||||
if [[ "$(arch)" == "i386" || "$(arch)" == "x86_32" ]]; then
|
||||
PLATFORM="os.linux.x86_32"
|
||||
else
|
||||
PLATFORM="os.linux.x86_64"
|
||||
fi
|
||||
|
||||
RELEASE="$METEOR_RELEASE"
|
||||
|
||||
DIR_PREFIX="/usr/local"
|
||||
|
||||
TARBALL_URL="$https://meteorinstall-4168.kxcdn.com/packages-bootstrap/${RELEASE}/meteor-bootstrap-${PLATFORM}.tar.gz"
|
||||
INSTALL_TMPDIR="$meteor_dir/.meteor-install-tmp"
|
||||
TARBALL_FILE="$meteor_dir/.meteor-tarball-tmp"
|
||||
|
||||
# Remove temporary files now in case they exist.
|
||||
meteor_cleanUp
|
||||
|
||||
if [ -d $INSTALL_TMPDIR ]; then
|
||||
rm -rf $INSTALL_TMPDIR
|
||||
fi
|
||||
mkdir "$INSTALL_TMPDIR"
|
||||
|
||||
if [ ! -f ${TARBALL_FILE} ]; then
|
||||
echo "Downloading Meteor distribution"
|
||||
# keep trying to curl the file until it works (resuming where possible)
|
||||
MAX_ATTEMPTS=10
|
||||
RETRY_DELAY_SECS=5
|
||||
set +e
|
||||
ATTEMPTS=0
|
||||
while [ $ATTEMPTS -lt $MAX_ATTEMPTS ]
|
||||
do
|
||||
ATTEMPTS=$((ATTEMPTS + 1))
|
||||
|
||||
curl --progress-bar --fail --continue-at - \
|
||||
"$TARBALL_URL" --output "$TARBALL_FILE"
|
||||
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
break
|
||||
fi
|
||||
|
||||
echo "Retrying download in $RETRY_DELAY_SECS seconds..."
|
||||
sleep $RETRY_DELAY_SECS
|
||||
done
|
||||
fi
|
||||
|
||||
if [ ! -f ${TARBALL_FILE} ]; then
|
||||
echo $'meteor tarball could not be downloaded'
|
||||
exit 7272452
|
||||
fi
|
||||
|
||||
tar -xzf "$TARBALL_FILE" -C "$INSTALL_TMPDIR" -o
|
||||
|
||||
if [ ! -f ${INSTALL_TMPDIR}/.meteor/meteor ]; then
|
||||
echo $'tarball not extracted'
|
||||
exit 693252
|
||||
fi
|
||||
|
||||
mv "${INSTALL_TMPDIR}/.meteor" "$meteor_dir"
|
||||
|
||||
meteor_cleanUp
|
||||
|
||||
echo ''
|
||||
echo "Meteor ${RELEASE} has been installed in $meteor_dir/.meteor"
|
||||
|
||||
METEOR_SYMLINK_TARGET="$(readlink "$meteor_dir/.meteor/meteor")"
|
||||
METEOR_TOOL_DIRECTORY="$(dirname "$METEOR_SYMLINK_TARGET")"
|
||||
LAUNCHER="$meteor_dir/.meteor/$METEOR_TOOL_DIRECTORY/scripts/admin/launch-meteor"
|
||||
|
||||
if cp "$LAUNCHER" "$DIR_PREFIX/bin/meteor" >/dev/null 2>&1; then
|
||||
echo "Writing a launcher script to $DIR_PREFIX/bin/meteor for your convenience."
|
||||
cat <<"EOF"
|
||||
|
||||
To get started fast:
|
||||
|
||||
$ meteor create ~/my_cool_app
|
||||
$ cd ~/my_cool_app
|
||||
$ meteor
|
||||
|
||||
Or see the docs at:
|
||||
|
||||
docs.meteor.com
|
||||
|
||||
EOF
|
||||
elif type sudo >/dev/null 2>&1; then
|
||||
echo "Writing a launcher script to $DIR_PREFIX/bin/meteor for your convenience."
|
||||
echo "This may prompt for your password."
|
||||
|
||||
# New macs (10.9+) don't ship with /usr/local, however it is still in
|
||||
# the default PATH. We still install there, we just need to create the
|
||||
# directory first.
|
||||
# XXX this means that we can run sudo too many times. we should never
|
||||
# run it more than once if it fails the first time
|
||||
if [ ! -d "$DIR_PREFIX/bin" ] ; then
|
||||
sudo mkdir -m 755 "$DIR_PREFIX" || true
|
||||
sudo mkdir -m 755 "$DIR_PREFIX/bin" || true
|
||||
fi
|
||||
|
||||
if sudo cp "$LAUNCHER" "$DIR_PREFIX/bin/meteor"; then
|
||||
cat <<"EOF"
|
||||
|
||||
To get started fast:
|
||||
|
||||
$ meteor create ~/my_cool_app
|
||||
$ cd ~/my_cool_app
|
||||
$ meteor
|
||||
|
||||
Or see the docs at:
|
||||
|
||||
docs.meteor.com
|
||||
|
||||
EOF
|
||||
else
|
||||
cat <<EOF
|
||||
|
||||
Couldn't write the launcher script. Please either:
|
||||
|
||||
(1) Run the following as root:
|
||||
cp "$LAUNCHER" /usr/bin/meteor
|
||||
(2) Add "\$meteor_dir/.meteor" to your path, or
|
||||
(3) Rerun this command to try again.
|
||||
|
||||
Then to get started, take a look at 'meteor --help' or see the docs at
|
||||
docs.meteor.com.
|
||||
EOF
|
||||
fi
|
||||
else
|
||||
cat <<EOF
|
||||
|
||||
Now you need to do one of the following:
|
||||
|
||||
(1) Add "\$meteor_dir/.meteor" to your path, or
|
||||
(2) Run this command as root:
|
||||
cp "$LAUNCHER" /usr/bin/meteor
|
||||
|
||||
Then to get started, take a look at 'meteor --help' or see the docs at
|
||||
docs.meteor.com.
|
||||
EOF
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function install_meteor {
|
||||
apt-get -yq install curl
|
||||
if [ ! -d $INSTALL_DIR/meteor ]; then
|
||||
mkdir $INSTALL_DIR/meteor
|
||||
fi
|
||||
cd $INSTALL_DIR/meteor
|
||||
install_meteor_script
|
||||
}
|
||||
|
||||
function remove_meteor {
|
||||
if [ -f /usr/local/bin/meteor ]; then
|
||||
rm /usr/local/bin/meteor
|
||||
fi
|
||||
if [ -f /usr/bin/meteor ]; then
|
||||
rm /usr/bin/meteor
|
||||
fi
|
||||
}
|
||||
|
||||
# NOTE: deliberately no exit 0
|
|
@ -917,4 +917,20 @@ function create_default_web_site {
|
|||
fi
|
||||
}
|
||||
|
||||
function install_composer {
|
||||
# curl -sS https://getcomposer.org/installer | php
|
||||
if [ -f ~/${PROJECT_NAME}/image_build/composer_install ]; then
|
||||
cat ~/${PROJECT_NAME}/image_build/composer_install | php
|
||||
else
|
||||
if [ -f /home/$MY_USERNAME/${PROJECT_NAME}/image_build/composer_install ]; then
|
||||
cat /home/$MY_USERNAME/${PROJECT_NAME}/image_build/composer_install | php
|
||||
fi
|
||||
fi
|
||||
php composer.phar install
|
||||
if [ ! "$?" = "0" ]; then
|
||||
echo $'Unable to run composer install'
|
||||
exit 7252198
|
||||
fi
|
||||
}
|
||||
|
||||
# NOTE: deliberately no exit 0
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<!-- 2017-05-28 Sun 11:33 -->
|
||||
<!-- 2017-07-27 Thu 15:16 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title></title>
|
||||
|
@ -248,6 +248,14 @@ for the JavaScript code in this tag.
|
|||
<h1>CryptPad</h1>
|
||||
</center>
|
||||
|
||||
<div class="org-center">
|
||||
|
||||
<div class="figure">
|
||||
<p><img src="images/cryptpad.jpg" alt="cryptpad.jpg" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
This is similar to <a href="./app_etherpad.html">EtherPad</a> but with better security and more document types which can be collaboratively edited in real time. It includes not just text editing but also creating presentations, voting and editing source code.
|
||||
</p>
|
||||
|
@ -264,9 +272,9 @@ Enabling someone to edit a document is as simple as sending them the URL via a c
|
|||
Documents are stored locally within the browser of each user and the server just acts as a coordinator. No documents are stored on the server.
|
||||
</p>
|
||||
|
||||
<div id="outline-container-orgd443efe" class="outline-2">
|
||||
<h2 id="orgd443efe">Installation</h2>
|
||||
<div class="outline-text-2" id="text-orgd443efe">
|
||||
<div id="outline-container-orgf7a5294" class="outline-2">
|
||||
<h2 id="orgf7a5294">Installation</h2>
|
||||
<div class="outline-text-2" id="text-orgf7a5294">
|
||||
<p>
|
||||
Log into your system with:
|
||||
</p>
|
||||
|
|
|
@ -0,0 +1,323 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<!-- 2017-07-25 Tue 23:23 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title></title>
|
||||
<meta name="generator" content="Org mode" />
|
||||
<meta name="author" content="Bob Mottram" />
|
||||
<meta name="description" content="How to use KanBoard"
|
||||
/>
|
||||
<meta name="keywords" content="freedombone, kanboard" />
|
||||
<style type="text/css">
|
||||
<!--/*--><![CDATA[/*><!--*/
|
||||
.title { text-align: center;
|
||||
margin-bottom: .2em; }
|
||||
.subtitle { text-align: center;
|
||||
font-size: medium;
|
||||
font-weight: bold;
|
||||
margin-top:0; }
|
||||
.todo { font-family: monospace; color: red; }
|
||||
.done { font-family: monospace; color: green; }
|
||||
.priority { font-family: monospace; color: orange; }
|
||||
.tag { background-color: #eee; font-family: monospace;
|
||||
padding: 2px; font-size: 80%; font-weight: normal; }
|
||||
.timestamp { color: #bebebe; }
|
||||
.timestamp-kwd { color: #5f9ea0; }
|
||||
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
|
||||
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
|
||||
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
|
||||
.underline { text-decoration: underline; }
|
||||
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
|
||||
p.verse { margin-left: 3%; }
|
||||
pre {
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 3px 3px 3px #eee;
|
||||
padding: 8pt;
|
||||
font-family: monospace;
|
||||
overflow: auto;
|
||||
margin: 1.2em;
|
||||
}
|
||||
pre.src {
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
padding-top: 1.2em;
|
||||
}
|
||||
pre.src:before {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
top: -10px;
|
||||
right: 10px;
|
||||
padding: 3px;
|
||||
border: 1px solid black;
|
||||
}
|
||||
pre.src:hover:before { display: inline;}
|
||||
/* Languages per Org manual */
|
||||
pre.src-asymptote:before { content: 'Asymptote'; }
|
||||
pre.src-awk:before { content: 'Awk'; }
|
||||
pre.src-C:before { content: 'C'; }
|
||||
/* pre.src-C++ doesn't work in CSS */
|
||||
pre.src-clojure:before { content: 'Clojure'; }
|
||||
pre.src-css:before { content: 'CSS'; }
|
||||
pre.src-D:before { content: 'D'; }
|
||||
pre.src-ditaa:before { content: 'ditaa'; }
|
||||
pre.src-dot:before { content: 'Graphviz'; }
|
||||
pre.src-calc:before { content: 'Emacs Calc'; }
|
||||
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
|
||||
pre.src-fortran:before { content: 'Fortran'; }
|
||||
pre.src-gnuplot:before { content: 'gnuplot'; }
|
||||
pre.src-haskell:before { content: 'Haskell'; }
|
||||
pre.src-hledger:before { content: 'hledger'; }
|
||||
pre.src-java:before { content: 'Java'; }
|
||||
pre.src-js:before { content: 'Javascript'; }
|
||||
pre.src-latex:before { content: 'LaTeX'; }
|
||||
pre.src-ledger:before { content: 'Ledger'; }
|
||||
pre.src-lisp:before { content: 'Lisp'; }
|
||||
pre.src-lilypond:before { content: 'Lilypond'; }
|
||||
pre.src-lua:before { content: 'Lua'; }
|
||||
pre.src-matlab:before { content: 'MATLAB'; }
|
||||
pre.src-mscgen:before { content: 'Mscgen'; }
|
||||
pre.src-ocaml:before { content: 'Objective Caml'; }
|
||||
pre.src-octave:before { content: 'Octave'; }
|
||||
pre.src-org:before { content: 'Org mode'; }
|
||||
pre.src-oz:before { content: 'OZ'; }
|
||||
pre.src-plantuml:before { content: 'Plantuml'; }
|
||||
pre.src-processing:before { content: 'Processing.js'; }
|
||||
pre.src-python:before { content: 'Python'; }
|
||||
pre.src-R:before { content: 'R'; }
|
||||
pre.src-ruby:before { content: 'Ruby'; }
|
||||
pre.src-sass:before { content: 'Sass'; }
|
||||
pre.src-scheme:before { content: 'Scheme'; }
|
||||
pre.src-screen:before { content: 'Gnu Screen'; }
|
||||
pre.src-sed:before { content: 'Sed'; }
|
||||
pre.src-sh:before { content: 'shell'; }
|
||||
pre.src-sql:before { content: 'SQL'; }
|
||||
pre.src-sqlite:before { content: 'SQLite'; }
|
||||
/* additional languages in org.el's org-babel-load-languages alist */
|
||||
pre.src-forth:before { content: 'Forth'; }
|
||||
pre.src-io:before { content: 'IO'; }
|
||||
pre.src-J:before { content: 'J'; }
|
||||
pre.src-makefile:before { content: 'Makefile'; }
|
||||
pre.src-maxima:before { content: 'Maxima'; }
|
||||
pre.src-perl:before { content: 'Perl'; }
|
||||
pre.src-picolisp:before { content: 'Pico Lisp'; }
|
||||
pre.src-scala:before { content: 'Scala'; }
|
||||
pre.src-shell:before { content: 'Shell Script'; }
|
||||
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
|
||||
/* additional language identifiers per "defun org-babel-execute"
|
||||
in ob-*.el */
|
||||
pre.src-cpp:before { content: 'C++'; }
|
||||
pre.src-abc:before { content: 'ABC'; }
|
||||
pre.src-coq:before { content: 'Coq'; }
|
||||
pre.src-groovy:before { content: 'Groovy'; }
|
||||
/* additional language identifiers from org-babel-shell-names in
|
||||
ob-shell.el: ob-shell is the only babel language using a lambda to put
|
||||
the execution function name together. */
|
||||
pre.src-bash:before { content: 'bash'; }
|
||||
pre.src-csh:before { content: 'csh'; }
|
||||
pre.src-ash:before { content: 'ash'; }
|
||||
pre.src-dash:before { content: 'dash'; }
|
||||
pre.src-ksh:before { content: 'ksh'; }
|
||||
pre.src-mksh:before { content: 'mksh'; }
|
||||
pre.src-posh:before { content: 'posh'; }
|
||||
/* Additional Emacs modes also supported by the LaTeX listings package */
|
||||
pre.src-ada:before { content: 'Ada'; }
|
||||
pre.src-asm:before { content: 'Assembler'; }
|
||||
pre.src-caml:before { content: 'Caml'; }
|
||||
pre.src-delphi:before { content: 'Delphi'; }
|
||||
pre.src-html:before { content: 'HTML'; }
|
||||
pre.src-idl:before { content: 'IDL'; }
|
||||
pre.src-mercury:before { content: 'Mercury'; }
|
||||
pre.src-metapost:before { content: 'MetaPost'; }
|
||||
pre.src-modula-2:before { content: 'Modula-2'; }
|
||||
pre.src-pascal:before { content: 'Pascal'; }
|
||||
pre.src-ps:before { content: 'PostScript'; }
|
||||
pre.src-prolog:before { content: 'Prolog'; }
|
||||
pre.src-simula:before { content: 'Simula'; }
|
||||
pre.src-tcl:before { content: 'tcl'; }
|
||||
pre.src-tex:before { content: 'TeX'; }
|
||||
pre.src-plain-tex:before { content: 'Plain TeX'; }
|
||||
pre.src-verilog:before { content: 'Verilog'; }
|
||||
pre.src-vhdl:before { content: 'VHDL'; }
|
||||
pre.src-xml:before { content: 'XML'; }
|
||||
pre.src-nxml:before { content: 'XML'; }
|
||||
/* add a generic configuration mode; LaTeX export needs an additional
|
||||
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
|
||||
pre.src-conf:before { content: 'Configuration File'; }
|
||||
|
||||
table { border-collapse:collapse; }
|
||||
caption.t-above { caption-side: top; }
|
||||
caption.t-bottom { caption-side: bottom; }
|
||||
td, th { vertical-align:top; }
|
||||
th.org-right { text-align: center; }
|
||||
th.org-left { text-align: center; }
|
||||
th.org-center { text-align: center; }
|
||||
td.org-right { text-align: right; }
|
||||
td.org-left { text-align: left; }
|
||||
td.org-center { text-align: center; }
|
||||
dt { font-weight: bold; }
|
||||
.footpara { display: inline; }
|
||||
.footdef { margin-bottom: 1em; }
|
||||
.figure { padding: 1em; }
|
||||
.figure p { text-align: center; }
|
||||
.inlinetask {
|
||||
padding: 10px;
|
||||
border: 2px solid gray;
|
||||
margin: 10px;
|
||||
background: #ffffcc;
|
||||
}
|
||||
#org-div-home-and-up
|
||||
{ text-align: right; font-size: 70%; white-space: nowrap; }
|
||||
textarea { overflow-x: auto; }
|
||||
.linenr { font-size: smaller }
|
||||
.code-highlighted { background-color: #ffff00; }
|
||||
.org-info-js_info-navigation { border-style: none; }
|
||||
#org-info-js_console-label
|
||||
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
|
||||
.org-info-js_search-highlight
|
||||
{ background-color: #ffff00; color: #000000; font-weight: bold; }
|
||||
.org-svg { width: 90%; }
|
||||
/*]]>*/-->
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="freedombone.css" />
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
@licstart The following is the entire license notice for the
|
||||
JavaScript code in this tag.
|
||||
|
||||
Copyright (C) 2012-2017 Free Software Foundation, Inc.
|
||||
|
||||
The JavaScript code in this tag is free software: you can
|
||||
redistribute it and/or modify it under the terms of the GNU
|
||||
General Public License (GNU GPL) as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option)
|
||||
any later version. The code is distributed WITHOUT ANY WARRANTY;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
|
||||
|
||||
As additional permission under GNU GPL version 3 section 7, you
|
||||
may distribute non-source (e.g., minimized or compacted) forms of
|
||||
that code without the copy of the GNU GPL normally required by
|
||||
section 4, provided you include this license notice and a URL
|
||||
through which recipients can access the Corresponding Source.
|
||||
|
||||
|
||||
@licend The above is the entire license notice
|
||||
for the JavaScript code in this tag.
|
||||
*/
|
||||
<!--/*--><![CDATA[/*><!--*/
|
||||
function CodeHighlightOn(elem, id)
|
||||
{
|
||||
var target = document.getElementById(id);
|
||||
if(null != target) {
|
||||
elem.cacheClassElem = elem.className;
|
||||
elem.cacheClassTarget = target.className;
|
||||
target.className = "code-highlighted";
|
||||
elem.className = "code-highlighted";
|
||||
}
|
||||
}
|
||||
function CodeHighlightOff(elem, id)
|
||||
{
|
||||
var target = document.getElementById(id);
|
||||
if(elem.cacheClassElem)
|
||||
elem.className = elem.cacheClassElem;
|
||||
if(elem.cacheClassTarget)
|
||||
target.className = elem.cacheClassTarget;
|
||||
}
|
||||
/*]]>*///-->
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="preamble" class="status">
|
||||
<a name="top" id="top"></a>
|
||||
</div>
|
||||
<div id="content">
|
||||
<div class="org-center">
|
||||
|
||||
<div class="figure">
|
||||
<p><img src="images/logo.png" alt="logo.png" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<center>
|
||||
<h1>KanBoard</h1>
|
||||
</center>
|
||||
|
||||
<p>
|
||||
Kanbans are one way of managing projects. They're traditionally used in businesses but can also be useful for personal TODO lists or within open source or DIY projects. If you have a list of things which need to be done and want to keep track of progress then this provides a way to do that.
|
||||
</p>
|
||||
|
||||
<div id="outline-container-orgfd145f9" class="outline-2">
|
||||
<h2 id="orgfd145f9">Installation</h2>
|
||||
<div class="outline-text-2" id="text-orgfd145f9">
|
||||
<p>
|
||||
Log into your system with:
|
||||
</p>
|
||||
|
||||
<div class="org-src-container">
|
||||
<pre><code class="src src-bash">ssh myusername@mydomain -p 2222
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Using cursor keys, space bar and Enter key select <b>Administrator controls</b> and type in your password.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Select <b>Add/Remove Apps</b> then <b>kanboard</b>. You will then be asked for a domain name and if you are using FreeDNS also the code for the domain which can be found under <b>Dynamic DNS</b> on the FreeDNS site (the random string from "<i>quick cron example</i>" which appears after <i>update.php?</i> and before <i>>></i>). For more details on obtaining a domain and making it accessible via dynamic DNS see the <a href="./faq.html">FAQ</a>. Typically the domain name you use will be a subdomain, such as <i>kanban.mydomainname.net</i>. It will need to be a domain which you have bought somewhere and own and not one of the FreeDNS subdomains, otherwise you won't be able to get a SSL/TLS certificate for it.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
After the install has completed go to <b>Security settings</b> and select <b>Create a new Let's Encrypt certificate</b> and enter the domain name that you are using for KanBoard. If you're using the "onion only" version of the system then you don't need to do this. If the certificate is obtained successfully then you will see a congratulations message.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org2e3435d" class="outline-2">
|
||||
<h2 id="org2e3435d">Initial setup</h2>
|
||||
<div class="outline-text-2" id="text-org2e3435d">
|
||||
<p>
|
||||
If you have just obtained a Lets Encrypt certificate as above then go to <b>About</b> on the administrator control panel and you should see your KanBoard domain listed there along with an onion address. You can then navigate to your site in a browser.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The default login is username "admin" and password "admin". Obviously the first thing you'll need to do is log in and change the password, which can be done by going to "My Profile" on the drop down list on the right hand side.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more details of how to use KanBoard see the <a href="https://kanboard.net/documentation">documentation here</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="postamble" class="status">
|
||||
|
||||
<style type="text/css">
|
||||
.back-to-top {
|
||||
position: fixed;
|
||||
bottom: 2em;
|
||||
right: 0px;
|
||||
text-decoration: none;
|
||||
color: #000000;
|
||||
background-color: rgba(235, 235, 235, 0.80);
|
||||
font-size: 12px;
|
||||
padding: 1em;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.back-to-top:hover {
|
||||
background-color: rgba(135, 135, 135, 0.50);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="back-to-top">
|
||||
<a href="#top">Back to top</a> | <a href="mailto:bob@freedombone.net">E-mail me</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -3,7 +3,7 @@
|
|||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<!-- 2017-06-25 Sun 21:57 -->
|
||||
<!-- 2017-07-25 Tue 23:25 -->
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title></title>
|
||||
|
@ -264,9 +264,9 @@ The base install of the system just contains an email server and Mutt client, bu
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org63f1146" class="outline-2">
|
||||
<h2 id="org63f1146">CryptPad</h2>
|
||||
<div class="outline-text-2" id="text-org63f1146">
|
||||
<div id="outline-container-org9a19246" class="outline-2">
|
||||
<h2 id="org9a19246">CryptPad</h2>
|
||||
<div class="outline-text-2" id="text-org9a19246">
|
||||
<p>
|
||||
Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
|
||||
</p>
|
||||
|
@ -276,9 +276,9 @@ Collaborate on editing documents, presentations and source code, or vote on thin
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orgf372cd2" class="outline-2">
|
||||
<h2 id="orgf372cd2">DLNA</h2>
|
||||
<div class="outline-text-2" id="text-orgf372cd2">
|
||||
<div id="outline-container-orgaf887a3" class="outline-2">
|
||||
<h2 id="orgaf887a3">DLNA</h2>
|
||||
<div class="outline-text-2" id="text-orgaf887a3">
|
||||
<p>
|
||||
Enables you to use the system as a music server which any DLNA compatible devices can connect to within your home network.
|
||||
</p>
|
||||
|
@ -288,9 +288,9 @@ Enables you to use the system as a music server which any DLNA compatible device
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orge69d870" class="outline-2">
|
||||
<h2 id="orge69d870">Dokuwiki</h2>
|
||||
<div class="outline-text-2" id="text-orge69d870">
|
||||
<div id="outline-container-org24b3d95" class="outline-2">
|
||||
<h2 id="org24b3d95">Dokuwiki</h2>
|
||||
<div class="outline-text-2" id="text-org24b3d95">
|
||||
<p>
|
||||
A databaseless wiki system.
|
||||
</p>
|
||||
|
@ -300,9 +300,9 @@ A databaseless wiki system.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org748292e" class="outline-2">
|
||||
<h2 id="org748292e">Emacs</h2>
|
||||
<div class="outline-text-2" id="text-org748292e">
|
||||
<div id="outline-container-orga7568ea" class="outline-2">
|
||||
<h2 id="orga7568ea">Emacs</h2>
|
||||
<div class="outline-text-2" id="text-orga7568ea">
|
||||
<p>
|
||||
If you use the Mutt client to read your email then this will set it up to use emacs for composing new mail.
|
||||
</p>
|
||||
|
@ -312,9 +312,9 @@ If you use the Mutt client to read your email then this will set it up to use em
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org9e62d1f" class="outline-2">
|
||||
<h2 id="org9e62d1f">Etherpad</h2>
|
||||
<div class="outline-text-2" id="text-org9e62d1f">
|
||||
<div id="outline-container-org3d4300f" class="outline-2">
|
||||
<h2 id="org3d4300f">Etherpad</h2>
|
||||
<div class="outline-text-2" id="text-org3d4300f">
|
||||
<p>
|
||||
Collaborate on creating documents in real time. Maybe you're planning a holiday with other family members or creating documentation for a Free Software project along with other volunteers. Etherpad is hard to beat for simplicity and speed. Only users of the system will be able to access it.
|
||||
</p>
|
||||
|
@ -324,9 +324,9 @@ Collaborate on creating documents in real time. Maybe you're planning a holiday
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org8eb5191" class="outline-2">
|
||||
<h2 id="org8eb5191">Friendica</h2>
|
||||
<div class="outline-text-2" id="text-org8eb5191">
|
||||
<div id="outline-container-org91f769f" class="outline-2">
|
||||
<h2 id="org91f769f">Friendica</h2>
|
||||
<div class="outline-text-2" id="text-org91f769f">
|
||||
<p>
|
||||
Federated social network system.
|
||||
</p>
|
||||
|
@ -336,9 +336,9 @@ Federated social network system.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orge13ef3e" class="outline-2">
|
||||
<h2 id="orge13ef3e">Ghost</h2>
|
||||
<div class="outline-text-2" id="text-orge13ef3e">
|
||||
<div id="outline-container-org6266e6b" class="outline-2">
|
||||
<h2 id="org6266e6b">Ghost</h2>
|
||||
<div class="outline-text-2" id="text-org6266e6b">
|
||||
<p>
|
||||
Modern looking blogging system.
|
||||
</p>
|
||||
|
@ -348,9 +348,9 @@ Modern looking blogging system.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org18ba256" class="outline-2">
|
||||
<h2 id="org18ba256">GNU Social</h2>
|
||||
<div class="outline-text-2" id="text-org18ba256">
|
||||
<div id="outline-container-orge7307c0" class="outline-2">
|
||||
<h2 id="orge7307c0">GNU Social</h2>
|
||||
<div class="outline-text-2" id="text-orge7307c0">
|
||||
<p>
|
||||
Federated social network. You can "<i>remote follow</i>" other users within the GNU Social federation.
|
||||
</p>
|
||||
|
@ -360,9 +360,9 @@ Federated social network. You can "<i>remote follow</i>" other users within the
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orgbf05b19" class="outline-2">
|
||||
<h2 id="orgbf05b19">Gogs</h2>
|
||||
<div class="outline-text-2" id="text-orgbf05b19">
|
||||
<div id="outline-container-org42d8a6c" class="outline-2">
|
||||
<h2 id="org42d8a6c">Gogs</h2>
|
||||
<div class="outline-text-2" id="text-org42d8a6c">
|
||||
<p>
|
||||
Lightweight git project hosting system. You can mirror projects from Github, or if Github turns evil then just host your own projects while retaining the familiar <i>fork-and-pull</i> workflow. If you can use Github then you can also use Gogs.
|
||||
</p>
|
||||
|
@ -372,9 +372,9 @@ Lightweight git project hosting system. You can mirror projects from Github, or
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org14e55c0" class="outline-2">
|
||||
<h2 id="org14e55c0">HTMLy</h2>
|
||||
<div class="outline-text-2" id="text-org14e55c0">
|
||||
<div id="outline-container-org21d5b80" class="outline-2">
|
||||
<h2 id="org21d5b80">HTMLy</h2>
|
||||
<div class="outline-text-2" id="text-org21d5b80">
|
||||
<p>
|
||||
Databaseless blogging system. Quite simple and with a markdown-like format.
|
||||
</p>
|
||||
|
@ -384,9 +384,9 @@ Databaseless blogging system. Quite simple and with a markdown-like format.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org4db6ae4" class="outline-2">
|
||||
<h2 id="org4db6ae4">Hubzilla</h2>
|
||||
<div class="outline-text-2" id="text-org4db6ae4">
|
||||
<div id="outline-container-org47d8fc7" class="outline-2">
|
||||
<h2 id="org47d8fc7">Hubzilla</h2>
|
||||
<div class="outline-text-2" id="text-org47d8fc7">
|
||||
<p>
|
||||
Web publishing platform with social network like features and good privacy controls so that it's possible to specify who can see which content. Includes photo albums, calendar, wiki and file storage.
|
||||
</p>
|
||||
|
@ -396,9 +396,9 @@ Web publishing platform with social network like features and good privacy contr
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org7fae7fd" class="outline-2">
|
||||
<h2 id="org7fae7fd">IRC Server (ngirc)</h2>
|
||||
<div class="outline-text-2" id="text-org7fae7fd">
|
||||
<div id="outline-container-org71113c6" class="outline-2">
|
||||
<h2 id="org71113c6">IRC Server (ngirc)</h2>
|
||||
<div class="outline-text-2" id="text-org71113c6">
|
||||
<p>
|
||||
Run your own IRC chat channel which can be secured with a password and accessible via an onion address. A bouncer is included so that you can receive messages sent while you were offline. Works with Hexchat and other popular clients.
|
||||
</p>
|
||||
|
@ -408,18 +408,30 @@ Run your own IRC chat channel which can be secured with a password and accessibl
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org0422600" class="outline-2">
|
||||
<h2 id="org0422600">Jitsi Meet</h2>
|
||||
<div class="outline-text-2" id="text-org0422600">
|
||||
<div id="outline-container-org9f28087" class="outline-2">
|
||||
<h2 id="org9f28087">Jitsi Meet</h2>
|
||||
<div class="outline-text-2" id="text-org9f28087">
|
||||
<p>
|
||||
Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-orgb944eab" class="outline-2">
|
||||
<h2 id="orgb944eab">Koel</h2>
|
||||
<div class="outline-text-2" id="text-orgb944eab">
|
||||
<div id="outline-container-orgbad5922" class="outline-2">
|
||||
<h2 id="orgbad5922">KanBoard</h2>
|
||||
<div class="outline-text-2" id="text-orgbad5922">
|
||||
<p>
|
||||
A simple kanban system for managing projects or TODO lists.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="./app_kanboard.html">How to use it</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org6529912" class="outline-2">
|
||||
<h2 id="org6529912">Koel</h2>
|
||||
<div class="outline-text-2" id="text-org6529912">
|
||||
<p>
|
||||
Access your music collection from any internet connected device.
|
||||
</p>
|
||||
|
@ -429,9 +441,9 @@ Access your music collection from any internet connected device.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orgbbbba81" class="outline-2">
|
||||
<h2 id="orgbbbba81">Lychee</h2>
|
||||
<div class="outline-text-2" id="text-orgbbbba81">
|
||||
<div id="outline-container-orgc0eae1a" class="outline-2">
|
||||
<h2 id="orgc0eae1a">Lychee</h2>
|
||||
<div class="outline-text-2" id="text-orgc0eae1a">
|
||||
<p>
|
||||
Make your photo albums available on the web.
|
||||
</p>
|
||||
|
@ -441,9 +453,9 @@ Make your photo albums available on the web.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org6ff2173" class="outline-2">
|
||||
<h2 id="org6ff2173">Mailpile</h2>
|
||||
<div class="outline-text-2" id="text-org6ff2173">
|
||||
<div id="outline-container-orga4bfc9d" class="outline-2">
|
||||
<h2 id="orga4bfc9d">Mailpile</h2>
|
||||
<div class="outline-text-2" id="text-orga4bfc9d">
|
||||
<p>
|
||||
Modern email client which supports GPG encryption.
|
||||
</p>
|
||||
|
@ -453,9 +465,9 @@ Modern email client which supports GPG encryption.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orgbed2d4b" class="outline-2">
|
||||
<h2 id="orgbed2d4b">Matrix</h2>
|
||||
<div class="outline-text-2" id="text-orgbed2d4b">
|
||||
<div id="outline-container-org672b48e" class="outline-2">
|
||||
<h2 id="org672b48e">Matrix</h2>
|
||||
<div class="outline-text-2" id="text-org672b48e">
|
||||
<p>
|
||||
Multi-user chat with some security and moderation controls.
|
||||
</p>
|
||||
|
@ -465,9 +477,9 @@ Multi-user chat with some security and moderation controls.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org35530e4" class="outline-2">
|
||||
<h2 id="org35530e4">Mediagoblin</h2>
|
||||
<div class="outline-text-2" id="text-org35530e4">
|
||||
<div id="outline-container-orgce218ca" class="outline-2">
|
||||
<h2 id="orgce218ca">Mediagoblin</h2>
|
||||
<div class="outline-text-2" id="text-orgce218ca">
|
||||
<p>
|
||||
Publicly host video and audio files so that you don't need to use YouTube/Vimeo/etc.
|
||||
</p>
|
||||
|
@ -477,9 +489,9 @@ Publicly host video and audio files so that you don't need to use YouTube/Vimeo/
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org5500ed4" class="outline-2">
|
||||
<h2 id="org5500ed4">Mumble</h2>
|
||||
<div class="outline-text-2" id="text-org5500ed4">
|
||||
<div id="outline-container-orgb224245" class="outline-2">
|
||||
<h2 id="orgb224245">Mumble</h2>
|
||||
<div class="outline-text-2" id="text-orgb224245">
|
||||
<p>
|
||||
The popular VoIP and text chat system. Say goodbye to old-fashioned telephony conferences with silly dial codes. Also works well on mobile.
|
||||
</p>
|
||||
|
@ -489,9 +501,9 @@ The popular VoIP and text chat system. Say goodbye to old-fashioned telephony co
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orgc0f99a0" class="outline-2">
|
||||
<h2 id="orgc0f99a0">NextCloud</h2>
|
||||
<div class="outline-text-2" id="text-orgc0f99a0">
|
||||
<div id="outline-container-org2786fbb" class="outline-2">
|
||||
<h2 id="org2786fbb">NextCloud</h2>
|
||||
<div class="outline-text-2" id="text-org2786fbb">
|
||||
<p>
|
||||
Store files on your server and sync them with laptops or mobile devices. Includes many plugins including videoconferencing and collaborative document editing.
|
||||
</p>
|
||||
|
@ -501,9 +513,9 @@ Store files on your server and sync them with laptops or mobile devices. Include
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orga3e49f8" class="outline-2">
|
||||
<h2 id="orga3e49f8">PI-Hole</h2>
|
||||
<div class="outline-text-2" id="text-orga3e49f8">
|
||||
<div id="outline-container-orgaad15be" class="outline-2">
|
||||
<h2 id="orgaad15be">PI-Hole</h2>
|
||||
<div class="outline-text-2" id="text-orgaad15be">
|
||||
<p>
|
||||
The black hole for web adverts. Block adverts at the domain name level within your local network. It can significantly reduce bandwidth, speed up page load times and protect your systems from being tracked by spyware.
|
||||
</p>
|
||||
|
@ -513,9 +525,9 @@ The black hole for web adverts. Block adverts at the domain name level within yo
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org6d5133e" class="outline-2">
|
||||
<h2 id="org6d5133e">PostActiv</h2>
|
||||
<div class="outline-text-2" id="text-org6d5133e">
|
||||
<div id="outline-container-org0cb789f" class="outline-2">
|
||||
<h2 id="org0cb789f">PostActiv</h2>
|
||||
<div class="outline-text-2" id="text-org0cb789f">
|
||||
<p>
|
||||
An alternative federated social networking system compatible with GNU Social. It includes some optimisations and fixes currently not available within the main GNU Social project.
|
||||
</p>
|
||||
|
@ -525,9 +537,9 @@ An alternative federated social networking system compatible with GNU Social. It
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org82cb46a" class="outline-2">
|
||||
<h2 id="org82cb46a">Profanity</h2>
|
||||
<div class="outline-text-2" id="text-org82cb46a">
|
||||
<div id="outline-container-org6b2db26" class="outline-2">
|
||||
<h2 id="org6b2db26">Profanity</h2>
|
||||
<div class="outline-text-2" id="text-org6b2db26">
|
||||
<p>
|
||||
A shell based XMPP client which you can run on the Freedombone server via ssh.
|
||||
</p>
|
||||
|
@ -537,9 +549,9 @@ A shell based XMPP client which you can run on the Freedombone server via ssh.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org0544cbf" class="outline-2">
|
||||
<h2 id="org0544cbf">Riot Web</h2>
|
||||
<div class="outline-text-2" id="text-org0544cbf">
|
||||
<div id="outline-container-org4dea572" class="outline-2">
|
||||
<h2 id="org4dea572">Riot Web</h2>
|
||||
<div class="outline-text-2" id="text-org4dea572">
|
||||
<p>
|
||||
A browser based user interface for the Matrix federated communications system, including WebRTC audio and video chat.
|
||||
</p>
|
||||
|
@ -549,9 +561,9 @@ A browser based user interface for the Matrix federated communications system, i
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-orga52c58b" class="outline-2">
|
||||
<h2 id="orga52c58b">SearX</h2>
|
||||
<div class="outline-text-2" id="text-orga52c58b">
|
||||
<div id="outline-container-org7e88433" class="outline-2">
|
||||
<h2 id="org7e88433">SearX</h2>
|
||||
<div class="outline-text-2" id="text-org7e88433">
|
||||
<p>
|
||||
A metasearch engine for customised and private web searches.
|
||||
</p>
|
||||
|
@ -561,9 +573,9 @@ A metasearch engine for customised and private web searches.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org8f2b9fe" class="outline-2">
|
||||
<h2 id="org8f2b9fe">tt-rss</h2>
|
||||
<div class="outline-text-2" id="text-org8f2b9fe">
|
||||
<div id="outline-container-orgcfc1af4" class="outline-2">
|
||||
<h2 id="orgcfc1af4">tt-rss</h2>
|
||||
<div class="outline-text-2" id="text-orgcfc1af4">
|
||||
<p>
|
||||
Private RSS reader. Pulls in RSS/Atom feeds via Tor and is only accessible via an onion address. Have "<i>the right to read</i>" without the Surveillance State knowing what you're reading. Also available with a user interface suitable for viewing on mobile devices via a browser such as OrFox.
|
||||
</p>
|
||||
|
@ -573,9 +585,9 @@ Private RSS reader. Pulls in RSS/Atom feeds via Tor and is only accessible via a
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org96317fb" class="outline-2">
|
||||
<h2 id="org96317fb">Syncthing</h2>
|
||||
<div class="outline-text-2" id="text-org96317fb">
|
||||
<div id="outline-container-org526d1e5" class="outline-2">
|
||||
<h2 id="org526d1e5">Syncthing</h2>
|
||||
<div class="outline-text-2" id="text-org526d1e5">
|
||||
<p>
|
||||
Possibly the best way to synchronise files across all of your devices. Once it has been set up it "just works" with no user intervention needed.
|
||||
</p>
|
||||
|
@ -585,9 +597,9 @@ Possibly the best way to synchronise files across all of your devices. Once it h
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org6118146" class="outline-2">
|
||||
<h2 id="org6118146">Tahoe-LAFS</h2>
|
||||
<div class="outline-text-2" id="text-org6118146">
|
||||
<div id="outline-container-org43bcb4f" class="outline-2">
|
||||
<h2 id="org43bcb4f">Tahoe-LAFS</h2>
|
||||
<div class="outline-text-2" id="text-org43bcb4f">
|
||||
<p>
|
||||
Robust and encrypted storage of files on one or more server.
|
||||
</p>
|
||||
|
@ -597,9 +609,9 @@ Robust and encrypted storage of files on one or more server.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org7850375" class="outline-2">
|
||||
<h2 id="org7850375">Tox</h2>
|
||||
<div class="outline-text-2" id="text-org7850375">
|
||||
<div id="outline-container-org29d522e" class="outline-2">
|
||||
<h2 id="org29d522e">Tox</h2>
|
||||
<div class="outline-text-2" id="text-org29d522e">
|
||||
<p>
|
||||
Client and bootstrap node for the Tox chat/VoIP system.
|
||||
</p>
|
||||
|
@ -609,9 +621,9 @@ Client and bootstrap node for the Tox chat/VoIP system.
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org37c0a88" class="outline-2">
|
||||
<h2 id="org37c0a88">Turtl</h2>
|
||||
<div class="outline-text-2" id="text-org37c0a88">
|
||||
<div id="outline-container-org71eba9a" class="outline-2">
|
||||
<h2 id="org71eba9a">Turtl</h2>
|
||||
<div class="outline-text-2" id="text-org71eba9a">
|
||||
<p>
|
||||
A system for privately creating and sharing notes and images, similar to Evernote but without the spying.
|
||||
</p>
|
||||
|
@ -621,18 +633,18 @@ A system for privately creating and sharing notes and images, similar to Evernot
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="outline-container-org6042f9a" class="outline-2">
|
||||
<h2 id="org6042f9a">Vim</h2>
|
||||
<div class="outline-text-2" id="text-org6042f9a">
|
||||
<div id="outline-container-org95cabfd" class="outline-2">
|
||||
<h2 id="org95cabfd">Vim</h2>
|
||||
<div class="outline-text-2" id="text-org95cabfd">
|
||||
<p>
|
||||
If you use the Mutt client to read your email then this will set it up to use vim for composing new mail.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outline-container-org51cc377" class="outline-2">
|
||||
<h2 id="org51cc377">XMPP</h2>
|
||||
<div class="outline-text-2" id="text-org51cc377">
|
||||
<div id="outline-container-org07897b8" class="outline-2">
|
||||
<h2 id="org07897b8">XMPP</h2>
|
||||
<div class="outline-text-2" id="text-org07897b8">
|
||||
<p>
|
||||
Chat server which can be used together with client such as Gajim or Conversations to provide end-to-end content security and also onion routed metadata security. Includes advanced features such as <i>client state notification</i> to save battery power on your mobile devices, support for seamless roaming between networks and <i>message carbons</i> so that you can receive the same messages while being simultaneously logged in to your account on more than one device.
|
||||
</p>
|
||||
|
|
Loading…
Reference in New Issue