Browse Source

Merge branch 'stretch' of https://github.com/bashrc/freedombone

Bob Mottram 7 years ago
parent
commit
8ee6075366
48 changed files with 2238 additions and 1869 deletions
  1. 34
    0
      doc/EN/app_bludit.org
  2. 0
    45
      doc/EN/app_ghost.org
  3. 49
    0
      doc/EN/app_peertube.org
  4. 4
    4
      doc/EN/apps.org
  5. BIN
      img/peertube.jpg
  6. 1
    1
      src/freedombone-app-akaunting
  7. 338
    0
      src/freedombone-app-bludit
  8. 2
    2
      src/freedombone-app-cryptpad
  9. 11
    18
      src/freedombone-app-dlna
  10. 12
    19
      src/freedombone-app-edith
  11. 11
    18
      src/freedombone-app-etherpad
  12. 40
    27
      src/freedombone-app-fedwiki
  13. 13
    18
      src/freedombone-app-friendica
  14. 0
    603
      src/freedombone-app-ghost
  15. 15
    21
      src/freedombone-app-gnusocial
  16. 11
    16
      src/freedombone-app-hubzilla
  17. 20
    27
      src/freedombone-app-icecast
  18. 11
    17
      src/freedombone-app-irc
  19. 12
    19
      src/freedombone-app-keyserver
  20. 13
    20
      src/freedombone-app-koel
  21. 1
    1
      src/freedombone-app-mailpile
  22. 2
    2
      src/freedombone-app-matrix
  23. 292
    33
      src/freedombone-app-peertube
  24. 47
    43
      src/freedombone-app-pihole
  25. 96
    57
      src/freedombone-app-pleroma
  26. 15
    22
      src/freedombone-app-postactiv
  27. 26
    23
      src/freedombone-app-scuttlebot
  28. 11
    18
      src/freedombone-app-searx
  29. 19
    21
      src/freedombone-app-tahoelafs
  30. 13
    20
      src/freedombone-app-vpn
  31. 12
    18
      src/freedombone-app-xmpp
  32. 177
    38
      src/freedombone-base-email
  33. 252
    256
      src/freedombone-config
  34. 2
    2
      src/freedombone-image
  35. 13
    14
      src/freedombone-image-customise
  36. 2
    2
      src/freedombone-image-makefile
  37. 3
    3
      src/freedombone-syncthing
  38. 181
    167
      src/freedombone-template
  39. 9
    3
      src/freedombone-upgrade
  40. 7
    2
      src/freedombone-utils-avahi
  41. 2
    2
      src/freedombone-utils-dns
  42. 3
    0
      src/freedombone-utils-firewall
  43. 7
    6
      src/freedombone-utils-login
  44. 124
    16
      src/freedombone-utils-nodejs
  45. 2
    2
      src/freedombone-utils-onion
  46. 11
    36
      website/EN/app_bludit.html
  47. 50
    16
      website/EN/app_peertube.html
  48. 262
    171
      website/EN/apps.html

+ 34
- 0
doc/EN/app_bludit.org View File

1
+#+TITLE:
2
+#+AUTHOR: Bob Mottram
3
+#+EMAIL: bob@freedombone.net
4
+#+KEYWORDS: freedombone, bludit, blog
5
+#+DESCRIPTION: How to use Bludit
6
+#+OPTIONS: ^:nil toc:nil
7
+#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="freedombone.css" />
8
+
9
+#+BEGIN_CENTER
10
+[[file:images/logo.png]]
11
+#+END_CENTER
12
+
13
+#+BEGIN_EXPORT html
14
+<center>
15
+<h1>Bludit</h1>
16
+</center>
17
+#+END_EXPORT
18
+
19
+This is a databaseless blogging system which uses markdown files. It's not very complex and so there is not much to go wrong, and it should run well on any server hardware.
20
+
21
+* Installation
22
+Log into your system with:
23
+
24
+#+begin_src bash
25
+ssh myusername@mydomain -p 2222
26
+#+end_src
27
+
28
+Using cursor keys, space bar and Enter key select *Administrator controls* and type in your password.
29
+
30
+Select *Add/Remove Apps* then *bluit*. Enter the subdomain that you which to use, such as *blog.mydomain.net*, and optionally a FreeDNS code.
31
+
32
+Now in a browser navigate to your subdomain. You will need to enter some details for the database. You'll be asked to provide an initial administrator password.
33
+
34
+From there on it's all pretty straightforward. If you need to publish a draft the post status can be changed on a drop down list on the right hand side.

+ 0
- 45
doc/EN/app_ghost.org View File

1
-#+TITLE:
2
-#+AUTHOR: Bob Mottram
3
-#+EMAIL: bob@freedombone.net
4
-#+KEYWORDS: freedombone, ghost
5
-#+DESCRIPTION: How to use Ghost
6
-#+OPTIONS: ^:nil toc:nil
7
-#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="freedombone.css" />
8
-
9
-#+BEGIN_CENTER
10
-[[file:images/logo.png]]
11
-#+END_CENTER
12
-
13
-#+BEGIN_EXPORT html
14
-<center>
15
-<h1>Ghost</h1>
16
-</center>
17
-#+END_EXPORT
18
-
19
-Ghost is a blogging system which uses markdown formatted posts. It's quite simple to use, and also looks nice even on small mobile screens.
20
-
21
-* Installation
22
-Log into your system with:
23
-
24
-#+begin_src bash
25
-ssh myusername@mydomain -p 2222
26
-#+end_src
27
-
28
-Using cursor keys, space bar and Enter key select *Administrator controls* and type in your password.
29
-
30
-Select *Add/Remove Apps* then *ghost*. 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 /blog.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.
31
-
32
-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 Ghost. 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.
33
-
34
-* Initial setup
35
-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 Ghost blog domain listed there along with an onion address. You can then navigate to your site in a browser.
36
-
37
-To see the login password for your site go to *Passwords* on the *Administrator control panel* and select the appropriate username and app. The passwords will be different for each user and may not be the same as the password which you used to originally ssh into the system.
38
-
39
-Navigate to https://yourghostblogdomain/ghost and click on *create your account*
40
-
41
-Enter your email address, password and blog title.
42
-
43
-When prompted to invite users click on *I'll do this later*
44
-
45
-Under *Settings* on the *General* option you can set a description, background image and so on.

+ 49
- 0
doc/EN/app_peertube.org View File

1
+#+TITLE:
2
+#+AUTHOR: Bob Mottram
3
+#+EMAIL: bob@freedombone.net
4
+#+KEYWORDS: freedombone, peertube
5
+#+DESCRIPTION: How to use PeerTube
6
+#+OPTIONS: ^:nil toc:nil
7
+#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="freedombone.css" />
8
+
9
+#+BEGIN_CENTER
10
+[[file:images/logo.png]]
11
+#+END_CENTER
12
+
13
+#+BEGIN_CENTER
14
+[[file:images/peertube.jpg]]
15
+#+END_CENTER
16
+
17
+This is a video hosting system similar to Mediagoblin but using webtorrent to help distribute the files to or between clients. This should be more practical for situations where a video becomes popular because the load is then spread across the network, with performance increasing with the number of nodes. However, the torrenting aspect of it only works with WebRTC enabled browsers and so this means it's unlikely to fully work with a Tor browser. Without WebRTC then from a user point of view it's effectively the same thing as Mediagoblin.
18
+
19
+* Installation
20
+Log into your system with:
21
+
22
+#+begin_src bash
23
+ssh myusername@mydomain -p 2222
24
+#+end_src
25
+
26
+Using cursor keys, space bar and Enter key select *Administrator controls* and type in your password.
27
+
28
+Select *Add/Remove Apps* then *peertube*. 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 /video.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.
29
+
30
+* Initial setup
31
+Navigate to your site and select *Signup* to create a new account. By default the maximum number of accounts on your system is limited to a small number so that millions of random internet users can't then begin uploading dubious content. After that it's pretty straightforward.
32
+
33
+If you wish it's possible to turn off further signups via the *Administrator control panel* under *App settings* for *peertube*.
34
+
35
+* Importing videos from YouTube/Vimeo/Dailymotion
36
+It's possible to import videos from the main proprietary video hosting sites. /Only do this if they're videos which you made, or if the license is Creative Commons/. Hosting arbitrary videos under nonfree licenses is likely to get you into trouble, and we know how that works out from the P2P wars of the 2000s (i.e. badly).
37
+
38
+Go to the *Administrator control panel*, select *App settings* then *peertube* then *Import videos from YouTube/Vimeo/Dailymotion*. Enter your PeerTube login details and then you may specify either the individual video URL or the channel URL if you want to import a whole channel.
39
+
40
+* Importing videos from your desktop
41
+The most convenient way to add new videos to PeerTube is if you have the *syncthing* app installed. Set up [[./app_syncthing.html][syncthing]] with a folder called ~/Sync in your home directory. Create a subdirectory called *~/Sync/peertube_upload*. Within that directory make a text file called *login.txt*. This will contain your PeerTube login details.
42
+
43
+The first line of login.txt should be your username, the second line should be the password and optionally the third line can contain the words *public* and/or *nsfw*, if you want to make imported videos immediately public or mark them as not suitable for work.
44
+
45
+Prepare your videos in *ogv*, *mp4* or *webm* format. To minimize bandwidth usage try to keep your videos as small as possible. Giant videos with incredibly high resolution tend to result in a bad user experience. Often just converting your videos to *webm* using *ffmpeg* will keep the size down.
46
+
47
+Now copy or drag and drop your videos into the *~/Sync/peertube_upload* directory. Syncthing will sync to the server and automatically add the videos to PeerTube. Depending on how large the videos are this may take some time.
48
+
49
+Imported videos can be seen by logging into PeerTube, selecting *My account* then the *My videos* tab. You can then view them, add a description and select to make them public if you wish.

+ 4
- 4
doc/EN/apps.org View File

29
 It's like ordinary email, but with [[https://en.wikipedia.org/wiki/I2P][i2p]] as the transport mechanism.
29
 It's like ordinary email, but with [[https://en.wikipedia.org/wiki/I2P][i2p]] as the transport mechanism.
30
 
30
 
31
 [[./app_bdsmail.html][How to use it]]
31
 [[./app_bdsmail.html][How to use it]]
32
+* Bludit
33
+This is a simple databaseless blogging system which uses markdown files. It should run well on any hardware.
34
+
35
+[[./app_bludit.html][How to use it]]
32
 * CryptPad
36
 * CryptPad
33
 Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
37
 Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
34
 
38
 
63
 Federated social network system.
67
 Federated social network system.
64
 
68
 
65
 [[./app_friendica.html][How to use it]]
69
 [[./app_friendica.html][How to use it]]
66
-* Ghost
67
-Modern looking blogging system.
68
-
69
-[[./app_ghost.html][How to use it]]
70
 * GNU Social
70
 * GNU Social
71
 Federated social network based on the OStatus protocol. You can "/remote follow/" other users within the GNU Social federation.
71
 Federated social network based on the OStatus protocol. You can "/remote follow/" other users within the GNU Social federation.
72
 
72
 

BIN
img/peertube.jpg View File


+ 1
- 1
src/freedombone-app-akaunting View File

54
     # copy jquery locally
54
     # copy jquery locally
55
     jquery_version='1.12.4'
55
     jquery_version='1.12.4'
56
     if [ ! -f jquery-${jquery_version}.js ]; then
56
     if [ ! -f jquery-${jquery_version}.js ]; then
57
-        cd "/var/www/$GHOST_DOMAIN_NAME/htdocs" || exit 3276324
57
+        cd "/var/www/$AKAUNTING_DOMAIN_NAME/htdocs" || exit 3276324
58
         wget https://code.jquery.com/jquery-${jquery_version}.js
58
         wget https://code.jquery.com/jquery-${jquery_version}.js
59
         jquery_hash=$(sha256sum jquery-${jquery_version}.js | awk -F ' ' '{print $1}')
59
         jquery_hash=$(sha256sum jquery-${jquery_version}.js | awk -F ' ' '{print $1}')
60
         if [[ "$jquery_hash" != '430f36f9b5f21aae8cc9dca6a81c4d3d84da5175eaedcf2fdc2c226302cb3575' ]]; then
60
         if [[ "$jquery_hash" != '430f36f9b5f21aae8cc9dca6a81c4d3d84da5175eaedcf2fdc2c226302cb3575' ]]; then

+ 338
- 0
src/freedombone-app-bludit View File

1
+#!/bin/bash
2
+#
3
+# .---.                  .              .
4
+# |                      |              |
5
+# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
6
+# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
7
+# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
8
+#
9
+#                    Freedom in the Cloud
10
+#
11
+# License
12
+# =======
13
+#
14
+# Copyright (C) 2018 Bob Mottram <bob@freedombone.net>
15
+#
16
+# This program is free software: you can redistribute it and/or modify
17
+# it under the terms of the GNU Affero General Public License as published by
18
+# the Free Software Foundation, either version 3 of the License, or
19
+# (at your option) any later version.
20
+#
21
+# This program is distributed in the hope that it will be useful,
22
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
23
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
+# GNU Affero General Public License for more details.
25
+#
26
+# You should have received a copy of the GNU Affero General Public License
27
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
+
29
+VARIANTS='full full-vim'
30
+
31
+IN_DEFAULT_INSTALL=0
32
+SHOW_ON_ABOUT=1
33
+
34
+BLUDIT_DOMAIN_NAME=
35
+BLUDIT_CODE=
36
+BLUDIT_ONION_PORT=9844
37
+BLUDIT_REPO="https://github.com/bludit/bludit"
38
+BLUDIT_COMMIT='0e27e31a84421b3e6bd000a77bc89c2dff3c446a'
39
+
40
+bludit_variables=(ONION_ONLY
41
+                  BLUDIT_DOMAIN_NAME
42
+                  BLUDIT_CODE
43
+                  DDNS_PROVIDER
44
+                  MY_USERNAME)
45
+
46
+function logging_on_bludit {
47
+    echo -n ''
48
+}
49
+
50
+function logging_off_bludit {
51
+    echo -n ''
52
+}
53
+
54
+function remove_user_bludit {
55
+    remove_username="$1"
56
+
57
+    "${PROJECT_NAME}-pass" -u "$remove_username" --rmapp bludit
58
+}
59
+
60
+function add_user_bludit {
61
+    new_username="$1"
62
+    new_user_password="$2"
63
+
64
+    "${PROJECT_NAME}-pass" -u "$new_username" -a bludit -p "$new_user_password"
65
+    echo '0'
66
+}
67
+
68
+function install_interactive_bludit {
69
+    if [ ! "$ONION_ONLY" ]; then
70
+        ONION_ONLY='no'
71
+    fi
72
+
73
+    if [[ "$ONION_ONLY" != "no" ]]; then
74
+        BLUDIT_DOMAIN_NAME='bludit.local'
75
+        write_config_param "BLUDIT_DOMAIN_NAME" "$BLUDIT_DOMAIN_NAME"
76
+    else
77
+        interactive_site_details "bludit" "BLUDIT_DOMAIN_NAME" "BLUDIT_CODE"
78
+    fi
79
+    APP_INSTALLED=1
80
+}
81
+
82
+function change_password_bludit {
83
+    curr_username="$1"
84
+    new_user_password="$2"
85
+
86
+    read_config_param 'BLUDIT_DOMAIN_NAME'
87
+
88
+    "${PROJECT_NAME}-pass" -u "$curr_username" -a bludit -p "$new_user_password"
89
+}
90
+
91
+function reconfigure_bludit {
92
+    # This is used if you need to switch identity. Dump old keys and generate new ones
93
+    echo -n ''
94
+}
95
+
96
+function upgrade_bludit {
97
+    CURR_BLUDIT_COMMIT=$(get_completion_param "bludit commit")
98
+    if [[ "$CURR_BLUDIT_COMMIT" == "$BLUDIT_COMMIT" ]]; then
99
+        return
100
+    fi
101
+
102
+    if grep -q "bludit domain" "$COMPLETION_FILE"; then
103
+        BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
104
+    fi
105
+
106
+    # update to the next commit
107
+    set_repo_commit "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" "bludit commit" "$BLUDIT_COMMIT" $BLUDIT_REPO
108
+    chown -R www-data:www-data "/var/www/${BLUDIT_DOMAIN_NAME}/htdocs"
109
+}
110
+
111
+function backup_local_bludit {
112
+    BLUDIT_DOMAIN_NAME='bludit'
113
+    if grep -q "bludit domain" "$COMPLETION_FILE"; then
114
+        BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
115
+    fi
116
+
117
+    source_directory=/var/www/${BLUDIT_DOMAIN_NAME}/htdocs
118
+
119
+    suspend_site "${BLUDIT_DOMAIN_NAME}"
120
+
121
+    dest_directory=bludit
122
+    backup_directory_to_usb "$source_directory" $dest_directory
123
+
124
+    restart_site
125
+}
126
+
127
+function restore_local_bludit {
128
+    if ! grep -q "bludit domain" "$COMPLETION_FILE"; then
129
+        return
130
+    fi
131
+    BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
132
+    if [ "$BLUDIT_DOMAIN_NAME" ]; then
133
+        temp_restore_dir=/root/tempbludit
134
+        bludit_dir=/var/www/${BLUDIT_DOMAIN_NAME}/htdocs
135
+
136
+        restore_directory_from_usb $temp_restore_dir bludit
137
+        if [ -d $temp_restore_dir ]; then
138
+            if [ -d "$temp_restore_dir$bludit_dir" ]; then
139
+                cp -rp "$temp_restore_dir$bludit_dir"/* "$bludit_dir"/
140
+            else
141
+                if [ ! -d "$bludit_dir" ]; then
142
+                    mkdir "$bludit_dir"
143
+                fi
144
+                cp -rp "$temp_restore_dir"/* "$bludit_dir"/
145
+            fi
146
+            chown -R www-data:www-data "$bludit_dir"
147
+            rm -rf $temp_restore_dir
148
+        fi
149
+
150
+    fi
151
+}
152
+
153
+function backup_remote_bludit {
154
+    BLUDIT_DOMAIN_NAME='bludit'
155
+    if grep -q "bludit domain" "$COMPLETION_FILE"; then
156
+        BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
157
+    fi
158
+
159
+    source_directory=/var/www/${BLUDIT_DOMAIN_NAME}/htdocs
160
+
161
+    suspend_site "${BLUDIT_DOMAIN_NAME}"
162
+
163
+    dest_directory=bludit
164
+    backup_directory_to_friend "$source_directory" $dest_directory
165
+
166
+    restart_site
167
+}
168
+
169
+function restore_remote_bludit {
170
+    if ! grep -q "bludit domain" "$COMPLETION_FILE"; then
171
+        return
172
+    fi
173
+    BLUDIT_DOMAIN_NAME=$(get_completion_param "bludit domain")
174
+    if [ "$BLUDIT_DOMAIN_NAME" ]; then
175
+        temp_restore_dir=/root/tempbludit
176
+        bludit_dir=/var/www/${BLUDIT_DOMAIN_NAME}/htdocs
177
+
178
+        restore_directory_from_friend $temp_restore_dir bludit
179
+        if [ -d $temp_restore_dir ]; then
180
+            if [ -d "$temp_restore_dir$bludit_dir" ]; then
181
+                cp -rp "$temp_restore_dir$bludit_dir"/* "$bludit_dir"/
182
+            else
183
+                if [ ! -d "$bludit_dir" ]; then
184
+                    mkdir "$bludit_dir"
185
+                fi
186
+                cp -rp $temp_restore_dir/* "$bludit_dir"/
187
+            fi
188
+            chown -R www-data:www-data "$bludit_dir"
189
+            rm -rf $temp_restore_dir
190
+        fi
191
+
192
+    fi
193
+}
194
+
195
+function remove_bludit {
196
+    nginx_dissite "$BLUDIT_DOMAIN_NAME"
197
+    remove_certs "$BLUDIT_DOMAIN_NAME"
198
+
199
+
200
+    if [ -d "/var/www/$BLUDIT_DOMAIN_NAME" ]; then
201
+        rm -rf "/var/www/$BLUDIT_DOMAIN_NAME"
202
+    fi
203
+    if [ -f "/etc/nginx/sites-available/$BLUDIT_DOMAIN_NAME" ]; then
204
+        rm "/etc/nginx/sites-available/$BLUDIT_DOMAIN_NAME"
205
+    fi
206
+    remove_onion_service bludit ${BLUDIT_ONION_PORT}
207
+    if grep -q "bludit" /etc/crontab; then
208
+        sed -i "/bludit/d" /etc/crontab
209
+    fi
210
+    remove_app bludit
211
+    remove_completion_param install_bludit
212
+    sed -i '/bludit/d' "$COMPLETION_FILE"
213
+
214
+    remove_ddns_domain "$BLUDIT_DOMAIN_NAME"
215
+}
216
+
217
+function install_bludit {
218
+    apt-get -yq install php-gettext php-curl php-gd php-mysql git curl
219
+    apt-get -yq install memcached php-memcached php-intl exiftool libfcgi0ldbl
220
+
221
+    if [ ! "$BLUDIT_DOMAIN_NAME" ]; then
222
+        echo $'No domain name was given'
223
+        exit 3568356
224
+    fi
225
+
226
+    if [ -d "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" ]; then
227
+        rm -rf "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
228
+    fi
229
+    if [ -d /repos/bludit ]; then
230
+        mkdir "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
231
+        cp -r -p /repos/bludit/. "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
232
+        cd "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" || exit 324687356
233
+        git pull
234
+    else
235
+        git_clone $BLUDIT_REPO "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
236
+    fi
237
+
238
+    if [ ! -d "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" ]; then
239
+        echo $'Unable to clone bludit repo'
240
+        exit 87525
241
+    fi
242
+
243
+    cd "/var/www/$BLUDIT_DOMAIN_NAME/htdocs" || exit 36587356
244
+    git checkout $BLUDIT_COMMIT -b $BLUDIT_COMMIT
245
+    set_completion_param "bludit commit" "$BLUDIT_COMMIT"
246
+
247
+    chmod g+w "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
248
+    chown -R www-data:www-data "/var/www/$BLUDIT_DOMAIN_NAME/htdocs"
249
+
250
+    add_ddns_domain "$BLUDIT_DOMAIN_NAME"
251
+
252
+    BLUDIT_ONION_HOSTNAME=$(add_onion_service bludit 80 ${BLUDIT_ONION_PORT})
253
+
254
+    bludit_nginx_site=/etc/nginx/sites-available/$BLUDIT_DOMAIN_NAME
255
+    if [[ "$ONION_ONLY" == "no" ]]; then
256
+        nginx_http_redirect "$BLUDIT_DOMAIN_NAME" "index index.php"
257
+        { echo 'server {';
258
+          echo '  listen 443 ssl;';
259
+          echo '  #listen [::]:443 ssl;';
260
+          echo "  server_name $BLUDIT_DOMAIN_NAME;";
261
+          echo ''; } >> "$bludit_nginx_site"
262
+        nginx_compress "$BLUDIT_DOMAIN_NAME"
263
+        echo '' >> "$bludit_nginx_site"
264
+        echo '  # Security' >> "$bludit_nginx_site"
265
+        nginx_ssl "$BLUDIT_DOMAIN_NAME"
266
+
267
+        nginx_security_options "$BLUDIT_DOMAIN_NAME"
268
+
269
+        { echo '  add_header Strict-Transport-Security max-age=15768000;';
270
+          echo '';
271
+          echo '  # Logs';
272
+          echo '  access_log /dev/null;';
273
+          echo '  error_log /dev/null;';
274
+          echo '';
275
+          echo '  # Root';
276
+          echo "  root /var/www/$BLUDIT_DOMAIN_NAME/htdocs;";
277
+          echo '';
278
+          echo '  index index.php;';
279
+          echo '  location ~ \.php {';
280
+          echo '    include snippets/fastcgi-php.conf;';
281
+          echo '    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;';
282
+          echo '    fastcgi_read_timeout 30;';
283
+          echo '  }';
284
+          echo '';
285
+          echo '  # Location';
286
+          echo '  location / {'; } >> "$bludit_nginx_site"
287
+        nginx_limits "$BLUDIT_DOMAIN_NAME" '15m'
288
+        { echo "    try_files \$uri \$uri/ /index.php?\$args;";
289
+          echo '  }';
290
+          echo '}'; } >> "$bludit_nginx_site"
291
+    else
292
+        echo -n '' > "$bludit_nginx_site"
293
+    fi
294
+    { echo 'server {';
295
+      echo "    listen 127.0.0.1:$BLUDIT_ONION_PORT default_server;";
296
+      echo "    server_name $BLUDIT_ONION_HOSTNAME;";
297
+      echo ''; } >> "$bludit_nginx_site"
298
+    nginx_compress "$BLUDIT_DOMAIN_NAME"
299
+    echo '' >> "$bludit_nginx_site"
300
+    nginx_security_options "$BLUDIT_DOMAIN_NAME"
301
+    { echo '';
302
+      echo '  # Logs';
303
+      echo '  access_log /dev/null;';
304
+      echo '  error_log /dev/null;';
305
+      echo '';
306
+      echo '  # Root';
307
+      echo "  root /var/www/$BLUDIT_DOMAIN_NAME/htdocs;";
308
+      echo '';
309
+      echo '  index index.php;';
310
+      echo '  location ~ \.php {';
311
+      echo '    include snippets/fastcgi-php.conf;';
312
+      echo '    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;';
313
+      echo '    fastcgi_read_timeout 30;';
314
+      echo '  }';
315
+      echo '';
316
+      echo '  # Location';
317
+      echo '  location / {'; } >> "$bludit_nginx_site"
318
+    nginx_limits "$BLUDIT_DOMAIN_NAME" '15m'
319
+    { echo "    try_files \$uri \$uri/ index.php?\$args;";
320
+      echo '  }';
321
+      echo '}'; } >> "$bludit_nginx_site"
322
+
323
+    configure_php
324
+
325
+    create_site_certificate "$BLUDIT_DOMAIN_NAME" 'yes'
326
+
327
+    nginx_ensite "$BLUDIT_DOMAIN_NAME"
328
+
329
+    systemctl restart php7.0-fpm
330
+    systemctl restart nginx
331
+
332
+    "${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a bludit -p "$BLUDIT_ADMIN_PASSWORD"
333
+    set_completion_param "bludit domain" "$BLUDIT_DOMAIN_NAME"
334
+
335
+    APP_INSTALLED=1
336
+}
337
+
338
+# NOTE: deliberately there is no "exit 0"

+ 2
- 2
src/freedombone-app-cryptpad View File

368
 
368
 
369
     cryptpad_nginx_site=$rootdir/etc/nginx/sites-available/cryptpad
369
     cryptpad_nginx_site=$rootdir/etc/nginx/sites-available/cryptpad
370
     { echo 'server {';
370
     { echo 'server {';
371
-      echo "  listen 80 default_server;";
371
+      echo '  listen [::]:80 default_server;';
372
       echo "  server_name P${PEER_ID}.local;";
372
       echo "  server_name P${PEER_ID}.local;";
373
       echo '';
373
       echo '';
374
       echo '  # Logs';
374
       echo '  # Logs';
389
       echo '  }';
389
       echo '  }';
390
       echo '';
390
       echo '';
391
       echo '  location = /cryptpad_websocket {';
391
       echo '  location = /cryptpad_websocket {';
392
-      echo "    proxy_pass http://localhost:$CRYPTPAD_PORT;";
392
+      echo "    proxy_pass http://[::]:$CRYPTPAD_PORT;";
393
       echo "    proxy_set_header X-Real-IP \$remote_addr;";
393
       echo "    proxy_set_header X-Real-IP \$remote_addr;";
394
       echo "    proxy_set_header Host \$host;";
394
       echo "    proxy_set_header Host \$host;";
395
       echo "    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;";
395
       echo "    proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;";

+ 11
- 18
src/freedombone-app-dlna View File

47
 }
47
 }
48
 
48
 
49
 function configure_interactive_dlna {
49
 function configure_interactive_dlna {
50
+    W=(1 $"Attach a drive containing playable media"
51
+       2 $"Remove a drive containing playable media")
52
+
50
     while true
53
     while true
51
     do
54
     do
52
-        data=$(mktemp 2>/dev/null)
53
-        dialog --backtitle $"Freedombone Control Panel" \
54
-               --title $"Media Menu" \
55
-               --radiolist $"Choose an operation:" 13 70 3 \
56
-               1 $"Attach a drive containing playable media" off \
57
-               2 $"Remove a drive containing playable media" off \
58
-               3 $"Exit" on 2> "$data"
59
-        sel=$?
60
-        case $sel in
61
-            1) rm -f "$data"
62
-               break;;
63
-            255) rm -f "$data"
64
-                 break;;
65
-        esac
66
-        case $(cat "$data") in
55
+        # shellcheck disable=SC2068
56
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Media Menu" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
57
+
58
+        if [ ! "$selection" ]; then
59
+            break
60
+        fi
61
+
62
+        case $selection in
67
             1) attach-music;;
63
             1) attach-music;;
68
             2) remove-music;;
64
             2) remove-music;;
69
-            3) rm -f "$data"
70
-               break;;
71
         esac
65
         esac
72
-        rm -f "$data"
73
     done
66
     done
74
 }
67
 }
75
 
68
 

+ 12
- 19
src/freedombone-app-edith View File

131
 }
131
 }
132
 
132
 
133
 function configure_interactive_edith {
133
 function configure_interactive_edith {
134
+    W=(1 $"Enable login"
135
+       2 $"Browse notes")
136
+
134
     while true
137
     while true
135
     do
138
     do
136
-        data=$(mktemp 2>/dev/null)
137
-        dialog --backtitle $"Freedombone Control Panel" \
138
-               --title $"Edith" \
139
-               --radiolist $"Choose an operation:" 10 50 3 \
140
-               1 $"Enable login" off \
141
-               2 $"Browse notes" off \
142
-               3 $"Exit" on 2> "$data"
143
-        sel=$?
144
-        case $sel in
145
-            1) rm -f "$data"
146
-               break;;
147
-            255) rm -f "$data"
148
-                 break;;
149
-        esac
150
-        case $(cat "$data") in
139
+        # shellcheck disable=SC2068
140
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Edith" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
141
+
142
+        if [ ! "$selection" ]; then
143
+            break
144
+        fi
145
+
146
+        case $selection in
151
             1) edith_enable_login;;
147
             1) edith_enable_login;;
152
             2) edith_browse;;
148
             2) edith_browse;;
153
-            3) rm -f "$data"
154
-               break;;
155
         esac
149
         esac
156
-        rm -f "$data"
157
     done
150
     done
158
 }
151
 }
159
 
152
 
460
     fi
453
     fi
461
 
454
 
462
     if [[ "$ONION_ONLY" != "no" ]]; then
455
     if [[ "$ONION_ONLY" != "no" ]]; then
463
-        GHOST_DOMAIN_NAME='edith.local'
456
+        EDITH_DOMAIN_NAME='edith.local'
464
         write_config_param "EDITH_DOMAIN_NAME" "$EDITH_DOMAIN_NAME"
457
         write_config_param "EDITH_DOMAIN_NAME" "$EDITH_DOMAIN_NAME"
465
     else
458
     else
466
         function_check interactive_site_details
459
         function_check interactive_site_details

+ 11
- 18
src/freedombone-app-etherpad View File

269
 }
269
 }
270
 
270
 
271
 function configure_interactive_etherpad {
271
 function configure_interactive_etherpad {
272
+    W=(1 $"Set Title"
273
+       2 $"Set a welcome message")
274
+
272
     while true
275
     while true
273
     do
276
     do
274
-        data=$(mktemp 2>/dev/null)
275
-        dialog --backtitle $"Freedombone Control Panel" \
276
-               --title $"Etherpad Settings" \
277
-               --radiolist $"Choose an operation:" 12 70 3 \
278
-               1 $"Set Title" off \
279
-               2 $"Set a welcome message" off \
280
-               3 $"Exit" on 2> "$data"
281
-        sel=$?
282
-        case $sel in
283
-            1) rm -f "$data"
284
-               return;;
285
-            255) rm -f "$data"
286
-                 return;;
287
-        esac
288
-        case $(cat "$data") in
277
+        # shellcheck disable=SC2068
278
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Etherpad" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
279
+
280
+        if [ ! "$selection" ]; then
281
+            break
282
+        fi
283
+
284
+        case $selection in
289
             1) etherpad_set_title;;
285
             1) etherpad_set_title;;
290
             2) etherpad_set_welcome_message;;
286
             2) etherpad_set_welcome_message;;
291
-            3) rm -f "$data"
292
-               break;;
293
         esac
287
         esac
294
-        rm -f "$data"
295
     done
288
     done
296
 }
289
 }
297
 
290
 

+ 40
- 27
src/freedombone-app-fedwiki View File

55
 
55
 
56
 function fedwiki_remove_bad_links {
56
 function fedwiki_remove_bad_links {
57
     if [[ $ONION_ONLY == 'no' ]]; then
57
     if [[ $ONION_ONLY == 'no' ]]; then
58
-        sed -i "s|link[href='https://maxcdn.bootstrapcdn.com.*|link[href='https://${FEDWIKI_DOMAIN_NAME}/fonts-font-awesome/css/font-awesome.min.css']\").length) {|g" /usr/local/lib/node_modules/wiki/node_modules/wiki-security-friends/client/security.js
58
+        sed -i "s|link\\[href='https://maxcdn.bootstrapcdn.com.*|link\\[href='https://${FEDWIKI_DOMAIN_NAME}/fonts-font-awesome/css/font-awesome.min.css']\").length) {|g" /var/lib/wiki/node_modules/wiki-security-friends/client/security.js
59
 
59
 
60
-        sed -i "s|\$('<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com.*|\$('<link rel=\"stylesheet\" href=\"https://${FEDWIKI_DOMAIN_NAME}/fonts-font-awesome/css/font-awesome.min.css\">').appendTo(\"head\");|g" /usr/local/lib/node_modules/wiki/node_modules/wiki-security-friends/client/security.js
60
+        sed -i "s|\$('<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com.*|\$('<link rel=\"stylesheet\" href=\"https://${FEDWIKI_DOMAIN_NAME}/fonts-font-awesome/css/font-awesome.min.css\">').appendTo(\"head\");|g" /var/lib/wiki/node_modules/wiki-security-friends/client/security.js
61
     else
61
     else
62
         FEDWIKI_ONION_HOSTNAME=$(cat /var/lib/tor/hidden_service_fedwiki/hostname)
62
         FEDWIKI_ONION_HOSTNAME=$(cat /var/lib/tor/hidden_service_fedwiki/hostname)
63
-        sed -i "s|link[href='https://maxcdn.bootstrapcdn.com.*|link[href='http://${FEDWIKI_ONION_HOSTNAME}/fonts-font-awesome/css/font-awesome.min.css']\").length) {|g" /usr/local/lib/node_modules/wiki/node_modules/wiki-security-friends/client/security.js
63
+        sed -i "s|link\\[href='https://maxcdn.bootstrapcdn.com.*|link\\[href='http://${FEDWIKI_ONION_HOSTNAME}/fonts-font-awesome/css/font-awesome.min.css']\").length) {|g" /var/lib/wiki/node_modules/wiki-security-friends/client/security.js
64
 
64
 
65
-        sed -i "s|\$('<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com.*|\$('<link rel=\"stylesheet\" href=\"http://${FEDWIKI_ONION_HOSTNAME}/fonts-font-awesome/css/font-awesome.min.css\">').appendTo(\"head\");|g" /usr/local/lib/node_modules/wiki/node_modules/wiki-security-friends/client/security.js
65
+        sed -i "s|\$('<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com.*|\$('<link rel=\"stylesheet\" href=\"http://${FEDWIKI_ONION_HOSTNAME}/fonts-font-awesome/css/font-awesome.min.css\">').appendTo(\"head\");|g" /var/lib/wiki/node_modules/wiki-security-friends/client/security.js
66
     fi
66
     fi
67
 
67
 
68
-    if [ -f /usr/local/lib/node_modules/wiki/node_modules/localforage/docs/theme/style.css ]; then
69
-        sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/localforage/docs/theme/style.css
68
+    if [ -f /var/lib/wiki/node_modules/localforage/docs/theme/style.css ]; then
69
+        sed -i '/googleapi/d' /var/lib/wiki/node_modules/localforage/docs/theme/style.css
70
     fi
70
     fi
71
 
71
 
72
-    if [ -f /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/addAlternativeDialog.html ]; then
73
-        sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/addAlternativeDialog.html
72
+    if [ -f /var/lib/wiki/node_modules/wiki-security-passportjs/views/addAlternativeDialog.html ]; then
73
+        sed -i '/googleapi/d' /var/lib/wiki/node_modules/wiki-security-passportjs/views/addAlternativeDialog.html
74
     fi
74
     fi
75
 
75
 
76
-    if [ -f /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/done.html ]; then
77
-        sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/done.html
76
+    if [ -f /var/lib/wiki/node_modules/wiki-security-passportjs/views/done.html ]; then
77
+        sed -i '/googleapi/d' /var/lib/wiki/node_modules/wiki-security-passportjs/views/done.html
78
     fi
78
     fi
79
 
79
 
80
-    if [ -f /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/personaDialog.html ]; then
81
-        sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/personaDialog.html
80
+    if [ -f /var/lib/wiki/node_modules/wiki-security-passportjs/views/personaDialog.html ]; then
81
+        sed -i '/googleapi/d' /var/lib/wiki/node_modules/wiki-security-passportjs/views/personaDialog.html
82
     fi
82
     fi
83
 
83
 
84
-    if [ -f /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/securityDialog.html ]; then
85
-        sed -i '/googleapi/d' /usr/local/lib/node_modules/wiki/node_modules/wiki-security-passportjs/views/securityDialog.html
84
+    if [ -f /var/lib/wiki/node_modules/wiki-security-passportjs/views/securityDialog.html ]; then
85
+        sed -i '/googleapi/d' /var/lib/wiki/node_modules/wiki-security-passportjs/views/securityDialog.html
86
     fi
86
     fi
87
 
87
 
88
-    if [ -d /usr/local/lib/node_modules/wiki/node_modules/passport-google-oauth20 ]; then
89
-        rm -rf /usr/local/lib/node_modules/wiki/node_modules/passport-google-oauth20
88
+    if [ -d /var/lib/wiki/node_modules/passport-google-oauth20 ]; then
89
+        rm -rf /var/lib/wiki/node_modules/passport-google-oauth20
90
     fi
90
     fi
91
 
91
 
92
-    if [ -d /usr/local/lib/node_modules/wiki/node_modules/passport-oauth2 ]; then
93
-        rm -rf /usr/local/lib/node_modules/wiki/node_modules/passport-oauth2
92
+    if [ -d /var/lib/wiki/node_modules/passport-oauth2 ]; then
93
+        rm -rf /var/lib/wiki/node_modules/passport-oauth2
94
     fi
94
     fi
95
 
95
 
96
-    if [ -d /usr/local/lib/node_modules/wiki/node_modules/passport-twitter ]; then
97
-        rm -rf /usr/local/lib/node_modules/wiki/node_modules/passport-twitter
96
+    if [ -d /var/lib/wiki/node_modules/passport-twitter ]; then
97
+        rm -rf /var/lib/wiki/node_modules/passport-twitter
98
     fi
98
     fi
99
 
99
 
100
-    if [ -d /usr/local/lib/node_modules/wiki/node_modules/passport-github ]; then
101
-        rm -rf /usr/local/lib/node_modules/wiki/node_modules/passport-github
100
+    if [ -d /var/lib/wiki/node_modules/passport-github ]; then
101
+        rm -rf /var/lib/wiki/node_modules/passport-github
102
     fi
102
     fi
103
 }
103
 }
104
 
104
 
168
 
168
 
169
     systemctl stop fedwiki
169
     systemctl stop fedwiki
170
     npm upgrade -g wiki@$FEDWIKI_VERSION
170
     npm upgrade -g wiki@$FEDWIKI_VERSION
171
+
172
+    cp -r /root/.npm-global/lib/node_modules/wiki/* /var/lib/wiki/
173
+    cp /root/.npm-global/bin/wiki /var/lib/wiki/wiki
174
+    chown -R fedwiki:fedwiki /var/lib/wiki
175
+
171
     fedwiki_remove_bad_links
176
     fedwiki_remove_bad_links
177
+
172
     chown -R fedwiki:fedwiki $FEDWIKI_DATA
178
     chown -R fedwiki:fedwiki $FEDWIKI_DATA
173
     systemctl start fedwiki
179
     systemctl start fedwiki
174
 
180
 
302
     if [ -d "/var/www/$FEDWIKI_DOMAIN_NAME" ]; then
308
     if [ -d "/var/www/$FEDWIKI_DOMAIN_NAME" ]; then
303
         rm -rf "/var/www/$FEDWIKI_DOMAIN_NAME"
309
         rm -rf "/var/www/$FEDWIKI_DOMAIN_NAME"
304
     fi
310
     fi
311
+    if [ -d /var/lib/wiki ]; then
312
+        rm -rf /var/lib/wiki
313
+    fi
305
     remove_config_param FEDWIKI_DOMAIN_NAME
314
     remove_config_param FEDWIKI_DOMAIN_NAME
306
     remove_config_param FEDWIKI_CODE
315
     remove_config_param FEDWIKI_CODE
307
     function_check remove_onion_service
316
     function_check remove_onion_service
437
         exit 783533
446
         exit 783533
438
     fi
447
     fi
439
 
448
 
440
-    if [ ! -f /usr/local/bin/wiki ]; then
449
+    if [ ! -f /root/.npm-global/bin/wiki ]; then
441
         echo $'wiki was not installed'
450
         echo $'wiki was not installed'
442
         exit 5293524
451
         exit 5293524
443
     fi
452
     fi
444
 
453
 
445
-    if [ ! -d /usr/local/lib/node_modules/wiki ]; then
446
-        echo $'wiki directory not found /usr/local/lib/node_modules/wiki'
454
+    if [ ! -d /root/.npm-global/lib/node_modules/wiki ]; then
455
+        echo $'wiki directory not found /root/.npm-global/lib/node_modules/wiki'
447
         exit 6285324
456
         exit 6285324
448
     fi
457
     fi
449
 
458
 
453
         FEDWIKI_COOKIE="$(create_password 20)"
462
         FEDWIKI_COOKIE="$(create_password 20)"
454
     fi
463
     fi
455
 
464
 
465
+    cp -r /root/.npm-global/lib/node_modules/wiki /var/lib
466
+    cp /root/.npm-global/bin/wiki /var/lib/wiki
467
+    chown -R fedwiki:fedwiki /var/lib/wiki
468
+
456
     { echo '[Unit]';
469
     { echo '[Unit]';
457
       echo 'Description=Fedwiki federated wiki';
470
       echo 'Description=Fedwiki federated wiki';
458
       echo 'After=syslog.target';
471
       echo 'After=syslog.target';
461
       echo '[Service]';
474
       echo '[Service]';
462
       echo 'User=fedwiki';
475
       echo 'User=fedwiki';
463
       echo 'Group=fedwiki';
476
       echo 'Group=fedwiki';
464
-      echo "WorkingDirectory=/usr/local/lib/node_modules/wiki";
465
-      echo "ExecStart=/usr/local/bin/wiki --security_type friends --session_duration 7 --data $FEDWIKI_DATA -p $FEDWIKI_PORT --cookieSecret '${FEDWIKI_COOKIE}'";
477
+      echo "WorkingDirectory=/var/lib/wiki";
478
+      echo "ExecStart=/var/lib/wiki/wiki --security_type friends --session_duration 7 --data $FEDWIKI_DATA -p $FEDWIKI_PORT --cookieSecret '${FEDWIKI_COOKIE}'";
466
       echo 'StandardOutput=syslog';
479
       echo 'StandardOutput=syslog';
467
       echo 'StandardError=syslog';
480
       echo 'StandardError=syslog';
468
       echo 'SyslogIdentifier=fedwiki';
481
       echo 'SyslogIdentifier=fedwiki';

+ 13
- 18
src/freedombone-app-friendica View File

152
 }
152
 }
153
 
153
 
154
 function configure_interactive_friendica {
154
 function configure_interactive_friendica {
155
+    W=(1 $"Set channel directory server"
156
+       2 $"Renew SSL certificate"
157
+       3 $"Close new account registrations"
158
+       4 $"Allow new account registrations")
159
+
155
     while true
160
     while true
156
     do
161
     do
157
-        data=$(mktemp 2>/dev/null)
158
-        dialog --backtitle $"Freedombone Control Panel" \
159
-               --title $"Friendica" \
160
-               --radiolist $"Choose an operation:" 15 70 6 \
161
-               1 $"Set channel directory server" off \
162
-               2 $"Renew SSL certificate" off \
163
-               3 $"Close new account registrations" off \
164
-               4 $"Allow new account registrations" off \
165
-               5 $"Back to main menu" on 2> "$data"
166
-        sel=$?
167
-        case $sel in
168
-            1) break;;
169
-            255) break;;
170
-        esac
171
-        case $(cat "$data") in
162
+        # shellcheck disable=SC2068
163
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Friendica" --menu $"Choose an operation, or ESC to exit:" 14 60 4 "${W[@]}" 3>&2 2>&1 1>&3)
164
+
165
+        if [ ! "$selection" ]; then
166
+            break
167
+        fi
168
+
169
+        case $selection in
172
             1) friendica_channel_directory_server;;
170
             1) friendica_channel_directory_server;;
173
             2) friendica_renew_cert;;
171
             2) friendica_renew_cert;;
174
             3) friendica_close_registrations;;
172
             3) friendica_close_registrations;;
175
             4) friendica_allow_registrations;;
173
             4) friendica_allow_registrations;;
176
-            5) rm -f "$data"
177
-               break;;
178
         esac
174
         esac
179
-        rm -f "$data"
180
     done
175
     done
181
 }
176
 }
182
 
177
 

+ 0
- 603
src/freedombone-app-ghost View File

1
-#!/bin/bash
2
-#
3
-# .---.                  .              .
4
-# |                      |              |
5
-# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
6
-# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
7
-# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
8
-#
9
-#                    Freedom in the Cloud
10
-#
11
-# Ghost blog
12
-#
13
-# License
14
-# =======
15
-#
16
-# Copyright (C) 2016-2018 Bob Mottram <bob@freedombone.net>
17
-#
18
-# This program is free software: you can redistribute it and/or modify
19
-# it under the terms of the GNU Affero General Public License as published by
20
-# the Free Software Foundation, either version 3 of the License, or
21
-# (at your option) any later version.
22
-#
23
-# This program is distributed in the hope that it will be useful,
24
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
25
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
-# GNU Affero General Public License for more details.
27
-#
28
-# You should have received a copy of the GNU Affero General Public License
29
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
30
-
31
-VARIANTS="full full-vim writer"
32
-
33
-IN_DEFAULT_INSTALL=0
34
-SHOW_ON_ABOUT=1
35
-
36
-GHOST_VERSION=1.19.0
37
-GHOST_DOMAIN_NAME=
38
-GHOST_CODE=
39
-GHOST_ONION_PORT=8104
40
-GHOST_PORT=2368
41
-
42
-ghost_variables=(GHOST_DOMAIN_NAME
43
-                 GHOST_CODE
44
-                 GHOST_ADMIN_PASSWORD
45
-                 ONION_ONLY
46
-                 DDNS_PROVIDER
47
-                 MY_USERNAME)
48
-
49
-function ghost_bust {
50
-    # kill the started ghost process
51
-    kill_pid=$(pgrep "ghost run" | head -n 1)
52
-    kill -9 "$kill_pid"
53
-
54
-    kill_pid=$(pgrep "ghost" | head -n 1)
55
-    kill -9 "$kill_pid"
56
-
57
-    kill_pid=$(pgrep "ghost" | head -n 1)
58
-    kill -9 "$kill_pid"
59
-}
60
-
61
-function logging_on_ghost {
62
-    echo -n ''
63
-}
64
-
65
-function logging_off_ghost {
66
-    echo -n ''
67
-}
68
-
69
-function ghost_replace_jquery {
70
-    curr_domain="https://$GHOST_DOMAIN_NAME"
71
-    if [[ "$ONION_ONLY" != 'no' ]]; then
72
-        curr_domain="http://$GHOST_ONION_HOSTNAME"
73
-    fi
74
-
75
-    sed -i "s|src=\"https://code.jquery.com/jquery-.*|src=\"$curr_domain/jquery-${jquery_version}.js\"|g" current/content/themes/casper/default.hbs
76
-    sed -i "s|src=\"https://code.jquery.com/jquery-.*|src=\"$curr_domain/jquery-${jquery_version}.js\"></script>|g" current/node_modules/gscan/app/tpl/layouts/default.hbs
77
-    sed -i "s|http://code.jquery.com/jquery.js|$curr_domain/jquery-${jquery_version}.js|g" current/node_modules/jsdom/README.md
78
-    sed -i "s|https://code.jquery.com/jquery.js|$curr_domain/jquery-${jquery_version}.js|g" current/node_modules/jsdom/README.md
79
-
80
-    cd "/var/www/${GHOST_DOMAIN_NAME}/htdocs/current" || exit 3468368
81
-    find ./ -type f -exec sed -i -e "s|https://code.jquery.com|$curr_domain|g" {} \;
82
-    find ./ -type f -exec sed -i -e "s|http://code.jquery.com|$curr_domain|g" {} \;
83
-}
84
-
85
-function ghost_rss_button {
86
-    # remove feedly -aaargh!
87
-    sed -i 's|http://cloud.feedly.com/#subscription/feed/{{@blog.url}}/rss/|{{@blog.url}}/rss/|g' /var/www/$GHOST_DOMAIN_NAME/htdocs/versions/${GHOST_VERSION}/content/themes/casper/partials/site-nav.hbs
88
-    sed -i 's|http://cloud.feedly.com/#subscription/feed/{{url absolute="true"}}/rss/|{{url absolute="true"}}rss/|g' /var/www/$GHOST_DOMAIN_NAME/htdocs/versions/${GHOST_VERSION}/content/themes/casper/author.hbs
89
-
90
-}
91
-
92
-function ghost_remove_offsite_links {
93
-    curr_domain="$GHOST_DOMAIN_NAME"
94
-    if [[ "$ONION_ONLY" != 'no' ]]; then
95
-        curr_domain="$GHOST_ONION_HOSTNAME"
96
-    fi
97
-
98
-    ghost_rss_button
99
-
100
-    # remove google font links
101
-    cd "/var/www/$GHOST_DOMAIN_NAME/htdocs/current" || exit 246872424
102
-    find ./ -type f -exec sed -i -e "s/fonts.googleapis.com/$curr_domain/g" {} \;
103
-
104
-    # copy jquery locally
105
-    previous_jquery_version='1.12.0'
106
-    jquery_version='1.12.4'
107
-    if [ ! -f /var/www/$GHOST_DOMAIN_NAME/htdocs/jquery-${jquery_version}.js ]; then
108
-        cd "/var/www/$GHOST_DOMAIN_NAME/htdocs" || exit 3468746824
109
-        wget https://code.jquery.com/jquery-${jquery_version}.js
110
-        jquery_hash=$(sha256sum jquery-${jquery_version}.js | awk -F ' ' '{print $1}')
111
-        if [[ "$jquery_hash" != '430f36f9b5f21aae8cc9dca6a81c4d3d84da5175eaedcf2fdc2c226302cb3575' ]]; then
112
-            echo $'Unexpected jquery hash value'
113
-            exit 258442
114
-        fi
115
-    fi
116
-    ghost_replace_jquery
117
-    previous_jquery_version='1.11.3'
118
-    ghost_replace_jquery
119
-}
120
-
121
-function ghost_replace_proprietary_services {
122
-    replace_file="$1"
123
-
124
-    sed -i 's|Twitter Profile|GNU Social Profile|g' "$replace_file"
125
-    sed -i 's|Twitter profile|GNU Social Profile|g' "$replace_file"
126
-    sed -i 's|Twitter Username|GNU Social Username|g' "$replace_file"
127
-    sed -i 's|twitter.com|quitter.se|g' "$replace_file"
128
-    sed -i 's|Facebook Page|Hubzilla Channel|g' "$replace_file"
129
-    sed -i 's|Facebook Profile|Hubzilla Channel|g' "$replace_file"
130
-    sed -i 's|Facebook profile|Hubzilla Channel|g' "$replace_file"
131
-    sed -i 's|www.facebook.com/username|hubzilladomain/username|g' "$replace_file"
132
-    sed -i 's|www.facebook.com/ghost|hubzilladomain/username|g' "$replace_file"
133
-    sed -i 's|www.facebook.com/testuser|hubzilladomain/username|g' "$replace_file"
134
-    sed -i 's|www.facebook.com/testing|hubzilladomain/username|g' "$replace_file"
135
-    sed -i 's|www.facebook.com/test|hubzilladomain/username|g' "$replace_file"
136
-    sed -i 's|www.facebook.com/yourUsername|hubzilladomain/username|g' "$replace_file"
137
-    sed -i 's|www.facebook.com/yourPage|hubzilladomain/username|g' "$replace_file"
138
-    sed -i 's|Facebook Username|Hubzilla Channel|g' "$replace_file"
139
-    sed -i 's|www.facebook.com|hubzilladomain|g' "$replace_file"
140
-    sed -i 's|facebook value|hubzilla value|g' "$replace_file"
141
-
142
-    sed -i '/<section class="share">/,/<\/section>/d' "$replace_file"
143
-}
144
-
145
-function ghost_replace_services {
146
-    ghost_replace_proprietary_services /var/www/${GHOST_DOMAIN_NAME}/htdocs/content/themes/casper/post.hbs
147
-}
148
-
149
-function remove_user_ghost {
150
-    remove_username="$1"
151
-}
152
-
153
-function add_user_ghost {
154
-    if [[ $(app_is_installed ghost) == "0" ]]; then
155
-        echo '0'
156
-        return
157
-    fi
158
-
159
-    new_username="$1"
160
-    new_user_password="$2"
161
-
162
-    echo '0'
163
-}
164
-
165
-function install_interactive_ghost {
166
-    if [ ! "$ONION_ONLY" ]; then
167
-        ONION_ONLY='no'
168
-    fi
169
-
170
-    if [[ $ONION_ONLY != "no" ]]; then
171
-        GHOST_DOMAIN_NAME='ghost.local'
172
-        write_config_param "GHOST_DOMAIN_NAME" "$GHOST_DOMAIN_NAME"
173
-    else
174
-        function_check interactive_site_details
175
-        interactive_site_details "ghost" "GHOST_DOMAIN_NAME" "GHOST_CODE"
176
-    fi
177
-    APP_INSTALLED=1
178
-}
179
-
180
-function change_password_ghost {
181
-    #GHOST_USERNAME="$1"
182
-    GHOST_PASSWORD="$2"
183
-    if [ ${#GHOST_PASSWORD} -lt 8 ]; then
184
-        echo $'Ghost password is too short'
185
-        return
186
-    fi
187
-    #"${PROJECT_NAME}-pass" -u "$GHOST_USERNAME" -a ghost -p "$GHOST_PASSWORD"
188
-}
189
-
190
-function reconfigure_ghost {
191
-    echo -n ''
192
-}
193
-
194
-function upgrade_ghost {
195
-    CURR_GHOST_VERSION=$(get_completion_param "ghost version")
196
-    if [[ "${CURR_GHOST_VERSION}" == "${GHOST_VERSION}" ]]; then
197
-        return
198
-    fi
199
-
200
-    read_config_param GHOST_DOMAIN_NAME
201
-
202
-    if [ ! -d /var/www/$GHOST_DOMAIN_NAME/htdocs ]; then
203
-        return
204
-    fi
205
-
206
-    systemctl stop ghost
207
-    ghost_bust
208
-
209
-    cd "/var/www/$GHOST_DOMAIN_NAME/htdocs" || exit 3468463
210
-
211
-    npm i -g ghost-cli
212
-    /usr/local/bin/ghost update &
213
-    sleep 200
214
-    ghost_bust
215
-
216
-    ghost_replace_services
217
-    ghost_remove_offsite_links
218
-
219
-    chown root:root /usr/local/bin/ghost
220
-    chown -R root:root /usr/local/lib
221
-    chown -R ghost: /var/www/${GHOST_DOMAIN_NAME}/htdocs
222
-    systemctl restart ghost
223
-    sed -i "s|ghost version.*|ghost version:${GHOST_VERSION}|g" "${COMPLETION_FILE}"
224
-}
225
-
226
-function backup_local_ghost {
227
-    GHOST_DOMAIN_NAME='ghost.local'
228
-    if grep -q "ghost domain" "$COMPLETION_FILE"; then
229
-        GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain")
230
-    fi
231
-
232
-    suspend_site "${GHOST_DOMAIN_NAME}"
233
-    systemctl stop ghost
234
-
235
-    ghost_path=/var/www/${GHOST_DOMAIN_NAME}/htdocs/content
236
-    if [ -d "$ghost_path" ]; then
237
-        backup_directory_to_usb "$ghost_path" ghostcontent
238
-    fi
239
-
240
-    ghost_path=/var/www/${GHOST_DOMAIN_NAME}/htdocs/current/content
241
-    if [ -d "$ghost_path" ]; then
242
-        backup_directory_to_usb "$ghost_path" ghostcurrent
243
-    fi
244
-
245
-    systemctl start ghost
246
-    restart_site
247
-}
248
-
249
-function restore_local_ghost {
250
-    GHOST_DOMAIN_NAME='ghost.local'
251
-    if grep -q "ghost domain" "$COMPLETION_FILE"; then
252
-        GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain")
253
-    fi
254
-    if [ "$GHOST_DOMAIN_NAME" ]; then
255
-        suspend_site "${GHOST_DOMAIN_NAME}"
256
-        systemctl stop ghost
257
-
258
-        temp_restore_dir=/root/tempghostcontent
259
-        function_check restore_directory_from_usb
260
-        restore_directory_from_usb $temp_restore_dir ghostcontent
261
-        if [ -d $temp_restore_dir ]; then
262
-            if [ -d "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
263
-                cp -r "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"* "/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"
264
-            else
265
-                if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
266
-                    mkdir "/var/www/$GHOST_DOMAIN_NAME/htdocs/content"
267
-                fi
268
-                cp -r $temp_restore_dir/* "/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"
269
-            fi
270
-            chown -R ghost:ghost "/var/www/$GHOST_DOMAIN_NAME/htdocs/content"
271
-            rm -rf $temp_restore_dir
272
-        fi
273
-
274
-        temp_restore_dir=/root/tempghostcurrent
275
-        function_check restore_directory_from_usb
276
-        restore_directory_from_usb $temp_restore_dir ghostcurrent
277
-        if [ -d $temp_restore_dir ]; then
278
-            if [ -d "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content" ]; then
279
-                cp -r "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"* "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"
280
-            else
281
-                if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content" ]; then
282
-                    mkdir -p "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content"
283
-                fi
284
-                cp -r $temp_restore_dir/* "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"
285
-            fi
286
-            chown -R ghost:ghost "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content"
287
-            rm -rf $temp_restore_dir
288
-        fi
289
-
290
-        systemctl start ghost
291
-        restart_site
292
-    fi
293
-}
294
-
295
-function backup_remote_ghost {
296
-    GHOST_DOMAIN_NAME='ghost.local'
297
-    if grep -q "ghost domain" "$COMPLETION_FILE"; then
298
-        GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain")
299
-    fi
300
-
301
-    suspend_site "${GHOST_DOMAIN_NAME}"
302
-
303
-    temp_backup_dir=/var/www/${GHOST_DOMAIN_NAME}/htdocs/content
304
-    if [ -d "$temp_backup_dir" ]; then
305
-        backup_directory_to_friend "$temp_backup_dir" ghostcontent
306
-    else
307
-        restart_site
308
-        echo $"Ghost domain specified but not found in /var/www/${GHOST_DOMAIN_NAME}"
309
-        exit 2578
310
-    fi
311
-
312
-    temp_backup_dir=/var/www/${GHOST_DOMAIN_NAME}/htdocs/current/content
313
-    if [ -d "$temp_backup_dir" ]; then
314
-        backup_directory_to_friend "$temp_backup_dir" ghostcurrent
315
-    else
316
-        restart_site
317
-        echo $"Ghost domain specified but not found in $temp_backup_dir"
318
-        exit 78353
319
-    fi
320
-
321
-    restart_site
322
-}
323
-
324
-function restore_remote_ghost {
325
-    GHOST_DOMAIN_NAME='ghost.local'
326
-    if grep -q "ghost domain" "$COMPLETION_FILE"; then
327
-        GHOST_DOMAIN_NAME=$(get_completion_param "ghost domain")
328
-    fi
329
-    suspend_site "${GHOST_DOMAIN_NAME}"
330
-
331
-    systemctl stop ghost
332
-
333
-    temp_restore_dir=/root/tempghostcontent
334
-    function_check restore_directory_from_friend
335
-    restore_directory_from_friend $temp_restore_dir ghostcontent
336
-    if [ -d $temp_restore_dir ]; then
337
-        if [ -d "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
338
-            cp -r "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"* "/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"
339
-        else
340
-            if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
341
-                mkdir "/var/www/$GHOST_DOMAIN_NAME/htdocs/content"
342
-            fi
343
-            cp -r $temp_restore_dir/* "/var/www/$GHOST_DOMAIN_NAME/htdocs/content/"
344
-        fi
345
-        chown -R ghost: "/var/www/$GHOST_DOMAIN_NAME/htdocs"
346
-        rm -rf $temp_restore_dir
347
-    fi
348
-
349
-    temp_restore_dir=/root/tempghostcurrent
350
-    function_check restore_directory_from_friend
351
-    restore_directory_from_friend $temp_restore_dir ghostcurrent
352
-    if [ -d $temp_restore_dir ]; then
353
-        if [ -d "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content" ]; then
354
-            cp -r "$temp_restore_dir/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"* "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"
355
-        else
356
-            if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content" ]; then
357
-                mkdir -p "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content"
358
-            fi
359
-            cp -r $temp_restore_dir/* "/var/www/$GHOST_DOMAIN_NAME/htdocs/current/content/"
360
-        fi
361
-        chown -R ghost: "/var/www/$GHOST_DOMAIN_NAME/htdocs"
362
-        rm -rf $temp_restore_dir
363
-    fi
364
-
365
-    systemctl start ghost
366
-    restart_site
367
-}
368
-
369
-function remove_ghost {
370
-    if [ ${#GHOST_DOMAIN_NAME} -eq 0 ]; then
371
-        return
372
-    fi
373
-
374
-    systemctl stop ghost
375
-    systemctl disable ghost
376
-    rm /etc/systemd/system/ghost.service
377
-    systemctl daemon-reload
378
-
379
-    npm uninstall -g ghost-cli
380
-
381
-    function_check remove_nodejs
382
-    remove_nodejs ghost
383
-
384
-    read_config_param "GHOST_DOMAIN_NAME"
385
-    nginx_dissite "$GHOST_DOMAIN_NAME"
386
-    remove_certs "${GHOST_DOMAIN_NAME}"
387
-    if [ -f "/etc/nginx/sites-available/$GHOST_DOMAIN_NAME" ]; then
388
-        rm -f "/etc/nginx/sites-available/$GHOST_DOMAIN_NAME"
389
-    fi
390
-    if [ -d "/var/www/$GHOST_DOMAIN_NAME" ]; then
391
-        rm -rf "/var/www/$GHOST_DOMAIN_NAME"
392
-    fi
393
-    remove_config_param GHOST_DOMAIN_NAME
394
-    remove_config_param GHOST_CODE
395
-    function_check remove_onion_service
396
-    remove_onion_service ghost ${GHOST_ONION_PORT}
397
-    remove_completion_param "install_ghost"
398
-    sed -i '/Ghost/d' "$COMPLETION_FILE"
399
-    sed -i '/ghost/d' "$COMPLETION_FILE"
400
-
401
-    groupdel -f ghost
402
-    userdel -r ghost
403
-
404
-    function_check remove_ddns_domain
405
-    remove_ddns_domain "$GHOST_DOMAIN_NAME"
406
-}
407
-
408
-function install_ghost {
409
-    check_ram_availability 900
410
-
411
-    if [ ! $ONION_ONLY ]; then
412
-        ONION_ONLY='no'
413
-    fi
414
-
415
-    if [ ! "$GHOST_DOMAIN_NAME" ]; then
416
-        echo $'The ghost domain name was not specified'
417
-        exit 5062
418
-    fi
419
-
420
-    # for the avatar changing command
421
-    apt-get -yq install unzip wget
422
-
423
-    if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs" ]; then
424
-        mkdir -p "/var/www/$GHOST_DOMAIN_NAME/htdocs"
425
-    fi
426
-    cd "/var/www/$GHOST_DOMAIN_NAME/htdocs" || exit 26422842
427
-
428
-    function_check install_nodejs
429
-    install_nodejs ghost
430
-
431
-    # now install ghost itself
432
-    npm install -g ghost-cli@latest
433
-    if [ ! -f /usr/local/bin/ghost ]; then
434
-        echo $'ghost was not installed'
435
-        exit 738539
436
-    fi
437
-
438
-    GHOST_ONION_HOSTNAME=$(add_onion_service ghost 80 ${GHOST_ONION_PORT})
439
-
440
-    npm install -g yarn
441
-    yarn install --no-emoji --no-progress
442
-    yarn cache clean
443
-    adduser --system --home="/var/www/${GHOST_DOMAIN_NAME}/htdocs/" --group ghost
444
-    rm -rf "/var/www/$GHOST_DOMAIN_NAME/htdocs/"*
445
-    printf 'y' | ghost install ${GHOST_VERSION} --user ghost --db=sqlite3 --port ${GHOST_PORT} --verbose
446
-
447
-    if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/versions" ]; then
448
-        echo $'versions directory was not found'
449
-        exit 782523462
450
-    fi
451
-    if [ ! -d "/var/www/$GHOST_DOMAIN_NAME/htdocs/content" ]; then
452
-        echo $'content directory was not found'
453
-        exit 68352682
454
-    fi
455
-
456
-    npm install -g knex-migrator
457
-    if [ ! -f "/var/www/$GHOST_DOMAIN_NAME/htdocs/versions/${GHOST_VERSION}/MigratorConfig.js" ]; then
458
-        echo $'MigratorConfig.js was not found'
459
-        exit 62783538
460
-    fi
461
-    cp "/var/www/$GHOST_DOMAIN_NAME/htdocs/versions/${GHOST_VERSION}/MigratorConfig.js" "/var/www/$GHOST_DOMAIN_NAME/htdocs"
462
-    chown -R ghost: "/var/www/$GHOST_DOMAIN_NAME/htdocs"
463
-    cd "/var/www/$GHOST_DOMAIN_NAME/htdocs/current" || exit 783452464
464
-    knex-migrator init
465
-
466
-    ghost_bust
467
-
468
-    echo '{' > "/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.development.json"
469
-    if [[ "$ONION_ONLY" == 'no' ]]; then
470
-        # NOTE: url must be http, not https
471
-        echo "  \"url\": \"http://${GHOST_DOMAIN_NAME}\"," >> "/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.development.json"
472
-    else
473
-        echo "  \"url\": \"http://${GHOST_ONION_HOSTNAME}\"," >> "/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.development.json"
474
-    fi
475
-    { echo '    "paths": {';
476
-      echo "        \"contentPath\": \"/var/www/${GHOST_DOMAIN_NAME}/htdocs/content\"";
477
-      echo '    }';
478
-      echo '}'; } >> "/var/www/${GHOST_DOMAIN_NAME}/htdocs/config.development.json"
479
-
480
-    { echo '[Unit]';
481
-      echo 'Description=Ghost Blog';
482
-      echo 'After=syslog.target';
483
-      echo 'After=network.target';
484
-      echo '';
485
-      echo '[Service]';
486
-      echo 'Type=simple';
487
-      echo 'User=ghost';
488
-      echo 'Group=ghost';
489
-      echo "WorkingDirectory=/var/www/${GHOST_DOMAIN_NAME}/htdocs";
490
-      echo "ExecStart=/usr/local/bin/ghost run -D";
491
-      echo "ExecStop=/usr/local/bin/ghost stop";
492
-      echo "ExecRestart=/usr/local/bin/ghost restart";
493
-      echo 'Restart=always';
494
-      echo 'RestartSec=60';
495
-      echo "Environment=NODE_ENV=development PORT=${GHOST_PORT}";
496
-      echo '';
497
-      echo '[Install]';
498
-      echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/ghost.service
499
-
500
-    ghost_remove_offsite_links
501
-
502
-    chown -R ghost: "/var/www/${GHOST_DOMAIN_NAME}/htdocs"
503
-
504
-    systemctl enable ghost
505
-    systemctl daemon-reload
506
-    systemctl start ghost
507
-
508
-    if [[ ${ONION_ONLY} == "no" ]]; then
509
-        function_check nginx_http_redirect
510
-        nginx_http_redirect "${GHOST_DOMAIN_NAME}"
511
-        { echo 'server {';
512
-          echo '    listen 443 ssl;';
513
-          echo '    #listen [::]:443 ssl;';
514
-          echo "    root /var/www/${GHOST_DOMAIN_NAME}/htdocs;";
515
-          echo "    server_name ${GHOST_DOMAIN_NAME};";
516
-          echo '    access_log /dev/null;';
517
-          echo "    error_log /dev/null;";
518
-          echo ''; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
519
-        function_check nginx_ssl
520
-        nginx_ssl "${GHOST_DOMAIN_NAME}"
521
-        function_check nginx_security_options
522
-        nginx_security_options "${GHOST_DOMAIN_NAME}"
523
-        { echo '    add_header Strict-Transport-Security max-age=0;';
524
-          echo '';
525
-          echo '    location / {'; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
526
-        function_check nginx_limits
527
-        nginx_limits "${GHOST_DOMAIN_NAME}" '10G'
528
-        { echo "        proxy_pass http://localhost:${GHOST_PORT};";
529
-          echo '    }';
530
-          echo '';
531
-          echo '    fastcgi_buffers 64 4K;';
532
-          echo '';
533
-          echo '    error_page 403 /core/templates/403.php;';
534
-          echo '    error_page 404 /core/templates/404.php;';
535
-          echo '';
536
-          echo '    location = /robots.txt {';
537
-          echo '        allow all;';
538
-          echo '        log_not_found off;';
539
-          echo '        access_log /dev/null;';
540
-          echo '    }';
541
-          echo '}';
542
-          echo ''; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
543
-    else
544
-        echo -n '' > "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
545
-    fi
546
-    { echo 'server {';
547
-      echo "    listen 127.0.0.1:${GHOST_ONION_PORT} default_server;";
548
-      echo "    root /var/www/$GHOST_DOMAIN_NAME/htdocs;";
549
-      echo "    server_name $GHOST_ONION_HOSTNAME;";
550
-      echo '    access_log /dev/null;';
551
-      echo "    error_log /dev/null;";
552
-      echo ''; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
553
-    function_check nginx_security_options
554
-    nginx_security_options "${GHOST_DOMAIN_NAME}"
555
-    { echo '    add_header Strict-Transport-Security max-age=0;';
556
-      echo '';
557
-      echo '    location / {'; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
558
-    function_check nginx_limits
559
-    nginx_limits "${GHOST_DOMAIN_NAME}" '10G'
560
-    { echo "        proxy_pass http://localhost:${GHOST_PORT};";
561
-      echo '    }';
562
-      echo '';
563
-      echo '    fastcgi_buffers 64 4K;';
564
-      echo '';
565
-      echo '    error_page 403 /core/templates/403.php;';
566
-      echo '    error_page 404 /core/templates/404.php;';
567
-      echo '';
568
-      echo '    location = /robots.txt {';
569
-      echo '        allow all;';
570
-      echo '        log_not_found off;';
571
-      echo '        access_log /dev/null;';
572
-      echo '    }';
573
-      echo '}'; } >> "/etc/nginx/sites-available/${GHOST_DOMAIN_NAME}"
574
-
575
-    function_check create_site_certificate
576
-    create_site_certificate "$GHOST_DOMAIN_NAME" 'yes'
577
-
578
-    ghost_replace_services
579
-
580
-    function_check nginx_ensite
581
-    nginx_ensite "$GHOST_DOMAIN_NAME"
582
-
583
-    systemctl restart nginx
584
-
585
-    "${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a ghost -p "$GHOST_ADMIN_PASSWORD"
586
-
587
-    function_check add_ddns_domain
588
-    add_ddns_domain "$GHOST_DOMAIN_NAME"
589
-
590
-    chown root:root /usr/local/bin/ghost
591
-    chown -R root:root /usr/local/lib
592
-    chown -R ghost: "/var/www/${GHOST_DOMAIN_NAME}/htdocs"
593
-    set_completion_param "ghost domain" "$GHOST_DOMAIN_NAME"
594
-    if ! grep -q "ghost version:" "${COMPLETION_FILE}"; then
595
-        echo "ghost version:${GHOST_VERSION}" >> "${COMPLETION_FILE}"
596
-    else
597
-        sed -i "s|ghost version.*|ghost version:${GHOST_VERSION}|g" "${COMPLETION_FILE}"
598
-    fi
599
-
600
-    APP_INSTALLED=1
601
-}
602
-
603
-# NOTE: deliberately no exit 0

+ 15
- 21
src/freedombone-app-gnusocial View File

306
     read_config_param GNUSOCIAL_EXPIRE_MONTHS
306
     read_config_param GNUSOCIAL_EXPIRE_MONTHS
307
     while true
307
     while true
308
     do
308
     do
309
-        data=$(mktemp 2>/dev/null)
310
-        dialog --backtitle $"Freedombone Control Panel" \
311
-               --title $"GNU Social" \
312
-               --radiolist $"Choose an operation:" 16 70 7 \
313
-               1 $"Set a background image" off \
314
-               2 $"Set the title" off \
315
-               3 $"Set post expiry period (currently $GNUSOCIAL_EXPIRE_MONTHS months)" off \
316
-               4 $"Select Qvitter user interface" off \
317
-               5 $"Select Pleroma user interface" off \
318
-               6 $"Select Classic user interface" off \
319
-               7 $"Exit" on 2> "$data"
320
-        sel=$?
321
-        case $sel in
322
-            1) rm -f "$data"
323
-               return;;
324
-            255) rm -f "$data"
325
-                 return;;
326
-        esac
327
-        case $(cat "$data") in
309
+        W=(1 $"Set a background image"
310
+           2 $"Set the title"
311
+           3 $"Set post expiry period (currently $GNUSOCIAL_EXPIRE_MONTHS months)"
312
+           4 $"Select Qvitter user interface"
313
+           5 $"Select Pleroma user interface"
314
+           6 $"Select Classic user interface")
315
+
316
+        # shellcheck disable=SC2068
317
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"GNU Social" --menu $"Choose an operation, or ESC to exit:" 15 60 6 "${W[@]}" 3>&2 2>&1 1>&3)
318
+
319
+        if [ ! "$selection" ]; then
320
+            break
321
+        fi
322
+
323
+        case $selection in
328
             1) gnusocial_set_background_image;;
324
             1) gnusocial_set_background_image;;
329
             2) gnusocial_set_title;;
325
             2) gnusocial_set_title;;
330
             3) gnusocial_set_expire_months;;
326
             3) gnusocial_set_expire_months;;
331
             4) gnusocial_use_qvitter gnusocial;;
327
             4) gnusocial_use_qvitter gnusocial;;
332
             5) gnusocial_use_pleroma gnusocial;;
328
             5) gnusocial_use_pleroma gnusocial;;
333
             6) gnusocial_use_classic gnusocial;;
329
             6) gnusocial_use_classic gnusocial;;
334
-            7) break;;
335
         esac
330
         esac
336
-        rm -f "$data"
337
     done
331
     done
338
 }
332
 }
339
 
333
 

+ 11
- 16
src/freedombone-app-hubzilla View File

138
 }
138
 }
139
 
139
 
140
 function configure_interactive_hubzilla {
140
 function configure_interactive_hubzilla {
141
+    W=(1 $"Set channel directory server"
142
+       2 $"Renew SSL certificate")
143
+
141
     while true
144
     while true
142
     do
145
     do
143
-        data=$(mktemp 2>/dev/null)
144
-        dialog --backtitle $"Freedombone Control Panel" \
145
-               --title $"Hubzilla" \
146
-               --radiolist $"Choose an operation:" 13 70 4 \
147
-               1 $"Set channel directory server" off \
148
-               2 $"Renew SSL certificate" off \
149
-               3 $"Back to main menu" on 2> "$data"
150
-        sel=$?
151
-        case $sel in
152
-            1) break;;
153
-            255) break;;
154
-        esac
155
-        case $(cat "$data") in
146
+        # shellcheck disable=SC2068
147
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Hubzilla" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
148
+
149
+        if [ ! "$selection" ]; then
150
+            break
151
+        fi
152
+
153
+        case $selection in
156
             1) hubzilla_channel_directory_server;;
154
             1) hubzilla_channel_directory_server;;
157
             2) hubzilla_renew_cert;;
155
             2) hubzilla_renew_cert;;
158
-            3) rm -f "$data"
159
-               break;;
160
         esac
156
         esac
161
-        rm -f "$data"
162
     done
157
     done
163
 }
158
 }
164
 
159
 

+ 20
- 27
src/freedombone-app-icecast View File

401
 }
401
 }
402
 
402
 
403
 function configure_interactive_icecast {
403
 function configure_interactive_icecast {
404
+    W=(1 $"Import stream files from directory"
405
+       2 $"Import stream files from USB drive"
406
+       3 $"Format a USB drive for stream file storage"
407
+       4 $"Export stream files to USB drive"
408
+       5 $"Manually edit playlist"
409
+       6 $"Enable login for stream visitors"
410
+       7 $"Change password for stream visitors"
411
+       8 $"Re-scan playlist"
412
+       9 $"Restart stream"
413
+       10 $"Set Stream Name/Description/Genre"
414
+       11 $"Set maximum number of clients/streams")
415
+
404
     while true
416
     while true
405
     do
417
     do
406
-        data=$(mktemp 2>/dev/null)
407
-        dialog --backtitle $"Freedombone Control Panel" \
408
-               --title $"Icecast" \
409
-               --radiolist $"Choose an operation:" 19 70 12 \
410
-               1 $"Import stream files from directory" off \
411
-               2 $"Import stream files from USB drive" off \
412
-               3 $"Format a USB drive for stream file storage" off \
413
-               4 $"Export stream files to USB drive" off \
414
-               5 $"Manually edit playlist" off \
415
-               6 $"Enable login for stream visitors" off \
416
-               7 $"Change password for stream visitors" off \
417
-               8 $"Re-scan playlist" off \
418
-               9 $"Restart stream" off \
419
-               10 $"Set Stream Name/Description/Genre" off \
420
-               11 $"Set maximum number of clients/streams" off \
421
-               12 $"Exit" on 2> "$data"
422
-        sel=$?
423
-        case $sel in
424
-            1) rm -f "$data"
425
-               break;;
426
-            255) rm -f "$data"
427
-                 break;;
428
-        esac
429
-        case $(cat "$data") in
418
+        # shellcheck disable=SC2068
419
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Icecast" --menu $"Choose an operation, or ESC to exit:" 20 60 11 "${W[@]}" 3>&2 2>&1 1>&3)
420
+
421
+        if [ ! "$selection" ]; then
422
+            break
423
+        fi
424
+
425
+        case $selection in
430
             1) icecast_import_from_directory;;
426
             1) icecast_import_from_directory;;
431
             2) icecast_import_from_usb;;
427
             2) icecast_import_from_usb;;
432
             3) icecast_format_drive;;
428
             3) icecast_format_drive;;
443
                start_icecast;;
439
                start_icecast;;
444
             10) icecast_set_stream_name;;
440
             10) icecast_set_stream_name;;
445
             11) icecast_set_maximum_streams;;
441
             11) icecast_set_maximum_streams;;
446
-            12) rm -f "$data"
447
-                break;;
448
         esac
442
         esac
449
-        rm -f "$data"
450
     done
443
     done
451
 }
444
 }
452
 
445
 

+ 11
- 17
src/freedombone-app-irc View File

398
         return
398
         return
399
     fi
399
     fi
400
 
400
 
401
+    W=(1 $"Set a password for all IRC users"
402
+       2 $"Show current IRC login password")
403
+
401
     while true
404
     while true
402
     do
405
     do
403
-        data=$(mktemp 2>/dev/null)
404
-        dialog --backtitle $"Freedombone Control Panel" \
405
-               --title $"IRC Menu" \
406
-               --radiolist $"Choose an operation:" 14 70 4 \
407
-               1 $"Set a password for all IRC users" off \
408
-               2 $"Show current IRC login password" off \
409
-               3 $"Exit" on 2> "$data"
410
-        sel=$?
411
-        case $sel in
412
-            1) rm -f "$data"
413
-               break;;
414
-            255) rm -f "$data"
415
-                 break;;
416
-        esac
417
-        case $(cat "$data") in
406
+        # shellcheck disable=SC2068
407
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"IRC" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
408
+
409
+        if [ ! "$selection" ]; then
410
+            break
411
+        fi
412
+
413
+        case $selection in
418
             1) irc_set_global_password;;
414
             1) irc_set_global_password;;
419
             2) irc_show_password;;
415
             2) irc_show_password;;
420
-            3) break;;
421
         esac
416
         esac
422
-        rm -f "$data"
423
     done
417
     done
424
 }
418
 }
425
 
419
 

+ 12
- 19
src/freedombone-app-keyserver View File

531
 }
531
 }
532
 
532
 
533
 function configure_interactive_keyserver {
533
 function configure_interactive_keyserver {
534
+    W=(1 $"Remove a key"
535
+       2 $"Sync with other keyserver"
536
+       3 $"Edit sync keyservers")
537
+
534
     while true
538
     while true
535
     do
539
     do
536
-        data=$(mktemp 2>/dev/null)
537
-        dialog --backtitle $"Freedombone Control Panel" \
538
-               --title $"SKS Keyserver" \
539
-               --radiolist $"Choose an operation:" 12 70 4 \
540
-               1 $"Remove a key" off \
541
-               2 $"Sync with other keyserver" off \
542
-               3 $"Edit sync keyservers" off \
543
-               4 $"Exit" on 2> "$data"
544
-        sel=$?
545
-        case $sel in
546
-            1) rm -f "$data"
547
-               return;;
548
-            255) rm -f "$data"
549
-                 return;;
550
-        esac
551
-        case $(cat "$data") in
540
+        # shellcheck disable=SC2068
541
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"SKS Keyserver" --menu $"Choose an operation, or ESC to exit:" 11 60 3 "${W[@]}" 3>&2 2>&1 1>&3)
542
+
543
+        if [ ! "$selection" ]; then
544
+            break
545
+        fi
546
+
547
+        case $selection in
552
             1) keyserver_remove_key;;
548
             1) keyserver_remove_key;;
553
             2) keyserver_sync;;
549
             2) keyserver_sync;;
554
             3) keyserver_edit;;
550
             3) keyserver_edit;;
555
-            4) rm -f "$data"
556
-               break;;
557
         esac
551
         esac
558
-        rm -f "$data"
559
     done
552
     done
560
 }
553
 }
561
 
554
 

+ 13
- 20
src/freedombone-app-koel View File

272
 
272
 
273
 
273
 
274
 function configure_interactive_koel {
274
 function configure_interactive_koel {
275
+    W=(1 $"Import music from directory"
276
+       2 $"Import music from USB drive"
277
+       3 $"Export music to USB drive"
278
+       4 $"Format a USB drive for music storage")
279
+
275
     while true
280
     while true
276
     do
281
     do
277
-        data=$(mktemp 2>/dev/null)
278
-        dialog --backtitle $"Freedombone Control Panel" \
279
-               --title $"Koel" \
280
-               --radiolist $"Choose an operation:" 12 70 5 \
281
-               1 $"Import music from directory" off \
282
-               2 $"Import music from USB drive" off \
283
-               3 $"Export music to USB drive" off \
284
-               4 $"Format a USB drive for music storage" off \
285
-               5 $"Exit" on 2> "$data"
286
-        sel=$?
287
-        case $sel in
288
-            1) rm -f "$data"
289
-               break;;
290
-            255) rm -f "$data"
291
-                 break;;
292
-        esac
293
-        case $(cat "$data") in
282
+        # shellcheck disable=SC2068
283
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Koel" --menu $"Choose an operation, or ESC to exit:" 12 60 4 "${W[@]}" 3>&2 2>&1 1>&3)
284
+
285
+        if [ ! "$selection" ]; then
286
+            break
287
+        fi
288
+
289
+        case $selection in
294
             1) koel_import_from_directory;;
290
             1) koel_import_from_directory;;
295
             2) koel_import_from_usb;;
291
             2) koel_import_from_usb;;
296
             3) koel_export_to_usb;;
292
             3) koel_export_to_usb;;
297
             4) format_music_drive;;
293
             4) format_music_drive;;
298
-            5) rm -f "$data"
299
-               break;;
300
         esac
294
         esac
301
-        rm -f "$data"
302
     done
295
     done
303
 }
296
 }
304
 
297
 

+ 1
- 1
src/freedombone-app-mailpile View File

227
       echo 'User=mailpile';
227
       echo 'User=mailpile';
228
       echo 'Group=mailpile';
228
       echo 'Group=mailpile';
229
       echo "WorkingDirectory=/var/www/$MAILPILE_DOMAIN_NAME/mail";
229
       echo "WorkingDirectory=/var/www/$MAILPILE_DOMAIN_NAME/mail";
230
-      echo "ExecStart=/var/www/$MAILPILE_DOMAIN_NAME/mail/mp --www=0.0.0.0:${MAILPILE_PORT} --wait";
230
+      echo "ExecStart=/var/www/$MAILPILE_DOMAIN_NAME/mail/mp --www=127.0.0.1:${MAILPILE_PORT} --wait";
231
       echo 'Restart=always';
231
       echo 'Restart=always';
232
       echo 'RestartSec=10';
232
       echo 'RestartSec=10';
233
       echo '';
233
       echo '';

+ 2
- 2
src/freedombone-app-matrix View File

125
     matrix_nginx_site=/etc/nginx/sites-available/$MATRIX_DOMAIN_NAME
125
     matrix_nginx_site=/etc/nginx/sites-available/$MATRIX_DOMAIN_NAME
126
     if [[ $ONION_ONLY == "no" ]]; then
126
     if [[ $ONION_ONLY == "no" ]]; then
127
         { echo 'server {';
127
         { echo 'server {';
128
-          echo "  listen 0.0.0.0:443;";
128
+          echo "  listen 443;";
129
           echo "  server_name ${MATRIX_DOMAIN_NAME};";
129
           echo "  server_name ${MATRIX_DOMAIN_NAME};";
130
           echo '';
130
           echo '';
131
           echo '  # Security'; } > $matrix_nginx_site
131
           echo '  # Security'; } > $matrix_nginx_site
154
           echo '}';
154
           echo '}';
155
           echo '';
155
           echo '';
156
           echo 'server {';
156
           echo 'server {';
157
-          echo "  listen 0.0.0.0:${MATRIX_HTTP_PORT};";
157
+          echo "  listen ${MATRIX_HTTP_PORT};";
158
           echo "  server_name ${MATRIX_DOMAIN_NAME};";
158
           echo "  server_name ${MATRIX_DOMAIN_NAME};";
159
           echo '';
159
           echo '';
160
           echo '  # Security'; } >> $matrix_nginx_site
160
           echo '  # Security'; } >> $matrix_nginx_site

+ 292
- 33
src/freedombone-app-peertube View File

39
 PEERTUBE_DOMAIN_NAME=
39
 PEERTUBE_DOMAIN_NAME=
40
 PEERTUBE_CODE=
40
 PEERTUBE_CODE=
41
 PEERTUBE_REPO="https://github.com/Chocobozzz/PeerTube"
41
 PEERTUBE_REPO="https://github.com/Chocobozzz/PeerTube"
42
-PEERTUBE_COMMIT='fef2c7164e025b12a64185dbab058ef4129733c6'
42
+PEERTUBE_COMMIT='f209b32afaffbb8b93c265525ebde182ab66c37a'
43
 PEERTUBE_ONION_PORT=8136
43
 PEERTUBE_ONION_PORT=8136
44
 PEERTUBE_PORT=9004
44
 PEERTUBE_PORT=9004
45
 MESH_PEERTUBE_PORT=8500
45
 MESH_PEERTUBE_PORT=8500
54
                     ARCHITECTURE
54
                     ARCHITECTURE
55
                     MY_EMAIL_ADDRESS)
55
                     MY_EMAIL_ADDRESS)
56
 
56
 
57
+function peertube_import_from_syncthing {
58
+    peertubedomain="https://$PEERTUBE_DOMAIN_NAME"
59
+    nodecmd='node'
60
+
61
+    if [[ "$ONION_ONLY" != 'no' ]]; then
62
+        peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)"
63
+        nodecmd='torsocks node'
64
+    fi
65
+
66
+    { echo '#!/bin/bash';
67
+      echo '';
68
+      echo 'LOCKFILE=/tmp/.peertube.lock';
69
+      echo '';
70
+      echo 'if [ -f /root/.peertube.lock ]; then';
71
+      echo "    lockctr=\$(cat \$LOCKFILE)";
72
+      echo "    lockctr=\$((lockctr+1))";
73
+      echo "    echo \"\$lockctr\" > \$LOCKFILE";
74
+      echo "    if [ \$lockctr -ge 30 ]; then";
75
+      echo "        rm \$LOCKFILE";
76
+      echo '    else';
77
+      echo '        exit 0';
78
+      echo '    fi';
79
+      echo 'fi';
80
+      echo '';
81
+      echo "MY_USERNAME=\$(cat /root/${PROJECT_NAME}.cfg | grep MY_USERNAME | awk -F '=' '{print \$2}')";
82
+      echo "if [ ! \"\$MY_USERNAME\" ]; then";
83
+      echo '    exit 0';
84
+      echo 'fi';
85
+      echo '';
86
+      echo "search_dir=/home/\$MY_USERNAME/Sync/peertube_upload";
87
+      echo "if [ ! -f \$search_dir/login.txt ]; then";
88
+      echo '    exit 0';
89
+      echo 'fi';
90
+      echo "import_script=${PEERTUBE_DIR}/dist/server/tools/upload.js";
91
+      echo "if [ ! -f \$import_script ]; then";
92
+      echo '    exit 0';
93
+      echo 'fi';
94
+      echo '';
95
+      echo "peertubedomain=\"$peertubedomain\"";
96
+      echo "peertubeuser=\$(sed -n 1p < \"\$search_dir/login.txt\")";
97
+      echo "peertubepassword=\$(sed -n 2p < \"\$search_dir/login.txt\")";
98
+      echo 'peertubensfw=';
99
+      echo "if grep -q 'nsfw' \"\$search_dir/login.txt\"; then";
100
+      echo "    peertubensfw='--nsfw'";
101
+      echo 'fi';
102
+      echo "if grep -q 'NSFW' \"\$search_dir/login.txt\"; then";
103
+      echo "    peertubensfw='--nsfw'";
104
+      echo 'fi';
105
+      echo '';
106
+      echo "peertubeprivate='-P 3'";
107
+      echo "if grep -q 'public' \"\$search_dir/login.txt\"; then";
108
+      echo "    peertubeprivate='-P 1'";
109
+      echo 'fi';
110
+      echo "if grep -q 'Public' \"\$search_dir/login.txt\"; then";
111
+      echo "    peertubeprivate='-P 1'";
112
+      echo 'fi';
113
+      echo '';
114
+      echo 'failed_uploads=0';
115
+      echo '';
116
+      echo "cd ${PEERTUBE_DIR} || exit 32468356";
117
+      echo "echo \"0\" > \$LOCKFILE";
118
+      echo '';
119
+      echo "for video_file in \$search_dir/*; do";
120
+      echo "    if [[ \"\$video_file\" == *'.ogv' || \"\$video_file\" == *'.mp4' || \"\$video_file\" == *'.webm' ]]; then";
121
+      echo "        if ! grep -q \"\$video_file\" /root/.peertube_uploaded; then";
122
+      echo "            peertubetitle=\$(basename \"\$video_file\" | awk -F '.' '{print \$1}' | sed 's|_| |g' | sed 's|-| |g')";
123
+      echo "            if $nodecmd \$import_script -n \"\$peertubetitle\" \$peertubensfw \$peertubeprivate -u \"\$peertubedomain\" -U \"\$peertubeuser\" --password \"\$peertubepassword\" -f \"\$video_file\"; then";
124
+      echo "                echo \"\$video_file\" >> /root/.peertube_uploaded";
125
+      echo "                rm \$LOCKFILE";
126
+      echo "                exit 0";
127
+      echo '            else';
128
+      echo "                failed_uploads=\$((failed_uploads+1))";
129
+      echo "                if [ \$failed_uploads -gt 1 ]; then";
130
+      echo "                    rm \$LOCKFILE";
131
+      echo '                    exit 0';
132
+      echo '                fi';
133
+      echo '            fi';
134
+      echo '        fi';
135
+      echo '    fi';
136
+      echo 'done';
137
+      echo '';
138
+      echo "rm \$LOCKFILE"; } > /usr/bin/peertubesync
139
+
140
+    chmod +x /usr/bin/peertubesync
141
+    cron_add_mins 1 /usr/bin/peertubesync
142
+}
143
+
57
 function peertube_create_database {
144
 function peertube_create_database {
58
     if [ -f "$IMAGE_PASSWORD_FILE" ]; then
145
     if [ -f "$IMAGE_PASSWORD_FILE" ]; then
59
         PEERTUBE_ADMIN_PASSWORD="$(printf "%s" "$(cat "$IMAGE_PASSWORD_FILE")")"
146
         PEERTUBE_ADMIN_PASSWORD="$(printf "%s" "$(cat "$IMAGE_PASSWORD_FILE")")"
149
     systemctl restart peertube
236
     systemctl restart peertube
150
 }
237
 }
151
 
238
 
239
+function peertube_import_from_file {
240
+    read_config_param MY_USERNAME
241
+    read_config_param PEERTUBE_DOMAIN_NAME
242
+    read_config_param ONION_ONLY
243
+
244
+    data2=$(mktemp 2>/dev/null)
245
+    dialog --backtitle $"Freedombone Control Panel" \
246
+           --title $"Import Video from file" \
247
+           --form $"Enter your PeerTube login details and video title" 10 65 4 \
248
+           $"Username:" 1 1 "$MY_USERNAME" 1 18 16 15 \
249
+           $"Password:" 2 1 "" 2 18 40 10000 \
250
+           $"Video Title:" 3 1 "" 3 18 40 1000 \
251
+           $"NSFW:" 4 1 $"no" 4 18 4 4 \
252
+           2> "$data2"
253
+    sel=$?
254
+    case $sel in
255
+        1) rm -f "$data2"
256
+           return;;
257
+        255) rm -f "$data2"
258
+             return;;
259
+    esac
260
+    peertubeuser=$(sed -n 1p < "$data2")
261
+    peertubepassword=$(sed -n 2p < "$data2")
262
+    peertubetitle=$(sed -n 3p < "$data2")
263
+    peertubensfw=$(sed -n 4p < "$data2")
264
+    rm -f "$data2"
265
+
266
+    peertubedomain="https://$PEERTUBE_DOMAIN_NAME"
267
+    nodecmd='node'
268
+
269
+    if [[ "$ONION_ONLY" != 'no' ]]; then
270
+        peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)"
271
+        nodecmd='torsocks node'
272
+    fi
273
+
274
+    data2=$(mktemp 2>/dev/null)
275
+    dialog --title "Choose the video file (select with spacebar)" --fselect "/home/$MY_USERNAME/" 30 60 2> "$data2"
276
+    selected_file=$(cat "$data2")
277
+    rm -f "$data2"
278
+    if [ ! "$selected_file" ]; then
279
+        return
280
+    fi
281
+    if [[ "$selected_file" != *'.ogv' && "$selected_file" != *'.mp4' && "$selected_file" != *'.webm' ]]; then
282
+        dialog --title $"Import video from file" \
283
+               --msgbox $"The video should be in ogv, mp4 or webm format" 6 75
284
+        return
285
+    fi
286
+
287
+    cd $PEERTUBE_DIR || exit 32468356
288
+    import_script=$PEERTUBE_DIR/dist/server/tools/upload.js
289
+    if [ ! -f $import_script ]; then
290
+        dialog --title $"Import videos" \
291
+               --msgbox $"upload script was not found" 6 75
292
+        return
293
+    fi
294
+
295
+    nsfwstr=
296
+    if [[ "$peertubensfw" == *'y'* || "$peertubensfw" == *'Y'* ]]; then
297
+        nsfwstr='--nsfw'
298
+    fi
299
+
300
+    titlestr=$(basename "$selected_file" | awk -F '.' '{print $1}' | sed 's|_| |g' | sed 's|-| |g')
301
+    if [ "$peertubetitle" ]; then
302
+        titlestr="-n \"$peertubetitle\""
303
+    fi
304
+
305
+    clear
306
+    $nodecmd $import_script $nsfwstr "$titlestr" -u "$peertubedomain" -U "$peertubeuser" --password "$peertubepassword" -f "$selected_file"
307
+
308
+    dialog --title $"Import video from file" \
309
+           --msgbox $"Video imported from $selected_file" 6 75
310
+}
311
+
312
+function peertube_import_videos {
313
+    read_config_param MY_USERNAME
314
+    read_config_param PEERTUBE_DOMAIN_NAME
315
+    read_config_param ONION_ONLY
316
+
317
+    data2=$(mktemp 2>/dev/null)
318
+    dialog --backtitle $"Freedombone Control Panel" \
319
+           --title $"Import Videos from legacy sites" \
320
+           --form $"Enter a channel of video URL for YouTube/Vimeo/Dailymotion" 10 75 4 \
321
+           $"Username:" 1 1 "$MY_USERNAME" 1 22 16 15 \
322
+           $"Password:" 2 1 "" 2 22 50 10000 \
323
+           $"Video/Channel URL:" 3 1 "" 3 22 50 10000 \
324
+           2> "$data2"
325
+    sel=$?
326
+    case $sel in
327
+        1) rm -f "$data2"
328
+           return;;
329
+        255) rm -f "$data2"
330
+             return;;
331
+    esac
332
+    peertubeuser=$(sed -n 1p < "$data2")
333
+    peertubepassword=$(sed -n 2p < "$data2")
334
+    video_url=$(sed -n 3p < "$data2")
335
+    rm -f "$data2"
336
+
337
+    peertubedomain="https://$PEERTUBE_DOMAIN_NAME"
338
+    nodecmd='node'
339
+
340
+    if [[ "$ONION_ONLY" != 'no' ]]; then
341
+        peertubedomain="http://$(cat /var/lib/tor/hidden_service_peertube/hostname)"
342
+        nodecmd='torsocks node'
343
+    fi
344
+
345
+    if [ ${#peertubeuser} -lt 3 ]; then
346
+        dialog --title $"Import videos from legacy sites" \
347
+               --msgbox $"Username was not valid" 6 75
348
+        return
349
+    fi
350
+
351
+    if [ ${#peertubepassword} -lt 3 ]; then
352
+        dialog --title $"Import videos from legacy sites" \
353
+               --msgbox $"Password was not valid" 6 75
354
+        return
355
+    fi
356
+
357
+    if [[ "$video_url" == *' '* || "$video_url" == *','* || "$video_url" == *'@'* ]]; then
358
+        dialog --title $"Import videos from legacy sites" \
359
+               --msgbox $"Video/channel URL was not valid" 6 75
360
+        return
361
+    fi
362
+
363
+    if [ ${#video_url} -lt 8 ]; then
364
+        dialog --title $"Import videos from legacy sites" \
365
+               --msgbox $"Video/channel URL was not valid" 6 75
366
+        return
367
+    fi
368
+
369
+    cd $PEERTUBE_DIR || exit 32468356
370
+    import_script=$PEERTUBE_DIR/dist/server/tools/import-videos.js
371
+    if [ ! -f $import_script ]; then
372
+        dialog --title $"Import videos from legacy sites" \
373
+               --msgbox $"import-videos script was not found" 6 75
374
+        return
375
+    fi
376
+
377
+    clear
378
+    $nodecmd $import_script -u "$peertubedomain" -U "$peertubeuser" --password "$peertubepassword" -t "$video_url"
379
+
380
+    dialog --title $"Import videos from legacy sites" \
381
+           --msgbox $"Video/s imported from $video_url" 6 75
382
+}
383
+
152
 function configure_interactive_peertube {
384
 function configure_interactive_peertube {
385
+    W=(1 $"Set administrator email address"
386
+       2 $"Disable or enable signups"
387
+       3 $"Import videos from YouTube/Vimeo/Dailymotion"
388
+       4 $"Import video from file")
389
+
153
     while true
390
     while true
154
     do
391
     do
155
-        data=$(mktemp 2>/dev/null)
156
-        dialog --backtitle $"Freedombone Control Panel" \
157
-               --title $"PeerTube" \
158
-               --radiolist $"Choose an operation:" 10 70 4 \
159
-               1 $"Set administrator email address" off \
160
-               2 $"Disable or enable signups" off \
161
-               3 $"Exit" on 2> "$data"
162
-        sel=$?
163
-        case $sel in
164
-            1) break;;
165
-            255) break;;
166
-        esac
167
-        case $(cat "$data") in
392
+        # shellcheck disable=SC2068
393
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"PeerTube" --menu $"Choose an operation, or ESC to exit:" 12 60 4 "${W[@]}" 3>&2 2>&1 1>&3)
394
+
395
+        if [ ! "$selection" ]; then
396
+            break
397
+        fi
398
+
399
+        case $selection in
168
             1) peertube_set_admin_email;;
400
             1) peertube_set_admin_email;;
169
             2) peertube_disable_signups;;
401
             2) peertube_disable_signups;;
170
-            3) rm -f "$data"
171
-               break;;
402
+            3) peertube_import_videos;;
403
+            4) peertube_import_from_file;;
172
         esac
404
         esac
173
-        rm -f "$data"
174
     done
405
     done
175
 }
406
 }
176
 
407
 
189
 }
420
 }
190
 
421
 
191
 function upgrade_peertube {
422
 function upgrade_peertube {
423
+    peertube_import_from_syncthing
424
+
192
     CURR_PEERTUBE_COMMIT=$(get_completion_param "peertube commit")
425
     CURR_PEERTUBE_COMMIT=$(get_completion_param "peertube commit")
193
     if [[ "$CURR_PEERTUBE_COMMIT" == "$PEERTUBE_COMMIT" ]]; then
426
     if [[ "$CURR_PEERTUBE_COMMIT" == "$PEERTUBE_COMMIT" ]]; then
194
         return
427
         return
342
     remove_onion_service peertube ${PEERTUBE_ONION_PORT}
575
     remove_onion_service peertube ${PEERTUBE_ONION_PORT}
343
     remove_completion_param "install_peertube"
576
     remove_completion_param "install_peertube"
344
     sed -i '/peertube/d' "$COMPLETION_FILE"
577
     sed -i '/peertube/d' "$COMPLETION_FILE"
578
+    sed -i '/peertubesync/d' /etc/crontab
579
+
580
+    if [ -f /usr/bin/peertubesync ]; then
581
+        rm /usr/bin/peertubesync
582
+    fi
583
+    if [ -f /root/peertube_uploaded ]; then
584
+        rm /root/peertube_uploaded
585
+    fi
345
 
586
 
346
     function_check drop_database_postgresql
587
     function_check drop_database_postgresql
347
     drop_database_postgresql peertube peertube
588
     drop_database_postgresql peertube peertube
622
     if [[ "$VARIANT" != "meshclient" && "$VARIANT" != "meshusb" ]]; then
863
     if [[ "$VARIANT" != "meshclient" && "$VARIANT" != "meshusb" ]]; then
623
         return
864
         return
624
     fi
865
     fi
625
-    if [[ "$ARCHITECTURE" != 'x86_64' && "$ARCHITECTURE" != 'amd64' ]]; then
866
+    if [[ "$ARCHITECTURE" != 'x86_64' && "$ARCHITECTURE" != 'amd64' && "$ARCHITECTURE" != 'i386' ]]; then
626
         return
867
         return
627
     fi
868
     fi
628
 
869
 
629
-    chroot "$rootdir" apt-get -yq install ffmpeg curl
870
+    chroot "$rootdir" apt-get -yq install ffmpeg curl redis-tools redis-server
630
 
871
 
631
     function_check install_postgresql
872
     function_check install_postgresql
632
     install_postgresql
873
     install_postgresql
653
 apt-get -y update
894
 apt-get -y update
654
 apt-get -yq install yarn
895
 apt-get -yq install yarn
655
 
896
 
656
-#npm install --arch=$NPM_ARCH -g yarn
657
-#if [ ! "\$?" = "0" ]; then
897
+#if ! npm install --arch=$NPM_ARCH -g yarn@1.5.1; then
658
 #    echo $'PeerTube Failed to install yarn'
898
 #    echo $'PeerTube Failed to install yarn'
659
 #    exit 79353234
899
 #    exit 79353234
660
 #fi
900
 #fi
661
-#npm install --arch=$NPM_ARCH webpack@3.10.0 --no-optional
662
-#if [ ! "\$?" = "0" ]; then
901
+#if ! npm install --arch=$NPM_ARCH webpack@3.10.0 --no-optional; then
663
 #    echo $'PeerTube failed to install webpack'
902
 #    echo $'PeerTube failed to install webpack'
664
 #    exit 68386353
903
 #    exit 68386353
665
 #fi
904
 #fi
666
 yarn install
905
 yarn install
667
 yarn run build:prod
906
 yarn run build:prod
668
-yarn add -D webpack
669
-if [ ! "\$?" = "0" ]; then
907
+if ! yarn add -D webpack; then
670
     echo $'PeerTube failed to add webpack'
908
     echo $'PeerTube failed to add webpack'
671
     exit 67342823
909
     exit 67342823
672
 fi
910
 fi
673
-yarn install --ignore-optional
674
-if [ ! "\$?" = "0" ]; then
911
+if ! yarn install --ignore-optional; then
675
     echo $'PeerTube failed to run yarn install'
912
     echo $'PeerTube failed to run yarn install'
676
     exit 63754235
913
     exit 63754235
677
 fi
914
 fi
678
-npm install --arch=$NPM_ARCH
679
-if [ ! "\$?" = "0" ]; then
915
+if ! npm install --arch=$NPM_ARCH -g npm@4; then
916
+    # https://github.com/KraigM/homebridge-harmonyhub/issues/119
917
+    echo $'Failed to downgrade npm'
918
+    exit 3476835
919
+fi
920
+cp /root/.npm-global/bin/npm /usr/local/bin/npm
921
+if ! npm install --arch=$NPM_ARCH; then
680
     echo $'PeerTube failed to install peertube'
922
     echo $'PeerTube failed to install peertube'
681
     exit 7835243
923
     exit 7835243
682
 fi
924
 fi
683
-npm run build --arch=$NPM_ARCH
684
-if [ ! "\$?" = "0" ]; then
925
+if ! npm install --arch=$NPM_ARCH -g "npm@${NPM_VERSION}"; then
926
+    echo $'Failed to restore npm after downgrade'
927
+    exit 5737583
928
+fi
929
+cp /root/.npm-global/bin/npm /usr/local/bin/npm
930
+if ! npm run build --arch=$NPM_ARCH; then
685
     echo $'PeerTube failed to build peertube'
931
     echo $'PeerTube failed to build peertube'
686
     exit 5293593
932
     exit 5293593
687
 fi
933
 fi
737
         exit 783523
983
         exit 783523
738
     fi
984
     fi
739
 
985
 
740
-    apt-get -yq install ffmpeg
986
+    apt-get -yq install ffmpeg redis-tools redis-server
741
 
987
 
742
     function_check install_postgresql
988
     function_check install_postgresql
743
     install_postgresql
989
     install_postgresql
772
     git checkout $PEERTUBE_COMMIT -b $PEERTUBE_COMMIT
1018
     git checkout $PEERTUBE_COMMIT -b $PEERTUBE_COMMIT
773
     set_completion_param "peertube commit" "$PEERTUBE_COMMIT"
1019
     set_completion_param "peertube commit" "$PEERTUBE_COMMIT"
774
 
1020
 
775
-    if ! npm install -g yarn; then
1021
+    if ! npm install -g yarn@1.5.1; then
776
         echo $'Failed to install yarn'
1022
         echo $'Failed to install yarn'
777
         exit 79353234
1023
         exit 79353234
778
     fi
1024
     fi
781
         echo $'Failed to run yarn install'
1027
         echo $'Failed to run yarn install'
782
         exit 63754235
1028
         exit 63754235
783
     fi
1029
     fi
1030
+    if ! npm install -g npm@4; then
1031
+        # https://github.com/KraigM/homebridge-harmonyhub/issues/119
1032
+        echo $'Failed to downgrade npm'
1033
+        exit 3476835
1034
+    fi
1035
+    cp /root/.npm-global/bin/npm /usr/local/bin/npm
784
     if ! npm install; then
1036
     if ! npm install; then
785
         echo $'Failed to install peertube'
1037
         echo $'Failed to install peertube'
786
         exit 7835243
1038
         exit 7835243
787
     fi
1039
     fi
1040
+    if ! npm install -g "npm@${NPM_VERSION}"; then
1041
+        echo $'Failed to restore npm after downgrade'
1042
+        exit 5737583
1043
+    fi
1044
+    cp /root/.npm-global/bin/npm /usr/local/bin/npm
788
     if ! npm run build; then
1045
     if ! npm run build; then
789
         echo $'Failed to build peertube'
1046
         echo $'Failed to build peertube'
790
         exit 5293593
1047
         exit 5293593
834
     # update the admin email address after creation of the database
1091
     # update the admin email address after creation of the database
835
     sed -i "s|email: .*|email: '$MY_EMAIL_ADDRESS'|g" $PEERTUBE_DIR/config/production.yaml
1092
     sed -i "s|email: .*|email: '$MY_EMAIL_ADDRESS'|g" $PEERTUBE_DIR/config/production.yaml
836
 
1093
 
1094
+    peertube_import_from_syncthing
1095
+
837
     set_completion_param "peertube domain" "$PEERTUBE_DOMAIN_NAME"
1096
     set_completion_param "peertube domain" "$PEERTUBE_DOMAIN_NAME"
838
     APP_INSTALLED=1
1097
     APP_INSTALLED=1
839
 }
1098
 }

+ 47
- 43
src/freedombone-app-pihole View File

37
 SHOW_ON_ABOUT=0
37
 SHOW_ON_ABOUT=0
38
 
38
 
39
 PIHOLE_IFACE=eth0
39
 PIHOLE_IFACE=eth0
40
-PIHOLE_DNS1='85.214.73.63'
41
-PIHOLE_DNS2='213.73.91.35'
40
+PIHOLE_DNS1='91.239.100.100'
41
+PIHOLE_DNS2='89.233.43.71'
42
 
42
 
43
 piholeBasename=pihole
43
 piholeBasename=pihole
44
 piholeDir=/etc/$piholeBasename
44
 piholeDir=/etc/$piholeBasename
134
 function pihole_change_upstream_dns {
134
 function pihole_change_upstream_dns {
135
     data=$(mktemp 2>/dev/null)
135
     data=$(mktemp 2>/dev/null)
136
     dialog --backtitle $"Ad Blocker Upstream DNS" \
136
     dialog --backtitle $"Ad Blocker Upstream DNS" \
137
-           --radiolist $"Pick a domain name service (DNS):" 28 50 19 \
138
-           1 $"Digital Courage" on \
139
-           2 $"German Privacy Foundation 1" off \
140
-           3 $"German Privacy Foundation 2" off \
141
-           4 $"Chaos Computer Club" off \
142
-           5 $"ClaraNet" off \
143
-           6 $"OpenNIC 1" off \
144
-           7 $"OpenNIC 2" off \
145
-           8 $"OpenNIC 3" off \
146
-           9 $"OpenNIC 4" off \
147
-           10 $"OpenNIC 5" off \
148
-           11 $"OpenNIC 6" off \
149
-           12 $"OpenNIC 7" off \
150
-           13 $"PowerNS" off \
151
-           14 $"ValiDOM" off \
152
-           15 $"Freie Unzensierte" off \
153
-           16 $"DNS.Watch" off \
154
-           17 $"uncensoreddns.org" off \
155
-           18 $"Lorraine Data Network" off \
156
-           19 $"Google" off 2> "$data"
137
+           --radiolist $"Pick a domain name service (DNS):" 29 50 20 \
138
+           1 $"UncensoredDNS" on \
139
+           2 $"Digital Courage" off \
140
+           3 $"German Privacy Foundation 1" off \
141
+           4 $"German Privacy Foundation 2" off \
142
+           5 $"Chaos Computer Club" off \
143
+           6 $"ClaraNet" off \
144
+           7 $"OpenNIC 1" off \
145
+           8 $"OpenNIC 2" off \
146
+           9 $"OpenNIC 3" off \
147
+           10 $"OpenNIC 4" off \
148
+           11 $"OpenNIC 5" off \
149
+           12 $"OpenNIC 6" off \
150
+           13 $"OpenNIC 7" off \
151
+           14 $"PowerNS" off \
152
+           15 $"ValiDOM" off \
153
+           16 $"Freie Unzensierte" off \
154
+           17 $"DNS.Watch" off \
155
+           18 $"uncensoreddns.org" off \
156
+           19 $"Lorraine Data Network" off \
157
+           20 $"Google" off 2> "$data"
157
     sel=$?
158
     sel=$?
158
     case $sel in
159
     case $sel in
159
         1) rm -f "$data"
160
         1) rm -f "$data"
162
              exit 1;;
163
              exit 1;;
163
     esac
164
     esac
164
     case $(cat "$data") in
165
     case $(cat "$data") in
165
-        1) PIHOLE_DNS1='85.214.73.63'
166
+        1) PIHOLE_DNS1='91.239.100.100'
167
+           PIHOLE_DNS2='89.233.43.71'
168
+           ;;
169
+        2) PIHOLE_DNS1='85.214.73.63'
166
            PIHOLE_DNS2='213.73.91.35'
170
            PIHOLE_DNS2='213.73.91.35'
167
            ;;
171
            ;;
168
-        2) PIHOLE_DNS1='87.118.100.175'
172
+        3) PIHOLE_DNS1='87.118.100.175'
169
            PIHOLE_DNS2='94.75.228.29'
173
            PIHOLE_DNS2='94.75.228.29'
170
            ;;
174
            ;;
171
-        3) PIHOLE_DNS1='85.25.251.254'
175
+        4) PIHOLE_DNS1='85.25.251.254'
172
            PIHOLE_DNS2='2.141.58.13'
176
            PIHOLE_DNS2='2.141.58.13'
173
            ;;
177
            ;;
174
-        4) PIHOLE_DNS1='213.73.91.35'
178
+        5) PIHOLE_DNS1='213.73.91.35'
175
            PIHOLE_DNS2='85.214.73.63'
179
            PIHOLE_DNS2='85.214.73.63'
176
            ;;
180
            ;;
177
-        5) PIHOLE_DNS1='212.82.225.7'
181
+        6) PIHOLE_DNS1='212.82.225.7'
178
            PIHOLE_DNS2='212.82.226.212'
182
            PIHOLE_DNS2='212.82.226.212'
179
            ;;
183
            ;;
180
-        6) PIHOLE_DNS1='58.6.115.42'
184
+        7) PIHOLE_DNS1='58.6.115.42'
181
            PIHOLE_DNS2='58.6.115.43'
185
            PIHOLE_DNS2='58.6.115.43'
182
            ;;
186
            ;;
183
-        7) PIHOLE_DNS1='119.31.230.42'
187
+        8) PIHOLE_DNS1='119.31.230.42'
184
            PIHOLE_DNS2='200.252.98.162'
188
            PIHOLE_DNS2='200.252.98.162'
185
            ;;
189
            ;;
186
-        8) PIHOLE_DNS1='217.79.186.148'
190
+        9) PIHOLE_DNS1='217.79.186.148'
187
            PIHOLE_DNS2='81.89.98.6'
191
            PIHOLE_DNS2='81.89.98.6'
188
            ;;
192
            ;;
189
-        9) PIHOLE_DNS1='78.159.101.37'
190
-           PIHOLE_DNS2='203.167.220.153'
191
-           ;;
192
-        10) PIHOLE_DNS1='82.229.244.191'
193
+        10) PIHOLE_DNS1='78.159.101.37'
194
+            PIHOLE_DNS2='203.167.220.153'
195
+            ;;
196
+        11) PIHOLE_DNS1='82.229.244.191'
193
             PIHOLE_DNS2='82.229.244.191'
197
             PIHOLE_DNS2='82.229.244.191'
194
             ;;
198
             ;;
195
-        11) PIHOLE_DNS1='216.87.84.211'
199
+        12) PIHOLE_DNS1='216.87.84.211'
196
             PIHOLE_DNS2='66.244.95.20'
200
             PIHOLE_DNS2='66.244.95.20'
197
             ;;
201
             ;;
198
-        12) PIHOLE_DNS1='207.192.69.155'
202
+        13) PIHOLE_DNS1='207.192.69.155'
199
             PIHOLE_DNS2='72.14.189.120'
203
             PIHOLE_DNS2='72.14.189.120'
200
             ;;
204
             ;;
201
-        13) PIHOLE_DNS1='194.145.226.26'
205
+        14) PIHOLE_DNS1='194.145.226.26'
202
             PIHOLE_DNS2='77.220.232.44'
206
             PIHOLE_DNS2='77.220.232.44'
203
             ;;
207
             ;;
204
-        14) PIHOLE_DNS1='78.46.89.147'
208
+        15) PIHOLE_DNS1='78.46.89.147'
205
             PIHOLE_DNS2='88.198.75.145'
209
             PIHOLE_DNS2='88.198.75.145'
206
             ;;
210
             ;;
207
-        15) PIHOLE_DNS1='85.25.149.144'
211
+        16) PIHOLE_DNS1='85.25.149.144'
208
             PIHOLE_DNS2='87.106.37.196'
212
             PIHOLE_DNS2='87.106.37.196'
209
             ;;
213
             ;;
210
-        16) PIHOLE_DNS1='84.200.69.80'
214
+        17) PIHOLE_DNS1='84.200.69.80'
211
             PIHOLE_DNS2='84.200.70.40'
215
             PIHOLE_DNS2='84.200.70.40'
212
             ;;
216
             ;;
213
-        17) PIHOLE_DNS1='91.239.100.100'
217
+        18) PIHOLE_DNS1='91.239.100.100'
214
             PIHOLE_DNS2='89.233.43.71'
218
             PIHOLE_DNS2='89.233.43.71'
215
             ;;
219
             ;;
216
-        18) PIHOLE_DNS1='80.67.188.188'
220
+        19) PIHOLE_DNS1='80.67.188.188'
217
             PIHOLE_DNS2='89.234.141.66'
221
             PIHOLE_DNS2='89.234.141.66'
218
             ;;
222
             ;;
219
-        19) PIHOLE_DNS1='8.8.8.8'
223
+        20) PIHOLE_DNS1='8.8.8.8'
220
             PIHOLE_DNS2='4.4.4.4'
224
             PIHOLE_DNS2='4.4.4.4'
221
             dialog --title $"WARNING" \
225
             dialog --title $"WARNING" \
222
                    --msgbox $"\\nGoogle's main purpose for providing DNS resolvers is to spy upon people and know which sites they are visiting.\\n\\nThis is something to consider, and you should only really be using Google DNS as a last resort if other resolvers are unavailable." 12 60
226
                    --msgbox $"\\nGoogle's main purpose for providing DNS resolvers is to spy upon people and know which sites they are visiting.\\n\\nThis is something to consider, and you should only really be using Google DNS as a last resort if other resolvers are unavailable." 12 60

+ 96
- 57
src/freedombone-app-pleroma View File

38
 PLEROMA_PORT=4000
38
 PLEROMA_PORT=4000
39
 PLEROMA_ONION_PORT=8011
39
 PLEROMA_ONION_PORT=8011
40
 PLEROMA_REPO="https://git.pleroma.social/pleroma/pleroma.git"
40
 PLEROMA_REPO="https://git.pleroma.social/pleroma/pleroma.git"
41
-PLEROMA_COMMIT='c50c7745bc8b8f52ba07c69c0d2505df54da0f59'
41
+PLEROMA_COMMIT='7130e9ddb16286efd7d01088e816f05e82cfa2a1'
42
 PLEROMA_ADMIN_PASSWORD=
42
 PLEROMA_ADMIN_PASSWORD=
43
 PLEROMA_DIR=/etc/pleroma
43
 PLEROMA_DIR=/etc/pleroma
44
 PLEROMA_SECRET_KEY=""
44
 PLEROMA_SECRET_KEY=""
674
     read_config_param PLEROMA_EXPIRE_MONTHS
674
     read_config_param PLEROMA_EXPIRE_MONTHS
675
     while true
675
     while true
676
     do
676
     do
677
-        data=$(mktemp 2>/dev/null)
678
-        dialog --backtitle $"Freedombone Control Panel" \
679
-               --title $"Pleroma" \
680
-               --radiolist $"Choose an operation:" 15 70 6 \
681
-               1 $"Set a background image" off \
682
-               2 $"Set the title" off \
683
-               3 $"Disable new account registrations" off \
684
-               4 $"Add a custom emoji" off \
685
-               5 $"Set post expiry period (currently $PLEROMA_EXPIRE_MONTHS months)" off \
686
-               6 $"Exit" on 2> "$data"
687
-        sel=$?
688
-        case $sel in
689
-            1) rm -f "$data"
690
-               return;;
691
-            255) rm -f "$data"
692
-                 return;;
693
-        esac
694
-        case $(cat "$data") in
677
+        W=(1 $"Set a background image"
678
+           2 $"Set the title"
679
+           3 $"Disable new account registrations"
680
+           4 $"Add a custom emoji"
681
+           5 $"Set post expiry period (currently $PLEROMA_EXPIRE_MONTHS months)")
682
+
683
+        # shellcheck disable=SC2068
684
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Pleroma" --menu $"Choose an operation, or ESC to exit:" 14 60 5 "${W[@]}" 3>&2 2>&1 1>&3)
685
+
686
+        if [ ! "$selection" ]; then
687
+            break
688
+        fi
689
+
690
+        case $selection in
695
             1) pleroma_set_background_image;;
691
             1) pleroma_set_background_image;;
696
             2) pleroma_set_title;;
692
             2) pleroma_set_title;;
697
             3) pleroma_disable_registrations;;
693
             3) pleroma_disable_registrations;;
698
             4) pleroma_add_emoji;;
694
             4) pleroma_add_emoji;;
699
             5) pleroma_set_expire_months;;
695
             5) pleroma_set_expire_months;;
700
-            6) rm -f "$data"
701
-               break;;
702
         esac
696
         esac
703
-        rm -f "$data"
704
     done
697
     done
705
 }
698
 }
706
 
699
 
1020
         function_check nginx_http_redirect
1013
         function_check nginx_http_redirect
1021
         nginx_http_redirect "$PLEROMA_DOMAIN_NAME" "index index.html"
1014
         nginx_http_redirect "$PLEROMA_DOMAIN_NAME" "index index.html"
1022
         { echo '';
1015
         { echo '';
1023
-        echo 'proxy_cache_path /tmp/pleroma-media-cache levels=1:2 keys_zone=pleroma_media_cache:10m max_size=100m inactive=80m use_temp_path=off;';
1024
-        echo '';
1025
-        echo 'server {';
1026
-        echo '  listen 443 ssl;';
1027
-        echo '  #listen [::]:443 ssl;';
1028
-        echo "  server_name $PLEROMA_DOMAIN_NAME;";
1029
-        echo ''; } >> "$pleroma_nginx_site"
1030
-        function_check nginx_compress
1031
-        nginx_compress "$PLEROMA_DOMAIN_NAME"
1032
-        echo '' >> "$pleroma_nginx_site"
1033
-        echo '  # Security' >> "$pleroma_nginx_site"
1016
+          echo 'proxy_cache_path /tmp/pleroma-media-cache levels=1:2 keys_zone=pleroma_media_cache:10m max_size=100m inactive=80m use_temp_path=off;';
1017
+          echo '';
1018
+          echo 'server {';
1019
+          echo '  listen 443 ssl http2;';
1020
+          echo '  #listen [::]:443 ssl http2;';
1021
+          echo "  server_name $PLEROMA_DOMAIN_NAME;";
1022
+          echo '';
1023
+          echo '  # Security'; } >> "$pleroma_nginx_site"
1034
         function_check nginx_ssl
1024
         function_check nginx_ssl
1035
         nginx_ssl "$PLEROMA_DOMAIN_NAME"
1025
         nginx_ssl "$PLEROMA_DOMAIN_NAME"
1036
 
1026
 
1046
           echo "  root $PLEROMA_DIR;";
1036
           echo "  root $PLEROMA_DIR;";
1047
           echo '';
1037
           echo '';
1048
           echo '  index index.html;';
1038
           echo '  index index.html;';
1049
-          echo '  location / {'; } >> "$pleroma_nginx_site"
1050
-        function_check nginx_limits
1051
-        nginx_limits "$PLEROMA_DOMAIN_NAME" '15m'
1052
-        { echo "    add_header 'Access-Control-Allow-Origin' '*';";
1039
+          echo '';
1040
+          echo '  gzip_vary on;';
1041
+          echo '  gzip_proxied any;';
1042
+          echo '  gzip_comp_level 6;';
1043
+          echo '  gzip_buffers 16 8k;';
1044
+          echo '  gzip_http_version 1.1;';
1045
+          echo '  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/activity+json application/atom+xml;';
1046
+          echo '';
1047
+          echo '  location / {';
1048
+          echo '    client_max_body_size 15m;';
1049
+          echo '    client_body_buffer_size 15m;';
1050
+          echo '';
1051
+          echo '    limit_conn conn_limit_per_ip 50;';
1052
+          echo '    limit_req zone=req_limit_per_ip burst=50 nodelay;';
1053
+          echo '';
1054
+          echo "    add_header 'Access-Control-Allow-Origin' '*' always;";
1055
+          echo "    add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always;";
1056
+          echo "    add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;";
1057
+          echo "    if (\$request_method = OPTIONS) {";
1058
+          echo '        return 204;';
1059
+          echo '    }';
1060
+          echo '';
1053
           echo '    proxy_http_version 1.1;';
1061
           echo '    proxy_http_version 1.1;';
1054
           echo "    proxy_set_header Upgrade \$http_upgrade;";
1062
           echo "    proxy_set_header Upgrade \$http_upgrade;";
1055
           echo '    proxy_set_header Connection "upgrade";';
1063
           echo '    proxy_set_header Connection "upgrade";';
1058
           echo "    proxy_pass http://localhost:$PLEROMA_PORT;";
1066
           echo "    proxy_pass http://localhost:$PLEROMA_PORT;";
1059
           echo '  }';
1067
           echo '  }';
1060
           echo '';
1068
           echo '';
1061
-          echo '  location /proxy {'; } >> "$pleroma_nginx_site"
1062
-        nginx_limits "$PLEROMA_DOMAIN_NAME" '15m'
1063
-        { echo '    proxy_cache pleroma_media_cache;';
1069
+          echo '  location /proxy {';
1070
+          echo '    client_max_body_size 15m;';
1071
+          echo '    client_body_buffer_size 15m;';
1072
+          echo '';
1073
+          echo '    limit_conn conn_limit_per_ip 50;';
1074
+          echo '    limit_req zone=req_limit_per_ip burst=50 nodelay;';
1075
+          echo '';
1076
+          echo '    proxy_cache pleroma_media_cache;';
1064
           echo '    proxy_cache_lock on;';
1077
           echo '    proxy_cache_lock on;';
1065
           echo "    proxy_pass http://localhost:$PLEROMA_PORT;";
1078
           echo "    proxy_pass http://localhost:$PLEROMA_PORT;";
1066
           echo '  }';
1079
           echo '  }';
1071
         echo '' >> "$pleroma_nginx_site"
1084
         echo '' >> "$pleroma_nginx_site"
1072
     fi
1085
     fi
1073
     { echo 'server {';
1086
     { echo 'server {';
1074
-      echo "    listen 127.0.0.1:$PLEROMA_ONION_PORT default_server;";
1087
+      echo "    listen 127.0.0.1:$PLEROMA_ONION_PORT default_server http2;";
1075
       echo "    server_name $PLEROMA_ONION_HOSTNAME;";
1088
       echo "    server_name $PLEROMA_ONION_HOSTNAME;";
1076
       echo ''; } >> "$pleroma_nginx_site"
1089
       echo ''; } >> "$pleroma_nginx_site"
1077
-    function_check nginx_compress
1078
-    nginx_compress "$PLEROMA_DOMAIN_NAME"
1079
-    echo '' >> "$pleroma_nginx_site"
1080
     function_check nginx_security_options
1090
     function_check nginx_security_options
1081
     nginx_security_options "$PLEROMA_DOMAIN_NAME"
1091
     nginx_security_options "$PLEROMA_DOMAIN_NAME"
1082
     { echo '';
1092
     { echo '';
1087
       echo "  root $PLEROMA_DIR;";
1097
       echo "  root $PLEROMA_DIR;";
1088
       echo '';
1098
       echo '';
1089
       echo '  index index.html;';
1099
       echo '  index index.html;';
1090
-      echo '  location / {'; } >> "$pleroma_nginx_site"
1091
-    function_check nginx_limits
1092
-    nginx_limits "$PLEROMA_DOMAIN_NAME" '15m'
1093
-    { echo "      add_header 'Access-Control-Allow-Origin' '*';";
1094
-      echo '      proxy_http_version 1.1;';
1095
-      echo "      proxy_set_header Upgrade \$http_upgrade;";
1096
-      echo '      proxy_set_header Connection "upgrade";';
1097
-      echo "      proxy_set_header Host \$http_host;";
1098
       echo '';
1100
       echo '';
1099
-      echo "      proxy_pass http://localhost:$PLEROMA_PORT;";
1101
+      echo '  gzip_vary on;';
1102
+      echo '  gzip_proxied any;';
1103
+      echo '  gzip_comp_level 6;';
1104
+      echo '  gzip_buffers 16 8k;';
1105
+      echo '  gzip_http_version 1.1;';
1106
+      echo '  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript application/activity+json application/atom+xml;';
1107
+      echo '';
1108
+      echo '  location / {';
1109
+      echo '    client_max_body_size 15m;';
1110
+      echo '    client_body_buffer_size 15m;';
1111
+      echo '';
1112
+      echo '    limit_conn conn_limit_per_ip 50;';
1113
+      echo '    limit_req zone=req_limit_per_ip burst=50 nodelay;';
1114
+      echo '';
1115
+      echo "    add_header 'Access-Control-Allow-Origin' '*' always;";
1116
+      echo "    add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS' always;";
1117
+      echo "    add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type' always;";
1118
+      echo "    if (\$request_method = OPTIONS) {";
1119
+      echo '        return 204;';
1120
+      echo '    }';
1121
+      echo '';
1122
+      echo '    proxy_http_version 1.1;';
1123
+      echo "    proxy_set_header Upgrade \$http_upgrade;";
1124
+      echo '    proxy_set_header Connection "upgrade";';
1125
+      echo "    proxy_set_header Host \$http_host;";
1126
+      echo '';
1127
+      echo "    proxy_pass http://localhost:$PLEROMA_PORT;";
1100
       echo '  }';
1128
       echo '  }';
1101
       echo '';
1129
       echo '';
1102
-      echo '  location /proxy {'; } >> "$pleroma_nginx_site"
1103
-    nginx_limits "$PLEROMA_DOMAIN_NAME" '15m'
1104
-    { echo '    proxy_cache pleroma_media_cache;';
1130
+      echo '  location /proxy {';
1131
+      echo '    client_max_body_size 15m;';
1132
+      echo '    client_body_buffer_size 15m;';
1133
+      echo '';
1134
+      echo '    limit_conn conn_limit_per_ip 50;';
1135
+      echo '    limit_req zone=req_limit_per_ip burst=50 nodelay;';
1136
+      echo '';
1137
+      echo '    proxy_cache pleroma_media_cache;';
1105
       echo '    proxy_cache_lock on;';
1138
       echo '    proxy_cache_lock on;';
1106
       echo "    proxy_pass http://localhost:$PLEROMA_PORT;";
1139
       echo "    proxy_pass http://localhost:$PLEROMA_PORT;";
1107
       echo '  }';
1140
       echo '  }';
1185
       echo 'WantedBy=multi-user.target';
1218
       echo 'WantedBy=multi-user.target';
1186
       echo 'Alias=pleroma.service'; } > /etc/systemd/system/pleroma.service
1219
       echo 'Alias=pleroma.service'; } > /etc/systemd/system/pleroma.service
1187
 
1220
 
1221
+
1222
+    # avoid mixed content warnings
1223
+    sed -i '/config :pleroma, :media_proxy/!b;n;c####enabled: true,' $PLEROMA_DIR/config/config.exs
1224
+    sed -i 's|####enabled|  enabled|g' $PLEROMA_DIR/config/config.exs
1225
+    sed -i 's|redirect_on_failure:.*|redirect_on_failure: false|g' $PLEROMA_DIR/config/config.exs
1226
+
1188
     # set registrations open initially
1227
     # set registrations open initially
1189
     sed -i 's|registrations_open:.*|registrations_open: true,|g' $PLEROMA_DIR/config/config.exs
1228
     sed -i 's|registrations_open:.*|registrations_open: true,|g' $PLEROMA_DIR/config/config.exs
1190
     sed -i 's|"registrationOpen":.*|"registrationOpen": true,|g' $PLEROMA_DIR/priv/static/static/config.json
1229
     sed -i 's|"registrationOpen":.*|"registrationOpen": true,|g' $PLEROMA_DIR/priv/static/static/config.json
1191
 
1230
 
1192
     if ! grep -q "media_proxy" $PLEROMA_DIR/priv/static/static/config.json; then
1231
     if ! grep -q "media_proxy" $PLEROMA_DIR/priv/static/static/config.json; then
1193
-        sed -i '/"name":/a "media_proxy": false,' $PLEROMA_DIR/priv/static/static/config.json
1232
+        sed -i '/"name":/a "media_proxy": true,' $PLEROMA_DIR/priv/static/static/config.json
1194
         sed -i 's|"media_proxy"|  "media_proxy"|g' $PLEROMA_DIR/priv/static/static/config.json
1233
         sed -i 's|"media_proxy"|  "media_proxy"|g' $PLEROMA_DIR/priv/static/static/config.json
1195
     else
1234
     else
1196
         sed -i 's|"media_proxy".*|"media_proxy": false,|g' $PLEROMA_DIR/priv/static/static/config.json
1235
         sed -i 's|"media_proxy".*|"media_proxy": false,|g' $PLEROMA_DIR/priv/static/static/config.json

+ 15
- 22
src/freedombone-app-postactiv View File

320
     read_config_param "POSTACTIV_EXPIRE_MONTHS"
320
     read_config_param "POSTACTIV_EXPIRE_MONTHS"
321
     while true
321
     while true
322
     do
322
     do
323
-        data=$(mktemp 2>/dev/null)
324
-        dialog --backtitle $"Freedombone Control Panel" \
325
-               --title $"PostActiv" \
326
-               --radiolist $"Choose an operation:" 16 70 7 \
327
-               1 $"Set a background image" off \
328
-               2 $"Set the title" off \
329
-               3 $"Set post expiry period (currently $POSTACTIV_EXPIRE_MONTHS months)" off \
330
-               4 $"Select Qvitter user interface" off \
331
-               5 $"Select Pleroma user interface" off \
332
-               6 $"Select Classic user interface" off \
333
-               7 $"Exit" on 2> "$data"
334
-        sel=$?
335
-        case $sel in
336
-            1) rm -f "$data"
337
-               return;;
338
-            255) rm -f "$data"
339
-                 return;;
340
-        esac
341
-        case $(cat "$data") in
323
+        W=(1 $"Set a background image"
324
+           2 $"Set the title"
325
+           3 $"Set post expiry period (currently $POSTACTIV_EXPIRE_MONTHS months)"
326
+           4 $"Select Qvitter user interface"
327
+           5 $"Select Pleroma user interface"
328
+           6 $"Select Classic user interface")
329
+
330
+        # shellcheck disable=SC2068
331
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"PostActiv" --menu $"Choose an operation, or ESC to exit:" 15 60 6 "${W[@]}" 3>&2 2>&1 1>&3)
332
+
333
+        if [ ! "$selection" ]; then
334
+            break
335
+        fi
336
+
337
+        case $selection in
342
             1) postactiv_set_background_image;;
338
             1) postactiv_set_background_image;;
343
             2) postactiv_set_title;;
339
             2) postactiv_set_title;;
344
             3) postactiv_set_expire_months;;
340
             3) postactiv_set_expire_months;;
345
             4) gnusocial_use_qvitter postactiv;;
341
             4) gnusocial_use_qvitter postactiv;;
346
             5) gnusocial_use_pleroma postactiv;;
342
             5) gnusocial_use_pleroma postactiv;;
347
             6) gnusocial_use_classic postactiv;;
343
             6) gnusocial_use_classic postactiv;;
348
-            7) rm -f "$data"
349
-               break;;
350
         esac
344
         esac
351
-        rm -f "$data"
352
     done
345
     done
353
 }
346
 }
354
 
347
 

+ 26
- 23
src/freedombone-app-scuttlebot View File

67
 }
67
 }
68
 
68
 
69
 function configure_interactive_scuttlebot {
69
 function configure_interactive_scuttlebot {
70
+    W=(1 $"Create an invite")
71
+
70
     while true
72
     while true
71
     do
73
     do
72
-        data=$(mktemp 2>/dev/null)
73
-        dialog --backtitle $"Freedombone Control Panel" \
74
-               --title $"Scuttlebot" \
75
-               --radiolist $"Choose an operation:" 10 50 2 \
76
-               1 $"Create an invite" off \
77
-               2 $"Exit" on 2> "$data"
78
-        sel=$?
79
-        case $sel in
80
-            1) rm -f "$data"
81
-               return;;
82
-            255) rm -f "$data"
83
-                 return;;
84
-        esac
85
-        case $(cat "$data") in
74
+        # shellcheck disable=SC2068
75
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Scuttlebot" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
76
+
77
+        if [ ! "$selection" ]; then
78
+            break
79
+        fi
80
+
81
+        case $selection in
86
             1) scuttlebot_create_invite;;
82
             1) scuttlebot_create_invite;;
87
-            2) rm -f "$data"
88
-               break;;
89
         esac
83
         esac
90
-        rm -f "$data"
91
     done
84
     done
92
 }
85
 }
93
 
86
 
450
         mkdir -p /etc/scuttlebot
443
         mkdir -p /etc/scuttlebot
451
     fi
444
     fi
452
 
445
 
446
+    npm install -g dat
447
+
453
     # an unprivileged user to run as
448
     # an unprivileged user to run as
454
     useradd -d /etc/scuttlebot/ scuttlebot
449
     useradd -d /etc/scuttlebot/ scuttlebot
455
 
450
 
488
         exit 73528
483
         exit 73528
489
     fi
484
     fi
490
 
485
 
491
-    { echo '{';
492
-      echo "  \"host\": \"${DEFAULT_DOMAIN_NAME}\",";
493
-      echo "  \"port\": ${SCUTTLEBOT_PORT},";
486
+    SCUTTLEBOT_ONION_HOSTNAME=$(add_onion_service scuttlebot 80 ${SCUTTLEBOT_ONION_PORT})
487
+
488
+    if [[ "$ONION_ONLY" == 'no' ]]; then
489
+        { echo '{';
490
+          echo "  \"host\": \"${DEFAULT_DOMAIN_NAME}\",";
491
+          echo '  "tor-only": false,'; } > /etc/scuttlebot/.ssb/config
492
+    else
493
+        { echo '{';
494
+          echo "  \"host\": \"${SCUTTLEBOT_ONION_HOSTNAME}\",";
495
+          echo '  "tor-only": true,'; } > /etc/scuttlebot/.ssb/config
496
+    fi
497
+
498
+    { echo "  \"port\": ${SCUTTLEBOT_PORT},";
494
       echo '  "timeout": 30000,';
499
       echo '  "timeout": 30000,';
495
       echo '  "pub": true,';
500
       echo '  "pub": true,';
496
       echo '  "local": true,';
501
       echo '  "local": true,';
505
       echo '  "logging": {';
510
       echo '  "logging": {';
506
       echo '    "level": "error"';
511
       echo '    "level": "error"';
507
       echo '  }';
512
       echo '  }';
508
-      echo '}'; } > /etc/scuttlebot/.ssb/config
513
+      echo '}'; } >> /etc/scuttlebot/.ssb/config
509
     chown scuttlebot:scuttlebot /etc/scuttlebot/.ssb/config
514
     chown scuttlebot:scuttlebot /etc/scuttlebot/.ssb/config
510
     systemctl restart scuttlebot.service
515
     systemctl restart scuttlebot.service
511
 
516
 
512
     firewall_add scuttlebot ${SCUTTLEBOT_PORT}
517
     firewall_add scuttlebot ${SCUTTLEBOT_PORT}
513
     firewall_add git_ssb ${GIT_SSB_PORT}
518
     firewall_add git_ssb ${GIT_SSB_PORT}
514
 
519
 
515
-
516
-    SCUTTLEBOT_ONION_HOSTNAME=$(add_onion_service scuttlebot 80 ${SCUTTLEBOT_ONION_PORT})
517
     scuttlebot_git_setup
520
     scuttlebot_git_setup
518
     git_ssb_script
521
     git_ssb_script
519
 
522
 

+ 11
- 18
src/freedombone-app-searx View File

175
 }
175
 }
176
 
176
 
177
 function configure_interactive_searx {
177
 function configure_interactive_searx {
178
+    W=(1 $"Set a background image"
179
+       2 $"Enable login")
180
+
178
     while true
181
     while true
179
     do
182
     do
180
-        data=$(mktemp 2>/dev/null)
181
-        dialog --backtitle $"Freedombone Control Panel" \
182
-               --title $"SearX Metasearch" \
183
-               --radiolist $"Choose an operation:" 12 70 3 \
184
-               1 $"Set a background image" off \
185
-               2 $"Enable login" off \
186
-               3 $"Exit" on 2> "$data"
187
-        sel=$?
188
-        case $sel in
189
-            1) rm -f "$data"
190
-               return;;
191
-            255) rm -f "$data"
192
-                 return;;
193
-        esac
194
-        case $(cat "$data") in
183
+        # shellcheck disable=SC2068
184
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"SearX" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
185
+
186
+        if [ ! "$selection" ]; then
187
+            break
188
+        fi
189
+
190
+        case $selection in
195
             1) searx_set_background_image;;
191
             1) searx_set_background_image;;
196
             2) searx_enable_login;;
192
             2) searx_enable_login;;
197
-            3) rm -f "$data"
198
-               break;;
199
         esac
193
         esac
200
-        rm -f "$data"
201
     done
194
     done
202
 }
195
 }
203
 
196
 

+ 19
- 21
src/freedombone-app-tahoelafs View File

188
 }
188
 }
189
 
189
 
190
 function configure_interactive_tahoelafs {
190
 function configure_interactive_tahoelafs {
191
-    data=$(mktemp 2>/dev/null)
192
-    dialog --backtitle $"Freedombone Configuration" \
193
-           --title $"Tahoe-LAFS" \
194
-           --radiolist $"The least authority is always the best" 11 50 5 \
195
-           1 "Add a storage node" off \
196
-           2 "Manually edit storage nodes" off \
197
-           3 "Shares settings" off \
198
-           4 "Back to main menu" on 2> "$data"
199
-    sel=$?
200
-    case $sel in
201
-        1) rm -f "$data"
202
-           exit 1;;
203
-        255) rm -f "$data"
204
-             exit 1;;
205
-    esac
206
-    case $(cat "$data") in
207
-        1) add_tahoelafs_storage_node_interactive;;
208
-        2) edit_tahoelafs_nodes;;
209
-        3) edit_tahoelafs_shares;;
210
-    esac
211
-    rm -f "$data"
191
+    W=(1 $"Add a storage node"
192
+       2 $"Manually edit storage nodes"
193
+       3 $"Shares settings")
194
+
195
+    while true
196
+    do
197
+        # shellcheck disable=SC2068
198
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"Tahoe-LAFS" --menu $"Choose an operation, or ESC to exit:" 12 60 3 "${W[@]}" 3>&2 2>&1 1>&3)
199
+
200
+        if [ ! "$selection" ]; then
201
+            break
202
+        fi
203
+
204
+        case $selection in
205
+            1) add_tahoelafs_storage_node_interactive;;
206
+            2) edit_tahoelafs_nodes;;
207
+            3) edit_tahoelafs_shares;;
208
+        esac
209
+    done
212
 }
210
 }
213
 
211
 
214
 function tahoelafs_setup_client_config {
212
 function tahoelafs_setup_client_config {

+ 13
- 20
src/freedombone-app-vpn View File

201
     read_config_param VPN_TLS_PORT
201
     read_config_param VPN_TLS_PORT
202
     while true
202
     while true
203
     do
203
     do
204
-        data=$(mktemp 2>/dev/null)
205
-        dialog --backtitle $"Freedombone Control Panel" \
206
-               --title $"VPN Configuration" \
207
-               --radiolist $"Choose an operation:" 13 70 3 \
208
-               1 $"Change TLS port (currently $VPN_TLS_PORT)" off \
209
-               2 $"Regenerate keys for a user" off \
210
-               3 $"Exit" on 2> "$data"
211
-        sel=$?
212
-        case $sel in
213
-            1) rm -f "$data"
214
-               return;;
215
-            255) rm -f "$data"
216
-                 return;;
217
-        esac
218
-        case $(cat "$data") in
204
+        W=(1 $"Change TLS port (currently $VPN_TLS_PORT)"
205
+           2 $"Regenerate keys for a user")
206
+
207
+        # shellcheck disable=SC2068
208
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"VPN" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
209
+
210
+        if [ ! "$selection" ]; then
211
+            break
212
+        fi
213
+
214
+        case $selection in
219
             1) vpn_change_tls_port;;
215
             1) vpn_change_tls_port;;
220
             2) vpn_regenerate_client_keys;;
216
             2) vpn_regenerate_client_keys;;
221
-            3) rm -f "$data"
222
-               break;;
223
         esac
217
         esac
224
-        rm -f "$data"
225
     done
218
     done
226
 }
219
 }
227
 
220
 
688
       echo 'dh /etc/openvpn/dh2048.pem';
681
       echo 'dh /etc/openvpn/dh2048.pem';
689
       echo 'server 10.8.0.0 255.255.255.0';
682
       echo 'server 10.8.0.0 255.255.255.0';
690
       echo 'push "redirect-gateway def1 bypass-dhcp"';
683
       echo 'push "redirect-gateway def1 bypass-dhcp"';
691
-      echo "push \"dhcp-option DNS 85.214.73.63\"";
692
-      echo "push \"dhcp-option DNS 213.73.91.35\"";
684
+      echo "push \"dhcp-option DNS 91.239.100.100\"";
685
+      echo "push \"dhcp-option DNS 89.233.43.71\"";
693
       echo 'keepalive 5 30';
686
       echo 'keepalive 5 30';
694
       echo 'comp-lzo';
687
       echo 'comp-lzo';
695
       echo 'persist-key';
688
       echo 'persist-key';

+ 12
- 18
src/freedombone-app-xmpp View File

181
 }
181
 }
182
 
182
 
183
 function configure_interactive_xmpp {
183
 function configure_interactive_xmpp {
184
+    W=(1 $"Add an ICANN to onion domain mapping"
185
+       2 $"Remove an ICANN to onion domain mapping")
186
+
184
     while true
187
     while true
185
     do
188
     do
186
-        data=$(mktemp 2>/dev/null)
187
-        dialog --backtitle $"Freedombone Control Panel" \
188
-               --title $"XMPP" \
189
-               --radiolist $"Choose an operation:" 12 70 3 \
190
-               1 $"Add an ICANN to onion domain mapping" off \
191
-               2 $"Remove an ICANN to onion domain mapping" off \
192
-               3 $"Return to administrator control panel" on 2> "$data"
193
-        sel=$?
194
-        case $sel in
195
-            1) rm -f "$data"
196
-               return;;
197
-            255) rm -f "$data"
198
-                 return;;
199
-        esac
200
-        case $(cat "$data") in
189
+        # shellcheck disable=SC2068
190
+        selection=$(dialog --backtitle $"Freedombone Administrator Control Panel" --title $"XMPP" --menu $"Choose an operation, or ESC to exit:" 10 60 2 "${W[@]}" 3>&2 2>&1 1>&3)
191
+
192
+        if [ ! "$selection" ]; then
193
+            break
194
+        fi
195
+
196
+        case $selection in
201
             1) xmpp_add_onion_address_interactive;;
197
             1) xmpp_add_onion_address_interactive;;
202
             2) xmpp_remove_onion_address_interactive;;
198
             2) xmpp_remove_onion_address_interactive;;
203
-            3) rm -f "$data"
204
-               break;;
205
         esac
199
         esac
206
-        rm -f "$data"
207
     done
200
     done
208
 }
201
 }
209
 
202
 
619
     remove_onion_service xmpp 5222 5223 5269
612
     remove_onion_service xmpp 5222 5223 5269
620
     sed -i '/HiddenServiceVersion 2/d' /etc/tor/torrc
613
     sed -i '/HiddenServiceVersion 2/d' /etc/tor/torrc
621
 
614
 
615
+    apt-mark -q unhold prosody
622
     apt-get -yq remove --purge prosody
616
     apt-get -yq remove --purge prosody
623
     rm /etc/cron.daily/prosody
617
     rm /etc/cron.daily/prosody
624
     if [ -f "$INSTALL_DIR/$prosody_modules_filename" ]; then
618
     if [ -f "$INSTALL_DIR/$prosody_modules_filename" ]; then

+ 177
- 38
src/freedombone-base-email View File

31
 # the default email address
31
 # the default email address
32
 MY_EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME
32
 MY_EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME
33
 
33
 
34
+# When sending mail to riseup.net route to this onion address
35
+RISEUP_EMAIL_ONION='wy6zk3pmcwiyhiao.onion'
36
+
34
 # If you want to run a public mailing list specify its name here.
37
 # If you want to run a public mailing list specify its name here.
35
 # There should be no spaces in the name
38
 # There should be no spaces in the name
36
 PUBLIC_MAILING_LIST=
39
 PUBLIC_MAILING_LIST=
68
 # refresh gpg keys every few hours
71
 # refresh gpg keys every few hours
69
 REFRESH_GPG_KEYS_HOURS=2
72
 REFRESH_GPG_KEYS_HOURS=2
70
 
73
 
74
+exim_version='4.89'
75
+
76
+function rebuild_exim_with_socks {
77
+    exim_socks_installed=$(get_completion_param "exim_socks")
78
+    if [[ "$exim_socks_installed" == 'true' ]]; then
79
+        return
80
+    fi
81
+
82
+    # shellcheck disable=SC2154
83
+    if [ ! -d "$INSTALL_DIR/exim4" ]; then
84
+        mkdir -p "$INSTALL_DIR/exim4"
85
+    fi
86
+    cd "$INSTALL_DIR/exim4" || exit 3468356
87
+    rm -rf "$INSTALL_DIR/exim4/"*
88
+    apt-get -qy install build-essential fakeroot devscripts
89
+    apt-get source exim4-daemon-heavy
90
+    apt-get -qy build-dep exim4-daemon-heavy
91
+    cd "${INSTALL_DIR}/exim4/exim4-${exim_version}" || exit 356835685
92
+
93
+    { echo 'Description: Socks proxying';
94
+      echo ' Support for socks proxying of outgoing mail';
95
+      echo ' This is to support onion email addresses, which require support for SOCKS5';
96
+      echo ' .';
97
+      echo " exim4 (${exim_version}-2+deb9u3) stretch-security; urgency=high";
98
+      echo ' .';
99
+      echo '   * Non-maintainer upload by the Security Team.';
100
+      echo '   * Fix base64d() buffer size (CVE-2018-6789) (Closes: #890000)';
101
+      echo 'Author: Salvatore Bonaccorso <carnil@debian.org>';
102
+      echo 'Bug-Debian: https://bugs.debian.org/890000';
103
+      echo '';
104
+      echo '---';
105
+      echo 'The information above should follow the Patch Tagging Guidelines, please';
106
+      echo 'checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here';
107
+      echo 'are templates for supplementary fields that you might want to add:';
108
+      echo '';
109
+      echo 'Origin: <vendor|upstream|other>, <url of original patch>';
110
+      echo 'Bug: <url in upstream bugtracker>';
111
+      echo 'Bug-Debian: https://bugs.debian.org/<bugnumber>';
112
+      echo 'Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>';
113
+      echo 'Forwarded: <no|not-needed|url proving that it has been forwarded>';
114
+      echo 'Reviewed-By: <name and email of someone who approved the patch>';
115
+      echo "Last-Update: $(date +%Y-%m-%d)";
116
+      echo '';
117
+      echo '--- /dev/null';
118
+      echo "+++ exim4-${exim_version}/Local/Makefile";
119
+      echo '@@ -0,0 +1,32 @@';
120
+      echo '+BIN_DIRECTORY=/usr/exim/bin';
121
+      echo '+CONFIGURE_FILE=/usr/exim/configure';
122
+      echo '+EXIM_USER=';
123
+      echo '+SPOOL_DIRECTORY=/var/spool/exim';
124
+      echo '+ROUTER_ACCEPT=yes';
125
+      echo '+ROUTER_DNSLOOKUP=yes';
126
+      echo '+ROUTER_IPLITERAL=yes';
127
+      echo '+ROUTER_MANUALROUTE=yes';
128
+      echo '+ROUTER_QUERYPROGRAM=yes';
129
+      echo '+ROUTER_REDIRECT=yes';
130
+      echo '+TRANSPORT_APPENDFILE=yes';
131
+      echo '+TRANSPORT_AUTOREPLY=yes';
132
+      echo '+TRANSPORT_PIPE=yes';
133
+      echo '+TRANSPORT_SMTP=yes';
134
+      echo '+LOOKUP_DBM=yes';
135
+      echo '+LOOKUP_LSEARCH=yes';
136
+      echo '+LOOKUP_DNSDB=yes';
137
+      echo '+PCRE_CONFIG=yes';
138
+      echo '+EXIM_MONITOR=eximon.bin';
139
+      echo '+FIXED_NEVER_USERS=root';
140
+      echo '+HEADERS_CHARSET="ISO-8859-1"';
141
+      echo '+DLOPEN_LOCAL_SCAN=yes';
142
+      echo '+LDFLAGS += -rdynamic';
143
+      echo '+CFLAGS += -fvisibility=hidden';
144
+      echo '+SYSLOG_LOG_PID=yes';
145
+      echo '+EXICYCLOG_MAX=10';
146
+      echo '+COMPRESS_COMMAND=/usr/bin/gzip';
147
+      echo '+COMPRESS_SUFFIX=gz';
148
+      echo '+ZCAT_COMMAND=/usr/bin/zcat';
149
+      echo '+SUPPORT_SOCKS=yes';
150
+      echo '+SYSTEM_ALIASES_FILE=/etc/aliases';
151
+      echo '+EXIM_TMPDIR="/tmp"'; } > debian/patches/SOCKS
152
+
153
+    debuild -us -uc
154
+    cd "$INSTALL_DIR/exim4" || exit 3468356
155
+    mv exim4_${exim_version}-*.deb exim4_${exim_version}_all.deb
156
+    if [ ! -f exim4_${exim_version}_all.deb ]; then
157
+        ls -l "$INSTALL_DIR/exim4/exim4_"*.deb
158
+        echo "exim4_${exim_version}_all.deb not found"
159
+        exit 63857368
160
+    fi
161
+    apt-mark -q unhold exim4
162
+    dpkg -i exim4_${exim_version}_all.deb
163
+    apt-mark -q hold exim4
164
+    apt-get -yq remove --purge at
165
+
166
+    systemctl restart exim4
167
+    if [[ $(systemctl is-active exim4) != 'active' ]]; then
168
+        apt-mark -q unhold exim4
169
+        apt-get -yq install exim4 --reinstall
170
+        systemctl restart exim4
171
+    fi
172
+
173
+    rm -rf "$INSTALL_DIR/exim4"
174
+
175
+    set_completion_param "exim_socks" "true"
176
+}
177
+
71
 function email_create_template {
178
 function email_create_template {
72
     if [ ! -d /etc/skel/log ]; then
179
     if [ ! -d /etc/skel/log ]; then
73
         mkdir -m 700 /etc/skel/log
180
         mkdir -m 700 /etc/skel/log
117
     fi
224
     fi
118
 }
225
 }
119
 
226
 
120
-function configure_email_onion {
121
-    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
122
-        return
123
-    fi
124
-    if [[ "$SYSTEM_TYPE" == "mesh"* ]]; then
125
-        return
126
-    fi
127
-
227
+function create_email_onion_address {
128
     if ! grep -q "hidden_service_email" /etc/tor/torrc; then
228
     if ! grep -q "hidden_service_email" /etc/tor/torrc; then
129
         { echo 'HiddenServiceDir /var/lib/tor/hidden_service_email/';
229
         { echo 'HiddenServiceDir /var/lib/tor/hidden_service_email/';
230
+          echo 'HiddenServiceVersion 3';
130
           echo 'HiddenServicePort 25 127.0.0.1:25';
231
           echo 'HiddenServicePort 25 127.0.0.1:25';
131
           echo 'HiddenServicePort 587 127.0.0.1:587';
232
           echo 'HiddenServicePort 587 127.0.0.1:587';
132
           echo 'HiddenServicePort 465 127.0.0.1:465'; } >> /etc/tor/torrc
233
           echo 'HiddenServicePort 465 127.0.0.1:465'; } >> /etc/tor/torrc
133
-    fi
134
 
234
 
135
-    function_check onion_update
136
-    onion_update
235
+        function_check onion_update
236
+        onion_update
137
 
237
 
138
-    function_check wait_for_onion_service
139
-    wait_for_onion_service email
238
+        function_check wait_for_onion_service
239
+        wait_for_onion_service email
140
 
240
 
141
-    if [ ! -f /var/lib/tor/hidden_service_email/hostname ]; then
142
-        echo $"email onion site hostname not found"
143
-        systemctl restart tor
144
-        exit 782352
241
+        if [ ! -f /var/lib/tor/hidden_service_email/hostname ]; then
242
+            echo $"email onion site hostname not found"
243
+            systemctl restart tor
244
+            exit 782352
245
+        fi
246
+
247
+        onion_address=$(cat /var/lib/tor/hidden_service_email/hostname)
248
+        set_completion_param "email onion domain" "${onion_address}"
249
+        add_email_hostname "$onion_address"
250
+    else
251
+        onion_address=$(cat /var/lib/tor/hidden_service_email/hostname)
252
+    fi
253
+}
254
+
255
+function configure_email_onion {
256
+    if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
257
+        return
258
+    fi
259
+    if [[ "$SYSTEM_TYPE" == "mesh"* ]]; then
260
+        return
145
     fi
261
     fi
146
 
262
 
147
-    onion_address=$(cat /var/lib/tor/hidden_service_email/hostname)
148
-    set_completion_param "email onion domain" "${onion_address}"
149
-    add_email_hostname "$onion_address"
263
+    create_email_onion_address
150
 
264
 
151
-    apt-get -yq install tinycdb perl
265
+    #apt-get -yq install tinycdb perl
152
 
266
 
153
     # MX record should be:
267
     # MX record should be:
154
-    # _onion-mx._tcp.$DEFAULT_DOMAIN_NAME. 3600 IN SRV 0 5 25 $onion_address
268
+    # _onion-mx._tcp
269
+    # 20:$onion_address
270
+    # 3600 IN SRV 0 5 25 $onion_address
271
+
272
+    # Test with: exim -d -bt username@$onion_address
155
 
273
 
156
-    echo "$DEFAULT_DOMAIN_NAME $onion_address" > /etc/exim4/onionrelay.txt
157
-    cdb -m -c -t ~/onionrelay.tmp /etc/exim4/onionrelay.cdb /etc/exim4/onionrelay.txt
274
+    #echo "$DEFAULT_DOMAIN_NAME $onion_address" > /etc/exim4/onionrelay.txt
275
+    #cdb -m -c -t ~/onionrelay.tmp /etc/exim4/onionrelay.cdb /etc/exim4/onionrelay.txt
158
 
276
 
159
     { echo "perl_startup = do '/etc/exim4/perl-routines.pl'";
277
     { echo "perl_startup = do '/etc/exim4/perl-routines.pl'";
160
-      echo "perl_at_start"; } > /etc/exim4/conf.d/main/perl
278
+      echo "perl_at_start"; } > /etc/exim4/conf.d/main/00_exim4-config_perl
161
 
279
 
162
     { echo "use Net::DNS::Resolver;";
280
     { echo "use Net::DNS::Resolver;";
163
       echo "sub onionLookup {";
281
       echo "sub onionLookup {";
172
       echo "  return 'no_such_host';";
290
       echo "  return 'no_such_host';";
173
       echo "}"; } > /etc/exim4/perl-routines.pl
291
       echo "}"; } > /etc/exim4/perl-routines.pl
174
 
292
 
175
-    { echo "ONION_RELAYDB=/etc/exim4/onionrelay.cdb";
176
-      echo "domainlist onion_relays     = cdb;ONION_RELAYDB"; } > /etc/exim4/conf.d/domainlists
293
+    #{ echo "ONION_RELAYDB=/etc/exim4/onionrelay.cdb";
294
+    #  echo "domainlist onion_relays     = cdb;ONION_RELAYDB"; } > /etc/exim4/conf.d/main/48_exim4-config_onion_relays
177
 
295
 
178
-    { echo "# send things over tor where we have an entry for it";
179
-      echo "onionrelays:";
296
+    { echo "riseup:";
180
       echo "  driver    = manualroute";
297
       echo "  driver    = manualroute";
181
-      echo "  domains   = +onion_relays";
298
+      echo "  domains   = riseup.net";
182
       echo "  transport = onion_relay";
299
       echo "  transport = onion_relay";
183
-      echo "  # get the automap IP for the onion address from the tor daemon";
184
-      echo "  route_data = \${perl{onionLookup}{\${lookup{\$domain}cdb{ONION_RELAYDB}}}}";
185
-      echo "  no_more"; } > /etc/exim4/conf.d/router/50_exim4-config-onion
300
+      echo "  route_data = \${perl{onionLookup}{$RISEUP_EMAIL_ONION}}"
301
+      echo "  no_more"; } > /etc/exim4/conf.d/router/049_exim4-config-riseup
302
+
303
+    { echo "onionrelays:";
304
+      echo "  driver    = manualroute";
305
+      echo "  domains   = *.onion";
306
+      echo "  transport = onion_relay";
307
+      #echo "  route_data = \${lookup dnsdb{a=\$domain}}";
308
+      echo "  route_data = \${perl{onionLookup}{\$domain}}"
309
+      echo "  no_more"; } > /etc/exim4/conf.d/router/050_exim4-config-onionrelays
186
 
310
 
187
     { echo "onion_relay:";
311
     { echo "onion_relay:";
188
       echo "  driver = smtp";
312
       echo "  driver = smtp";
189
-      echo "  socks_proxy = 127.0.0.1 port=9050"; } > /etc/exim4/conf.d/transport/50_exim4-config_onion
313
+      echo "  socks_proxy = 127.0.0.1 port=9050"; } > /etc/exim4/conf.d/transport/050_exim4-config_onion_relay
190
 
314
 
191
     if ! grep -q "AutomapHostsOnResolve" /etc/tor/torrc; then
315
     if ! grep -q "AutomapHostsOnResolve" /etc/tor/torrc; then
192
         echo 'AutomapHostsOnResolve 1' >> /etc/tor/torrc
316
         echo 'AutomapHostsOnResolve 1' >> /etc/tor/torrc
209
         sed -i 's|DNSListenAddress.*|DNSListenAddress 127.0.0.1|g' /etc/tor/torrc
333
         sed -i 's|DNSListenAddress.*|DNSListenAddress 127.0.0.1|g' /etc/tor/torrc
210
     fi
334
     fi
211
 
335
 
336
+    update-exim4.conf.template -r
337
+    update-exim4.conf
212
     dpkg-reconfigure --frontend noninteractive exim4-config
338
     dpkg-reconfigure --frontend noninteractive exim4-config
213
     systemctl restart tor
339
     systemctl restart tor
214
     systemctl restart exim4
340
     systemctl restart exim4
237
         MY_EMAIL_ADDRESS="${MY_USERNAME}@${DEFAULT_DOMAIN_NAME}"
363
         MY_EMAIL_ADDRESS="${MY_USERNAME}@${DEFAULT_DOMAIN_NAME}"
238
         write_config_param "MY_EMAIL_ADDRESS" "$MY_EMAIL_ADDRESS"
364
         write_config_param "MY_EMAIL_ADDRESS" "$MY_EMAIL_ADDRESS"
239
     fi
365
     fi
366
+
367
+    if [[ $ONION_ONLY != 'no' ]]; then
368
+        my_email=$onion_address
369
+        MY_EMAIL_ADDRESS=$onion_address
370
+        write_config_param "MY_EMAIL_ADDRESS" "$MY_EMAIL_ADDRESS"
371
+    fi
240
 }
372
 }
241
 
373
 
242
 function backup_email {
374
 function backup_email {
827
     sed -i 's|pam_mail.so standard noenv|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/sshd
959
     sed -i 's|pam_mail.so standard noenv|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/sshd
828
     sed -i 's|pam_mail.so nopen|pam_mail.so dir=~/Maildir nopen|g' /etc/pam.d/su
960
     sed -i 's|pam_mail.so nopen|pam_mail.so dir=~/Maildir nopen|g' /etc/pam.d/su
829
 
961
 
830
-    { echo "dc_eximconfig_configtype='internet'";
831
-      echo "dc_other_hostnames='${DEFAULT_DOMAIN_NAME};mail.${DEFAULT_DOMAIN_NAME}'";
832
-      echo "dc_local_interfaces=''";
962
+    echo "dc_eximconfig_configtype='internet'" > /etc/exim4/update-exim4.conf.conf
963
+
964
+    if [[ $ONION_ONLY == 'no' ]]; then
965
+        echo "dc_other_hostnames='${DEFAULT_DOMAIN_NAME};mail.${DEFAULT_DOMAIN_NAME}'" >> /etc/exim4/update-exim4.conf.conf
966
+    else
967
+        echo "dc_other_hostnames='${onion_address}'" >> /etc/exim4/update-exim4.conf.conf
968
+    fi
969
+
970
+    { echo "dc_local_interfaces=''";
833
       echo "dc_readhost=''";
971
       echo "dc_readhost=''";
834
       echo "dc_relay_domains=''";
972
       echo "dc_relay_domains=''";
835
-      echo "dc_minimaldns='false'"; } > /etc/exim4/update-exim4.conf.conf
973
+      echo "dc_minimaldns='false'"; } >> /etc/exim4/update-exim4.conf.conf
836
     IPv4_address=$(get_ipv4_address)
974
     IPv4_address=$(get_ipv4_address)
837
     IPv4_address_base=$(echo "$IPv4_address" | awk -F '.' '{print $1"."$2"."$3}')
975
     IPv4_address_base=$(echo "$IPv4_address" | awk -F '.' '{print $1"."$2"."$3}')
838
     RELAY_NETS="${IPv4_address_base}.0/24"
976
     RELAY_NETS="${IPv4_address_base}.0/24"
1533
         return
1671
         return
1534
     fi
1672
     fi
1535
 
1673
 
1674
+    create_email_onion_address
1536
     check_email_address_exists
1675
     check_email_address_exists
1537
     install_email_basic
1676
     install_email_basic
1538
     configure_email_onion
1677
     configure_email_onion

+ 252
- 256
src/freedombone-config View File

323
 }
323
 }
324
 
324
 
325
 function dynamic_dns_setup {
325
 function dynamic_dns_setup {
326
-    data=$(mktemp 2>/dev/null)
327
-    dialog --backtitle $"Freedombone Configuration" \
328
-           --radiolist $"Choose Dynamic DNS provider:" 40 40 40 \
329
-           1 dyn.com off \
330
-           2 freedns.afraid.org on \
331
-           3 zoneedit.com off \
332
-           4 no-ip.com off \
333
-           5 easydns.com off \
334
-           6 tzo.com off \
335
-           7 3322.org off \
336
-           8 dnsomatic.com off \
337
-           9 dns.he.net off \
338
-           10 tunnelbroker.net off \
339
-           11 dynsip.org off \
340
-           12 sitelutions.com off \
341
-           13 dnsexit.com off \
342
-           14 changeip.com off \
343
-           15 zerigo.com off \
344
-           16 dhis.org off \
345
-           17 nsupdate.info off \
346
-           18 duckdns.org off \
347
-           19 loopia.com off \
348
-           20 namecheap.com off \
349
-           21 domains.google.com off \
350
-           22 ovh.com off \
351
-           23 dtdns.com off \
352
-           24 giradns.com off \
353
-           25 duiadns.net off \
354
-           26 ddnss.de off \
355
-           27 dynv6.com off \
356
-           28 ipv4.dynv6.com off \
357
-           29 default@spdyn.de off \
358
-           30 strato.com off \
359
-           31 freemyip.com off \
360
-           32 cloudxns.net off \
361
-           33 none off 2> "$data"
362
-    sel=$?
363
-    case $sel in
364
-        1) rm -f "$data"
365
-           exit 1;;
366
-        255) rm -f "$data"
367
-             exit 1;;
368
-    esac
369
-    case $(cat "$data") in
370
-        1) DDNS_PROVIDER="default@www.dyn.com";;
371
-        2) DDNS_PROVIDER="default@freedns.afraid.org";;
326
+    W=(1 freedns.afraid.org
327
+       2 dyn.com
328
+       3 zoneedit.com
329
+       4 no-ip.com
330
+       5 easydns.com
331
+       6 tzo.com
332
+       7 3322.org
333
+       8 dnsomatic.com
334
+       9 dns.he.net
335
+       10 tunnelbroker.net
336
+       11 dynsip.org
337
+       12 sitelutions.com
338
+       13 dnsexit.com
339
+       14 changeip.com
340
+       15 zerigo.com
341
+       16 dhis.org
342
+       17 nsupdate.info
343
+       18 duckdns.org
344
+       19 loopia.com
345
+       20 namecheap.com
346
+       21 domains.google.com
347
+       22 ovh.com
348
+       23 dtdns.com
349
+       24 giradns.com
350
+       25 duiadns.net
351
+       26 ddnss.de
352
+       27 dynv6.com
353
+       28 ipv4.dynv6.com
354
+       29 default@spdyn.de
355
+       30 strato.com
356
+       31 freemyip.com
357
+       32 cloudxns.net)
358
+
359
+    # shellcheck disable=SC2068
360
+    selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Dynamic DNS" --menu $"Choose Dynamic DNS provider, or ESC for none:" 24 60 32 "${W[@]}" 3>&2 2>&1 1>&3)
361
+
362
+    if [ ! "$selection" ]; then
363
+        if [ -f /etc/systemd/system/inadyn.service ]; then
364
+            systemctl stop inadyn
365
+            systemctl disable inadyn
366
+        fi
367
+        return
368
+    fi
369
+
370
+    case $selection in
371
+        1) DDNS_PROVIDER="default@freedns.afraid.org";;
372
+        2) DDNS_PROVIDER="default@www.dyn.com";;
372
         3) DDNS_PROVIDER="default@www.zoneedit.com";;
373
         3) DDNS_PROVIDER="default@www.zoneedit.com";;
373
         4) DDNS_PROVIDER="default@www.no-ip.com";;
374
         4) DDNS_PROVIDER="default@www.no-ip.com";;
374
         5) DDNS_PROVIDER="default@www.easydns.com";;
375
         5) DDNS_PROVIDER="default@www.easydns.com";;
400
         31) DDNS_PROVIDER="default@freemyip.com";;
401
         31) DDNS_PROVIDER="default@freemyip.com";;
401
         32) DDNS_PROVIDER="default@www.cloudxns.net";;
402
         32) DDNS_PROVIDER="default@www.cloudxns.net";;
402
         33) DDNS_PROVIDER="none";;
403
         33) DDNS_PROVIDER="none";;
403
-        255) rm -f "$data"
404
-             exit 1;;
405
     esac
404
     esac
406
-    rm -f "$data"
407
     save_configuration_values
405
     save_configuration_values
408
 
406
 
409
     valid_ddns_username=
407
     valid_ddns_username=
425
                     if [ "$possible_username" ]; then
423
                     if [ "$possible_username" ]; then
426
                         if [ ${#possible_username} -gt 1 ]; then
424
                         if [ ${#possible_username} -gt 1 ]; then
427
                             valid_ddns_username=$(cat "$data")
425
                             valid_ddns_username=$(cat "$data")
426
+                            # shellcheck disable=SC2034
428
                             DDNS_USERNAME="$valid_ddns_username"
427
                             DDNS_USERNAME="$valid_ddns_username"
429
                             rm -f "$data"
428
                             rm -f "$data"
430
                             break;
429
                             break;
491
 
490
 
492
 function choose_debian_repo {
491
 function choose_debian_repo {
493
     if [[ "$MINIMAL_INSTALL" == "no" ]]; then
492
     if [[ "$MINIMAL_INSTALL" == "no" ]]; then
494
-        data=$(mktemp 2>/dev/null)
495
-        dialog --backtitle $"Freedombone Configuration" \
496
-               --radiolist $"Where to download Debian packages from:" 25 45 49 \
497
-               1 $"Australia" off \
498
-               2 $"Austria" off \
499
-               3 $"Belarus" off \
500
-               4 $"Belgium" off \
501
-               5 $"Bosnia and Herzegovina" off \
502
-               6 $"Brazil" off \
503
-               7 $"Bulgaria" off \
504
-               8 $"Canada" off \
505
-               9 $"Chile" off \
506
-               10 $"China" off \
507
-               11 $"Croatia" off \
508
-               12 $"Czech Republic" off \
509
-               13 $"Denmark" off \
510
-               14 $"El Salvador" off \
511
-               15 $"Estonia" off \
512
-               16 $"Finland" off \
513
-               17 $"France 1" off \
514
-               18 $"France 2" off \
515
-               19 $"Germany 1" off \
516
-               20 $"Germany 2" off \
517
-               21 $"Greece" off \
518
-               22 $"Hungary" off \
519
-               23 $"Iceland" off \
520
-               24 $"Iran" off \
521
-               25 $"Ireland" off \
522
-               26 $"Italy" off \
523
-               27 $"Japan" off \
524
-               28 $"Korea" off \
525
-               29 $"Lithuania" off \
526
-               30 $"Mexico" off \
527
-               31 $"Netherlands" off \
528
-               32 $"New Caledonia" off \
529
-               33 $"New Zealand" off \
530
-               34 $"Norway" off \
531
-               35 $"Poland" off \
532
-               36 $"Portugal" off \
533
-               37 $"Romania" off \
534
-               38 $"Russia" off \
535
-               39 $"Slovakia" off \
536
-               40 $"Slovenia" off \
537
-               41 $"Spain" off \
538
-               42 $"Sweden" off \
539
-               43 $"Switzerland" off \
540
-               44 $"Taiwan" off \
541
-               45 $"Thailand" off \
542
-               46 $"Turkey" off \
543
-               47 $"Ukraine" off \
544
-               48 $"United Kingdom" off \
545
-               49 $"United States" on 2> "$data"
546
-        sel=$?
547
-        case $sel in
548
-            1) rm -f "$data"
549
-               exit 1;;
550
-            255) rm -f "$data"
551
-                 exit 1;;
552
-        esac
553
-        case $(cat "$data") in
554
-            1) DEBIAN_REPO='ftp.au.debian.org';;
555
-            2) DEBIAN_REPO='ftp.at.debian.org';;
556
-            3) DEBIAN_REPO='ftp.by.debian.org';;
557
-            4) DEBIAN_REPO='ftp.be.debian.org';;
558
-            5) DEBIAN_REPO='ftp.ba.debian.org';;
559
-            6) DEBIAN_REPO='ftp.br.debian.org';;
560
-            7) DEBIAN_REPO='ftp.bg.debian.org';;
561
-            8) DEBIAN_REPO='ftp.ca.debian.org';;
562
-            9) DEBIAN_REPO='ftp.cl.debian.org';;
563
-            10) DEBIAN_REPO='ftp.cn.debian.org';;
564
-            11) DEBIAN_REPO='ftp.hr.debian.org';;
565
-            12) DEBIAN_REPO='ftp.cz.debian.org';;
566
-            13) DEBIAN_REPO='ftp.dk.debian.org';;
567
-            14) DEBIAN_REPO='ftp.sv.debian.org';;
568
-            15) DEBIAN_REPO='ftp.ee.debian.org';;
569
-            16) DEBIAN_REPO='ftp.fi.debian.org';;
570
-            17) DEBIAN_REPO='ftp2.fr.debian.org';;
571
-            18) DEBIAN_REPO='ftp.fr.debian.org';;
572
-            19) DEBIAN_REPO='ftp2.de.debian.org';;
573
-            20) DEBIAN_REPO='ftp.de.debian.org';;
574
-            21) DEBIAN_REPO='ftp.gr.debian.org';;
575
-            22) DEBIAN_REPO='ftp.hu.debian.org';;
576
-            23) DEBIAN_REPO='ftp.is.debian.org';;
577
-            24) DEBIAN_REPO='ftp.ir.debian.org';;
578
-            25) DEBIAN_REPO='ftp.ie.debian.org';;
579
-            26) DEBIAN_REPO='ftp.it.debian.org';;
580
-            27) DEBIAN_REPO='ftp.jp.debian.org';;
581
-            28) DEBIAN_REPO='ftp.kr.debian.org';;
582
-            29) DEBIAN_REPO='ftp.lt.debian.org';;
583
-            30) DEBIAN_REPO='ftp.mx.debian.org';;
584
-            31) DEBIAN_REPO='ftp.nl.debian.org';;
585
-            32) DEBIAN_REPO='ftp.nc.debian.org';;
586
-            33) DEBIAN_REPO='ftp.nz.debian.org';;
587
-            34) DEBIAN_REPO='ftp.no.debian.org';;
588
-            35) DEBIAN_REPO='ftp.pl.debian.org';;
589
-            36) DEBIAN_REPO='ftp.pt.debian.org';;
590
-            37) DEBIAN_REPO='ftp.ro.debian.org';;
591
-            38) DEBIAN_REPO='ftp.ru.debian.org';;
592
-            39) DEBIAN_REPO='ftp.sk.debian.org';;
593
-            40) DEBIAN_REPO='ftp.si.debian.org';;
594
-            41) DEBIAN_REPO='ftp.es.debian.org';;
595
-            42) DEBIAN_REPO='ftp.se.debian.org';;
596
-            43) DEBIAN_REPO='ftp.ch.debian.org';;
597
-            44) DEBIAN_REPO='ftp.tw.debian.org';;
598
-            45) DEBIAN_REPO='ftp.th.debian.org';;
599
-            46) DEBIAN_REPO='ftp.tr.debian.org';;
600
-            47) DEBIAN_REPO='ftp.ua.debian.org';;
601
-            48) DEBIAN_REPO='ftp.uk.debian.org';;
602
-            49) DEBIAN_REPO='ftp.us.debian.org';;
603
-            255) rm -f "$data"
604
-                 exit 1;;
493
+
494
+        W=(1 $"United Kingdom"
495
+           2 $"United States"
496
+           3 $"Australia"
497
+           4 $"Austria"
498
+           5 $"Belarus"
499
+           6 $"Belgium"
500
+           7 $"Bosnia and Herzegovina"
501
+           8 $"Brazil"
502
+           9 $"Bulgaria"
503
+           10 $"Canada"
504
+           11 $"Chile"
505
+           12 $"China"
506
+           13 $"Croatia"
507
+           14 $"Czech Republic"
508
+           15 $"Denmark"
509
+           16 $"El Salvador"
510
+           17 $"Estonia"
511
+           18 $"Finland"
512
+           19 $"France 1"
513
+           20 $"France 2"
514
+           21 $"Germany 1"
515
+           22 $"Germany 2"
516
+           23 $"Greece"
517
+           24 $"Hungary"
518
+           25 $"Iceland"
519
+           26 $"Iran"
520
+           27 $"Ireland"
521
+           28 $"Italy"
522
+           29 $"Japan"
523
+           30 $"Korea"
524
+           31 $"Lithuania"
525
+           32 $"Mexico"
526
+           33 $"Netherlands"
527
+           34 $"New Caledonia"
528
+           35 $"New Zealand"
529
+           36 $"Norway"
530
+           37 $"Poland"
531
+           38 $"Portugal"
532
+           39 $"Romania"
533
+           40 $"Russia"
534
+           41 $"Slovakia"
535
+           42 $"Slovenia"
536
+           43 $"Spain"
537
+           44 $"Sweden"
538
+           45 $"Switzerland"
539
+           46 $"Taiwan"
540
+           47 $"Thailand"
541
+           48 $"Turkey"
542
+           49 $"Ukraine")
543
+
544
+        # shellcheck disable=SC2068
545
+        selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Debian Repo" --menu $"Where to download Debian packages from:" 24 60 49 "${W[@]}" 3>&2 2>&1 1>&3)
546
+
547
+        if [ ! "$selection" ]; then
548
+            selection='1'
549
+        fi
550
+
551
+        case $selection in
552
+            1) DEBIAN_REPO='ftp.uk.debian.org';;
553
+            2) DEBIAN_REPO='ftp.us.debian.org';;
554
+            3) DEBIAN_REPO='ftp.au.debian.org';;
555
+            4) DEBIAN_REPO='ftp.at.debian.org';;
556
+            5) DEBIAN_REPO='ftp.by.debian.org';;
557
+            6) DEBIAN_REPO='ftp.be.debian.org';;
558
+            7) DEBIAN_REPO='ftp.ba.debian.org';;
559
+            8) DEBIAN_REPO='ftp.br.debian.org';;
560
+            9) DEBIAN_REPO='ftp.bg.debian.org';;
561
+            10) DEBIAN_REPO='ftp.ca.debian.org';;
562
+            11) DEBIAN_REPO='ftp.cl.debian.org';;
563
+            12) DEBIAN_REPO='ftp.cn.debian.org';;
564
+            13) DEBIAN_REPO='ftp.hr.debian.org';;
565
+            14) DEBIAN_REPO='ftp.cz.debian.org';;
566
+            15) DEBIAN_REPO='ftp.dk.debian.org';;
567
+            16) DEBIAN_REPO='ftp.sv.debian.org';;
568
+            17) DEBIAN_REPO='ftp.ee.debian.org';;
569
+            18) DEBIAN_REPO='ftp.fi.debian.org';;
570
+            19) DEBIAN_REPO='ftp2.fr.debian.org';;
571
+            20) DEBIAN_REPO='ftp.fr.debian.org';;
572
+            21) DEBIAN_REPO='ftp2.de.debian.org';;
573
+            22) DEBIAN_REPO='ftp.de.debian.org';;
574
+            23) DEBIAN_REPO='ftp.gr.debian.org';;
575
+            24) DEBIAN_REPO='ftp.hu.debian.org';;
576
+            25) DEBIAN_REPO='ftp.is.debian.org';;
577
+            26) DEBIAN_REPO='ftp.ir.debian.org';;
578
+            27) DEBIAN_REPO='ftp.ie.debian.org';;
579
+            28) DEBIAN_REPO='ftp.it.debian.org';;
580
+            29) DEBIAN_REPO='ftp.jp.debian.org';;
581
+            30) DEBIAN_REPO='ftp.kr.debian.org';;
582
+            31) DEBIAN_REPO='ftp.lt.debian.org';;
583
+            32) DEBIAN_REPO='ftp.mx.debian.org';;
584
+            33) DEBIAN_REPO='ftp.nl.debian.org';;
585
+            34) DEBIAN_REPO='ftp.nc.debian.org';;
586
+            35) DEBIAN_REPO='ftp.nz.debian.org';;
587
+            36) DEBIAN_REPO='ftp.no.debian.org';;
588
+            37) DEBIAN_REPO='ftp.pl.debian.org';;
589
+            38) DEBIAN_REPO='ftp.pt.debian.org';;
590
+            39) DEBIAN_REPO='ftp.ro.debian.org';;
591
+            40) DEBIAN_REPO='ftp.ru.debian.org';;
592
+            41) DEBIAN_REPO='ftp.sk.debian.org';;
593
+            42) DEBIAN_REPO='ftp.si.debian.org';;
594
+            43) DEBIAN_REPO='ftp.es.debian.org';;
595
+            44) DEBIAN_REPO='ftp.se.debian.org';;
596
+            45) DEBIAN_REPO='ftp.ch.debian.org';;
597
+            46) DEBIAN_REPO='ftp.tw.debian.org';;
598
+            47) DEBIAN_REPO='ftp.th.debian.org';;
599
+            48) DEBIAN_REPO='ftp.tr.debian.org';;
600
+            49) DEBIAN_REPO='ftp.ua.debian.org';;
605
         esac
601
         esac
606
-        rm -f "$data"
607
         save_configuration_values
602
         save_configuration_values
608
     else
603
     else
604
+        # shellcheck disable=SC2034
609
         DEBIAN_REPO='ftp.de.debian.org'
605
         DEBIAN_REPO='ftp.de.debian.org'
610
     fi
606
     fi
611
 }
607
 }
634
                      exit 1;;
630
                      exit 1;;
635
             esac
631
             esac
636
         else
632
         else
633
+            # shellcheck disable=SC2034
637
             HWRNG_TYPE="beaglebone"
634
             HWRNG_TYPE="beaglebone"
638
         fi
635
         fi
639
         rm -f "$data"
636
         rm -f "$data"
664
         save_configuration_values
661
         save_configuration_values
665
     else
662
     else
666
         # enable for the minimal case
663
         # enable for the minimal case
664
+        # shellcheck disable=SC2034
667
         ENABLE_SOCIAL_KEY_MANAGEMENT="yes"
665
         ENABLE_SOCIAL_KEY_MANAGEMENT="yes"
668
     fi
666
     fi
669
 }
667
 }
775
                 if [ "$possible_name" ]; then
773
                 if [ "$possible_name" ]; then
776
                     if [ ${#possible_name} -gt 1 ]; then
774
                     if [ ${#possible_name} -gt 1 ]; then
777
                         valid_name="$possible_name"
775
                         valid_name="$possible_name"
776
+                        # shellcheck disable=SC2034
778
                         MY_NAME="$possible_name"
777
                         MY_NAME="$possible_name"
779
                         break;
778
                         break;
780
                     fi
779
                     fi
885
 done
884
 done
886
 
885
 
887
 function interactive_select_language {
886
 function interactive_select_language {
888
-    data=$(mktemp 2>/dev/null)
889
-    dialog --backtitle $"Freedombone Configuration" \
890
-           --radiolist $"Select your language:" 26 40 24 \
891
-           1 $"Afrikaans" off \
892
-           2 $"Albanian" off \
893
-           3 $"Arabic" off \
894
-           4 $"Basque" off \
895
-           5 $"Belarusian" off \
896
-           6 $"Bosnian" off \
897
-           7 $"Bulgarian" off \
898
-           8 $"Catalan" off \
899
-           9 $"Croatian" off \
900
-           10 $"Chinese (Simplified)" off \
901
-           11 $"Chinese (Traditional)" off \
902
-           12 $"Czech" off \
903
-           13 $"Danish" off \
904
-           14 $"Dutch" off \
905
-           15 $"English" on \
906
-           16 $"English (US)" off \
907
-           17 $"Estonian" off \
908
-           18 $"Farsi" off \
909
-           19 $"Filipino" off \
910
-           20 $"Finnish" off \
911
-           21 $"French" off \
912
-           22 $"French (Canada)" off \
913
-           23 $"Gaelic" off \
914
-           24 $"Gallego" off \
915
-           25 $"Georgian" off \
916
-           26 $"German" off \
917
-           27 $"German (Personal)" off \
918
-           28 $"Greek" off \
919
-           29 $"Gujarati" off \
920
-           30 $"Hebrew" off \
921
-           31 $"Hindi" off \
922
-           32 $"Hungarian" off \
923
-           33 $"Icelandic" off \
924
-           34 $"Indonesian" off \
925
-           35 $"Italian" off \
926
-           36 $"Japanese" off \
927
-           37 $"Kannada" off \
928
-           38 $"Khmer" off \
929
-           39 $"Korean" off \
930
-           40 $"Lao" off \
931
-           41 $"Lithuanian" off \
932
-           42 $"Latvian" off \
933
-           43 $"Malayalam" off \
934
-           44 $"Malaysian" off \
935
-           45 $"Maori (Ngai Tahu)" off \
936
-           46 $"Maori (Waikoto Uni)" off \
937
-           47 $"Mongolian" off \
938
-           48 $"Norwegian" off \
939
-           49 $"Norwegian (Primary)" off \
940
-           50 $"Nynorsk" off \
941
-           51 $"Polish" off \
942
-           52 $"Portuguese" off \
943
-           53 $"Portuguese (Brazil)" off \
944
-           54 $"Romanian" off \
945
-           55 $"Russian" off \
946
-           56 $"Samoan" off \
947
-           57 $"Serbian" off \
948
-           58 $"Slovak" off \
949
-           59 $"Slovenian" off \
950
-           60 $"Somali" off \
951
-           61 $"Spanish (International)" off \
952
-           62 $"Swedish" off \
953
-           63 $"Tagalog" off \
954
-           64 $"Tamil" off \
955
-           65 $"Thai" off \
956
-           66 $"Turkish" off \
957
-           67 $"Ukrainian" off \
958
-           68 $"Vietnamese" off 2> "$data"
959
-    sel=$?
960
-    case $sel in
961
-        1) rm -f "$data"
962
-           exit 1;;
963
-        255) rm -f "$data"
964
-             exit 1;;
965
-    esac
966
-    case $(cat "$data") in
967
-        1) DEFAULT_LANGUAGE='af_ZA.UTF-8';;
968
-        2) DEFAULT_LANGUAGE='sq_AL.UTF-8';;
969
-        3) DEFAULT_LANGUAGE='ar_SA.UTF-8';;
970
-        4) DEFAULT_LANGUAGE='eu_ES.UTF-8';;
971
-        5) DEFAULT_LANGUAGE='be_BY.UTF-8';;
972
-        6) DEFAULT_LANGUAGE='bs_BA.UTF-8';;
973
-        7) DEFAULT_LANGUAGE='bg_BG.UTF-8';;
974
-        8) DEFAULT_LANGUAGE='ca_ES.UTF-8';;
975
-        9) DEFAULT_LANGUAGE='hr_HR.UTF-8';;
976
-        10) DEFAULT_LANGUAGE='zh_CN.UTF-8';;
977
-        11) DEFAULT_LANGUAGE='zh_TW.UTF-8';;
978
-        12) DEFAULT_LANGUAGE='cs_CZ.UTF-8';;
979
-        13) DEFAULT_LANGUAGE='da_DK.UTF-8';;
980
-        14) DEFAULT_LANGUAGE='nl_NL.UTF-8';;
981
-        15) DEFAULT_LANGUAGE='en_GB.UTF-8';;
887
+    W=(1 $"English"
888
+       2 $"Afrikaans"
889
+       3 $"Albanian"
890
+       4 $"Arabic"
891
+       5 $"Basque"
892
+       6 $"Belarusian"
893
+       7 $"Bosnian"
894
+       8 $"Bulgarian"
895
+       9 $"Catalan"
896
+       10 $"Croatian"
897
+       11 $"Chinese (Simplified)"
898
+       12 $"Chinese (Traditional)"
899
+       13 $"Czech"
900
+       14 $"Danish"
901
+       15 $"Dutch"
902
+       16 $"English (US)"
903
+       17 $"Estonian"
904
+       18 $"Farsi"
905
+       19 $"Filipino"
906
+       20 $"Finnish"
907
+       21 $"French"
908
+       22 $"French (Canada)"
909
+       23 $"Gaelic"
910
+       24 $"Gallego"
911
+       25 $"Georgian"
912
+       26 $"German"
913
+       27 $"German (Personal)"
914
+       28 $"Greek"
915
+       29 $"Gujarati"
916
+       30 $"Hebrew"
917
+       31 $"Hindi"
918
+       32 $"Hungarian"
919
+       33 $"Icelandic"
920
+       34 $"Indonesian"
921
+       35 $"Italian"
922
+       36 $"Japanese"
923
+       37 $"Kannada"
924
+       38 $"Khmer"
925
+       39 $"Korean"
926
+       40 $"Lao"
927
+       41 $"Lithuanian"
928
+       42 $"Latvian"
929
+       43 $"Malayalam"
930
+       44 $"Malaysian"
931
+       45 $"Maori (Ngai Tahu)"
932
+       46 $"Maori (Waikoto Uni)"
933
+       47 $"Mongolian"
934
+       48 $"Norwegian"
935
+       49 $"Norwegian (Primary)"
936
+       50 $"Nynorsk"
937
+       51 $"Polish"
938
+       52 $"Portuguese"
939
+       53 $"Portuguese (Brazil)"
940
+       54 $"Romanian"
941
+       55 $"Russian"
942
+       56 $"Samoan"
943
+       57 $"Serbian"
944
+       58 $"Slovak"
945
+       59 $"Slovenian"
946
+       60 $"Somali"
947
+       61 $"Spanish (International)"
948
+       62 $"Swedish"
949
+       63 $"Tagalog"
950
+       64 $"Tamil"
951
+       65 $"Thai"
952
+       66 $"Turkish"
953
+       67 $"Ukrainian"
954
+       68 $"Vietnamese")
955
+
956
+    # shellcheck disable=SC2068
957
+    selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Language" --menu $"Select your language:" 24 60 68 "${W[@]}" 3>&2 2>&1 1>&3)
958
+
959
+    if [ ! "$selection" ]; then
960
+        selection='1'
961
+    fi
962
+
963
+    case $selection in
964
+        1) DEFAULT_LANGUAGE='en_GB.UTF-8';;
965
+        2) DEFAULT_LANGUAGE='af_ZA.UTF-8';;
966
+        3) DEFAULT_LANGUAGE='sq_AL.UTF-8';;
967
+        4) DEFAULT_LANGUAGE='ar_SA.UTF-8';;
968
+        5) DEFAULT_LANGUAGE='eu_ES.UTF-8';;
969
+        6) DEFAULT_LANGUAGE='be_BY.UTF-8';;
970
+        7) DEFAULT_LANGUAGE='bs_BA.UTF-8';;
971
+        8) DEFAULT_LANGUAGE='bg_BG.UTF-8';;
972
+        9) DEFAULT_LANGUAGE='ca_ES.UTF-8';;
973
+        10) DEFAULT_LANGUAGE='hr_HR.UTF-8';;
974
+        11) DEFAULT_LANGUAGE='zh_CN.UTF-8';;
975
+        12) DEFAULT_LANGUAGE='zh_TW.UTF-8';;
976
+        13) DEFAULT_LANGUAGE='cs_CZ.UTF-8';;
977
+        14) DEFAULT_LANGUAGE='da_DK.UTF-8';;
978
+        15) DEFAULT_LANGUAGE='nl_NL.UTF-8';;
982
         16) DEFAULT_LANGUAGE='en_US.UTF-8';;
979
         16) DEFAULT_LANGUAGE='en_US.UTF-8';;
983
         17) DEFAULT_LANGUAGE='et_EE.UTF-8';;
980
         17) DEFAULT_LANGUAGE='et_EE.UTF-8';;
984
         18) DEFAULT_LANGUAGE='fa_IR.UTF-8';;
981
         18) DEFAULT_LANGUAGE='fa_IR.UTF-8';;
1033
         67) DEFAULT_LANGUAGE='uk_UA.UTF-8';;
1030
         67) DEFAULT_LANGUAGE='uk_UA.UTF-8';;
1034
         68) DEFAULT_LANGUAGE='vi_VN.UTF-8';;
1031
         68) DEFAULT_LANGUAGE='vi_VN.UTF-8';;
1035
     esac
1032
     esac
1036
-    rm -f "$data"
1037
     save_configuration_values
1033
     save_configuration_values
1038
 
1034
 
1039
     please_wait
1035
     please_wait

+ 2
- 2
src/freedombone-image View File

83
 BOX_IP_ADDRESS="192.168.1.55"
83
 BOX_IP_ADDRESS="192.168.1.55"
84
 
84
 
85
 # DNS
85
 # DNS
86
-NAMESERVER1='213.73.91.35'
87
-NAMESERVER2='85.214.20.141'
86
+NAMESERVER1='91.239.100.100'
87
+NAMESERVER2='89.233.43.71'
88
 NAMESERVER3='213.73.91.35'
88
 NAMESERVER3='213.73.91.35'
89
 NAMESERVER4='85.214.73.63'
89
 NAMESERVER4='85.214.73.63'
90
 NAMESERVER5='84.200.69.80'
90
 NAMESERVER5='84.200.69.80'

+ 13
- 14
src/freedombone-image-customise View File

62
 BOX_IP_ADDRESS="192.168.1.55"
62
 BOX_IP_ADDRESS="192.168.1.55"
63
 
63
 
64
 # DNS
64
 # DNS
65
-NAMESERVER1='85.214.73.63'
66
-NAMESERVER2='213.73.91.35'
65
+NAMESERVER1='91.239.100.100'
66
+NAMESERVER2='89.233.43.71'
67
 NAMESERVER3='87.118.100.175'
67
 NAMESERVER3='87.118.100.175'
68
 NAMESERVER4='94.75.228.29'
68
 NAMESERVER4='94.75.228.29'
69
 NAMESERVER5='85.25.251.254'
69
 NAMESERVER5='85.25.251.254'
242
     if [[ $VARIANT != "meshclient" && $VARIANT != "meshusb" ]]; then
242
     if [[ $VARIANT != "meshclient" && $VARIANT != "meshusb" ]]; then
243
         # change the motd to show further install instructions
243
         # change the motd to show further install instructions
244
         echo $"
244
         echo $"
245
- .---.                  .              .
246
- |                      |              |
247
- |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
248
- |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
249
- '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
245
+       _____               _           _
246
+      |   __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
247
+      |   __|  _| -_| -_| . | . |     | . | . |   | -_|
248
+      |__|  |_| |___|___|___|___|_|_|_|___|___|_|_|___|
250
 
249
 
251
-                    Initial base install
250
+                                   Initial base install
252
 
251
 
253
 Your system is not yet installed. To complete the process run the
252
 Your system is not yet installed. To complete the process run the
254
 following commands, then enter your details.
253
 following commands, then enter your details.
259
 " > "$rootdir/etc/motd"
258
 " > "$rootdir/etc/motd"
260
     else
259
     else
261
         echo $"
260
         echo $"
262
- .---.                  .              .
263
- |                      |              |
264
- |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
265
- |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
266
- '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
261
+       _____               _           _
262
+      |   __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
263
+      |   __|  _| -_| -_| . | . |     | . | . |   | -_|
264
+      |__|  |_| |___|___|___|___|_|_|_|___|___|_|_|___|
267
 
265
 
268
-                    Freedom in the Mesh
266
+                                    Freedom in the Mesh
269
 " > "$rootdir/etc/motd"
267
 " > "$rootdir/etc/motd"
270
     fi
268
     fi
271
 }
269
 }
1941
     fi
1939
     fi
1942
 
1940
 
1943
     git clone "$CRYPTPAD_REPO" "$rootdir/repos/cryptpad"
1941
     git clone "$CRYPTPAD_REPO" "$rootdir/repos/cryptpad"
1942
+    git clone "$BLUDIT_REPO" "$rootdir/repos/bludit"
1944
     git clone "$DOKUWIKI_REPO" "$rootdir/repos/dokuwiki"
1943
     git clone "$DOKUWIKI_REPO" "$rootdir/repos/dokuwiki"
1945
     git clone "$ETHERPAD_REPO" "$rootdir/repos/etherpad"
1944
     git clone "$ETHERPAD_REPO" "$rootdir/repos/etherpad"
1946
     git clone "$FRIENDICA_REPO" "$rootdir/repos/friendica"
1945
     git clone "$FRIENDICA_REPO" "$rootdir/repos/friendica"

+ 2
- 2
src/freedombone-image-makefile View File

60
 BOX_IP_ADDRESS ?= "192.168.1.55"
60
 BOX_IP_ADDRESS ?= "192.168.1.55"
61
 
61
 
62
 # DNS
62
 # DNS
63
-NAMESERVER1 ?= '213.73.91.35'
64
-NAMESERVER2 ?= '85.214.20.141'
63
+NAMESERVER1 ?= '91.239.100.100'
64
+NAMESERVER2 ?= '89.233.43.71'
65
 NAMESERVER3 ?= '213.73.91.35'
65
 NAMESERVER3 ?= '213.73.91.35'
66
 NAMESERVER4 ?= '85.214.73.63'
66
 NAMESERVER4 ?= '85.214.73.63'
67
 NAMESERVER5 ?= '84.200.69.80'
67
 NAMESERVER5 ?= '84.200.69.80'

+ 3
- 3
src/freedombone-syncthing View File

113
             if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
113
             if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
114
                 echo "" > $TEMP_IDS_FILE
114
                 echo "" > $TEMP_IDS_FILE
115
                 while read -r line || [[ -n "$line" ]]; do
115
                 while read -r line || [[ -n "$line" ]]; do
116
-                    line2="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
116
+                    line2=$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
117
                     if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'*  && $line2 == *"-"* ]]; then
117
                     if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'*  && $line2 == *"-"* ]]; then
118
                         if [ ${#line2} -gt 10 ]; then
118
                         if [ ${#line2} -gt 10 ]; then
119
                             if ! grep -q "$line2" $TEMP_IDS_FILE; then
119
                             if ! grep -q "$line2" $TEMP_IDS_FILE; then
150
         if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
150
         if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
151
             if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
151
             if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
152
                 while read -r line || [[ -n "$line" ]]; do
152
                 while read -r line || [[ -n "$line" ]]; do
153
-                    line2="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
153
+                    line2=$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
154
                     if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'*  && $line2 == *"-"* ]]; then
154
                     if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'*  && $line2 == *"-"* ]]; then
155
                         if [ ${#line2} -gt 10 ]; then
155
                         if [ ${#line2} -gt 10 ]; then
156
                             if ! grep -q "$line2" $TEMP_IDS_FILE; then
156
                             if ! grep -q "$line2" $TEMP_IDS_FILE; then
189
         if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
189
         if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
190
             if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
190
             if [ -f "/home/$USERNAME/$SYNCTHING_USER_IDS_FILE" ]; then
191
                 while read -r line || [[ -n "$line" ]]; do
191
                 while read -r line || [[ -n "$line" ]]; do
192
-                    line2="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
192
+                    line2=$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
193
                     if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'*  && $line2 == *"-"* ]]; then
193
                     if [[ $line2 != *"#"* && $line2 != *"*"* && $line2 != *'/'*  && $line2 == *"-"* ]]; then
194
                         if [ ${#line2} -gt 10 ]; then
194
                         if [ ${#line2} -gt 10 ]; then
195
                             if ! grep -q "$line2" $TEMP_IDS_FILE; then
195
                             if ! grep -q "$line2" $TEMP_IDS_FILE; then

+ 181
- 167
src/freedombone-template View File

34
 app_name_lower=$(echo "${app_name}" | tr '[:upper:]' '[:lower:]')
34
 app_name_lower=$(echo "${app_name}" | tr '[:upper:]' '[:lower:]')
35
 app_name=$app_name_lower
35
 app_name=$app_name_lower
36
 app_name_upper=$(echo "${app_name}" | tr '[:lower:]' '[:upper:]')
36
 app_name_upper=$(echo "${app_name}" | tr '[:lower:]' '[:upper:]')
37
-echo "test: $app_name_upper"
38
 app_repo="TODO"
37
 app_repo="TODO"
39
 app_repo_commit='TODO'
38
 app_repo_commit='TODO'
40
 app_php=
39
 app_php=
240
     fi
239
     fi
241
 fi
240
 fi
242
 echo ''
241
 echo ''
243
-echo "${app_name}=(ONION_ONLY"
244
-echo "             ${app_name_upper}_DOMAIN_NAME"
245
-echo "             ${app_name_upper}_CODE"
246
-echo '             DDNS_PROVIDER'
247
-echo "             MY_USERNAME)"
242
+echo "${app_name}_variables=(ONION_ONLY"
243
+echo "                       ${app_name_upper}_DOMAIN_NAME"
244
+echo "                       ${app_name_upper}_CODE"
245
+echo '                       DDNS_PROVIDER'
246
+echo "                       MY_USERNAME)"
248
 echo ''
247
 echo ''
249
 echo "function logging_on_${app_name} {"
248
 echo "function logging_on_${app_name} {"
250
 echo "    echo -n ''"
249
 echo "    echo -n ''"
257
 echo "function remove_user_${app_name} {"
256
 echo "function remove_user_${app_name} {"
258
 echo "    remove_username=\"\$1\""
257
 echo "    remove_username=\"\$1\""
259
 echo ''
258
 echo ''
260
-echo "    \${PROJECT_NAME}-pass -u \$remove_username --rmapp ${app_name}"
259
+echo "    \"\${PROJECT_NAME}-pass\" -u \"\$remove_username\" --rmapp ${app_name}"
261
 echo '}'
260
 echo '}'
262
 echo ''
261
 echo ''
263
 echo "function add_user_${app_name} {"
262
 echo "function add_user_${app_name} {"
264
 echo "    new_username=\"\$1\""
263
 echo "    new_username=\"\$1\""
265
 echo "    new_user_password=\"\$2\""
264
 echo "    new_user_password=\"\$2\""
266
 echo ''
265
 echo ''
267
-echo "    \${PROJECT_NAME}-pass -u \$new_username -a ${app_name} -p \"\$new_user_password\""
266
+echo "    \"\${PROJECT_NAME}-pass\" -u \"\$new_username\" -a ${app_name} -p \"\$new_user_password\""
268
 echo "    echo '0'"
267
 echo "    echo '0'"
269
 echo '}'
268
 echo '}'
270
 echo ''
269
 echo ''
271
 echo "function install_interactive_${app_name} {"
270
 echo "function install_interactive_${app_name} {"
272
 if [ ! $app_onion_only ]; then
271
 if [ ! $app_onion_only ]; then
273
-    echo "    if [ ! \$ONION_ONLY ]; then"
272
+    echo "    if [ ! \"\$ONION_ONLY\" ]; then"
274
     echo "        ONION_ONLY='no'"
273
     echo "        ONION_ONLY='no'"
275
     echo '    fi'
274
     echo '    fi'
276
     echo ''
275
     echo ''
277
-    echo "    if [[ \$ONION_ONLY != \"no\" ]]; then"
276
+    echo "    if [[ \"\$ONION_ONLY\" != \"no\" ]]; then"
278
     echo "        ${app_name_upper}_DOMAIN_NAME='${app_name}.local'"
277
     echo "        ${app_name_upper}_DOMAIN_NAME='${app_name}.local'"
279
     echo "        write_config_param \"${app_name_upper}_DOMAIN_NAME\" \"\$${app_name_upper}_DOMAIN_NAME\""
278
     echo "        write_config_param \"${app_name_upper}_DOMAIN_NAME\" \"\$${app_name_upper}_DOMAIN_NAME\""
280
     echo '    else'
279
     echo '    else'
281
-    echo "        interactive_site_details \"${app_name}\" \"${app_name_upper}_DOMAIN_NAME\" \"${app_name}_CODE\""
280
+    echo "        interactive_site_details \"${app_name}\" \"${app_name_upper}_DOMAIN_NAME\" \"${app_name_upper}_CODE\""
282
     echo '    fi'
281
     echo '    fi'
283
 else
282
 else
284
     echo "    echo -n ''"
283
     echo "    echo -n ''"
292
 echo ''
291
 echo ''
293
 echo "    read_config_param '${app_name_upper}_DOMAIN_NAME'"
292
 echo "    read_config_param '${app_name_upper}_DOMAIN_NAME'"
294
 echo ''
293
 echo ''
295
-echo "    \${PROJECT_NAME}-pass -u \"\$curr_username\" -a ${app_name} -p \"\$new_user_password\""
294
+echo "    \"\${PROJECT_NAME}-pass\" -u \"\$curr_username\" -a ${app_name} -p \"\$new_user_password\""
296
 echo '}'
295
 echo '}'
297
 
296
 
298
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" || "$database_type" == "postgres"* ]]; then
297
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" || "$database_type" == "postgres"* ]]; then
361
 echo '        return'
360
 echo '        return'
362
 echo '    fi'
361
 echo '    fi'
363
 echo ''
362
 echo ''
364
-echo "    if grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
363
+echo "    if grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
365
 echo "        ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
364
 echo "        ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
366
 echo '    fi'
365
 echo '    fi'
367
 echo ''
366
 echo ''
368
 echo '    # update to the next commit'
367
 echo '    # update to the next commit'
369
 if [ ! "$app_dir" ]; then
368
 if [ ! "$app_dir" ]; then
370
-    echo "    set_repo_commit /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\" \$${app_name_upper}_REPO"
371
-    echo "    chown -R www-data:www-data /var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs"
369
+    echo "    set_repo_commit \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\" \$${app_name_upper}_REPO"
370
+    echo "    chown -R www-data:www-data \"/var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs\""
372
 else
371
 else
373
-    echo "    set_repo_commit ${app_dir} \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\" \$${app_name_upper}_REPO"
374
-    echo "    chown -R ${app_name}:${app_name} ${app_dir}"
372
+    echo "    set_repo_commit \"${app_dir}\" \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\" \$${app_name_upper}_REPO"
373
+    echo "    chown -R ${app_name}:${app_name} \"${app_dir}\""
375
 fi
374
 fi
376
 echo '}'
375
 echo '}'
377
 echo ''
376
 echo ''
378
 echo "function backup_local_${app_name} {"
377
 echo "function backup_local_${app_name} {"
379
 echo "    ${app_name_upper}_DOMAIN_NAME='${app_name}'"
378
 echo "    ${app_name_upper}_DOMAIN_NAME='${app_name}'"
380
-echo "    if grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
379
+echo "    if grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
381
 echo "        ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
380
 echo "        ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
382
 echo '    fi'
381
 echo '    fi'
383
 echo ''
382
 echo ''
387
     echo "    source_directory=${app_dir}"
386
     echo "    source_directory=${app_dir}"
388
 fi
387
 fi
389
 echo ''
388
 echo ''
390
-echo "    suspend_site \${${app_name_upper}_DOMAIN_NAME}"
389
+echo "    suspend_site \"\${${app_name_upper}_DOMAIN_NAME}\""
391
 echo ''
390
 echo ''
392
 echo "    dest_directory=${app_name}"
391
 echo "    dest_directory=${app_name}"
393
-echo "    backup_directory_to_usb \$source_directory \$dest_directory"
392
+echo "    backup_directory_to_usb \"\$source_directory\" \$dest_directory"
394
 echo ''
393
 echo ''
395
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
394
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
396
     echo "    backup_database_to_usb ${app_name}"
395
     echo "    backup_database_to_usb ${app_name}"
405
 echo '}'
404
 echo '}'
406
 echo ''
405
 echo ''
407
 echo "function restore_local_${app_name} {"
406
 echo "function restore_local_${app_name} {"
408
-echo "    if ! grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
407
+echo "    if ! grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
409
 echo '        return'
408
 echo '        return'
410
 echo '    fi'
409
 echo '    fi'
411
 echo "    ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
410
 echo "    ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
412
-echo "    if [ \$${app_name_upper}_DOMAIN_NAME ]; then"
411
+echo "    if [ \"\$${app_name_upper}_DOMAIN_NAME\" ]; then"
413
 echo "        temp_restore_dir=/root/temp${app_name}"
412
 echo "        temp_restore_dir=/root/temp${app_name}"
414
 if [ ! "$app_dir" ]; then
413
 if [ ! "$app_dir" ]; then
415
     echo "        ${app_name}_dir=/var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs"
414
     echo "        ${app_name}_dir=/var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs"
438
 fi
437
 fi
439
 echo "        restore_directory_from_usb \$temp_restore_dir ${app_name}"
438
 echo "        restore_directory_from_usb \$temp_restore_dir ${app_name}"
440
 echo "        if [ -d \$temp_restore_dir ]; then"
439
 echo "        if [ -d \$temp_restore_dir ]; then"
441
-echo "            if [ -d cp \$temp_restore_dir\$${app_name}_dir ]; then"
442
-echo "                cp -rp \$temp_restore_dir\$${app_name}_dir/* \$${app_name}_dir/"
440
+echo "            if [ -d \"\$temp_restore_dir\$${app_name}_dir\" ]; then"
441
+echo "                cp -rp \"\$temp_restore_dir\$${app_name}_dir\"/* \"\$${app_name}_dir\"/"
443
 echo '            else'
442
 echo '            else'
444
-echo "                if [ ! -d \$${app_name}_dir ]; then"
445
-echo "                    mkdir \$${app_name}_dir"
443
+echo "                if [ ! -d \"\$${app_name}_dir\" ]; then"
444
+echo "                    mkdir \"\$${app_name}_dir\""
446
 echo '                fi'
445
 echo '                fi'
447
-echo "                cp -rp \$temp_restore_dir/* \$${app_name}_dir/"
446
+echo "                cp -rp \"\$temp_restore_dir\"/* \"\$${app_name}_dir\"/"
448
 echo '            fi'
447
 echo '            fi'
449
-echo "            chown -R www-data:www-data \$${app_name}_dir"
448
+echo "            chown -R www-data:www-data \"\$${app_name}_dir\""
450
 echo "            rm -rf \$temp_restore_dir"
449
 echo "            rm -rf \$temp_restore_dir"
451
 echo '        fi'
450
 echo '        fi'
452
 echo ''
451
 echo ''
455
 echo ''
454
 echo ''
456
 echo "function backup_remote_${app_name} {"
455
 echo "function backup_remote_${app_name} {"
457
 echo "    ${app_name_upper}_DOMAIN_NAME='${app_name}'"
456
 echo "    ${app_name_upper}_DOMAIN_NAME='${app_name}'"
458
-echo "    if grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
457
+echo "    if grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
459
 echo "        ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
458
 echo "        ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
460
 echo '    fi'
459
 echo '    fi'
461
 echo ''
460
 echo ''
465
     echo "    source_directory=${app_dir}"
464
     echo "    source_directory=${app_dir}"
466
 fi
465
 fi
467
 echo ''
466
 echo ''
468
-echo "    suspend_site \${${app_name_upper}_DOMAIN_NAME}"
467
+echo "    suspend_site \"\${${app_name_upper}_DOMAIN_NAME}\""
469
 echo ''
468
 echo ''
470
 echo "    dest_directory=${app_name}"
469
 echo "    dest_directory=${app_name}"
471
-echo "    backup_directory_to_friend \$source_directory \$dest_directory"
472
-echo ''
470
+echo "    backup_directory_to_friend \"\$source_directory\" \$dest_directory"
473
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
471
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
474
     echo "    backup_database_to_friend ${app_name}"
472
     echo "    backup_database_to_friend ${app_name}"
473
+    echo ''
475
 fi
474
 fi
476
 if [[ "$database_type" == "postgres"* ]]; then
475
 if [[ "$database_type" == "postgres"* ]]; then
477
     echo '    USE_POSTGRESQL=1'
476
     echo '    USE_POSTGRESQL=1'
483
 echo '}'
482
 echo '}'
484
 echo ''
483
 echo ''
485
 echo "function restore_remote_${app_name} {"
484
 echo "function restore_remote_${app_name} {"
486
-echo "    if ! grep -q \"${app_name} domain\" \$COMPLETION_FILE; then"
485
+echo "    if ! grep -q \"${app_name} domain\" \"\$COMPLETION_FILE\"; then"
487
 echo '        return'
486
 echo '        return'
488
 echo '    fi'
487
 echo '    fi'
489
 echo "    ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
488
 echo "    ${app_name_upper}_DOMAIN_NAME=\$(get_completion_param \"${app_name} domain\")"
490
-echo "    if [ \$${app_name_upper}_DOMAIN_NAME ]; then"
489
+echo "    if [ \"\$${app_name_upper}_DOMAIN_NAME\" ]; then"
491
 echo "        temp_restore_dir=/root/temp${app_name}"
490
 echo "        temp_restore_dir=/root/temp${app_name}"
492
 if [ ! "$app_dir" ]; then
491
 if [ ! "$app_dir" ]; then
493
     echo "        ${app_name}_dir=/var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs"
492
     echo "        ${app_name}_dir=/var/www/\${${app_name_upper}_DOMAIN_NAME}/htdocs"
499
     echo "        ${app_name}_create_database"
498
     echo "        ${app_name}_create_database"
500
     echo ''
499
     echo ''
501
     echo "        restore_database_from_friend ${app_name}"
500
     echo "        restore_database_from_friend ${app_name}"
502
-    echo "        if [ -d \$temp_restore_dir ]; then"
501
+    echo "        if [ -d \"\$temp_restore_dir\" ]; then"
503
     echo "            rm -rf \$temp_restore_dir"
502
     echo "            rm -rf \$temp_restore_dir"
504
     echo '        fi'
503
     echo '        fi'
505
     echo ''
504
     echo ''
509
     echo ''
508
     echo ''
510
     echo '        USE_POSTGRESQL=1'
509
     echo '        USE_POSTGRESQL=1'
511
     echo "        restore_database_from_friend ${app_name}"
510
     echo "        restore_database_from_friend ${app_name}"
512
-    echo "        if [ -d \$temp_restore_dir ]; then"
511
+    echo "        if [ -d \"\$temp_restore_dir\" ]; then"
513
     echo "            rm -rf \$temp_restore_dir"
512
     echo "            rm -rf \$temp_restore_dir"
514
     echo '        fi'
513
     echo '        fi'
515
     echo ''
514
     echo ''
516
 fi
515
 fi
517
 echo "        restore_directory_from_friend \$temp_restore_dir ${app_name}"
516
 echo "        restore_directory_from_friend \$temp_restore_dir ${app_name}"
518
 echo "        if [ -d \$temp_restore_dir ]; then"
517
 echo "        if [ -d \$temp_restore_dir ]; then"
519
-echo "            if [ -d cp \$temp_restore_dir\$${app_name}_dir ]; then"
520
-echo "                cp -rp \$temp_restore_dir\$${app_name}_dir/* \$${app_name}_dir/"
518
+echo "            if [ -d \"\$temp_restore_dir\$${app_name}_dir\" ]; then"
519
+echo "                cp -rp \"\$temp_restore_dir\$${app_name}_dir\"/* \"\$${app_name}_dir\"/"
521
 echo '            else'
520
 echo '            else'
522
-echo "                if [ ! -d \$${app_name}_dir ]; then"
523
-echo "                    mkdir \$${app_name}_dir"
521
+echo "                if [ ! -d \"\$${app_name}_dir\" ]; then"
522
+echo "                    mkdir \"\$${app_name}_dir\""
524
 echo '                fi'
523
 echo '                fi'
525
-echo "                cp -rp \$temp_restore_dir/* \$${app_name}_dir/"
524
+echo "                cp -rp \$temp_restore_dir/* \"\$${app_name}_dir\"/"
526
 echo '            fi'
525
 echo '            fi'
527
-echo "            chown -R www-data:www-data \$${app_name}_dir"
526
+echo "            chown -R www-data:www-data \"\$${app_name}_dir\""
528
 echo "            rm -rf \$temp_restore_dir"
527
 echo "            rm -rf \$temp_restore_dir"
529
 echo '        fi'
528
 echo '        fi'
530
 echo ''
529
 echo ''
536
     echo "    remove_nodejs ${app_name}"
535
     echo "    remove_nodejs ${app_name}"
537
     echo ''
536
     echo ''
538
 fi
537
 fi
539
-echo "    nginx_dissite \$${app_name_upper}_DOMAIN_NAME"
540
-echo "    remove_certs \$${app_name_upper}_DOMAIN_NAME"
538
+echo "    nginx_dissite \"\$${app_name_upper}_DOMAIN_NAME\""
539
+echo "    remove_certs \"\$${app_name_upper}_DOMAIN_NAME\""
541
 echo ''
540
 echo ''
542
 if [ $app_daemon ]; then
541
 if [ $app_daemon ]; then
543
     echo "    if [ -f /etc/systemd/system/${app_name}.service ]; then"
542
     echo "    if [ -f /etc/systemd/system/${app_name}.service ]; then"
548
     echo "    userdel -r ${app_name}"
547
     echo "    userdel -r ${app_name}"
549
 fi
548
 fi
550
 echo ''
549
 echo ''
551
-echo "    if [ -d /var/www/\$${app_name_upper}_DOMAIN_NAME ]; then"
552
-echo "        rm -rf /var/www/\$${app_name_upper}_DOMAIN_NAME"
550
+echo "    if [ -d \"/var/www/\$${app_name_upper}_DOMAIN_NAME\" ]; then"
551
+echo "        rm -rf \"/var/www/\$${app_name_upper}_DOMAIN_NAME\""
553
 echo '    fi'
552
 echo '    fi'
554
-echo "    if [ -f /etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME ]; then"
555
-echo "        rm /etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME"
553
+echo "    if [ -f \"/etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME\" ]; then"
554
+echo "        rm \"/etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME\""
556
 echo '    fi'
555
 echo '    fi'
557
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
556
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
558
     echo "    drop_database ${app_name}"
557
     echo "    drop_database ${app_name}"
566
 echo '    fi'
565
 echo '    fi'
567
 echo "    remove_app ${app_name}"
566
 echo "    remove_app ${app_name}"
568
 echo "    remove_completion_param install_${app_name}"
567
 echo "    remove_completion_param install_${app_name}"
569
-echo "    sed -i '/${app_name}/d' \$COMPLETION_FILE"
568
+echo "    sed -i '/${app_name}/d' \"\$COMPLETION_FILE\""
570
 if [ "$app_port" ]; then
569
 if [ "$app_port" ]; then
571
     echo ''
570
     echo ''
572
     echo "    firewall_remove ${app_port} tcp"
571
     echo "    firewall_remove ${app_port} tcp"
573
 fi
572
 fi
574
 echo ''
573
 echo ''
575
-echo "    remove_ddns_domain \$${app_name_upper}_DOMAIN_NAME"
574
+echo "    remove_ddns_domain \"\$${app_name_upper}_DOMAIN_NAME\""
576
 echo '}'
575
 echo '}'
577
 echo ''
576
 echo ''
578
 echo "function install_${app_name} {"
577
 echo "function install_${app_name} {"
594
     echo '    apt-get -yq install memcached php-memcached php-intl exiftool libfcgi0ldbl'
593
     echo '    apt-get -yq install memcached php-memcached php-intl exiftool libfcgi0ldbl'
595
     echo ''
594
     echo ''
596
 fi
595
 fi
597
-echo "    if [ ! -d /var/www/\$${app_name_upper}_DOMAIN_NAME ]; then"
598
-echo "        mkdir /var/www/\$${app_name_upper}_DOMAIN_NAME"
596
+
597
+echo "    if [ ! \"\$${app_name_upper}_DOMAIN_NAME\" ]; then"
598
+echo "        echo \$'No domain name was given'"
599
+echo '        exit 3568356'
600
+echo '    fi'
601
+echo ''
602
+echo "    if [ -d \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" ]; then"
603
+echo "        rm -rf \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
599
 echo '    fi'
604
 echo '    fi'
600
-echo "    if [ ! -d /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs ]; then"
601
-echo "        if [ -d /repos/${app_name} ]; then"
602
-echo "            mkdir /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
605
+
606
+echo "      if [ -d /repos/${app_name} ]; then"
607
+echo "          mkdir \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
603
 if [ ! "$app_dir" ]; then
608
 if [ ! "$app_dir" ]; then
604
-    echo "            cp -r -p /repos/${app_name}/. /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
605
-    echo "            cd /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
609
+    echo "          cp -r -p /repos/${app_name}/. \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
610
+    echo "          cd \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" || exit 324687356"
606
 else
611
 else
607
-    echo "            cp -r -p /repos/${app_name}/. ${app_dir}"
608
-    echo "            cd ${app_dir}"
612
+    echo "          cp -r -p /repos/${app_name}/. \"${app_dir}\""
613
+    echo "          cd \"${app_dir}\" || exit 36487365"
609
 fi
614
 fi
610
-echo '            git pull'
611
-echo '        else'
615
+echo '          git pull'
616
+echo '      else'
612
 if [ ! "$app_dir" ]; then
617
 if [ ! "$app_dir" ]; then
613
-    echo "            git_clone \$${app_name_upper}_REPO /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
618
+    echo "          git_clone \$${app_name_upper}_REPO \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
614
 else
619
 else
615
-    echo "            git_clone \$${app_name_upper}_REPO ${app_dir}"
620
+    echo "          git_clone \$${app_name_upper}_REPO \"${app_dir}\""
616
 fi
621
 fi
617
-echo '        fi'
622
+echo '      fi'
618
 echo ''
623
 echo ''
619
 if [ ! "$app_dir" ]; then
624
 if [ ! "$app_dir" ]; then
620
-    echo "        if [ ! -d /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs ]; then"
625
+    echo "        if [ ! -d \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" ]; then"
621
 else
626
 else
622
-    echo "        if [ ! -d ${app_dir} ]; then"
627
+    echo "        if [ ! -d \"${app_dir}\" ]; then"
623
 fi
628
 fi
624
 echo "            echo \$'Unable to clone ${app_name} repo'"
629
 echo "            echo \$'Unable to clone ${app_name} repo'"
625
 echo '            exit 87525'
630
 echo '            exit 87525'
626
 echo '        fi'
631
 echo '        fi'
627
-echo '    fi'
628
 echo ''
632
 echo ''
629
 if [ ! "$app_dir" ]; then
633
 if [ ! "$app_dir" ]; then
630
-    echo "    cd /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
634
+    echo "    cd \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\" || exit 36587356"
631
 else
635
 else
632
-    echo "    cd ${app_dir}"
636
+    echo "    cd \"${app_dir}\" || exit 3463754637"
633
 fi
637
 fi
634
 echo "    git checkout \$${app_name_upper}_COMMIT -b \$${app_name_upper}_COMMIT"
638
 echo "    git checkout \$${app_name_upper}_COMMIT -b \$${app_name_upper}_COMMIT"
635
 echo "    set_completion_param \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\""
639
 echo "    set_completion_param \"${app_name} commit\" \"\$${app_name_upper}_COMMIT\""
636
 echo ''
640
 echo ''
637
-echo "    chmod g+w /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
638
-echo "    chown -R www-data:www-data /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs"
641
+echo "    chmod g+w \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
642
+echo "    chown -R www-data:www-data \"/var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs\""
639
 
643
 
640
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" || "$database_type" == "postgres"*  ]]; then
644
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" || "$database_type" == "postgres"*  ]]; then
641
     echo ''
645
     echo ''
642
     echo "    ${app_name}_create_database"
646
     echo "    ${app_name}_create_database"
643
 fi
647
 fi
644
 echo ''
648
 echo ''
645
-echo "    add_ddns_domain \$${app_name_upper}_DOMAIN_NAME"
649
+echo "    add_ddns_domain \"\$${app_name_upper}_DOMAIN_NAME\""
646
 echo ''
650
 echo ''
647
 echo "    ${app_name_upper}_ONION_HOSTNAME=\$(add_onion_service ${app_name} 80 \${${app_name_upper}_ONION_PORT})"
651
 echo "    ${app_name_upper}_ONION_HOSTNAME=\$(add_onion_service ${app_name} 80 \${${app_name_upper}_ONION_PORT})"
648
 echo ''
652
 echo ''
649
 echo "    ${app_name}_nginx_site=/etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME"
653
 echo "    ${app_name}_nginx_site=/etc/nginx/sites-available/\$${app_name_upper}_DOMAIN_NAME"
650
 
654
 
651
-if [ $app_onion_only ]; then
655
+if [ ! $app_onion_only ]; then
652
     echo "    if [[ \"\$ONION_ONLY\" == \"no\" ]]; then"
656
     echo "    if [[ \"\$ONION_ONLY\" == \"no\" ]]; then"
653
     if [[ "$app_php" == 'yes' ]]; then
657
     if [[ "$app_php" == 'yes' ]]; then
654
-        echo "        nginx_http_redirect \$${app_name_upper}_DOMAIN_NAME \"index index.php\""
658
+        echo "        nginx_http_redirect \"\$${app_name_upper}_DOMAIN_NAME\" \"index index.php\""
655
     else
659
     else
656
-        echo "        nginx_http_redirect \$${app_name_upper}_DOMAIN_NAME \"index index.html\""
660
+        echo "        nginx_http_redirect \"\$${app_name_upper}_DOMAIN_NAME\" \"index index.html\""
657
     fi
661
     fi
658
-    echo "        echo 'server {' >> \$${app_name}_nginx_site"
659
-    echo "        echo '  listen 443 ssl;' >> \$${app_name}_nginx_site"
660
-    echo "        echo '  #listen [::]:443 ssl;' >> \$${app_name}_nginx_site"
661
-    echo "        echo \"  server_name \$${app_name_upper}_DOMAIN_NAME;\" >> \$${app_name}_nginx_site"
662
-    echo "        echo '' >> \$${app_name}_nginx_site"
663
-    echo "        nginx_compress \$${app_name_upper}_DOMAIN_NAME"
664
-    echo "        echo '' >> \$${app_name}_nginx_site"
665
-    echo "        echo '  # Security' >> \$${app_name}_nginx_site"
666
-    echo "        nginx_ssl \$${app_name_upper}_DOMAIN_NAME"
667
-    echo ''
668
-    echo "        nginx_security_options \$${app_name_upper}_DOMAIN_NAME"
669
-    echo ''
670
-    echo "        echo '  add_header Strict-Transport-Security max-age=15768000;' >> \$${app_name}_nginx_site"
671
-    echo "        echo '' >> \$${app_name}_nginx_site"
672
-    echo "        echo '  # Logs' >> \$${app_name}_nginx_site"
673
-    echo "        echo '  access_log /dev/null;' >> \$${app_name}_nginx_site"
674
-    echo "        echo '  error_log /dev/null;' >> \$${app_name}_nginx_site"
675
-    echo "        echo '' >> \$${app_name}_nginx_site"
676
-    echo "        echo '  # Root' >> \$${app_name}_nginx_site"
677
-    echo "        echo \"  root /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs;\" >> \$${app_name}_nginx_site"
678
-    echo "        echo '' >> \$${app_name}_nginx_site"
662
+    echo "        { echo 'server {';"
663
+    echo "          echo '  listen 443 ssl;';"
664
+    echo "          echo '  #listen [::]:443 ssl;';"
665
+    echo "          echo \"  server_name \$${app_name_upper}_DOMAIN_NAME;\";"
666
+    echo "          echo ''; } >> \"\$${app_name}_nginx_site\""
667
+    echo "        nginx_compress \"\$${app_name_upper}_DOMAIN_NAME\""
668
+    echo "        echo '' >> \"\$${app_name}_nginx_site\""
669
+    echo "        echo '  # Security' >> \"\$${app_name}_nginx_site\""
670
+    echo "        nginx_ssl \"\$${app_name_upper}_DOMAIN_NAME\""
671
+    echo ''
672
+    echo "        nginx_security_options \"\$${app_name_upper}_DOMAIN_NAME\""
673
+    echo ''
674
+    echo "        { echo '  add_header Strict-Transport-Security max-age=15768000;';"
675
+    echo "          echo '';"
676
+    echo "          echo '  # Logs';"
677
+    echo "          echo '  access_log /dev/null;';"
678
+    echo "          echo '  error_log /dev/null;';"
679
+    echo "          echo '';"
680
+    echo "          echo '  # Root';"
681
+    echo "          echo \"  root /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs;\";"
682
+    echo "          echo '';"
679
     if [[ "$app_php" == 'yes' ]]; then
683
     if [[ "$app_php" == 'yes' ]]; then
680
-        echo "        echo '  index index.php;' >> \$${app_name}_nginx_site"
681
-        echo "        echo '  location ~ \\.php {' >> \$${app_name}_nginx_site"
682
-        echo "        echo '    include snippets/fastcgi-php.conf;' >> \$${app_name}_nginx_site"
683
-        echo "        echo '    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> \$${app_name}_nginx_site"
684
-        echo "        echo '    fastcgi_read_timeout 30;' >> \$${app_name}_nginx_site"
685
-        echo "        echo '  }' >> \$${app_name}_nginx_site"
686
-        echo "        echo '' >> \$${app_name}_nginx_site"
684
+        echo "          echo '  index index.php;';"
685
+        echo "          echo '  location ~ \\.php {';"
686
+        echo "          echo '    include snippets/fastcgi-php.conf;';"
687
+        echo "          echo '    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;';"
688
+        echo "          echo '    fastcgi_read_timeout 30;';"
689
+        echo "          echo '    fastcgi_param HTTPS on;';"
690
+        echo "          echo '  }';"
691
+        echo "          echo '';"
687
     else
692
     else
688
-        echo "        echo '  index index.html;' >> \$${app_name}_nginx_site"
693
+        echo "        echo '  index index.html;';"
689
     fi
694
     fi
690
-    echo "        echo '  # Location' >> \$${app_name}_nginx_site"
691
-    echo "        echo '  location / {' >> \$${app_name}_nginx_site"
692
-    echo "        nginx_limits \$${app_name_upper}_DOMAIN_NAME '15m'"
695
+    echo "          echo '  # Location';"
696
+    echo "          echo '  location / {'; } >> \"\$${app_name}_nginx_site\""
697
+    echo "        nginx_limits \"\$${app_name_upper}_DOMAIN_NAME\" '15m'"
693
     if [ ! $app_daemon ]; then
698
     if [ ! $app_daemon ]; then
694
-        echo "        echo '    try_files \$uri \$uri/ /index.html;' >> \$${app_name}_nginx_site"
699
+        if [[ "$app_php" != 'yes' ]]; then
700
+            echo "        { echo \"    try_files \\\$uri \\\$uri/ /index.html;\";"
701
+        else
702
+            echo "        { echo \"    try_files \\\$uri \\\$uri/ /index.php?\\\$args;\";"
703
+        fi
695
     else
704
     else
696
-        echo "        echo \"    proxy_pass http://localhost:\$${app_name_upper}_PORT_INTERNAL;\" >> \$${app_name}_nginx_site"
705
+        echo "        { echo \"    proxy_pass http://localhost:\$${app_name_upper}_PORT_INTERNAL;\";"
697
     fi
706
     fi
698
-    echo "        echo '  }' >> \$${app_name}_nginx_site"
699
-    echo "        echo '}' >> \$${app_name}_nginx_site"
707
+    echo "          echo '  }';"
708
+    echo "          echo '}'; } >> \"\$${app_name}_nginx_site\""
700
     echo '    else'
709
     echo '    else'
701
-    echo "        echo -n '' > \$${app_name}_nginx_site"
710
+    echo "        echo -n '' > \"\$${app_name}_nginx_site\""
702
     echo '    fi'
711
     echo '    fi'
703
 else
712
 else
704
-    echo "    echo -n '' > \$${app_name}_nginx_site"
705
-fi
706
-echo "    echo 'server {' >> \$${app_name}_nginx_site"
707
-echo "    echo \"    listen 127.0.0.1:\$${app_name_upper}_ONION_PORT default_server;\" >> \$${app_name}_nginx_site"
708
-echo "    echo \"    server_name \$${app_name_upper}_ONION_HOSTNAME;\" >> \$${app_name}_nginx_site"
709
-echo "    echo '' >> \$${app_name}_nginx_site"
710
-echo "    nginx_compress \$${app_name_upper}_DOMAIN_NAME"
711
-echo "    echo '' >> \$${app_name}_nginx_site"
712
-echo "    nginx_security_options \$${app_name_upper}_DOMAIN_NAME"
713
-echo "    echo '' >> \$${app_name}_nginx_site"
714
-echo "    echo '  # Logs' >> \$${app_name}_nginx_site"
715
-echo "    echo '  access_log /dev/null;' >> \$${app_name}_nginx_site"
716
-echo "    echo '  error_log /dev/null;' >> \$${app_name}_nginx_site"
717
-echo "    echo '' >> \$${app_name}_nginx_site"
718
-echo "    echo '  # Root' >> \$${app_name}_nginx_site"
719
-echo "    echo \"  root /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs;\" >> \$${app_name}_nginx_site"
720
-echo "    echo '' >> \$${app_name}_nginx_site"
713
+    echo "    echo -n '' > \"\$${app_name}_nginx_site\""
714
+fi
715
+echo "    { echo 'server {';"
716
+echo "      echo \"    listen 127.0.0.1:\$${app_name_upper}_ONION_PORT default_server;\";"
717
+echo "      echo \"    server_name \$${app_name_upper}_ONION_HOSTNAME;\";"
718
+echo "      echo ''; } >> \"\$${app_name}_nginx_site\""
719
+echo "    nginx_compress \"\$${app_name_upper}_DOMAIN_NAME\""
720
+echo "    echo '' >> \"\$${app_name}_nginx_site\""
721
+echo "    nginx_security_options \"\$${app_name_upper}_DOMAIN_NAME\""
722
+echo "    { echo '';"
723
+echo "      echo '  # Logs';"
724
+echo "      echo '  access_log /dev/null;';"
725
+echo "      echo '  error_log /dev/null;';"
726
+echo "      echo '';"
727
+echo "      echo '  # Root';"
728
+echo "      echo \"  root /var/www/\$${app_name_upper}_DOMAIN_NAME/htdocs;\";"
729
+echo "      echo '';"
721
 if [[ "$app_php" == 'yes' ]]; then
730
 if [[ "$app_php" == 'yes' ]]; then
722
-    echo "    echo '  index index.php;' >> \$${app_name}_nginx_site"
723
-    echo "    echo '  location ~ \\.php {' >> \$${app_name}_nginx_site"
724
-    echo "    echo '    include snippets/fastcgi-php.conf;' >> \$${app_name}_nginx_site"
725
-    echo "    echo '    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> \$${app_name}_nginx_site"
726
-    echo "    echo '    fastcgi_read_timeout 30;' >> \$${app_name}_nginx_site"
727
-    echo "    echo '  }' >> \$${app_name}_nginx_site"
728
-    echo "    echo '' >> \$${app_name}_nginx_site"
731
+    echo "      echo '  index index.php;';"
732
+    echo "      echo '  location ~ \\.php {';"
733
+    echo "      echo '    include snippets/fastcgi-php.conf;';"
734
+    echo "      echo '    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;';"
735
+    echo "      echo '    fastcgi_read_timeout 30;';"
736
+    echo "      echo '    fastcgi_param HTTPS off;';"
737
+    echo "      echo '  }';"
738
+    echo "      echo '';"
729
 else
739
 else
730
-    echo "        echo '  index index.html;' >> \$${app_name}_nginx_site"
740
+    echo "        echo '  index index.html;';"
731
 fi
741
 fi
732
-echo "    echo '  # Location' >> \$${app_name}_nginx_site"
733
-echo "    echo '  location / {' >> \$${app_name}_nginx_site"
734
-echo "    nginx_limits \$${app_name_upper}_DOMAIN_NAME '15m'"
742
+echo "      echo '  # Location';"
743
+echo "      echo '  location / {'; } >> \"\$${app_name}_nginx_site\""
744
+echo "    nginx_limits \"\$${app_name_upper}_DOMAIN_NAME\" '15m'"
735
 if [ ! $app_daemon ]; then
745
 if [ ! $app_daemon ]; then
736
-    echo "    echo '    try_files \$uri \$uri/ index.html;' >> \$${app_name}_nginx_site"
746
+    if [[ "$app_php" != 'yes' ]]; then
747
+        echo "    { echo \"    try_files \\\$uri \\\$uri/ index.html;\";"
748
+    else
749
+        echo "    { echo \"    try_files \\\$uri \\\$uri/ index.php?\\\$args;\";"
750
+    fi
737
 else
751
 else
738
-    echo "    echo \"    proxy_pass http://localhost:\$${app_name_upper}_PORT_INTERNAL;\" >> \$${app_name}_nginx_site"
752
+    echo "      echo \"    proxy_pass http://localhost:\$${app_name_upper}_PORT_INTERNAL;\";"
739
 fi
753
 fi
740
-echo "    echo '  }' >> \$${app_name}_nginx_site"
741
-echo "    echo '}' >> \$${app_name}_nginx_site"
754
+echo "      echo '  }';"
755
+echo "      echo '}'; } >> \"\$${app_name}_nginx_site\""
742
 if [[ "$app_php" == 'yes' ]]; then
756
 if [[ "$app_php" == 'yes' ]]; then
743
     echo ''
757
     echo ''
744
     echo '    configure_php'
758
     echo '    configure_php'
745
 fi
759
 fi
746
 if [ $app_daemon ]; then
760
 if [ $app_daemon ]; then
747
     echo ''
761
     echo ''
748
-    echo "    useradd -d TODO_PATH_TO_INSTALL -s /bin/false ${app_name}"
749
-    echo ''
750
-    echo "    echo '[Unit]' > /etc/systemd/system/${app_name}.service"
751
-    echo "    echo 'Description=${app_name}' >> /etc/systemd/system/${app_name}.service"
752
-    echo "    echo 'After=syslog.target' >> /etc/systemd/system/${app_name}.service"
753
-    echo "    echo 'After=network.target' >> /etc/systemd/system/${app_name}.service"
754
-    echo "    echo '' >> /etc/systemd/system/${app_name}.service"
755
-    echo "    echo '[Service]' >> /etc/systemd/system/${app_name}.service"
756
-    echo "    echo 'Type=simple' >> /etc/systemd/system/${app_name}.service"
757
-    echo "    echo 'User=${app_name}' >> /etc/systemd/system/${app_name}.service"
758
-    echo "    echo 'Group=${app_name}' >> /etc/systemd/system/${app_name}.service"
762
+    echo "    useradd -d \"TODO_PATH_TO_INSTALL\" -s /bin/false ${app_name}"
763
+    echo ''
764
+    echo "    { echo '[Unit]';"
765
+    echo "      echo 'Description=${app_name}';"
766
+    echo "      echo 'After=syslog.target';"
767
+    echo "      echo 'After=network.target';"
768
+    echo "      echo '';"
769
+    echo "      echo '[Service]';"
770
+    echo "      echo 'Type=simple';"
771
+    echo "      echo 'User=${app_name}';"
772
+    echo "      echo 'Group=${app_name}'; } > \"/etc/systemd/system/${app_name}.service\""
759
     if [ ! "$app_dir" ]; then
773
     if [ ! "$app_dir" ]; then
760
-        echo "    echo 'WorkingDirectory=TODO' >> /etc/systemd/system/${app_name}.service"
774
+        echo "    echo 'WorkingDirectory=TODO' >> \"/etc/systemd/system/${app_name}.service\""
761
     else
775
     else
762
-        echo "    echo 'WorkingDirectory=${app_dir}' >> /etc/systemd/system/${app_name}.service"
776
+        echo "    echo 'WorkingDirectory=${app_dir}' >> \"/etc/systemd/system/${app_name}.service\""
763
     fi
777
     fi
764
-    echo "    echo 'ExecStart=TODO' >> /etc/systemd/system/${app_name}.service"
765
-    echo "    echo 'Restart=always' >> /etc/systemd/system/${app_name}.service"
766
-    echo "    echo 'Environment=\"USER=${app_name}\"' >> /etc/systemd/system/${app_name}.service"
767
-    echo "    echo '' >> /etc/systemd/system/${app_name}.service"
768
-    echo "    echo '[Install]' >> /etc/systemd/system/${app_name}.service"
769
-    echo "    echo 'WantedBy=multi-user.target' >> /etc/systemd/system/${app_name}.service"
778
+    echo "    { echo 'ExecStart=TODO';"
779
+    echo "      echo 'Restart=always';"
780
+    echo "      echo 'Environment=\"USER=${app_name}\"';"
781
+    echo "      echo '';"
782
+    echo "      echo '[Install]';"
783
+    echo "      echo 'WantedBy=multi-user.target'; } >> \"/etc/systemd/system/${app_name}.service\""
770
     echo "    systemctl enable ${app_name}"
784
     echo "    systemctl enable ${app_name}"
771
     if [ "$app_dir" ]; then
785
     if [ "$app_dir" ]; then
772
-        echo "    chown -R ${app_name}:${app_name} ${app_dir}"
786
+        echo "    chown -R ${app_name}:${app_name} \"${app_dir}\""
773
     fi
787
     fi
774
     echo "    systemctl start ${app_name}"
788
     echo "    systemctl start ${app_name}"
775
 fi
789
 fi
776
 echo ''
790
 echo ''
777
-echo "    create_site_certificate \$${app_name_upper}_DOMAIN_NAME 'yes'"
791
+echo "    create_site_certificate \"\$${app_name_upper}_DOMAIN_NAME\" 'yes'"
778
 echo ''
792
 echo ''
779
-echo "    nginx_ensite \$${app_name_upper}_DOMAIN_NAME"
793
+echo "    nginx_ensite \"\$${app_name_upper}_DOMAIN_NAME\""
780
 echo ''
794
 echo ''
781
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
795
 if [[ "$database_type" == "mariadb" || "$database_type" == "mysql" ]]; then
782
     echo '    systemctl restart mariadb'
796
     echo '    systemctl restart mariadb'
786
 fi
800
 fi
787
 echo '    systemctl restart nginx'
801
 echo '    systemctl restart nginx'
788
 echo ''
802
 echo ''
789
-echo "    \${PROJECT_NAME}-pass -u \$MY_USERNAME -a ${app_name} -p \"\$${app_name_upper}_ADMIN_PASSWORD\""
803
+echo "    \"\${PROJECT_NAME}-pass\" -u \"\$MY_USERNAME\" -a ${app_name} -p \"\$${app_name_upper}_ADMIN_PASSWORD\""
790
 echo "    set_completion_param \"${app_name} domain\" \"\$${app_name_upper}_DOMAIN_NAME\""
804
 echo "    set_completion_param \"${app_name} domain\" \"\$${app_name_upper}_DOMAIN_NAME\""
791
 if [ "$app_port" ]; then
805
 if [ "$app_port" ]; then
792
     echo ''
806
     echo ''

+ 9
- 3
src/freedombone-upgrade View File

48
     source "$f"
48
     source "$f"
49
 done
49
 done
50
 
50
 
51
+source "/usr/share/${PROJECT_NAME}/base/${PROJECT_NAME}-base-email"
52
+
51
 read_config_param PROJECT_REPO
53
 read_config_param PROJECT_REPO
52
 read_config_param DEVELOPMENT_BRANCH
54
 read_config_param DEVELOPMENT_BRANCH
53
 read_config_param DEFAULT_DOMAIN_NAME
55
 read_config_param DEFAULT_DOMAIN_NAME
61
     fi
63
     fi
62
 fi
64
 fi
63
 
65
 
64
-if grep -q "cat /root/dbpass" /usr/bin/backupdatabases; then
65
-    # update to using the password manager
66
-    sed -i "s|cat /root/dbpass|freedombone-pass -u root -a mariadb|g" /usr/bin/backupdatabases
66
+if [ -f /usr/bin/backupdatabases ]; then
67
+    if grep -q "cat /root/dbpass" /usr/bin/backupdatabases; then
68
+        # update to using the password manager
69
+        sed -i "s|cat /root/dbpass|freedombone-pass -u root -a mariadb|g" /usr/bin/backupdatabases
70
+    fi
67
 fi
71
 fi
68
 
72
 
69
 #update-ca-certificates
73
 #update-ca-certificates
92
             exit 453536
96
             exit 453536
93
         fi
97
         fi
94
 
98
 
99
+        #rebuild_exim_with_socks
100
+        nodejs_upgrade
95
         apt-get -yq -t stretch-backports install certbot
101
         apt-get -yq -t stretch-backports install certbot
96
         email_install_tls
102
         email_install_tls
97
         email_disable_chunking
103
         email_disable_chunking

+ 7
- 2
src/freedombone-utils-avahi View File

65
     sed -i "s|#host-name=.*|host-name=P$PEER_ID|g" "$rootdir/etc/avahi/avahi-daemon.conf"
65
     sed -i "s|#host-name=.*|host-name=P$PEER_ID|g" "$rootdir/etc/avahi/avahi-daemon.conf"
66
     sed -i "s|use-ipv4=.*|use-ipv4=no|g" "$rootdir/etc/avahi/avahi-daemon.conf"
66
     sed -i "s|use-ipv4=.*|use-ipv4=no|g" "$rootdir/etc/avahi/avahi-daemon.conf"
67
     sed -i "s|use-ipv6=.*|use-ipv6=yes|g" "$rootdir/etc/avahi/avahi-daemon.conf"
67
     sed -i "s|use-ipv6=.*|use-ipv6=yes|g" "$rootdir/etc/avahi/avahi-daemon.conf"
68
-    #sed -i "s|#allow-interfaces=.*|allow-interfaces=wlan0, wlan1, wlan2, wlan3, wlan4, wlan5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
69
-    #sed -i "s|allow-interfaces=.*|allow-interfaces=wlan0, wlan1, wlan2, wlan3, wlan4, wlan5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
68
+
69
+    # Note: wlan interfaces must be allowed within avahi, otherwise the
70
+    #       *.local address will not resolve
71
+
72
+    sed -i "s|#allow-interfaces|allow-interfaces|g" "$rootdir/etc/avahi/avahi-daemon.conf"
73
+    sed -i "s|allow-interfaces=.*|allow-interfaces=wlan0, wlan1, wlan2, wlan3, wlan4, wlan5, eth0, eth1|g" "$rootdir/etc/avahi/avahi-daemon.conf"
74
+
70
     #sed -i "s|#deny-interfaces=.*|deny-interfaces=eth0, eth1, eth2, eth3, eth4, eth5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
75
     #sed -i "s|#deny-interfaces=.*|deny-interfaces=eth0, eth1, eth2, eth3, eth4, eth5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
71
     #sed -i "s|deny-interfaces=.*|deny-interfaces=eth0, eth1, eth2, eth3, eth4, eth5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
76
     #sed -i "s|deny-interfaces=.*|deny-interfaces=eth0, eth1, eth2, eth3, eth4, eth5|g" "$rootdir/etc/avahi/avahi-daemon.conf"
72
     sed -i "s|#disallow-other-stacks=.*|disallow-other-stacks=yes|g" "$rootdir/etc/avahi/avahi-daemon.conf"
77
     sed -i "s|#disallow-other-stacks=.*|disallow-other-stacks=yes|g" "$rootdir/etc/avahi/avahi-daemon.conf"

+ 2
- 2
src/freedombone-utils-dns View File

29
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
29
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
30
 
30
 
31
 # DNS
31
 # DNS
32
-NAMESERVER1='85.214.73.63'
33
-NAMESERVER2='213.73.91.35'
32
+NAMESERVER1='91.239.100.100'
33
+NAMESERVER2='89.233.43.71'
34
 NAMESERVER3='87.118.100.175'
34
 NAMESERVER3='87.118.100.175'
35
 NAMESERVER4='94.75.228.29'
35
 NAMESERVER4='94.75.228.29'
36
 NAMESERVER5='85.25.251.254'
36
 NAMESERVER5='85.25.251.254'

+ 3
- 0
src/freedombone-utils-firewall View File

603
         fi
603
         fi
604
         sed -i "/${unblocked_domain}/d" "$FIREWALL_DOMAINS"
604
         sed -i "/${unblocked_domain}/d" "$FIREWALL_DOMAINS"
605
     fi
605
     fi
606
+    if grep -q " $unblocked_domain" /etc/hosts; then
607
+        sed -i "/ $unblocked_domain/d" /etc/hosts
608
+    fi
606
 }
609
 }
607
 
610
 
608
 function firewall_drop_spoofed_packets {
611
 function firewall_drop_spoofed_packets {

+ 7
- 6
src/freedombone-utils-login View File

38
         rm -f /etc/init.d/motd
38
         rm -f /etc/init.d/motd
39
     fi
39
     fi
40
 
40
 
41
-    { echo ".---.                  .              .                   ";
42
-      echo "|                      |              |                   ";
43
-      echo "|--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-. ";
44
-      echo "|    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-' ";
45
-      echo "'    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'";
46
-      echo $'                  Freedom in the Cloud';
41
+    { echo '    _____               _           _';
42
+      echo '   |   __|___ ___ ___ _| |___ _____| |_ ___ ___ ___';
43
+      echo '   |   __|  _| -_| -_| . | . |     | . | . |   | -_|';
44
+      echo '   |__|  |_| |___|___|___|___|_|_|_|___|___|_|_|___|';
45
+      echo '';
46
+      echo $'                                Freedom in the Cloud';
47
       echo ''; } > /etc/motd
47
       echo ''; } > /etc/motd
48
+
48
     mark_completed "${FUNCNAME[0]}"
49
     mark_completed "${FUNCNAME[0]}"
49
 }
50
 }
50
 
51
 

+ 124
- 16
src/freedombone-utils-nodejs View File

35
 
35
 
36
 # change these versions at your peril. Things will often crash if you don't
36
 # change these versions at your peril. Things will often crash if you don't
37
 # have specifically the correct versions
37
 # have specifically the correct versions
38
-NODEJS_VERSION='6.11.4'
39
-NODEJS_N_VERSION='2.1.7'
40
-NPM_VERSION='4.0.5'
38
+NODEJS_VERSION='8.11.1'
39
+NODEJS_N_VERSION='2.1.8'
40
+NPM_VERSION='5.8.0'
41
 
41
 
42
 # This file keeps track of the apps needing nodejs
42
 # This file keeps track of the apps needing nodejs
43
 # so that it can be removed if tere are no apps which need it
43
 # so that it can be removed if tere are no apps which need it
60
     fi
60
     fi
61
 }
61
 }
62
 
62
 
63
+function nodejs_fix_cpu_detection {
64
+    # fix for failing cpu detection during image build with qemu, see https://github.com/npm/npm/issues/19265
65
+    if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js" ]; then
66
+        sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js"
67
+    fi
68
+
69
+    if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js" ]; then
70
+        sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js"
71
+    fi
72
+
73
+    if [ -f "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js" ]; then
74
+        sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/usr/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js"
75
+    fi
76
+
77
+
78
+    if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js" ]; then
79
+        sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/lib/farm.js"
80
+    fi
81
+
82
+    if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/node-gyp/lib/build.js" ]; then
83
+        sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/node-gyp/lib/build.js"
84
+    fi
85
+
86
+    if [ -f "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js" ]; then
87
+        sed -i "s/require('os').cpus().length/(require('os').cpus() || { length: 1 }).length/g" "$rootdir/.npm-global/lib/node_modules/npm/node_modules/worker-farm/examples/pi/index.js"
88
+    fi
89
+
90
+    # installing worker farm fixes the cpu detection bug
91
+    #$mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g worker-farm@1.6.0 --save
92
+}
93
+
63
 function mesh_install_nodejs {
94
 function mesh_install_nodejs {
64
     mesh_install_nodejs_prefix=
95
     mesh_install_nodejs_prefix=
65
     if [ "$rootdir" ]; then
96
     if [ "$rootdir" ]; then
72
     $mesh_install_nodejs_prefix wget https://deb.nodesource.com/gpgkey/nodesource.gpg.key -O /root/node.gpg.key
103
     $mesh_install_nodejs_prefix wget https://deb.nodesource.com/gpgkey/nodesource.gpg.key -O /root/node.gpg.key
73
     if [ ! -f "$rootdir/root/node.gpg.key" ]; then
104
     if [ ! -f "$rootdir/root/node.gpg.key" ]; then
74
         echo $'Unable to obtain gpg key for nodejs repo'
105
         echo $'Unable to obtain gpg key for nodejs repo'
106
+        NODE_UPGRADE=
75
         exit 6389252
107
         exit 6389252
76
     fi
108
     fi
77
     $mesh_install_nodejs_prefix apt-key add /root/node.gpg.key
109
     $mesh_install_nodejs_prefix apt-key add /root/node.gpg.key
78
-    echo "deb https://deb.nodesource.com/node_6.x stretch main" > "$rootdir/etc/apt/sources.list.d/nodesource.list"
79
-    echo "deb-src https://deb.nodesource.com/node_6.x stretch main" >> "$rootdir/etc/apt/sources.list.d/nodesource.list"
110
+    echo "deb https://deb.nodesource.com/node_8.x stretch main" > "$rootdir/etc/apt/sources.list.d/nodesource.list"
111
+    echo "deb-src https://deb.nodesource.com/node_8.x stretch main" >> "$rootdir/etc/apt/sources.list.d/nodesource.list"
80
 
112
 
113
+    $mesh_install_nodejs_prefix apt-mark -q unhold nodejs
81
     $mesh_install_nodejs_prefix apt-get update
114
     $mesh_install_nodejs_prefix apt-get update
82
     $mesh_install_nodejs_prefix apt-get -yq remove --purge nodejs
115
     $mesh_install_nodejs_prefix apt-get -yq remove --purge nodejs
83
 
116
 
84
-    if [ -d "$rootdir/usr/local/lib/node_modules" ]; then
85
-        rm -rf "$rootdir/usr/local/lib/node_modules"
117
+    if [ ! $NODE_UPGRADE ]; then
118
+        if [ -d "$rootdir/usr/local/lib/node_modules" ]; then
119
+            rm -rf "$rootdir/usr/local/lib/node_modules"
120
+        fi
86
     fi
121
     fi
122
+
87
     if [ -f "$rootdir/usr/local/bin/node" ]; then
123
     if [ -f "$rootdir/usr/local/bin/node" ]; then
88
         rm "$rootdir/usr/local/bin/node"
124
         rm "$rootdir/usr/local/bin/node"
89
     fi
125
     fi
90
     if [ -f "$rootdir/usr/bin/node" ]; then
126
     if [ -f "$rootdir/usr/bin/node" ]; then
91
-        rm /usr/bin/node
127
+        rm "$rootdir/usr/bin/node"
92
     fi
128
     fi
93
     if [ -f "$rootdir/usr/bin/nodejs" ]; then
129
     if [ -f "$rootdir/usr/bin/nodejs" ]; then
94
         rm "$rootdir/usr/bin/nodejs"
130
         rm "$rootdir/usr/bin/nodejs"
100
         cp "$rootdir/usr/bin/nodejs" "$rootdir/usr/bin/node"
136
         cp "$rootdir/usr/bin/nodejs" "$rootdir/usr/bin/node"
101
     fi
137
     fi
102
 
138
 
139
+    if [ -f "$rootdir/usr/bin/node" ]; then
140
+        cp "$rootdir/usr/bin/node" "$rootdir/usr/local/bin/node"
141
+    fi
142
+
143
+    $mesh_install_nodejs_prefix apt-mark -q hold nodejs
144
+
103
     if [ ! -f "${rootdir}/usr/bin/node" ]; then
145
     if [ ! -f "${rootdir}/usr/bin/node" ]; then
104
         if [ ! -f "${rootdir}/usr/local/bin/node" ]; then
146
         if [ ! -f "${rootdir}/usr/local/bin/node" ]; then
105
             if [ ! -f "${rootdir}/usr/bin/nodejs" ]; then
147
             if [ ! -f "${rootdir}/usr/bin/nodejs" ]; then
106
                 echo $'nodejs was not installed'
148
                 echo $'nodejs was not installed'
149
+                NODE_UPGRADE=
107
                 exit 63962
150
                 exit 63962
108
             fi
151
             fi
109
         fi
152
         fi
111
 
154
 
112
     if [ ! -f "$rootdir/usr/bin/node" ]; then
155
     if [ ! -f "$rootdir/usr/bin/node" ]; then
113
         echo $'/usr/bin/node not found'
156
         echo $'/usr/bin/node not found'
157
+        NODE_UPGRADE=
114
         exit 7235728
158
         exit 7235728
115
     fi
159
     fi
116
 
160
 
117
     get_npm_arch
161
     get_npm_arch
118
 
162
 
119
     $mesh_install_nodejs_prefix npm config set unsafe-perm true
163
     $mesh_install_nodejs_prefix npm config set unsafe-perm true
164
+    nodejs_setup_global_modules
165
+    nodejs_fix_cpu_detection
120
     $mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g npm@${NPM_VERSION} --save
166
     $mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g npm@${NPM_VERSION} --save
167
+    if [ -f "$rootdir/.npm-global/bin/npm" ]; then
168
+        cp "$rootdir/.npm-global/bin/npm" "$rootdir/usr/local/bin/npm"
169
+        cp "$rootdir/.npm-global/bin/npm" "$rootdir/usr/bin/npm"
170
+    fi
121
     if [ -f "$rootdir/usr/local/bin/npm" ]; then
171
     if [ -f "$rootdir/usr/local/bin/npm" ]; then
122
-        cp "$rootdir/usr/local/bin/npm" /usr/bin/npm
172
+        cp "$rootdir/usr/local/bin/npm" "$rootdir/usr/bin/npm"
123
     fi
173
     fi
124
     cp "$rootdir/usr/bin/npm" "$rootdir/root/npm"
174
     cp "$rootdir/usr/bin/npm" "$rootdir/root/npm"
125
 
175
 
126
     # update from the old debian nodejs version
176
     # update from the old debian nodejs version
127
     $mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g n@${NODEJS_N_VERSION} --save
177
     $mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g n@${NODEJS_N_VERSION} --save
128
-    $mesh_install_nodejs_prefix n --arch $N_ARCH ${NODEJS_VERSION}
129
-    cp "$rootdir/root/npm" "$rootdir/usr/bin/npm"
178
+    if [ ! "$rootdir" ]; then
179
+        # Don't do this if we're building an image,
180
+        # because cpu detection faults occur.
181
+        # This condition may no longer be needed in future once the bug is fixed
182
+        $mesh_install_nodejs_prefix n --arch $N_ARCH ${NODEJS_VERSION}
183
+        nodejs_fix_cpu_detection
184
+        cp "$rootdir/root/npm" "$rootdir/usr/bin/npm"
185
+        cp "$rootdir/root/npm" "$rootdir/usr/local/bin/npm"
130
 
186
 
131
-    # deliberate second install of npm
132
-    $mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g npm@${NPM_VERSION} --save
133
-    if [ -f "$rootdir/usr/local/bin/npm" ]; then
134
-        cp "$rootdir/usr/local/bin/npm" /usr/bin/npm
187
+        # deliberate second install of npm
188
+        $mesh_install_nodejs_prefix npm install --arch=$NPM_ARCH -g npm@${NPM_VERSION} --save
189
+        if [ -f "$rootdir/usr/local/bin/npm" ]; then
190
+            cp "$rootdir/usr/local/bin/npm" "$rootdir/usr/bin/npm"
191
+        fi
192
+        cp "$rootdir/usr/bin/npm" "$rootdir/root/npm"
193
+    fi
194
+    if [ -f "$rootdir/usr/bin/node" ]; then
195
+        cp "$rootdir/usr/bin/node" "$rootdir/usr/local/bin/node"
135
     fi
196
     fi
136
-    cp "$rootdir/usr/bin/npm" "$rootdir/root/npm"
137
 
197
 
138
     # check the version numbers
198
     # check the version numbers
139
     cat <<EOF > "$rootdir/usr/bin/test_nodejs_install"
199
     cat <<EOF > "$rootdir/usr/bin/test_nodejs_install"
152
     chmod +x "$rootdir/usr/bin/test_nodejs_install"
212
     chmod +x "$rootdir/usr/bin/test_nodejs_install"
153
     if ! $mesh_install_nodejs_prefix /usr/bin/test_nodejs_install; then
213
     if ! $mesh_install_nodejs_prefix /usr/bin/test_nodejs_install; then
154
         echo $"nodejs version numbers did not match. Architecture is $NPM_ARCH."
214
         echo $"nodejs version numbers did not match. Architecture is $NPM_ARCH."
215
+        NODE_UPGRADE=
155
         exit 76835282
216
         exit 76835282
156
     fi
217
     fi
157
     rm "$rootdir/usr/bin/test_nodejs_install"
218
     rm "$rootdir/usr/bin/test_nodejs_install"
219
+    NODE_UPGRADE=
220
+}
221
+
222
+function nodejs_upgrade {
223
+    if [ ! -f /etc/apt/sources.list.d/nodesource.list ]; then
224
+        return
225
+    fi
226
+    nodejs_setup_global_modules
227
+    if grep -q "node_8.x" /etc/apt/sources.list.d/nodesource.list; then
228
+        if [ -f /usr/local/bin/node ]; then
229
+            CURR_NODE_VERSION=$(node --version)
230
+            if [[ "$CURR_NODE_VERSION" == "v${NODEJS_VERSION}" ]]; then
231
+                return
232
+            fi
233
+        fi
234
+    fi
235
+    if [ -f /usr/local/bin/node ]; then
236
+        CURR_NODE_VERSION=$(node --version)
237
+        if [[ "$CURR_NODE_VERSION" == "v${NODEJS_VERSION}" ]]; then
238
+            return
239
+        fi
240
+    fi
241
+    read_config_param ARCHITECTURE
242
+    get_npm_arch
243
+    NODE_UPGRADE=1
244
+    rootdir=
245
+    mesh_install_nodejs
246
+    npm update -g
247
+}
248
+
249
+function nodejs_setup_global_modules {
250
+    if [ ! -f /usr/local/bin/node ]; then
251
+        return
252
+    fi
253
+    if [ ! -d "$rootdir/root/.npm-global" ]; then
254
+        mkdir "$rootdir/root/.npm-global"
255
+    fi
256
+    $mesh_install_nodejs_prefix npm config set prefix '/root/.npm-global'
257
+    if ! grep -q "PATH=/root/.npm-global/bin" "$rootdir/root/.bashrc"; then
258
+        echo "PATH=/root/.npm-global/bin:\$PATH" >> "$rootdir/root/.bashrc"
259
+    fi
260
+    if ! grep -q "NPM_CONFIG_PREFIX=" "$rootdir/root/.bashrc"; then
261
+        echo "export NPM_CONFIG_PREFIX=/root/.npm-global" >> "$rootdir/root/.bashrc"
262
+    fi
263
+    # shellcheck disable=SC2086
264
+    $mesh_install_nodejs_prefix export PATH=/root/.npm-global/bin:$PATH
265
+    $mesh_install_nodejs_prefix export NPM_CONFIG_PREFIX=/root/.npm-global
158
 }
266
 }
159
 
267
 
160
 function remove_nodejs {
268
 function remove_nodejs {

+ 2
- 2
src/freedombone-utils-onion View File

38
     extra_email_hostname="$1"
38
     extra_email_hostname="$1"
39
     email_hostnames=$(grep "dc_other_hostnames" /etc/exim4/update-exim4.conf.conf | awk -F "'" '{print $2}')
39
     email_hostnames=$(grep "dc_other_hostnames" /etc/exim4/update-exim4.conf.conf | awk -F "'" '{print $2}')
40
     if [[ "$email_hostnames" != *"$extra_email_hostname"* ]]; then
40
     if [[ "$email_hostnames" != *"$extra_email_hostname"* ]]; then
41
-        sed -i "s|dc_other_hostnames=.*|dc_other_hostnames='$email_hostnames;extra_email_hostname'|g" /etc/exim4/update-exim4.conf.conf
41
+        sed -i "s|dc_other_hostnames=.*|dc_other_hostnames='$email_hostnames;$extra_email_hostname'|g" /etc/exim4/update-exim4.conf.conf
42
         update-exim4.conf
42
         update-exim4.conf
43
         dpkg-reconfigure --frontend noninteractive exim4-config
43
         dpkg-reconfigure --frontend noninteractive exim4-config
44
         systemctl restart saslauthd
44
         systemctl restart saslauthd
169
     POSTACTIV_DOMAIN_NAME='postactiv.local'
169
     POSTACTIV_DOMAIN_NAME='postactiv.local'
170
     GNUSOCIAL_DOMAIN_NAME='gnusocial.local'
170
     GNUSOCIAL_DOMAIN_NAME='gnusocial.local'
171
     HTMLY_DOMAIN_NAME='htmly.local'
171
     HTMLY_DOMAIN_NAME='htmly.local'
172
-    GHOST_DOMAIN_NAME='ghost.local'
172
+    BLUDIT_DOMAIN_NAME='bludit.local'
173
     DOKUWIKI_DOMAIN_NAME='dokuwiki.local'
173
     DOKUWIKI_DOMAIN_NAME='dokuwiki.local'
174
     DEFAULT_DOMAIN_NAME="${LOCAL_NAME}.local"
174
     DEFAULT_DOMAIN_NAME="${LOCAL_NAME}.local"
175
     GIT_DOMAIN_NAME='gogs.local'
175
     GIT_DOMAIN_NAME='gogs.local'

website/EN/app_ghost.html → website/EN/app_bludit.html View File

3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
 <head>
5
 <head>
6
-<!-- 2018-02-21 Wed 16:16 -->
6
+<!-- 2018-03-31 Sat 18:25 -->
7
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8
 <meta name="viewport" content="width=device-width, initial-scale=1" />
8
 <meta name="viewport" content="width=device-width, initial-scale=1" />
9
 <title>&lrm;</title>
9
 <title>&lrm;</title>
10
 <meta name="generator" content="Org mode" />
10
 <meta name="generator" content="Org mode" />
11
 <meta name="author" content="Bob Mottram" />
11
 <meta name="author" content="Bob Mottram" />
12
-<meta name="description" content="How to use Ghost"
12
+<meta name="description" content="How to use Bludit"
13
  />
13
  />
14
-<meta name="keywords" content="freedombone, ghost" />
14
+<meta name="keywords" content="freedombone, bludit, blog" />
15
 <style type="text/css">
15
 <style type="text/css">
16
  <!--/*--><![CDATA[/*><!--*/
16
  <!--/*--><![CDATA[/*><!--*/
17
   .title  { text-align: center;
17
   .title  { text-align: center;
245
 </div>
245
 </div>
246
 
246
 
247
 <center>
247
 <center>
248
-<h1>Ghost</h1>
248
+<h1>Bludit</h1>
249
 </center>
249
 </center>
250
 
250
 
251
 <p>
251
 <p>
252
-Ghost is a blogging system which uses markdown formatted posts. It's quite simple to use, and also looks nice even on small mobile screens.
252
+This is a databaseless blogging system which uses markdown files. It's not very complex and so there is not much to go wrong, and it should run well on any server hardware.
253
 </p>
253
 </p>
254
 
254
 
255
-<div id="outline-container-orgae93cef" class="outline-2">
256
-<h2 id="orgae93cef">Installation</h2>
257
-<div class="outline-text-2" id="text-orgae93cef">
255
+<div id="outline-container-org09c48a1" class="outline-2">
256
+<h2 id="org09c48a1">Installation</h2>
257
+<div class="outline-text-2" id="text-org09c48a1">
258
 <p>
258
 <p>
259
 Log into your system with:
259
 Log into your system with:
260
 </p>
260
 </p>
269
 </p>
269
 </p>
270
 
270
 
271
 <p>
271
 <p>
272
-Select <b>Add/Remove Apps</b> then <b>ghost</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>&gt;&gt;</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>blog.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.
272
+Select <b>Add/Remove Apps</b> then <b>bluit</b>. Enter the subdomain that you which to use, such as <b>blog.mydomain.net</b>, and optionally a FreeDNS code.
273
 </p>
273
 </p>
274
 
274
 
275
 <p>
275
 <p>
276
-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 Ghost. 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.
277
-</p>
278
-</div>
279
-</div>
280
-
281
-<div id="outline-container-org1a75b29" class="outline-2">
282
-<h2 id="org1a75b29">Initial setup</h2>
283
-<div class="outline-text-2" id="text-org1a75b29">
284
-<p>
285
-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 Ghost blog domain listed there along with an onion address. You can then navigate to your site in a browser.
286
-</p>
287
-
288
-<p>
289
-To see the login password for your site go to <b>Passwords</b> on the <b>Administrator control panel</b> and select the appropriate username and app. The passwords will be different for each user and may not be the same as the password which you used to originally ssh into the system.
290
-</p>
291
-
292
-<p>
293
-Navigate to <a href="https://yourghostblogdomain/ghost">https://yourghostblogdomain/ghost</a> and click on <b>create your account</b>
294
-</p>
295
-
296
-<p>
297
-Enter your email address, password and blog title.
298
-</p>
299
-
300
-<p>
301
-When prompted to invite users click on <b>I'll do this later</b>
276
+Now in a browser navigate to your subdomain. You will need to enter some details for the database. You'll be asked to provide an initial administrator password.
302
 </p>
277
 </p>
303
 
278
 
304
 <p>
279
 <p>
305
-Under <b>Settings</b> on the <b>General</b> option you can set a description, background image and so on.
280
+From there on it's all pretty straightforward. If you need to publish a draft the post status can be changed on a drop down list on the right hand side.
306
 </p>
281
 </p>
307
 </div>
282
 </div>
308
 </div>
283
 </div>

+ 50
- 16
website/EN/app_peertube.html View File

3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
 <head>
5
 <head>
6
-<!-- 2017-12-03 Sun 12:48 -->
6
+<!-- 2018-04-01 Sun 20:32 -->
7
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8
 <meta name="viewport" content="width=device-width, initial-scale=1" />
8
 <meta name="viewport" content="width=device-width, initial-scale=1" />
9
 <title>&lrm;</title>
9
 <title>&lrm;</title>
244
 </div>
244
 </div>
245
 </div>
245
 </div>
246
 
246
 
247
-<center>
248
-<h1>PeerTube</h1>
249
-</center>
250
-
251
-<p>
252
-This is a video hosting system similar to Mediagoblin but using <a href="https://webtorrent.io/">webtorrent</a> to help distribute the files to or between clients. This should be more practical for situations where a video becomes popular because the load is then spread across the network, with performance increasing with the number of nodes. However, the torrenting aspect of it only works with WebRTC enabled browsers and so this means it's unlikely to fully work with a Tor browser. Without WebRTC then from a user point of view it's effectively the same thing as Mediagoblin.
253
-</p>
254
-
255
 <div class="org-center">
247
 <div class="org-center">
256
 
248
 
257
 <div class="figure">
249
 <div class="figure">
260
 </div>
252
 </div>
261
 </div>
253
 </div>
262
 
254
 
263
-<div id="outline-container-orgd4e2d94" class="outline-2">
264
-<h2 id="orgd4e2d94">Installation</h2>
265
-<div class="outline-text-2" id="text-orgd4e2d94">
255
+<p>
256
+This is a video hosting system similar to Mediagoblin but using webtorrent to help distribute the files to or between clients. This should be more practical for situations where a video becomes popular because the load is then spread across the network, with performance increasing with the number of nodes. However, the torrenting aspect of it only works with WebRTC enabled browsers and so this means it's unlikely to fully work with a Tor browser. Without WebRTC then from a user point of view it's effectively the same thing as Mediagoblin.
257
+</p>
258
+
259
+<div id="outline-container-org244b57b" class="outline-2">
260
+<h2 id="org244b57b">Installation</h2>
261
+<div class="outline-text-2" id="text-org244b57b">
266
 <p>
262
 <p>
267
 Log into your system with:
263
 Log into your system with:
268
 </p>
264
 </p>
282
 </div>
278
 </div>
283
 </div>
279
 </div>
284
 
280
 
285
-<div id="outline-container-org50ab03b" class="outline-2">
286
-<h2 id="org50ab03b">Initial setup</h2>
287
-<div class="outline-text-2" id="text-org50ab03b">
281
+<div id="outline-container-orgc8779c8" class="outline-2">
282
+<h2 id="orgc8779c8">Initial setup</h2>
283
+<div class="outline-text-2" id="text-orgc8779c8">
288
 <p>
284
 <p>
289
 Navigate to your site and select <b>Signup</b> to create a new account. By default the maximum number of accounts on your system is limited to a small number so that millions of random internet users can't then begin uploading dubious content. After that it's pretty straightforward.
285
 Navigate to your site and select <b>Signup</b> to create a new account. By default the maximum number of accounts on your system is limited to a small number so that millions of random internet users can't then begin uploading dubious content. After that it's pretty straightforward.
290
 </p>
286
 </p>
291
 
287
 
292
 <p>
288
 <p>
293
-One thing to be aware of is that after you upload a video it will take quite a while to transcode, and during that time you won't be able to play it or it will hang after playing. A way to avoid this wait is to ensure that your videos are already in mp4 format when you upload them.
289
+If you wish it's possible to turn off further signups via the <b>Administrator control panel</b> under <b>App settings</b> for <b>peertube</b>.
290
+</p>
291
+</div>
292
+</div>
293
+
294
+<div id="outline-container-orgb28bda0" class="outline-2">
295
+<h2 id="orgb28bda0">Importing videos from YouTube/Vimeo/Dailymotion</h2>
296
+<div class="outline-text-2" id="text-orgb28bda0">
297
+<p>
298
+It's possible to import videos from the main proprietary video hosting sites. <i>Only do this if they're videos which you made, or if the license is Creative Commons</i>. Hosting arbitrary videos under nonfree licenses is likely to get you into trouble, and we know how that works out from the P2P wars of the 2000s (i.e. badly).
299
+</p>
300
+
301
+<p>
302
+Go to the <b>Administrator control panel</b>, select <b>App settings</b> then <b>peertube</b> then <b>Import videos from YouTube/Vimeo/Dailymotion</b>. Enter your PeerTube login details and then you may specify either the individual video URL or the channel URL if you want to import a whole channel.
303
+</p>
304
+</div>
305
+</div>
306
+
307
+<div id="outline-container-orgcfb5e79" class="outline-2">
308
+<h2 id="orgcfb5e79">Importing videos from your desktop</h2>
309
+<div class="outline-text-2" id="text-orgcfb5e79">
310
+<p>
311
+The most convenient way to add new videos to PeerTube is if you have the <b>syncthing</b> app installed. Set up <a href="./app_syncthing.html">syncthing</a> with a folder called ~/Sync in your home directory. Create a subdirectory called <b>~/Sync/peertube_upload</b>. Within that directory make a text file called <b>login.txt</b>. This will contain your PeerTube login details.
312
+</p>
313
+
314
+<p>
315
+The first line of login.txt should be your username, the second line should be the password and optionally the third line can contain the words <b>public</b> and/or <b>nsfw</b>, if you want to make imported videos immediately public or mark them as not suitable for work.
316
+</p>
317
+
318
+<p>
319
+Prepare your videos in <b>ogv</b>, <b>mp4</b> or <b>webm</b> format. To minimize bandwidth usage try to keep your videos as small as possible. Giant videos with incredibly high resolution tend to result in a bad user experience. Often just converting your videos to <b>webm</b> using <b>ffmpeg</b> will keep the size down.
320
+</p>
321
+
322
+<p>
323
+Now copy or drag and drop your videos into the <b>~/Sync/peertube_upload</b> directory. Syncthing will sync to the server and automatically add the videos to PeerTube. Depending on how large the videos are this may take some time.
324
+</p>
325
+
326
+<p>
327
+Imported videos can be seen by logging into PeerTube, selecting <b>My account</b> then the <b>My videos</b> tab. You can then view them, add a description and select to make them public if you wish.
294
 </p>
328
 </p>
295
 </div>
329
 </div>
296
 </div>
330
 </div>

+ 262
- 171
website/EN/apps.html View File

3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
4
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
5
 <head>
5
 <head>
6
-<title></title>
7
-<!-- 2018-03-10 Sat 21:13 -->
8
-<meta  http-equiv="Content-Type" content="text/html;charset=utf-8" />
9
-<meta  name="generator" content="Org-mode" />
10
-<meta  name="author" content="Bob Mottram" />
11
-<meta  name="description" content="List of apps available on freedombone"
6
+<!-- 2018-03-31 Sat 18:28 -->
7
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8
+<meta name="viewport" content="width=device-width, initial-scale=1" />
9
+<title>&lrm;</title>
10
+<meta name="generator" content="Org mode" />
11
+<meta name="author" content="Bob Mottram" />
12
+<meta name="description" content="List of apps available on freedombone"
12
  />
13
  />
13
-<meta  name="keywords" content="freedombone, apps" />
14
+<meta name="keywords" content="freedombone, apps" />
14
 <style type="text/css">
15
 <style type="text/css">
15
  <!--/*--><![CDATA[/*><!--*/
16
  <!--/*--><![CDATA[/*><!--*/
16
-  .title  { text-align: center; }
17
+  .title  { text-align: center;
18
+             margin-bottom: .2em; }
19
+  .subtitle { text-align: center;
20
+              font-size: medium;
21
+              font-weight: bold;
22
+              margin-top:0; }
17
   .todo   { font-family: monospace; color: red; }
23
   .todo   { font-family: monospace; color: red; }
18
-  .done   { color: green; }
24
+  .done   { font-family: monospace; color: green; }
25
+  .priority { font-family: monospace; color: orange; }
19
   .tag    { background-color: #eee; font-family: monospace;
26
   .tag    { background-color: #eee; font-family: monospace;
20
             padding: 2px; font-size: 80%; font-weight: normal; }
27
             padding: 2px; font-size: 80%; font-weight: normal; }
21
   .timestamp { color: #bebebe; }
28
   .timestamp { color: #bebebe; }
22
   .timestamp-kwd { color: #5f9ea0; }
29
   .timestamp-kwd { color: #5f9ea0; }
23
-  .right  { margin-left: auto; margin-right: 0px;  text-align: right; }
24
-  .left   { margin-left: 0px;  margin-right: auto; text-align: left; }
25
-  .center { margin-left: auto; margin-right: auto; text-align: center; }
30
+  .org-right  { margin-left: auto; margin-right: 0px;  text-align: right; }
31
+  .org-left   { margin-left: 0px;  margin-right: auto; text-align: left; }
32
+  .org-center { margin-left: auto; margin-right: auto; text-align: center; }
26
   .underline { text-decoration: underline; }
33
   .underline { text-decoration: underline; }
27
   #postamble p, #preamble p { font-size: 90%; margin: .2em; }
34
   #postamble p, #preamble p { font-size: 90%; margin: .2em; }
28
   p.verse { margin-left: 3%; }
35
   p.verse { margin-left: 3%; }
49
     border: 1px solid black;
56
     border: 1px solid black;
50
   }
57
   }
51
   pre.src:hover:before { display: inline;}
58
   pre.src:hover:before { display: inline;}
52
-  pre.src-sh:before    { content: 'sh'; }
53
-  pre.src-bash:before  { content: 'sh'; }
59
+  /* Languages per Org manual */
60
+  pre.src-asymptote:before { content: 'Asymptote'; }
61
+  pre.src-awk:before { content: 'Awk'; }
62
+  pre.src-C:before { content: 'C'; }
63
+  /* pre.src-C++ doesn't work in CSS */
64
+  pre.src-clojure:before { content: 'Clojure'; }
65
+  pre.src-css:before { content: 'CSS'; }
66
+  pre.src-D:before { content: 'D'; }
67
+  pre.src-ditaa:before { content: 'ditaa'; }
68
+  pre.src-dot:before { content: 'Graphviz'; }
69
+  pre.src-calc:before { content: 'Emacs Calc'; }
54
   pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
70
   pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
55
-  pre.src-R:before     { content: 'R'; }
56
-  pre.src-perl:before  { content: 'Perl'; }
57
-  pre.src-java:before  { content: 'Java'; }
58
-  pre.src-sql:before   { content: 'SQL'; }
71
+  pre.src-fortran:before { content: 'Fortran'; }
72
+  pre.src-gnuplot:before { content: 'gnuplot'; }
73
+  pre.src-haskell:before { content: 'Haskell'; }
74
+  pre.src-hledger:before { content: 'hledger'; }
75
+  pre.src-java:before { content: 'Java'; }
76
+  pre.src-js:before { content: 'Javascript'; }
77
+  pre.src-latex:before { content: 'LaTeX'; }
78
+  pre.src-ledger:before { content: 'Ledger'; }
79
+  pre.src-lisp:before { content: 'Lisp'; }
80
+  pre.src-lilypond:before { content: 'Lilypond'; }
81
+  pre.src-lua:before { content: 'Lua'; }
82
+  pre.src-matlab:before { content: 'MATLAB'; }
83
+  pre.src-mscgen:before { content: 'Mscgen'; }
84
+  pre.src-ocaml:before { content: 'Objective Caml'; }
85
+  pre.src-octave:before { content: 'Octave'; }
86
+  pre.src-org:before { content: 'Org mode'; }
87
+  pre.src-oz:before { content: 'OZ'; }
88
+  pre.src-plantuml:before { content: 'Plantuml'; }
89
+  pre.src-processing:before { content: 'Processing.js'; }
90
+  pre.src-python:before { content: 'Python'; }
91
+  pre.src-R:before { content: 'R'; }
92
+  pre.src-ruby:before { content: 'Ruby'; }
93
+  pre.src-sass:before { content: 'Sass'; }
94
+  pre.src-scheme:before { content: 'Scheme'; }
95
+  pre.src-screen:before { content: 'Gnu Screen'; }
96
+  pre.src-sed:before { content: 'Sed'; }
97
+  pre.src-sh:before { content: 'shell'; }
98
+  pre.src-sql:before { content: 'SQL'; }
99
+  pre.src-sqlite:before { content: 'SQLite'; }
100
+  /* additional languages in org.el's org-babel-load-languages alist */
101
+  pre.src-forth:before { content: 'Forth'; }
102
+  pre.src-io:before { content: 'IO'; }
103
+  pre.src-J:before { content: 'J'; }
104
+  pre.src-makefile:before { content: 'Makefile'; }
105
+  pre.src-maxima:before { content: 'Maxima'; }
106
+  pre.src-perl:before { content: 'Perl'; }
107
+  pre.src-picolisp:before { content: 'Pico Lisp'; }
108
+  pre.src-scala:before { content: 'Scala'; }
109
+  pre.src-shell:before { content: 'Shell Script'; }
110
+  pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
111
+  /* additional language identifiers per "defun org-babel-execute"
112
+       in ob-*.el */
113
+  pre.src-cpp:before  { content: 'C++'; }
114
+  pre.src-abc:before  { content: 'ABC'; }
115
+  pre.src-coq:before  { content: 'Coq'; }
116
+  pre.src-groovy:before  { content: 'Groovy'; }
117
+  /* additional language identifiers from org-babel-shell-names in
118
+     ob-shell.el: ob-shell is the only babel language using a lambda to put
119
+     the execution function name together. */
120
+  pre.src-bash:before  { content: 'bash'; }
121
+  pre.src-csh:before  { content: 'csh'; }
122
+  pre.src-ash:before  { content: 'ash'; }
123
+  pre.src-dash:before  { content: 'dash'; }
124
+  pre.src-ksh:before  { content: 'ksh'; }
125
+  pre.src-mksh:before  { content: 'mksh'; }
126
+  pre.src-posh:before  { content: 'posh'; }
127
+  /* Additional Emacs modes also supported by the LaTeX listings package */
128
+  pre.src-ada:before { content: 'Ada'; }
129
+  pre.src-asm:before { content: 'Assembler'; }
130
+  pre.src-caml:before { content: 'Caml'; }
131
+  pre.src-delphi:before { content: 'Delphi'; }
132
+  pre.src-html:before { content: 'HTML'; }
133
+  pre.src-idl:before { content: 'IDL'; }
134
+  pre.src-mercury:before { content: 'Mercury'; }
135
+  pre.src-metapost:before { content: 'MetaPost'; }
136
+  pre.src-modula-2:before { content: 'Modula-2'; }
137
+  pre.src-pascal:before { content: 'Pascal'; }
138
+  pre.src-ps:before { content: 'PostScript'; }
139
+  pre.src-prolog:before { content: 'Prolog'; }
140
+  pre.src-simula:before { content: 'Simula'; }
141
+  pre.src-tcl:before { content: 'tcl'; }
142
+  pre.src-tex:before { content: 'TeX'; }
143
+  pre.src-plain-tex:before { content: 'Plain TeX'; }
144
+  pre.src-verilog:before { content: 'Verilog'; }
145
+  pre.src-vhdl:before { content: 'VHDL'; }
146
+  pre.src-xml:before { content: 'XML'; }
147
+  pre.src-nxml:before { content: 'XML'; }
148
+  /* add a generic configuration mode; LaTeX export needs an additional
149
+     (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
150
+  pre.src-conf:before { content: 'Configuration File'; }
59
 
151
 
60
   table { border-collapse:collapse; }
152
   table { border-collapse:collapse; }
61
   caption.t-above { caption-side: top; }
153
   caption.t-above { caption-side: top; }
62
   caption.t-bottom { caption-side: bottom; }
154
   caption.t-bottom { caption-side: bottom; }
63
   td, th { vertical-align:top;  }
155
   td, th { vertical-align:top;  }
64
-  th.right  { text-align: center;  }
65
-  th.left   { text-align: center;   }
66
-  th.center { text-align: center; }
67
-  td.right  { text-align: right;  }
68
-  td.left   { text-align: left;   }
69
-  td.center { text-align: center; }
156
+  th.org-right  { text-align: center;  }
157
+  th.org-left   { text-align: center;   }
158
+  th.org-center { text-align: center; }
159
+  td.org-right  { text-align: right;  }
160
+  td.org-left   { text-align: left;   }
161
+  td.org-center { text-align: center; }
70
   dt { font-weight: bold; }
162
   dt { font-weight: bold; }
71
-  .footpara:nth-child(2) { display: inline; }
72
-  .footpara { display: block; }
163
+  .footpara { display: inline; }
73
   .footdef  { margin-bottom: 1em; }
164
   .footdef  { margin-bottom: 1em; }
74
   .figure { padding: 1em; }
165
   .figure { padding: 1em; }
75
   .figure p { text-align: center; }
166
   .figure p { text-align: center; }
89
     { font-size: 10px; font-weight: bold; white-space: nowrap; }
180
     { font-size: 10px; font-weight: bold; white-space: nowrap; }
90
   .org-info-js_search-highlight
181
   .org-info-js_search-highlight
91
     { background-color: #ffff00; color: #000000; font-weight: bold; }
182
     { background-color: #ffff00; color: #000000; font-weight: bold; }
183
+  .org-svg { width: 90%; }
92
   /*]]>*/-->
184
   /*]]>*/-->
93
 </style>
185
 </style>
94
 <link rel="stylesheet" type="text/css" href="freedombone.css" />
186
 <link rel="stylesheet" type="text/css" href="freedombone.css" />
97
 @licstart  The following is the entire license notice for the
189
 @licstart  The following is the entire license notice for the
98
 JavaScript code in this tag.
190
 JavaScript code in this tag.
99
 
191
 
100
-Copyright (C) 2012-2013 Free Software Foundation, Inc.
192
+Copyright (C) 2012-2017 Free Software Foundation, Inc.
101
 
193
 
102
 The JavaScript code in this tag is free software: you can
194
 The JavaScript code in this tag is free software: you can
103
 redistribute it and/or modify it under the terms of the GNU
195
 redistribute it and/or modify it under the terms of the GNU
144
 <a name="top" id="top"></a>
236
 <a name="top" id="top"></a>
145
 </div>
237
 </div>
146
 <div id="content">
238
 <div id="content">
147
-<h1 class="title"></h1>
148
-<div class="center">
239
+<div class="org-center">
149
 
240
 
150
 <div class="figure">
241
 <div class="figure">
151
 <p><img src="images/logo.png" alt="logo.png" />
242
 <p><img src="images/logo.png" alt="logo.png" />
163
 The base install of the system just contains an email server and Mutt client, but not much else. In addition from within the <b>Administrator control panel</b> under <b>Add/remove apps</b> the following are installable. This list only applies on the home server version, with the mesh network version having a different and smaller set of apps.
254
 The base install of the system just contains an email server and Mutt client, but not much else. In addition from within the <b>Administrator control panel</b> under <b>Add/remove apps</b> the following are installable. This list only applies on the home server version, with the mesh network version having a different and smaller set of apps.
164
 </p>
255
 </p>
165
 
256
 
166
-<div class="center">
257
+<div class="org-center">
167
 
258
 
168
 <div class="figure">
259
 <div class="figure">
169
 <p><img src="images/controlpanel/control_panel_apps.jpg" alt="control_panel_apps.jpg" />
260
 <p><img src="images/controlpanel/control_panel_apps.jpg" alt="control_panel_apps.jpg" />
172
 </div>
263
 </div>
173
 
264
 
174
 
265
 
175
-<div id="outline-container-sec-1" class="outline-2">
176
-<h2 id="sec-1">Akaunting</h2>
177
-<div class="outline-text-2" id="text-1">
266
+<div id="outline-container-org28b5697" class="outline-2">
267
+<h2 id="org28b5697">Akaunting</h2>
268
+<div class="outline-text-2" id="text-org28b5697">
178
 <p>
269
 <p>
179
 A web based accounts system for small businesses or freelancers.
270
 A web based accounts system for small businesses or freelancers.
180
 </p>
271
 </p>
184
 </p>
275
 </p>
185
 </div>
276
 </div>
186
 </div>
277
 </div>
187
-<div id="outline-container-sec-2" class="outline-2">
188
-<h2 id="sec-2">BDS Mail</h2>
189
-<div class="outline-text-2" id="text-2">
278
+<div id="outline-container-org777bb3f" class="outline-2">
279
+<h2 id="org777bb3f">BDS Mail</h2>
280
+<div class="outline-text-2" id="text-org777bb3f">
190
 <p>
281
 <p>
191
 It's like ordinary email, but with <a href="https://en.wikipedia.org/wiki/I2P">i2p</a> as the transport mechanism.
282
 It's like ordinary email, but with <a href="https://en.wikipedia.org/wiki/I2P">i2p</a> as the transport mechanism.
192
 </p>
283
 </p>
196
 </p>
287
 </p>
197
 </div>
288
 </div>
198
 </div>
289
 </div>
199
-<div id="outline-container-sec-3" class="outline-2">
200
-<h2 id="sec-3">CryptPad</h2>
201
-<div class="outline-text-2" id="text-3">
290
+<div id="outline-container-orgebcec42" class="outline-2">
291
+<h2 id="orgebcec42">Bludit</h2>
292
+<div class="outline-text-2" id="text-orgebcec42">
293
+<p>
294
+This is a simple databaseless blogging system which uses markdown files. It should run well on any hardware.
295
+</p>
296
+
297
+<p>
298
+<a href="./app_bludit.html">How to use it</a>
299
+</p>
300
+</div>
301
+</div>
302
+<div id="outline-container-orgff63d63" class="outline-2">
303
+<h2 id="orgff63d63">CryptPad</h2>
304
+<div class="outline-text-2" id="text-orgff63d63">
202
 <p>
305
 <p>
203
 Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
306
 Collaborate on editing documents, presentations and source code, or vote on things. All with a good level of security.
204
 </p>
307
 </p>
208
 </p>
311
 </p>
209
 </div>
312
 </div>
210
 </div>
313
 </div>
211
-<div id="outline-container-sec-4" class="outline-2">
212
-<h2 id="sec-4">DLNA</h2>
213
-<div class="outline-text-2" id="text-4">
314
+<div id="outline-container-orgbb60849" class="outline-2">
315
+<h2 id="orgbb60849">DLNA</h2>
316
+<div class="outline-text-2" id="text-orgbb60849">
214
 <p>
317
 <p>
215
 Enables you to use the system as a music server which any DLNA compatible devices can connect to within your home network.
318
 Enables you to use the system as a music server which any DLNA compatible devices can connect to within your home network.
216
 </p>
319
 </p>
220
 </p>
323
 </p>
221
 </div>
324
 </div>
222
 </div>
325
 </div>
223
-<div id="outline-container-sec-5" class="outline-2">
224
-<h2 id="sec-5">Dokuwiki</h2>
225
-<div class="outline-text-2" id="text-5">
326
+<div id="outline-container-org5792c5f" class="outline-2">
327
+<h2 id="org5792c5f">Dokuwiki</h2>
328
+<div class="outline-text-2" id="text-org5792c5f">
226
 <p>
329
 <p>
227
 A databaseless wiki system.
330
 A databaseless wiki system.
228
 </p>
331
 </p>
232
 </p>
335
 </p>
233
 </div>
336
 </div>
234
 </div>
337
 </div>
235
-<div id="outline-container-sec-6" class="outline-2">
236
-<h2 id="sec-6">Edith</h2>
237
-<div class="outline-text-2" id="text-6">
338
+<div id="outline-container-orgfe3cb28" class="outline-2">
339
+<h2 id="orgfe3cb28">Edith</h2>
340
+<div class="outline-text-2" id="text-orgfe3cb28">
238
 <p>
341
 <p>
239
 Extremely simple and distraction-free notes system.
342
 Extremely simple and distraction-free notes system.
240
 </p>
343
 </p>
244
 </p>
347
 </p>
245
 </div>
348
 </div>
246
 </div>
349
 </div>
247
-<div id="outline-container-sec-7" class="outline-2">
248
-<h2 id="sec-7">Emacs</h2>
249
-<div class="outline-text-2" id="text-7">
350
+<div id="outline-container-org8962159" class="outline-2">
351
+<h2 id="org8962159">Emacs</h2>
352
+<div class="outline-text-2" id="text-org8962159">
250
 <p>
353
 <p>
251
 If you use the Mutt client to read your email then this will set it up to use emacs for composing new mail.
354
 If you use the Mutt client to read your email then this will set it up to use emacs for composing new mail.
252
 </p>
355
 </p>
256
 </p>
359
 </p>
257
 </div>
360
 </div>
258
 </div>
361
 </div>
259
-<div id="outline-container-sec-8" class="outline-2">
260
-<h2 id="sec-8">Email Server</h2>
261
-<div class="outline-text-2" id="text-8">
362
+<div id="outline-container-org1902633" class="outline-2">
363
+<h2 id="org1902633">Email Server</h2>
364
+<div class="outline-text-2" id="text-org1902633">
262
 <p>
365
 <p>
263
 Since many apps require email registration an email server is installed by default. You can find advice on using the email system <a href="./usage_email.html">here</a>.
366
 Since many apps require email registration an email server is installed by default. You can find advice on using the email system <a href="./usage_email.html">here</a>.
264
 </p>
367
 </p>
265
 </div>
368
 </div>
266
 </div>
369
 </div>
267
-<div id="outline-container-sec-9" class="outline-2">
268
-<h2 id="sec-9">Etherpad</h2>
269
-<div class="outline-text-2" id="text-9">
370
+<div id="outline-container-orgd4e27a5" class="outline-2">
371
+<h2 id="orgd4e27a5">Etherpad</h2>
372
+<div class="outline-text-2" id="text-orgd4e27a5">
270
 <p>
373
 <p>
271
 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.
374
 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.
272
 </p>
375
 </p>
276
 </p>
379
 </p>
277
 </div>
380
 </div>
278
 </div>
381
 </div>
279
-<div id="outline-container-sec-10" class="outline-2">
280
-<h2 id="sec-10">Federated wiki</h2>
281
-<div class="outline-text-2" id="text-10">
382
+<div id="outline-container-org71dc0a8" class="outline-2">
383
+<h2 id="org71dc0a8">Federated wiki</h2>
384
+<div class="outline-text-2" id="text-org71dc0a8">
282
 <p>
385
 <p>
283
 A new approach to creating wiki content.
386
 A new approach to creating wiki content.
284
 </p>
387
 </p>
288
 </p>
391
 </p>
289
 </div>
392
 </div>
290
 </div>
393
 </div>
291
-<div id="outline-container-sec-11" class="outline-2">
292
-<h2 id="sec-11">Friendica</h2>
293
-<div class="outline-text-2" id="text-11">
394
+<div id="outline-container-org6afa6fa" class="outline-2">
395
+<h2 id="org6afa6fa">Friendica</h2>
396
+<div class="outline-text-2" id="text-org6afa6fa">
294
 <p>
397
 <p>
295
 Federated social network system.
398
 Federated social network system.
296
 </p>
399
 </p>
300
 </p>
403
 </p>
301
 </div>
404
 </div>
302
 </div>
405
 </div>
303
-<div id="outline-container-sec-12" class="outline-2">
304
-<h2 id="sec-12">Ghost</h2>
305
-<div class="outline-text-2" id="text-12">
306
-<p>
307
-Modern looking blogging system.
308
-</p>
309
-
310
-<p>
311
-<a href="./app_ghost.html">How to use it</a>
312
-</p>
313
-</div>
314
-</div>
315
-<div id="outline-container-sec-13" class="outline-2">
316
-<h2 id="sec-13">GNU Social</h2>
317
-<div class="outline-text-2" id="text-13">
406
+<div id="outline-container-org0f25cd5" class="outline-2">
407
+<h2 id="org0f25cd5">GNU Social</h2>
408
+<div class="outline-text-2" id="text-org0f25cd5">
318
 <p>
409
 <p>
319
 Federated social network based on the OStatus protocol. You can "<i>remote follow</i>" other users within the GNU Social federation.
410
 Federated social network based on the OStatus protocol. You can "<i>remote follow</i>" other users within the GNU Social federation.
320
 </p>
411
 </p>
324
 </p>
415
 </p>
325
 </div>
416
 </div>
326
 </div>
417
 </div>
327
-<div id="outline-container-sec-14" class="outline-2">
328
-<h2 id="sec-14">Gogs</h2>
329
-<div class="outline-text-2" id="text-14">
418
+<div id="outline-container-org7d5a232" class="outline-2">
419
+<h2 id="org7d5a232">Gogs</h2>
420
+<div class="outline-text-2" id="text-org7d5a232">
330
 <p>
421
 <p>
331
 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.
422
 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.
332
 </p>
423
 </p>
336
 </p>
427
 </p>
337
 </div>
428
 </div>
338
 </div>
429
 </div>
339
-<div id="outline-container-sec-15" class="outline-2">
340
-<h2 id="sec-15">HTMLy</h2>
341
-<div class="outline-text-2" id="text-15">
430
+<div id="outline-container-org5421983" class="outline-2">
431
+<h2 id="org5421983">HTMLy</h2>
432
+<div class="outline-text-2" id="text-org5421983">
342
 <p>
433
 <p>
343
 Databaseless blogging system. Quite simple and with a markdown-like format.
434
 Databaseless blogging system. Quite simple and with a markdown-like format.
344
 </p>
435
 </p>
348
 </p>
439
 </p>
349
 </div>
440
 </div>
350
 </div>
441
 </div>
351
-<div id="outline-container-sec-16" class="outline-2">
352
-<h2 id="sec-16">Hubzilla</h2>
353
-<div class="outline-text-2" id="text-16">
442
+<div id="outline-container-org753029b" class="outline-2">
443
+<h2 id="org753029b">Hubzilla</h2>
444
+<div class="outline-text-2" id="text-org753029b">
354
 <p>
445
 <p>
355
 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.
446
 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.
356
 </p>
447
 </p>
360
 </p>
451
 </p>
361
 </div>
452
 </div>
362
 </div>
453
 </div>
363
-<div id="outline-container-sec-17" class="outline-2">
364
-<h2 id="sec-17">Icecast media stream</h2>
365
-<div class="outline-text-2" id="text-17">
454
+<div id="outline-container-org4588aff" class="outline-2">
455
+<h2 id="org4588aff">Icecast media stream</h2>
456
+<div class="outline-text-2" id="text-org4588aff">
366
 <p>
457
 <p>
367
 Make your own internet radio station.
458
 Make your own internet radio station.
368
 </p>
459
 </p>
372
 </p>
463
 </p>
373
 </div>
464
 </div>
374
 </div>
465
 </div>
375
-<div id="outline-container-sec-18" class="outline-2">
376
-<h2 id="sec-18">IRC Server (ngirc)</h2>
377
-<div class="outline-text-2" id="text-18">
466
+<div id="outline-container-org0dc73d8" class="outline-2">
467
+<h2 id="org0dc73d8">IRC Server (ngirc)</h2>
468
+<div class="outline-text-2" id="text-org0dc73d8">
378
 <p>
469
 <p>
379
 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.
470
 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.
380
 </p>
471
 </p>
384
 </p>
475
 </p>
385
 </div>
476
 </div>
386
 </div>
477
 </div>
387
-<div id="outline-container-sec-19" class="outline-2">
388
-<h2 id="sec-19">Jitsi Meet</h2>
389
-<div class="outline-text-2" id="text-19">
478
+<div id="outline-container-orgc8faaa0" class="outline-2">
479
+<h2 id="orgc8faaa0">Jitsi Meet</h2>
480
+<div class="outline-text-2" id="text-orgc8faaa0">
390
 <p>
481
 <p>
391
 Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
482
 Experimental WebRTC video conferencing system, similar to Google Hangouts. This may not be fully functional, but is hoped to be in the near future.
392
 </p>
483
 </p>
393
 </div>
484
 </div>
394
 </div>
485
 </div>
395
 
486
 
396
-<div id="outline-container-sec-20" class="outline-2">
397
-<h2 id="sec-20">KanBoard</h2>
398
-<div class="outline-text-2" id="text-20">
487
+<div id="outline-container-orgbc435d0" class="outline-2">
488
+<h2 id="orgbc435d0">KanBoard</h2>
489
+<div class="outline-text-2" id="text-orgbc435d0">
399
 <p>
490
 <p>
400
 A simple kanban system for managing projects or TODO lists.
491
 A simple kanban system for managing projects or TODO lists.
401
 </p>
492
 </p>
405
 </p>
496
 </p>
406
 </div>
497
 </div>
407
 </div>
498
 </div>
408
-<div id="outline-container-sec-21" class="outline-2">
409
-<h2 id="sec-21">Key Server</h2>
410
-<div class="outline-text-2" id="text-21">
499
+<div id="outline-container-org3ced426" class="outline-2">
500
+<h2 id="org3ced426">Key Server</h2>
501
+<div class="outline-text-2" id="text-org3ced426">
411
 <p>
502
 <p>
412
 An OpenPGP key server for storing and retrieving GPG public keys.
503
 An OpenPGP key server for storing and retrieving GPG public keys.
413
 </p>
504
 </p>
417
 </p>
508
 </p>
418
 </div>
509
 </div>
419
 </div>
510
 </div>
420
-<div id="outline-container-sec-22" class="outline-2">
421
-<h2 id="sec-22">Koel</h2>
422
-<div class="outline-text-2" id="text-22">
511
+<div id="outline-container-orgd689f61" class="outline-2">
512
+<h2 id="orgd689f61">Koel</h2>
513
+<div class="outline-text-2" id="text-orgd689f61">
423
 <p>
514
 <p>
424
 Access your music collection from any internet connected device.
515
 Access your music collection from any internet connected device.
425
 </p>
516
 </p>
429
 </p>
520
 </p>
430
 </div>
521
 </div>
431
 </div>
522
 </div>
432
-<div id="outline-container-sec-23" class="outline-2">
433
-<h2 id="sec-23">Lychee</h2>
434
-<div class="outline-text-2" id="text-23">
523
+<div id="outline-container-org0b6e716" class="outline-2">
524
+<h2 id="org0b6e716">Lychee</h2>
525
+<div class="outline-text-2" id="text-org0b6e716">
435
 <p>
526
 <p>
436
 Make your photo albums available on the web.
527
 Make your photo albums available on the web.
437
 </p>
528
 </p>
441
 </p>
532
 </p>
442
 </div>
533
 </div>
443
 </div>
534
 </div>
444
-<div id="outline-container-sec-24" class="outline-2">
445
-<h2 id="sec-24">Mailpile</h2>
446
-<div class="outline-text-2" id="text-24">
535
+<div id="outline-container-org5a5bf12" class="outline-2">
536
+<h2 id="org5a5bf12">Mailpile</h2>
537
+<div class="outline-text-2" id="text-org5a5bf12">
447
 <p>
538
 <p>
448
 Modern email client which supports GPG encryption.
539
 Modern email client which supports GPG encryption.
449
 </p>
540
 </p>
453
 </p>
544
 </p>
454
 </div>
545
 </div>
455
 </div>
546
 </div>
456
-<div id="outline-container-sec-25" class="outline-2">
457
-<h2 id="sec-25">Matrix</h2>
458
-<div class="outline-text-2" id="text-25">
547
+<div id="outline-container-org23fcc5d" class="outline-2">
548
+<h2 id="org23fcc5d">Matrix</h2>
549
+<div class="outline-text-2" id="text-org23fcc5d">
459
 <p>
550
 <p>
460
 Multi-user chat with some security and moderation controls.
551
 Multi-user chat with some security and moderation controls.
461
 </p>
552
 </p>
465
 </p>
556
 </p>
466
 </div>
557
 </div>
467
 </div>
558
 </div>
468
-<div id="outline-container-sec-26" class="outline-2">
469
-<h2 id="sec-26">Mediagoblin</h2>
470
-<div class="outline-text-2" id="text-26">
559
+<div id="outline-container-org152ef9d" class="outline-2">
560
+<h2 id="org152ef9d">Mediagoblin</h2>
561
+<div class="outline-text-2" id="text-org152ef9d">
471
 <p>
562
 <p>
472
 Publicly host video and audio files so that you don't need to use YouTube/Vimeo/etc.
563
 Publicly host video and audio files so that you don't need to use YouTube/Vimeo/etc.
473
 </p>
564
 </p>
477
 </p>
568
 </p>
478
 </div>
569
 </div>
479
 </div>
570
 </div>
480
-<div id="outline-container-sec-27" class="outline-2">
481
-<h2 id="sec-27">Mumble</h2>
482
-<div class="outline-text-2" id="text-27">
571
+<div id="outline-container-orgdf02288" class="outline-2">
572
+<h2 id="orgdf02288">Mumble</h2>
573
+<div class="outline-text-2" id="text-orgdf02288">
483
 <p>
574
 <p>
484
 The popular VoIP and text chat system. Say goodbye to old-fashioned telephony conferences with silly dial codes. Also works well on mobile.
575
 The popular VoIP and text chat system. Say goodbye to old-fashioned telephony conferences with silly dial codes. Also works well on mobile.
485
 </p>
576
 </p>
489
 </p>
580
 </p>
490
 </div>
581
 </div>
491
 </div>
582
 </div>
492
-<div id="outline-container-sec-28" class="outline-2">
493
-<h2 id="sec-28">NextCloud</h2>
494
-<div class="outline-text-2" id="text-28">
583
+<div id="outline-container-orga6e7867" class="outline-2">
584
+<h2 id="orga6e7867">NextCloud</h2>
585
+<div class="outline-text-2" id="text-orga6e7867">
495
 <p>
586
 <p>
496
 Store files on your server and sync them with laptops or mobile devices. Includes many plugins including videoconferencing and collaborative document editing.
587
 Store files on your server and sync them with laptops or mobile devices. Includes many plugins including videoconferencing and collaborative document editing.
497
 </p>
588
 </p>
501
 </p>
592
 </p>
502
 </div>
593
 </div>
503
 </div>
594
 </div>
504
-<div id="outline-container-sec-29" class="outline-2">
505
-<h2 id="sec-29">PeerTube</h2>
506
-<div class="outline-text-2" id="text-29">
595
+<div id="outline-container-org1f222c6" class="outline-2">
596
+<h2 id="org1f222c6">PeerTube</h2>
597
+<div class="outline-text-2" id="text-org1f222c6">
507
 <p>
598
 <p>
508
 Peer-to-peer video hosting. Similar to Mediagoblin, but the P2P aspect better enables the streaming load to be shared across servers.
599
 Peer-to-peer video hosting. Similar to Mediagoblin, but the P2P aspect better enables the streaming load to be shared across servers.
509
 </p>
600
 </p>
513
 </p>
604
 </p>
514
 </div>
605
 </div>
515
 </div>
606
 </div>
516
-<div id="outline-container-sec-30" class="outline-2">
517
-<h2 id="sec-30">PI-Hole</h2>
518
-<div class="outline-text-2" id="text-30">
607
+<div id="outline-container-org93da9a8" class="outline-2">
608
+<h2 id="org93da9a8">PI-Hole</h2>
609
+<div class="outline-text-2" id="text-org93da9a8">
519
 <p>
610
 <p>
520
 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.
611
 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.
521
 </p>
612
 </p>
525
 </p>
616
 </p>
526
 </div>
617
 </div>
527
 </div>
618
 </div>
528
-<div id="outline-container-sec-31" class="outline-2">
529
-<h2 id="sec-31">Pleroma</h2>
530
-<div class="outline-text-2" id="text-31">
619
+<div id="outline-container-org23c546e" class="outline-2">
620
+<h2 id="org23c546e">Pleroma</h2>
621
+<div class="outline-text-2" id="text-org23c546e">
531
 <p>
622
 <p>
532
 Fediverse instance which is compatible with GNU Social and Mastodon, and suited for systems without much RAM or CPU resource.
623
 Fediverse instance which is compatible with GNU Social and Mastodon, and suited for systems without much RAM or CPU resource.
533
 </p>
624
 </p>
537
 </p>
628
 </p>
538
 </div>
629
 </div>
539
 </div>
630
 </div>
540
-<div id="outline-container-sec-32" class="outline-2">
541
-<h2 id="sec-32">PostActiv</h2>
542
-<div class="outline-text-2" id="text-32">
631
+<div id="outline-container-org9916ff6" class="outline-2">
632
+<h2 id="org9916ff6">PostActiv</h2>
633
+<div class="outline-text-2" id="text-org9916ff6">
543
 <p>
634
 <p>
544
 An alternative federated social networking system compatible with GNU Social, Pleroma and Mastodon. It includes some optimisations and fixes currently not available within the main GNU Social project.
635
 An alternative federated social networking system compatible with GNU Social, Pleroma and Mastodon. It includes some optimisations and fixes currently not available within the main GNU Social project.
545
 </p>
636
 </p>
549
 </p>
640
 </p>
550
 </div>
641
 </div>
551
 </div>
642
 </div>
552
-<div id="outline-container-sec-33" class="outline-2">
553
-<h2 id="sec-33">PrivateBin</h2>
554
-<div class="outline-text-2" id="text-33">
643
+<div id="outline-container-orgd4b23b3" class="outline-2">
644
+<h2 id="orgd4b23b3">PrivateBin</h2>
645
+<div class="outline-text-2" id="text-orgd4b23b3">
555
 <p>
646
 <p>
556
 A pastebin where the server has zero knowledge of the content being pasted.
647
 A pastebin where the server has zero knowledge of the content being pasted.
557
 </p>
648
 </p>
561
 </p>
652
 </p>
562
 </div>
653
 </div>
563
 </div>
654
 </div>
564
-<div id="outline-container-sec-34" class="outline-2">
565
-<h2 id="sec-34">Profanity</h2>
566
-<div class="outline-text-2" id="text-34">
655
+<div id="outline-container-org0082b2c" class="outline-2">
656
+<h2 id="org0082b2c">Profanity</h2>
657
+<div class="outline-text-2" id="text-org0082b2c">
567
 <p>
658
 <p>
568
 A shell based XMPP client which you can run on the Freedombone server via ssh.
659
 A shell based XMPP client which you can run on the Freedombone server via ssh.
569
 </p>
660
 </p>
573
 </p>
664
 </p>
574
 </div>
665
 </div>
575
 </div>
666
 </div>
576
-<div id="outline-container-sec-35" class="outline-2">
577
-<h2 id="sec-35">Riot Web</h2>
578
-<div class="outline-text-2" id="text-35">
667
+<div id="outline-container-orga4c89c0" class="outline-2">
668
+<h2 id="orga4c89c0">Riot Web</h2>
669
+<div class="outline-text-2" id="text-orga4c89c0">
579
 <p>
670
 <p>
580
 A browser based user interface for the Matrix federated communications system, including WebRTC audio and video chat.
671
 A browser based user interface for the Matrix federated communications system, including WebRTC audio and video chat.
581
 </p>
672
 </p>
585
 </p>
676
 </p>
586
 </div>
677
 </div>
587
 </div>
678
 </div>
588
-<div id="outline-container-sec-36" class="outline-2">
589
-<h2 id="sec-36">SearX</h2>
590
-<div class="outline-text-2" id="text-36">
679
+<div id="outline-container-orgfe0d758" class="outline-2">
680
+<h2 id="orgfe0d758">SearX</h2>
681
+<div class="outline-text-2" id="text-orgfe0d758">
591
 <p>
682
 <p>
592
 A metasearch engine for customised and private web searches.
683
 A metasearch engine for customised and private web searches.
593
 </p>
684
 </p>
597
 </p>
688
 </p>
598
 </div>
689
 </div>
599
 </div>
690
 </div>
600
-<div id="outline-container-sec-37" class="outline-2">
601
-<h2 id="sec-37">tt-rss</h2>
602
-<div class="outline-text-2" id="text-37">
691
+<div id="outline-container-org1a8ec29" class="outline-2">
692
+<h2 id="org1a8ec29">tt-rss</h2>
693
+<div class="outline-text-2" id="text-org1a8ec29">
603
 <p>
694
 <p>
604
 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.
695
 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.
605
 </p>
696
 </p>
609
 </p>
700
 </p>
610
 </div>
701
 </div>
611
 </div>
702
 </div>
612
-<div id="outline-container-sec-38" class="outline-2">
613
-<h2 id="sec-38">Syncthing</h2>
614
-<div class="outline-text-2" id="text-38">
703
+<div id="outline-container-orgc31b9a5" class="outline-2">
704
+<h2 id="orgc31b9a5">Syncthing</h2>
705
+<div class="outline-text-2" id="text-orgc31b9a5">
615
 <p>
706
 <p>
616
 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.
707
 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.
617
 </p>
708
 </p>
621
 </p>
712
 </p>
622
 </div>
713
 </div>
623
 </div>
714
 </div>
624
-<div id="outline-container-sec-39" class="outline-2">
625
-<h2 id="sec-39">Tahoe-LAFS</h2>
626
-<div class="outline-text-2" id="text-39">
715
+<div id="outline-container-org84b0dd7" class="outline-2">
716
+<h2 id="org84b0dd7">Tahoe-LAFS</h2>
717
+<div class="outline-text-2" id="text-org84b0dd7">
627
 <p>
718
 <p>
628
 Robust and encrypted storage of files on one or more server.
719
 Robust and encrypted storage of files on one or more server.
629
 </p>
720
 </p>
633
 </p>
724
 </p>
634
 </div>
725
 </div>
635
 </div>
726
 </div>
636
-<div id="outline-container-sec-40" class="outline-2">
637
-<h2 id="sec-40">Tox</h2>
638
-<div class="outline-text-2" id="text-40">
727
+<div id="outline-container-orge358056" class="outline-2">
728
+<h2 id="orge358056">Tox</h2>
729
+<div class="outline-text-2" id="text-orge358056">
639
 <p>
730
 <p>
640
 Client and bootstrap node for the Tox chat/VoIP system.
731
 Client and bootstrap node for the Tox chat/VoIP system.
641
 </p>
732
 </p>
645
 </p>
736
 </p>
646
 </div>
737
 </div>
647
 </div>
738
 </div>
648
-<div id="outline-container-sec-41" class="outline-2">
649
-<h2 id="sec-41">Turtl</h2>
650
-<div class="outline-text-2" id="text-41">
739
+<div id="outline-container-org252f43c" class="outline-2">
740
+<h2 id="org252f43c">Turtl</h2>
741
+<div class="outline-text-2" id="text-org252f43c">
651
 <p>
742
 <p>
652
 A system for privately creating and sharing notes and images, similar to Evernote but without the spying.
743
 A system for privately creating and sharing notes and images, similar to Evernote but without the spying.
653
 </p>
744
 </p>
657
 </p>
748
 </p>
658
 </div>
749
 </div>
659
 </div>
750
 </div>
660
-<div id="outline-container-sec-42" class="outline-2">
661
-<h2 id="sec-42">Vim</h2>
662
-<div class="outline-text-2" id="text-42">
751
+<div id="outline-container-orga8df5ec" class="outline-2">
752
+<h2 id="orga8df5ec">Vim</h2>
753
+<div class="outline-text-2" id="text-orga8df5ec">
663
 <p>
754
 <p>
664
 If you use the Mutt client to read your email then this will set it up to use vim for composing new mail.
755
 If you use the Mutt client to read your email then this will set it up to use vim for composing new mail.
665
 </p>
756
 </p>
666
 </div>
757
 </div>
667
 </div>
758
 </div>
668
 
759
 
669
-<div id="outline-container-sec-43" class="outline-2">
670
-<h2 id="sec-43">Virtual Private Network (VPN)</h2>
671
-<div class="outline-text-2" id="text-43">
760
+<div id="outline-container-orga3f5966" class="outline-2">
761
+<h2 id="orga3f5966">Virtual Private Network (VPN)</h2>
762
+<div class="outline-text-2" id="text-orga3f5966">
672
 <p>
763
 <p>
673
 Set up a VPN on your server so that you can bypass local internet censorship.
764
 Set up a VPN on your server so that you can bypass local internet censorship.
674
 </p>
765
 </p>
678
 </p>
769
 </p>
679
 </div>
770
 </div>
680
 </div>
771
 </div>
681
-<div id="outline-container-sec-44" class="outline-2">
682
-<h2 id="sec-44">XMPP</h2>
683
-<div class="outline-text-2" id="text-44">
772
+<div id="outline-container-org4a03248" class="outline-2">
773
+<h2 id="org4a03248">XMPP</h2>
774
+<div class="outline-text-2" id="text-org4a03248">
684
 <p>
775
 <p>
685
 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.
776
 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.
686
 </p>
777
 </p>