freedombone-app-akaunting 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. #!/bin/bash
  2. #
  3. # .---. . .
  4. # | | |
  5. # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
  6. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
  7. # ' ' --' --' -' - -' ' ' -' -' -' ' - --'
  8. #
  9. # Freedom in the Cloud
  10. #
  11. # Personal or small business accounts
  12. #
  13. # License
  14. # =======
  15. #
  16. # Copyright (C) 2017 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. VARIANTS='full full-vim media'
  31. IN_DEFAULT_INSTALL=0
  32. SHOW_ON_ABOUT=1
  33. AKAUNTING_DOMAIN_NAME=
  34. AKAUNTING_CODE=
  35. AKAUNTING_ONION_PORT=8341
  36. AKAUNTING_REPO="https://github.com/akaunting/akaunting"
  37. AKAUNTING_COMMIT='b68c840cded60d92b86e98fcbc26ce338cf93fef'
  38. AKAUNTING_ADMIN_PASSWORD=
  39. AKAUNTING_BACKGROUND_IMAGE_URL=
  40. akaunting_variables=(ONION_ONLY
  41. AKAUNTING_DOMAIN_NAME
  42. AKAUNTING_CODE
  43. DDNS_PROVIDER
  44. MY_USERNAME)
  45. function akaunting_remove_bad_links {
  46. cd /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  47. # copy jquery locally
  48. jquery_version='1.12.4'
  49. if [ ! -f jquery-${jquery_version}.js ]; then
  50. cd /var/www/$GHOST_DOMAIN_NAME/htdocs
  51. wget https://code.jquery.com/jquery-${jquery_version}.js
  52. jquery_hash=$(sha256sum jquery-${jquery_version}.js | awk -F ' ' '{print $1}')
  53. if [[ "$jquery_hash" != '430f36f9b5f21aae8cc9dca6a81c4d3d84da5175eaedcf2fdc2c226302cb3575' ]]; then
  54. echo $'Unexpected jquery hash value'
  55. exit 78363527
  56. fi
  57. fi
  58. sed -i '/googleapi/d' resources/assets/sass/app.scss
  59. sed -i "s|ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js|$AKAUNTING_DOMAIN_NAME/jquery-${jquery_version}.js|g" vendor/league/flysystem/docs/_layouts/default.html
  60. sed -i '/googleapi/d' vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views/503.blade.php
  61. sed -i '/googleapi/d' vendor/almasaeed2010/adminlte/build/less/AdminLTE-without-plugins.less
  62. sed -i '/googleapi/d' vendor/almasaeed2010/adminlte/build/less/AdminLTE.less
  63. sed -i '/googleapi/d' vendor/almasaeed2010/adminlte/dist/css/AdminLTE.css
  64. sed -i '/googleapi/d' vendor/almasaeed2010/adminlte/dist/css/AdminLTE.min.css
  65. sed -i '/googleapi/d' vendor/almasaeed2010/adminlte/dist/css/alt/AdminLTE-without-plugins.css
  66. sed -i '/googleapi/d' vendor/almasaeed2010/adminlte/dist/css/alt/AdminLTE-without-plugins.min.css
  67. sed -i "s|ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js|$AKAUNTING_DOMAIN_NAME/jquery-${jquery_version}.js|g" vendor/almasaeed2010/adminlte/plugins/ckeditor/samples/old/jquery.html
  68. chown -R www-data:www-data /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  69. }
  70. function logging_on_akaunting {
  71. echo -n ''
  72. }
  73. function logging_off_akaunting {
  74. echo -n ''
  75. }
  76. function remove_user_akaunting {
  77. remove_username="$1"
  78. ${PROJECT_NAME}-pass -u $remove_username --rmapp akaunting
  79. }
  80. function add_user_akaunting {
  81. new_username="$1"
  82. new_user_password="$2"
  83. ${PROJECT_NAME}-pass -u $new_username -a akaunting -p "$new_user_password"
  84. echo '0'
  85. }
  86. function install_interactive_akaunting {
  87. if [ ! $ONION_ONLY ]; then
  88. ONION_ONLY='no'
  89. fi
  90. if [[ $ONION_ONLY != "no" ]]; then
  91. AKAUNTING_DOMAIN_NAME='akaunting.local'
  92. else
  93. AKAUNTING_DETAILS_COMPLETE=
  94. while [ ! $AKAUNTING_DETAILS_COMPLETE ]
  95. do
  96. data=$(tempfile 2>/dev/null)
  97. trap "rm -f $data" 0 1 2 5 15
  98. if [[ $DDNS_PROVIDER == "default@freedns.afraid.org" ]]; then
  99. dialog --backtitle $"Freedombone Configuration" \
  100. --title $"Akaunting Configuration" \
  101. --form $"\nPlease enter your Akaunting details.\n\nIMPORTANT: This should be a domain name which is supported by Let's Encrypt:" 14 65 2 \
  102. $"Domain:" 1 1 "$(grep 'AKAUNTING_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 25 33 40 \
  103. $"Code:" 2 1 "$(grep 'AKAUNTING_CODE' temp.cfg | awk -F '=' '{print $2}')" 2 25 33 255 \
  104. 2> $data
  105. else
  106. dialog --backtitle $"Freedombone Configuration" \
  107. --title $"Akaunting Configuration" \
  108. --form $"\nPlease enter your Akaunting details.\n\nIMPORTANT: This should be a domain name which is supported by Let's Encrypt:" 14 65 2 \
  109. $"Domain:" 1 1 "$(grep 'AKAUNTING_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 25 33 40 \
  110. 2> $data
  111. fi
  112. sel=$?
  113. case $sel in
  114. 1) exit 1;;
  115. 255) exit 1;;
  116. esac
  117. AKAUNTING_DOMAIN_NAME=$(cat $data | sed -n 1p)
  118. if [ $AKAUNTING_DOMAIN_NAME ]; then
  119. if [[ $AKAUNTING_DOMAIN_NAME == "$HUBZILLA_DOMAIN_NAME" ]]; then
  120. AKAUNTING_DOMAIN_NAME=""
  121. fi
  122. TEST_DOMAIN_NAME=$AKAUNTING_DOMAIN_NAME
  123. validate_domain_name
  124. if [[ $TEST_DOMAIN_NAME != $AKAUNTING_DOMAIN_NAME ]]; then
  125. AKAUNTING_DOMAIN_NAME=
  126. dialog --title $"Domain name validation" --msgbox "$TEST_DOMAIN_NAME" 15 50
  127. else
  128. if [[ $DDNS_PROVIDER == "default@freedns.afraid.org" ]]; then
  129. AKAUNTING_CODE=$(cat $data | sed -n 2p)
  130. validate_freedns_code "$AKAUNTING_CODE"
  131. if [ ! $VALID_CODE ]; then
  132. AKAUNTING_DOMAIN_NAME=
  133. fi
  134. fi
  135. fi
  136. fi
  137. if [ $AKAUNTING_DOMAIN_NAME ]; then
  138. AKAUNTING_DETAILS_COMPLETE="yes"
  139. fi
  140. done
  141. write_config_param "AKAUNTING_CODE" "$AKAUNTING_CODE"
  142. fi
  143. write_config_param "AKAUNTING_DOMAIN_NAME" "$AKAUNTING_DOMAIN_NAME"
  144. APP_INSTALLED=1
  145. }
  146. function change_password_akaunting {
  147. curr_username="$1"
  148. new_user_password="$2"
  149. read_config_param 'AKAUNTING_DOMAIN_NAME'
  150. ${PROJECT_NAME}-pass -u "$curr_username" -a akaunting -p "$new_user_password"
  151. }
  152. function akaunting_create_database {
  153. if [ -f $IMAGE_PASSWORD_FILE ]; then
  154. AKAUNTING_ADMIN_PASSWORD="$(printf `cat $IMAGE_PASSWORD_FILE`)"
  155. else
  156. if [ ! $AKAUNTING_ADMIN_PASSWORD ]; then
  157. AKAUNTING_ADMIN_PASSWORD="$(create_password ${MINIMUM_PASSWORD_LENGTH})"
  158. fi
  159. fi
  160. if [ ! $AKAUNTING_ADMIN_PASSWORD ]; then
  161. return
  162. fi
  163. function_check create_database
  164. create_database akaunting "$AKAUNTING_ADMIN_PASSWORD" $MY_USERNAME
  165. }
  166. function reconfigure_akaunting {
  167. echo -n ''
  168. }
  169. function upgrade_akaunting {
  170. CURR_AKAUNTING_COMMIT=$(get_completion_param "akaunting commit")
  171. if [[ "$CURR_AKAUNTING_COMMIT" == "$AKAUNTING_COMMIT" ]]; then
  172. return
  173. fi
  174. if grep -q "akaunting domain" $COMPLETION_FILE; then
  175. AKAUNTING_DOMAIN_NAME=$(get_completion_param "akaunting domain")
  176. fi
  177. # update to the next commit
  178. function_check set_repo_commit
  179. set_repo_commit /var/www/$AKAUNTING_DOMAIN_NAME/htdocs "akaunting commit" "$AKAUNTING_COMMIT" $AKAUNTING_REPO
  180. cd /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  181. install_composer
  182. akaunting_remove_bad_links
  183. chown -R www-data:www-data /var/www/${AKAUNTING_DOMAIN_NAME}/htdocs
  184. }
  185. function backup_local_akaunting {
  186. akaunting_path=/var/www/${AKAUNTING_DOMAIN_NAME}/htdocs
  187. if [ -d $akaunting_path ]; then
  188. suspend_site ${AKAUNTING_DOMAIN_NAME}
  189. function_check backup_database_to_usb
  190. backup_database_to_usb akaunting
  191. backup_directory_to_usb $akaunting_path akaunting
  192. restart_site
  193. fi
  194. }
  195. function restore_local_akaunting {
  196. temp_restore_dir=/root/tempakaunting
  197. akaunting_dir=/var/www/${AKAUNTING_DOMAIN_NAME}/htdocs
  198. suspend_site ${AKAUNTING_DOMAIN_NAME}
  199. function_check akaunting_create_database
  200. akaunting_create_database
  201. restore_database akaunting ${AKAUNTING_DOMAIN_NAME}
  202. chown www-data:www-data $akaunting_dir
  203. restart_site
  204. }
  205. function backup_remote_akaunting {
  206. akaunting_path=/var/www/${AKAUNTING_DOMAIN_NAME}/htdocs
  207. if [ -d $akaunting_path ]; then
  208. suspend_site ${AKAUNTING_DOMAIN_NAME}
  209. function_check backup_database_to_friend
  210. backup_database_to_friend akaunting
  211. backup_directory_to_friend $akaunting_path akaunting
  212. restart_site
  213. fi
  214. }
  215. function restore_remote_akaunting {
  216. temp_restore_dir=/root/tempakaunting
  217. akaunting_dir=/var/www/${AKAUNTING_DOMAIN_NAME}/htdocs
  218. suspend_site ${AKAUNTING_DOMAIN_NAME}
  219. function_check akaunting_create_database
  220. akaunting_create_database
  221. restore_database_from_friend akaunting ${AKAUNTING_DOMAIN_NAME}
  222. chown www-data:www-data $akaunting_dir
  223. restart_site
  224. }
  225. function remove_akaunting {
  226. if [ ${#AKAUNTING_DOMAIN_NAME} -eq 0 ]; then
  227. return
  228. fi
  229. read_config_param "AKAUNTING_DOMAIN_NAME"
  230. read_config_param "MY_USERNAME"
  231. echo "Removing $AKAUNTING_DOMAIN_NAME"
  232. nginx_dissite $AKAUNTING_DOMAIN_NAME
  233. remove_certs $AKAUNTING_DOMAIN_NAME
  234. if [ -d /var/www/$AKAUNTING_DOMAIN_NAME ]; then
  235. rm -rf /var/www/$AKAUNTING_DOMAIN_NAME
  236. fi
  237. if [ -f /etc/nginx/sites-available/$AKAUNTING_DOMAIN_NAME ]; then
  238. rm /etc/nginx/sites-available/$AKAUNTING_DOMAIN_NAME
  239. fi
  240. function_check drop_database
  241. drop_database akaunting
  242. function_check remove_onion_service
  243. remove_onion_service akaunting ${AKAUNTING_ONION_PORT}
  244. if grep -q "akaunting" /etc/crontab; then
  245. sed -i "/akaunting/d" /etc/crontab
  246. fi
  247. remove_app akaunting
  248. remove_completion_param install_akaunting
  249. sed -i '/akaunting/d' $COMPLETION_FILE
  250. function_check remove_ddns_domain
  251. remove_ddns_domain $AKAUNTING_DOMAIN_NAME
  252. }
  253. function install_akaunting {
  254. if [ ! $ONION_ONLY ]; then
  255. ONION_ONLY='no'
  256. fi
  257. if [ ! $AKAUNTING_DOMAIN_NAME ]; then
  258. echo $'No domain name was given for akaunting'
  259. exit 89353
  260. fi
  261. function_check install_mariadb
  262. install_mariadb
  263. function_check get_mariadb_password
  264. get_mariadb_password
  265. apt-get -yq install php-gettext php-curl php-gd php-mysql git curl
  266. apt-get -yq install memcached php-memcached php-intl exiftool libfcgi0ldbl
  267. if [ ! -d /var/www/$AKAUNTING_DOMAIN_NAME ]; then
  268. mkdir /var/www/$AKAUNTING_DOMAIN_NAME
  269. fi
  270. if [ ! -d /var/www/$AKAUNTING_DOMAIN_NAME/htdocs ]; then
  271. if [ -d /repos/akaunting ]; then
  272. mkdir /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  273. cp -r -p /repos/akaunting/. /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  274. cd /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  275. git pull
  276. else
  277. function_check git_clone
  278. git_clone $AKAUNTING_REPO /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  279. fi
  280. if [ ! -d /var/www/$AKAUNTING_DOMAIN_NAME/htdocs ]; then
  281. echo $'Unable to clone akaunting repo'
  282. exit 2589389
  283. fi
  284. fi
  285. cd /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  286. git checkout $AKAUNTING_COMMIT -b $AKAUNTING_COMMIT
  287. set_completion_param "akaunting commit" "$AKAUNTING_COMMIT"
  288. chmod g+w /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  289. chown -R www-data:www-data /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  290. cd /var/www/$AKAUNTING_DOMAIN_NAME/htdocs
  291. install_composer
  292. function_check akaunting_create_database
  293. akaunting_create_database
  294. function_check add_ddns_domain
  295. add_ddns_domain $AKAUNTING_DOMAIN_NAME
  296. AKAUNTING_ONION_HOSTNAME=$(add_onion_service akaunting 80 ${AKAUNTING_ONION_PORT})
  297. akaunting_nginx_site=/etc/nginx/sites-available/$AKAUNTING_DOMAIN_NAME
  298. if [[ $ONION_ONLY == "no" ]]; then
  299. function_check nginx_http_redirect
  300. nginx_http_redirect $AKAUNTING_DOMAIN_NAME "index index.php"
  301. echo 'server {' >> $akaunting_nginx_site
  302. echo ' listen 443 ssl;' >> $akaunting_nginx_site
  303. echo ' listen [::]:443 ssl;' >> $akaunting_nginx_site
  304. echo " server_name $AKAUNTING_DOMAIN_NAME;" >> $akaunting_nginx_site
  305. echo '' >> $akaunting_nginx_site
  306. function_check nginx_compress
  307. nginx_compress $AKAUNTING_DOMAIN_NAME
  308. echo '' >> $akaunting_nginx_site
  309. echo ' # Security' >> $akaunting_nginx_site
  310. function_check nginx_ssl
  311. nginx_ssl $AKAUNTING_DOMAIN_NAME
  312. function_check nginx_disable_sniffing
  313. nginx_disable_sniffing $AKAUNTING_DOMAIN_NAME
  314. echo ' add_header Strict-Transport-Security max-age=15768000;' >> $akaunting_nginx_site
  315. echo '' >> $akaunting_nginx_site
  316. echo ' access_log /dev/null;' >> $akaunting_nginx_site
  317. echo ' error_log /dev/null;' >> $akaunting_nginx_site
  318. echo '' >> $akaunting_nginx_site
  319. echo " root /var/www/$AKAUNTING_DOMAIN_NAME/htdocs;" >> $akaunting_nginx_site
  320. echo '' >> $akaunting_nginx_site
  321. echo ' index index.php;' >> $akaunting_nginx_site
  322. echo '' >> $akaunting_nginx_site
  323. echo ' location ~ \.php {' >> $akaunting_nginx_site
  324. echo ' include snippets/fastcgi-php.conf;' >> $akaunting_nginx_site
  325. echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> $akaunting_nginx_site
  326. echo ' fastcgi_read_timeout 30;' >> $akaunting_nginx_site
  327. echo ' }' >> $akaunting_nginx_site
  328. echo '' >> $akaunting_nginx_site
  329. echo ' location / {' >> $akaunting_nginx_site
  330. function_check nginx_limits
  331. nginx_limits $AKAUNTING_DOMAIN_NAME '15m'
  332. echo ' try_files $uri $uri/ @akaunting;' >> $akaunting_nginx_site
  333. echo ' }' >> $akaunting_nginx_site
  334. echo '' >> $akaunting_nginx_site
  335. echo ' location @akaunting {' >> $akaunting_nginx_site
  336. echo ' rewrite ^(.*)$ /index.php?p=$1 last;' >> $akaunting_nginx_site
  337. echo ' }' >> $akaunting_nginx_site
  338. echo '' >> $akaunting_nginx_site
  339. echo ' location ~ /\.(ht|git) {' >> $akaunting_nginx_site
  340. echo ' deny all;' >> $akaunting_nginx_site
  341. echo ' }' >> $akaunting_nginx_site
  342. echo '' >> $akaunting_nginx_site
  343. echo '}' >> $akaunting_nginx_site
  344. else
  345. echo -n '' > $akaunting_nginx_site
  346. fi
  347. echo 'server {' >> $akaunting_nginx_site
  348. echo " listen 127.0.0.1:$AKAUNTING_ONION_PORT default_server;" >> $akaunting_nginx_site
  349. echo " server_name $AKAUNTING_ONION_HOSTNAME;" >> $akaunting_nginx_site
  350. echo '' >> $akaunting_nginx_site
  351. function_check nginx_compress
  352. nginx_compress $AKAUNTING_DOMAIN_NAME
  353. echo '' >> $akaunting_nginx_site
  354. function_check nginx_disable_sniffing
  355. nginx_disable_sniffing $AKAUNTING_DOMAIN_NAME
  356. echo '' >> $akaunting_nginx_site
  357. echo ' access_log /dev/null;' >> $akaunting_nginx_site
  358. echo ' error_log /dev/null;' >> $akaunting_nginx_site
  359. echo '' >> $akaunting_nginx_site
  360. echo " root /var/www/$AKAUNTING_DOMAIN_NAME/htdocs;" >> $akaunting_nginx_site
  361. echo '' >> $akaunting_nginx_site
  362. echo ' index index.php;' >> $akaunting_nginx_site
  363. echo '' >> $akaunting_nginx_site
  364. echo ' location ~ \.php {' >> $akaunting_nginx_site
  365. echo ' include snippets/fastcgi-php.conf;' >> $akaunting_nginx_site
  366. echo ' fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;' >> $akaunting_nginx_site
  367. echo ' fastcgi_read_timeout 30;' >> $akaunting_nginx_site
  368. echo ' }' >> $akaunting_nginx_site
  369. echo '' >> $akaunting_nginx_site
  370. echo ' location / {' >> $akaunting_nginx_site
  371. function_check nginx_limits
  372. nginx_limits $AKAUNTING_DOMAIN_NAME '15m'
  373. echo ' try_files $uri $uri/ @akaunting;' >> $akaunting_nginx_site
  374. echo ' }' >> $akaunting_nginx_site
  375. echo '' >> $akaunting_nginx_site
  376. echo ' location @akaunting {' >> $akaunting_nginx_site
  377. echo ' rewrite ^(.*)$ /index.php?p=$1 last;' >> $akaunting_nginx_site
  378. echo ' }' >> $akaunting_nginx_site
  379. echo '' >> $akaunting_nginx_site
  380. echo ' location ~ /\.(ht|git) {' >> $akaunting_nginx_site
  381. echo ' deny all;' >> $akaunting_nginx_site
  382. echo ' }' >> $akaunting_nginx_site
  383. echo '}' >> $akaunting_nginx_site
  384. function_check configure_php
  385. configure_php
  386. function_check create_site_certificate
  387. create_site_certificate $AKAUNTING_DOMAIN_NAME 'yes'
  388. function_check nginx_ensite
  389. nginx_ensite $AKAUNTING_DOMAIN_NAME
  390. akaunting_remove_bad_links
  391. systemctl restart mariadb
  392. systemctl restart php7.0-fpm
  393. systemctl restart nginx
  394. ${PROJECT_NAME}-pass -u $MY_USERNAME -a akaunting -p "$AKAUNTING_ADMIN_PASSWORD"
  395. set_completion_param "akaunting domain" "$AKAUNTING_DOMAIN_NAME"
  396. APP_INSTALLED=1
  397. }
  398. # NOTE: deliberately there is no "exit 0"