From 94448561b06af8d5816d0f304cf17699fba3252b Mon Sep 17 00:00:00 2001 From: Bob Mottram <bob@freedombone.net> Date: Mon, 30 Jul 2018 23:35:01 +0100 Subject: [PATCH] Initial setup configuration for web admin --- src/freedombone-installer | 194 +++++++++++++++++++++--------- src/freedombone-utils-webadmin | 67 ++++++++--- webadmin/EN/setup.html | 140 +++++++++++++++++++++ webadmin/EN/setup_installing.html | 75 ++++++++++++ webadmin/images/login.png | Bin 0 -> 16021 bytes webadmin/setup.php | 19 +++ 6 files changed, 423 insertions(+), 72 deletions(-) create mode 100644 webadmin/EN/setup.html create mode 100644 webadmin/EN/setup_installing.html create mode 100644 webadmin/images/login.png create mode 100755 webadmin/setup.php diff --git a/src/freedombone-installer b/src/freedombone-installer index 12a367044..e3d3d3c43 100755 --- a/src/freedombone-installer +++ b/src/freedombone-installer @@ -33,80 +33,166 @@ export TEXTDOMAIN=${PROJECT_NAME}-installer export TEXTDOMAINDIR="/usr/share/locale" CONFIGURATION_FILE="/root/${PROJECT_NAME}.cfg" +COMPLETION_FILE="/root/${PROJECT_NAME}-completed.txt" local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local -pending_removes="/var/www/${local_hostname}/htdocs/admin/pending_removes.txt" -pending_installs="/var/www/${local_hostname}/htdocs/admin/pending_installs.txt" +webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin" +setup_file="$webadmin_install_dir/setup.txt" +pending_removes="$webadmin_install_dir/pending_removes.txt" +pending_installs="$webadmin_install_dir/pending_installs.txt" while true do if [ -f /tmp/.upgrading ]; then sleep 2 else - if [ -f "$pending_installs" ]; then - linestr=$(head -n 1 "$pending_installs") - if [[ "$linestr" == "install_"* ]]; then - app_name=$(echo "$linestr" | awk -F '_' '{print $2}' | awk -F ',' '{print $1}') - if [ -f "/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-${app_name}" ]; then - app_domain=$(echo "$linestr" | awk -F ',' '{print $2}') - app_name_upper=$(echo "$app_name" | awk '{print toupper($0)}') - freedns_code=$(echo -n "$linestr" | awk -F ',' '{print $3}') - - # indicate that we are installing - if [[ "$linestr" != *'_running'* ]]; then - sed -i "s|${app_name}|${app_name}_running|g" "$pending_installs" - fi + if [ -f "$setup_file" ]; then + if ! grep -q 'install_final' "$COMPLETION_FILE"; then + # initial setup has not yet completed - if grep -q 'ONION_ONLY=no' $CONFIGURATION_FILE; then - # Add domain name to the config - if ! grep -q "${app_name_upper}_DOMAIN_NAME=" $CONFIGURATION_FILE; then - echo "${app_name_upper}_DOMAIN_NAME=${app_domain}" >> $CONFIGURATION_FILE - else - sed -i "s|${app_name_upper}_DOMAIN_NAME=.*|${app_name_upper}_DOMAIN_NAME=${app_domain}|g" $CONFIGURATION_FILE - fi + cp "/usr/share/${PROJECT_NAME}/webadmin/setup_installing.html" "$webadmin_install_dir/index.html" + + # get the username and domain from the setup.txt file + # created by setup.php + MY_USERNAME=$(head -n 1 "$setup_file" | awk -F ',' '{print $1}') + DEFAULT_DOMAIN_NAME=$(head -n 1 "$setup_file" | awk -F ',' '{print $2}') + + # change the username in the config file + if grep -q 'MY_USERNAME=' "$CONFIGURATION_FILE"; then + sed -i "s|MY_USERNAME=.*|MY_USERNAME=$MY_USERNAME|g" "$CONFIGURATION_FILE" + else + echo "MY_USERNAME=$MY_USERNAME" >> "$CONFIGURATION_FILE" + fi + + # change the full name in the config file + if grep -q 'MY_NAME=' "$CONFIGURATION_FILE"; then + sed -i "s|MY_NAME=.*|MY_USERNAME=$MY_USERNAME|g" "$CONFIGURATION_FILE" + else + echo "MY_NAME=$MY_USERNAME" >> "$CONFIGURATION_FILE" + fi + + # change the default domain in the config file + if grep -q 'DEFAULT_DOMAIN_NAME=' "$CONFIGURATION_FILE"; then + sed -i "s|DEFAULT_DOMAIN_NAME=.*|DEFAULT_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME|g" "$CONFIGURATION_FILE" + else + echo "DEFAULT_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME" >> "$CONFIGURATION_FILE" + fi + + # ensure that minimal install is set + if grep -q 'MINIMAL_INSTALL=' "$CONFIGURATION_FILE"; then + sed -i 's|MINIMAL_INSTALL=.*|MINIMAL_INSTALL=yes|g' "$CONFIGURATION_FILE" + else + echo 'MINIMAL_INSTALL=yes' >> "$CONFIGURATION_FILE" + fi + + # Do the initial setup which includes email + /usr/local/bin/freedombone -c "$CONFIGURATION_FILE" + fi + + if grep -q 'install_final' "$COMPLETION_FILE"; then + # initial setup has completed + + # switch on nginx authentication for freedombone.local + sed -i 's|#auth_basic|auth_basic|g' "/etc/nginx/sites-available/${local_hostname}" + + # Show the web admin index page (not the initial setup page) + if [ -f "$webadmin_install_dir/index.prev" ]; then + cp "$webadmin_install_dir/index.prev" "$webadmin_install_dir/index.html" + fi + + # Remove the initial setup page + if [ -f "$webadmin_install_dir/setup.prev" ]; then + rm "$webadmin_install_dir/setup.prev" + fi - # Add freedns code to the config - if [ "$freedns_code" ]; then - # shellcheck disable=SC2086 - ${app_name_upper}_CODE="${freedns_code}" + # Replace the installing screen with the main index page when done + # It should reload by itself + if [ -f "$webadmin_install_dir/setup_installing.prev" ]; then + cp "$webadmin_install_dir/index.prev" "$webadmin_install_dir/setup_installing.html" + fi + + # set permissions for web admin site at freedombone.local + chown www-data:www-data "$webadmin_install_dir/index.html" + + # remove the setup file created by setup.php + rm "$setup_file" + + # restart the web server + systemctl restart nginx + fi - if ! grep -q "${app_name_upper}_CODE=" $CONFIGURATION_FILE; then - echo "${app_name_upper}_CODE=${freedns_code}" >> $CONFIGURATION_FILE - else - sed -i "s|${app_name_upper}_CODE=.*|${app_name_upper}_CODE=${freedns_code}|g" $CONFIGURATION_FILE + sleep 1 + + else + if [ ! -f "$webadmin_install_dir/setup.prev" ]; then + # initial setup has completed + + if [ -f "$pending_installs" ]; then + linestr=$(head -n 1 "$pending_installs") + if [[ "$linestr" == "install_"* ]]; then + app_name=$(echo "$linestr" | awk -F '_' '{print $2}' | awk -F ',' '{print $1}') + if [ -f "/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-${app_name}" ]; then + app_domain=$(echo "$linestr" | awk -F ',' '{print $2}') + app_name_upper=$(echo "$app_name" | awk '{print toupper($0)}') + freedns_code=$(echo -n "$linestr" | awk -F ',' '{print $3}') + + # indicate that we are installing + if [[ "$linestr" != *'_running'* ]]; then + sed -i "s|${app_name}|${app_name}_running|g" "$pending_installs" fi + + if grep -q 'ONION_ONLY=no' $CONFIGURATION_FILE; then + # Add domain name to the config + if ! grep -q "${app_name_upper}_DOMAIN_NAME=" $CONFIGURATION_FILE; then + echo "${app_name_upper}_DOMAIN_NAME=${app_domain}" >> $CONFIGURATION_FILE + else + sed -i "s|${app_name_upper}_DOMAIN_NAME=.*|${app_name_upper}_DOMAIN_NAME=${app_domain}|g" $CONFIGURATION_FILE + fi + + # Add freedns code to the config + if [ "$freedns_code" ]; then + # shellcheck disable=SC2086 + ${app_name_upper}_CODE="${freedns_code}" + + if ! grep -q "${app_name_upper}_CODE=" $CONFIGURATION_FILE; then + echo "${app_name_upper}_CODE=${freedns_code}" >> $CONFIGURATION_FILE + else + sed -i "s|${app_name_upper}_CODE=.*|${app_name_upper}_CODE=${freedns_code}|g" $CONFIGURATION_FILE + fi + fi + fi + + /usr/local/bin/${PROJECT_NAME}-addremove add "${app_name}" fi + # remove the line + sed -i "/$linestr/d" "$pending_installs" + else + # if any unusual line is found then remove the file + rm "$pending_installs" fi - - /usr/local/bin/${PROJECT_NAME}-addremove add "${app_name}" fi - # remove the line - sed -i "/$linestr/d" "$pending_installs" - else - # if any unusual line is found then remove the file - rm "$pending_installs" - fi - fi - sleep 1 + sleep 1 - if [ -f "$pending_removes" ]; then - linestr=$(head -n 1 "$pending_removes") - if [[ "$linestr" == "remove_"* ]]; then - app_name=$(echo "$linestr" | awk -F '_' '{print $2}') - if [ -f "/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-${app_name}" ]; then - # indicate that we are removing - if [[ "$linestr" != *'_running'* ]]; then - sed -i "s|${app_name}|${app_name}_running|g" "$pending_removes" + if [ -f "$pending_removes" ]; then + linestr=$(head -n 1 "$pending_removes") + if [[ "$linestr" == "remove_"* ]]; then + app_name=$(echo "$linestr" | awk -F '_' '{print $2}') + if [ -f "/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-${app_name}" ]; then + # indicate that we are removing + if [[ "$linestr" != *'_running'* ]]; then + sed -i "s|${app_name}|${app_name}_running|g" "$pending_removes" + fi + /usr/local/bin/${PROJECT_NAME}-addremove remove "${app_name}" + fi + # remove the line + sed -i "/$linestr/d" "$pending_removes" + else + # if any unusual line is found then remove the file + rm "$pending_removes" fi - /usr/local/bin/${PROJECT_NAME}-addremove remove "${app_name}" fi - # remove the line - sed -i "/$linestr/d" "$pending_removes" - else - # if any unusual line is found then remove the file - rm "$pending_removes" fi fi diff --git a/src/freedombone-utils-webadmin b/src/freedombone-utils-webadmin index 5eef954ff..6eb460819 100755 --- a/src/freedombone-utils-webadmin +++ b/src/freedombone-utils-webadmin @@ -457,27 +457,37 @@ function web_admin_setup_login { $INSTALL_PACKAGES apache2-utils fi - read_config_param MY_USERNAME - webadmin_password=$("${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a webadmin) - if [ ! "$webadmin_password" ]; then + # if an nginx password file has not been created for web admin + if [ ! -f /etc/nginx/.webadminpasswd ]; then webadmin_password="$(create_password "${MINIMUM_PASSWORD_LENGTH}")" - "${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a webadmin -p "$webadmin_password" # create a password for users if [ ! -f /etc/nginx/.webadminpasswd ]; then touch /etc/nginx/.webadminpasswd fi - if grep -q "$MY_USERNAME:" /etc/nginx/.webadminpasswd; then - sed -i "/$MY_USERNAME:/d" /etc/nginx/.webadminpasswd + if grep -q "admin:" /etc/nginx/.webadminpasswd; then + sed -i "/admin:/d" /etc/nginx/.webadminpasswd fi - echo -n "$webadmin_password" | htpasswd -i -s -c /etc/nginx/.webadminpasswd "$MY_USERNAME" + # create a password file used by nginx + echo -n "$webadmin_password" | htpasswd -i -s -c /etc/nginx/.webadminpasswd "admin" if [ ! -f /etc/nginx/.webadminpasswd ]; then echo $'/etc/nginx/.webadminpasswd not found' - exit 5637653 + exit 2428956 fi - #echo -n "$webadmin_password" > "/var/www/${local_hostname}/htdocs/admin/initiallogin.txt" + # create a setup page with the initial password inserted + # and copy it to the index + cp "$webadmin_install_dir/index.html" "$webadmin_install_dir/index.prev" + cp "$webadmin_install_dir/setup.html" "$webadmin_install_dir/setup.prev" + sed -i "s|WEBADMINPASSWORD|${webadmin_password}|g" "$webadmin_install_dir/setup.prev" + cp "$webadmin_install_dir/setup.prev" "$webadmin_install_dir/index.html" + + # if initial setup has not yet happened then create + # a password file + if ! grep -q 'install_final' "$COMPLETION_FILE"; then + echo -n "$webadmin_password" > /root/login.txt + fi fi } @@ -485,20 +495,41 @@ function install_web_admin { # This is intended as an admin web user interface # similar to Plinth or the yunohost + # get the language subdirectory name + # This is usually EN language_subdir=$(web_admin_get_language_subdir) + # get the local name (usually freedombone.local) from avahi config local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local + # where the web admin files are + webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin" + + # whether or not to add authentication to freedombone.local + basic_auth_str='#auth_basic' + if grep -q 'install_final' "$COMPLETION_FILE"; then + # initial installation has completed + if [ -f /etc/nginx/.webadminpasswd ]; then + # a password was created + basic_auth_str='auth_basic' + fi + fi - if [ ! -d "/var/www/${local_hostname}/htdocs/admin" ]; then - mkdir -p "/var/www/${local_hostname}/htdocs/admin" + if [ ! -d "$webadmin_install_dir" ]; then + mkdir -p "$webadmin_install_dir" fi web_admin_installed= if [ -d "/usr/share/${PROJECT_NAME}/webadmin" ]; then if [ -d "/usr/share/${PROJECT_NAME}/webadmin/${language_subdir}" ]; then - cp -r "/usr/share/${PROJECT_NAME}/webadmin"/* "/var/www/${local_hostname}/htdocs/admin" - cp "/usr/share/${PROJECT_NAME}/webadmin/${language_subdir}"/*.html "/var/www/${local_hostname}/htdocs/admin" + cp -r "/usr/share/${PROJECT_NAME}/webadmin"/* "$webadmin_install_dir" + cp "/usr/share/${PROJECT_NAME}/webadmin/${language_subdir}"/*.html "$webadmin_install_dir" + + if [ -f "$webadmin_install_dir/setup.prev" ]; then + # We are still waiting for initial setup to happen + cp "$webadmin_install_dir/setup.prev" "$webadmin_install_dir/index.html" + fi + # if this is an onion only install then modify some php scripts read_config_param ONION_ONLY if [[ "$ONION_ONLY" != 'no' ]]; then web_admin_onion_only @@ -518,7 +549,7 @@ function install_web_admin { echo ' <body>'; echo " ${placeholderstr}"; echo ' </body>'; - echo '</html>'; } > "/var/www/${local_hostname}/htdocs/admin/index.html" + echo '</html>'; } > "$webadmin_install_dir/index.html" fi nginx_file=/etc/nginx/sites-available/$local_hostname @@ -533,8 +564,8 @@ function install_web_admin { echo ' error_log /dev/null;'; echo ''; echo ' location ^~ /admin {'; - echo " #auth_basic \"${WEBADMIN_LOGIN_TEXT}\";"; - echo ' #auth_basic_user_file /etc/nginx/.webadminpasswd;'; + echo " ${basic_auth_str} \"${WEBADMIN_LOGIN_TEXT}\";"; + echo " ${basic_auth_str}_user_file /etc/nginx/.webadminpasswd;"; echo " root /var/www/${local_hostname}/htdocs;"; echo ' index index.html;'; echo " error_page 405 = \$uri;"; @@ -576,8 +607,8 @@ function install_web_admin { { echo ' add_header Strict-Transport-Security max-age=0;'; echo ''; echo ' location ^~ /admin {'; - echo " #auth_basic \"${WEBADMIN_LOGIN_TEXT}\";"; - echo ' #auth_basic_user_file /etc/nginx/.webadminpasswd;'; + echo " ${basic_auth_str} \"${WEBADMIN_LOGIN_TEXT}\";"; + echo " ${basic_auth_str}_user_file /etc/nginx/.webadminpasswd;"; echo " root /var/www/${local_hostname}/htdocs;"; echo ' index index.html;'; echo " error_page 405 = \$uri;"; diff --git a/webadmin/EN/setup.html b/webadmin/EN/setup.html new file mode 100644 index 000000000..ee090685b --- /dev/null +++ b/webadmin/EN/setup.html @@ -0,0 +1,140 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Refresh" content="30"> + <style> + #headerpic { + width: 60%; + height: auto; + margin-right : auto; + margin-left : auto; + min-width : 220px; + } + + #loginicon { + width: 20%; + height: auto; + margin-right : auto; + margin-left : auto; + min-width : 220px; + } + + .header { + text-align: center; + padding: 32px; + } + + #iconpic { + width: 20%; + height: auto; + margin-right : auto; + margin-left : auto; + min-width : 120px; + } + + .card { + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); + max-width: 600px; + margin: auto; + text-align: center; + font-family: arial; + clear: both; + } + + .card input[type=text] { + width: 90%; + clear: both; + text-align: center; + } + + .appurl { + color: grey; + font-size: 100%; + } + + .welcomeheader { + color: black; + font-size: 200%; + font-weight: bold; + } + + .welcometext { + color: black; + font-size: 90%; + } + + .logintext { + color: black; + font-size: 120%; + font-weight: bold; + color: #981737; + } + + button { + border: none; + outline: 0; + display: inline-block; + padding: 8px; + color: white; + background-color: #000; + text-align: center; + cursor: pointer; + width: 100%; + font-size: 18px; + } + + a { + text-decoration: none; + color: black; + } + + button:hover, a:hover { + opacity: 0.7; + } + + .chip { + display: inline-block; + padding: 0 25px; + height: 50px; + font-size: 70%; + line-height: 50px; + border-radius: 25px; + background-color: #f1f1f1; + } + + .chip img { + float: left; + margin: 0 10px 0 -25px; + height: 50px; + width: 50px; + border-radius: 50%; + } + </style> + </head> + <body> + <div class="card"> + <div class="header"> + <img id="headerpic" class="img-responsive" src="images/logo.png"> + </div> + <img id="welcomeicon" class="img-responsive" src="images/login.png"> + <p class="welcometext">Thankyou for choosing the Freedombone home internet appliance.</p> + + <p class="welcometext">Please take a moment to write down the following credentials, or store them in your preferred password manager. <i>You will not be able to log in again otherwise.</i></p> + + <p class="logintext">Username: admin<br> + Password: WEBADMINPASSWORD + </p> + + <br> + + <form action="setup.php" method="post"> + <input type="hidden" name="my_username" value="admin"> + <input type="hidden" name="default_domain_name" value="freedombone.local"> + <input type="submit" name="setup" value="Continue"> + </form> + + <br> + + </div> + </body> +</html> diff --git a/webadmin/EN/setup_installing.html b/webadmin/EN/setup_installing.html new file mode 100644 index 000000000..a05d76015 --- /dev/null +++ b/webadmin/EN/setup_installing.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Refresh" content="10"> + <style> + #headerpic { + width: 60%; + height: auto; + margin-right : auto; + margin-left : auto; + min-width : 220px; + } + + .header { + text-align: center; + padding: 32px; + } + + #iconpic { + width: 20%; + height: auto; + margin-right : auto; + margin-left : auto; + min-width : 120px; + } + + .appurl { + color: grey; + font-size: 100%; + } + + .appdesc { + color: black; + font-size: 65%; + } + + button { + border: none; + outline: 0; + display: inline-block; + padding: 8px; + color: white; + background-color: #000; + text-align: center; + cursor: pointer; + width: 100%; + font-size: 18px; + } + + a { + text-decoration: none; + color: black; + } + + button:hover, a:hover { + opacity: 0.7; + } + + </style> + </head> + <body> + <div class="header"> + <a href="index.html"><img id="headerpic" class="img-responsive" src="images/logo.png"></a> + + <h2>Your appliance is being configured</h2> + + <p>This may take some time. Please be patient.</p> + + <form action="index.html"> + <input type="submit" value="Go Back" /> + </form> + </div> + + </body> +</html> diff --git a/webadmin/images/login.png b/webadmin/images/login.png new file mode 100644 index 0000000000000000000000000000000000000000..634b125484de88003f584501179beb9e0fce544b GIT binary patch literal 16021 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�IKbmIX7X#%D=ExbsgX`{1gK`)w z27{nvVct%u?w6+^<R3N}AGI5<lN>cBazL5sQ(el@)9m^vFeC+-MyaAPg*L6h&nd&q zIp#J`=56+ZHB`l|zZGJ7O%A}i{afz1tsJgCNOpdUrQfq8<(m|VA_sq)oOYadoI4os z^mO{4j{cY&U_>C=`22&BHLl_;VJS!*xTMD5v3xd4DT^?-Pu5YQ<X+u4>{8dkW=?Jk zWc<yQ&-00SuS5sypXE=6b|zHWWr>ldZx}DaHLex>Ll_L|`<|E5u+#>~2&VH2X>v3Q z5<#U^Y}eYgo<KYtxl0;suORZJA8*45wdg%cJFV-rCbt2`L-u?Mmw2=7Q=jB}tAx0L z|BsZj{}c>7BSrMGSf1jJ3z{1|ZAr_d$^sZ?$Xlyd@^J9`FJzT+*6768rz~B(9+ZGe z3X3-la+3jV!{eOH8bN8{1M4MfTjT)F<Gg1Ybm(mJ#F9ShUGKg|g)&JlF%Hh5de6_S z($~1_Gh9iI)10Vkt^X)TI^xx8TF#%u+|Y0W=m_c_^(fjh$ptH@5@OILsJJp>Z-RY$ z6a|Dn%AP2l2ibVuAD<;^;{P!(veHqGdITtu3xrZmS{mS!;6iHLcC78<o0Q1xf;>6< zk~&{!8{;+r0I=wPT7W^x2XAMnJ9J^6_iML}$tq|8utwV==0C`5Yr=$dDi;11XsLv( z+E)Txf)-qY>oH9$()TRTw-25L9~~X1+$%3<l^0WYvH<UaUl%De^1{AMGOE~_3iN$@ zx-cggvf7mU2&j@}l3rBL?vnVTYe*OfdUvjyc9$|2FZ4~YIWhq6NxT=Tg1<;Q(IQ?T zxIa4d<8Z-I=$Qf3{G8rgl9F740=%A^lpg_4eWA>82P}rgNq5a7h664ukdquTfXKK% zu2j+&@h889LZ!_W_V5a2l#dV>3t|)2Aj%YQx1FF%je@rz9Fn(wN1phb4I6w<5^hDE z&(UdrI4@Dd-pB%?lXSYIG~Zn8JCQ3O+G6x+B}w6bx(^UUDn$t=2?Zy7J8n0@hM(+} z9JKG-^Zb&@QXVgL4#bPCZ(<dAgd^Hw$LV~*Tk`VLn3%p1sc!gh!MWQpMH7yI_8cU- z(KGq~l&KHF4<Z$c1z;ukN3^))dEpr8`QiPdl2OdXQrgW)Ik^)P1)yG8iZi6s&f>tK zJI2RQeK|bOB{&u)RDe;or|!|$j({6k@(b~u$E*j^F{DE$HK^SIH(;1j5EmOQ5O{-P zQdh<r$tW5Eij3SRq7V_fQ?W-9NlvHcjh(F=5DG~fIv|5bLW-NBZibM)C8zqWM|GCz z!>9onH2UM04*tH=4ZIPKgA5=V_y5T%hS2bL0(=dz=YIz7Vawrr5}b)4!Y<n3zWw>9 zWUdyz6ulY*INCB-g~7)c`gZ4<#|vCTcAjEeZQPt3`TwEv_)jWwQ1fcXFj*|GeIPmi RpPB_ADJmyYE2JOze*kM+ZLa_T literal 0 HcmV?d00001 diff --git a/webadmin/setup.php b/webadmin/setup.php new file mode 100755 index 000000000..8facfcf45 --- /dev/null +++ b/webadmin/setup.php @@ -0,0 +1,19 @@ +<?php + +if (isset($_POST['setup'])) { + $my_username = htmlspecialchars($_POST['my_username']); + $default_domain_name = htmlspecialchars($_POST['default_domain_name']); + + if(!file_exists("setup.txt")) { + $setup_file = fopen("setup.txt", "w") or die("Unable to create setup file"); + fwrite($setup_file, $my_username.",".$default_domain_name."\n"); + fclose($); + } + + $output_filename = "setup_installing.html"; + $htmlfile = fopen("$output_filename", "r") or die("Unable to open $output_filename"); + echo fread($htmlfile,filesize("$output_filename")); + fclose($htmlfile); +} + +?> -- GitLab