majore update, adding multiple admins
This commit is contained in:
parent
c1a98c5ff6
commit
a25a906866
|
@ -14,3 +14,4 @@ rm -r /srv/www/html/panel/f3/.git
|
|||
find /srv/www/html/panel -type d -exec chmod 755 {} +
|
||||
find /srv/www/html/panel -type f -exec chmod 644 {} +
|
||||
chown -R vpanel:vpanel /srv/www/html/panel
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ class Panel {
|
|||
|
||||
}
|
||||
|
||||
public static function validateEmailPassword($password, $password_confirm) {
|
||||
public static function validatePassword($password, $password_confirm) {
|
||||
|
||||
global $f3;
|
||||
|
||||
|
@ -303,6 +303,136 @@ class Panel {
|
|||
|
||||
}
|
||||
|
||||
public static function validateUsername($username) {
|
||||
|
||||
global $f3;
|
||||
|
||||
$messages = array();
|
||||
|
||||
if(strlen($username) < 3) {
|
||||
|
||||
$messages[] = "Usernames must be at least 3 characters long.";
|
||||
|
||||
}
|
||||
|
||||
if(strlen($username) > 16) {
|
||||
|
||||
$messages[] = "Usernames can not be longer than 16 characters.";
|
||||
|
||||
}
|
||||
|
||||
if (!preg_match('/^[[:lower:][:digit:]\.\_\-]{3,16}$/', $username)) {
|
||||
|
||||
$messages[] = "Usernames can only contain letters, numbers, and the special characters . _ -";
|
||||
|
||||
}
|
||||
|
||||
if (preg_match('/^[[:digit:]\.\_\-]/', $username)) {
|
||||
|
||||
$messages[] = "Usernames must begin with an alphabetic character.";
|
||||
|
||||
}
|
||||
|
||||
if (preg_match('/[\.\_\-]$/', $username)) {
|
||||
|
||||
$messages[] = "Usernames may not end with a Special Character.";
|
||||
|
||||
}
|
||||
|
||||
if (preg_match('/[\.\_\-]{2,}/', $username)) {
|
||||
|
||||
$messages[] = "Usernames may not have consecutive Special Characters.";
|
||||
|
||||
}
|
||||
|
||||
if (count($messages) > 0) {
|
||||
if ($f3->exists('SESSION.messages')) {
|
||||
$f3->set('SESSION.messages', array_merge($f3->get('SESSION.messages'), $messages));
|
||||
} else {
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function verifyVhostDomainExists($domain) {
|
||||
|
||||
global $f3;
|
||||
|
||||
exec("/usr/local/bin/vhost-get.sh -d $domain -c", $output, $result_code);
|
||||
if ($result_code == 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
if (count($output) > 0) {
|
||||
if ($output[0] != "ERROR: $domain not found") {
|
||||
$f3->set('SESSION.messages', $output[0]);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function verifyCertificateExists($domain) {
|
||||
|
||||
global $f3;
|
||||
|
||||
exec("/usr/local/bin/letsencrypt-get.sh -d $domain -c", $output, $result_code);
|
||||
if ($result_code == 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
if (count($output) > 0) {
|
||||
if ($output[0] != "ERROR: Certificate for $domain not found") {
|
||||
$f3->set('SESSION.messages', $output[0]);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function verifyVmailDomainExists($domain) {
|
||||
|
||||
global $f3;
|
||||
|
||||
exec("/usr/local/bin/vmail-domains-get.sh -d $domain -c", $output, $result_code);
|
||||
if ($result_code == 0) {
|
||||
if (count($output) == 0) {
|
||||
return FALSE;
|
||||
} else {
|
||||
// add check for domain row???
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
$f3->set('SESSION.messages', "System error checking if email domain exists.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function verifyDkimExists($domain) {
|
||||
|
||||
global $f3;
|
||||
|
||||
exec("/usr/local/bin/vmail-dkim-get.sh -d $domain -c", $output, $result_code);
|
||||
if ($result_code == 0) {
|
||||
return TRUE;
|
||||
} else {
|
||||
if (count($output) > 0) {
|
||||
if ($output[0] != "ERROR: DKIM for $domain does not exist.") {
|
||||
if (count($output) > 0) {
|
||||
$f3->set('SESSION.messages', $output[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function vGet($cmd, $return404 = TRUE) {
|
||||
|
||||
global $f3;
|
||||
|
|
31
panel/classes/Panel/Cert.php
Normal file
31
panel/classes/Panel/Cert.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel;
|
||||
|
||||
class Cert extends \Panel {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
if ($f3->exists('SESSION.domain')) {
|
||||
|
||||
/* set base path for vhost links */
|
||||
if ($f3->get('NAV.mapping') == 'cert') {
|
||||
$f3->set('NAV.certbase', preg_replace('/\/$/', '', $f3->get('BASE')));
|
||||
} elseif ($f3->get('NAV.mapping') == 'vpanel') {
|
||||
$f3->set('NAV.certbase', preg_replace('/\/$/', '', $f3->get('BASE') . '/Certs/' . $f3->get('SESSION.cert')));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
92
panel/classes/Panel/Cert/Certs.php
Normal file
92
panel/classes/Panel/Cert/Certs.php
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Cert;
|
||||
|
||||
class Certs extends \Panel\Cert {
|
||||
|
||||
/* use this to make query */
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
if ($f3->exists('PARAMS.cert')) {
|
||||
$cert = $f3->get('PARAMS.cert');
|
||||
if ($cert_array = $f3->call('\Panel::vGet', array("letsencrypt-get.sh -d $cert -c", FALSE))) {
|
||||
$f3->set('cert_array', $cert_array[0]);
|
||||
}
|
||||
} else {
|
||||
if ($certs_array = $f3->call('\Panel::vGet', array("letsencrypt-get.sh -c", FALSE))) {
|
||||
$f3->set('certs_array', $certs_array);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
if ($f3->exists('PARAMS.cert')) {
|
||||
|
||||
$cert_array = $f3->get('cert_array');
|
||||
/* remove time from creation date */
|
||||
$start = $cert_array['start'];
|
||||
$start_array = explode(' ', $start);
|
||||
unset($start_array[2]);
|
||||
$start = implode(' ', $start_array);
|
||||
$cert_array['start'] = $start;
|
||||
/* remove time from expiration date */
|
||||
$end = $cert_array['end'];
|
||||
$end_array = explode(' ', $end);
|
||||
unset($end_array[2]);
|
||||
$end = implode(' ', $end_array);
|
||||
$cert_array['end'] = $end;
|
||||
/* remove main cert name from alternatives */
|
||||
// $common = $cert_array['common'];
|
||||
$alternative = $cert_array['alternative'];
|
||||
// $alternative = preg_replace("/^$common/", '', $alternative);
|
||||
// $alternative = trim($alternative);
|
||||
$alternative = preg_replace('/ /', '<br>', $alternative);
|
||||
$cert_array['alternative'] = $alternative;
|
||||
$f3->set('cert_array', $cert_array);
|
||||
|
||||
$cert = $f3->get('PARAMS.cert');
|
||||
$f3->set('page_header', "Certificate Details for $cert");
|
||||
echo \Template::instance()->render('cert/certs-cert.html');
|
||||
|
||||
} else {
|
||||
|
||||
$certs_array = $f3->get('certs_array');
|
||||
if (is_array($certs_array) && count($certs_array) > 0) {
|
||||
foreach ($certs_array as $k=>$cert_array) {
|
||||
/* remove time from expiration date */
|
||||
$end = $cert_array['end'];
|
||||
$end_array = explode(' ', $end);
|
||||
unset($end_array[2]);
|
||||
$end = implode(' ', $end_array);
|
||||
$cert_array['end'] = $end;
|
||||
/* remove main cert name from alternatives */
|
||||
// $common = $cert_array['common'];
|
||||
$alternative = $cert_array['alternative'];
|
||||
// $alternative = preg_replace("/^$common/", '', $alternative);
|
||||
// $alternative = trim($alternative);
|
||||
$alternative = preg_replace('/ /', '<br>', $alternative);
|
||||
$cert_array['alternative'] = $alternative;
|
||||
$certs_array[$k] = $cert_array;
|
||||
}
|
||||
$f3->set('certs_array', $certs_array);
|
||||
}
|
||||
|
||||
$f3->set('page_header', "Certificates");
|
||||
echo \Template::instance()->render('cert/certs.html');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
69
panel/classes/Panel/Cert/CertsAdd.php
Normal file
69
panel/classes/Panel/Cert/CertsAdd.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Cert;
|
||||
|
||||
class CertsAdd extends \Panel\Cert {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
if ($f3->exists('PARAMS.cert')) {
|
||||
$domain = $f3->get('PARAMS.cert');
|
||||
if ($f3->call('\Panel::validateDomain', $domain)) {
|
||||
if ($certdomain_dns = dns_get_record("$domain", DNS_A)) {
|
||||
if ($certdomain_dns[0]['ip'] == $_SERVER['SERVER_ADDR']) {
|
||||
if (is_dir('/var/tmp/letsencrypt/')) {
|
||||
if (is_writable('/var/tmp/letsencrypt/')) {
|
||||
touch("/var/tmp/letsencrypt/$domain");
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "A background job to create a Security Certificate for $domain has been started.";
|
||||
$messages[] = "It can take a few seconds, up to one minute, for this job to complete.";
|
||||
$messages[] = "Wait few seconds and then reload this page to check for the new Security Certificate.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "System error with Security Certificate system.";
|
||||
$messages[] = "Please try again later.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
}
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "System error with Security Certificate system.";
|
||||
$messages[] = "Please try again later.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
}
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "DNS for $domain does not point to this server IP.";
|
||||
$messages[] = "Please update DNS and try again.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
}
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "Error verifying DNS, try again later.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
}
|
||||
}
|
||||
parse_str($f3->get('QUERY'), $output);
|
||||
if (isset($output['r'])) {
|
||||
$f3->reroute($output['r']);
|
||||
}
|
||||
|
||||
}
|
||||
/* default reroute as fallback */
|
||||
$f3->reroute('/');
|
||||
}
|
||||
|
||||
}
|
70
panel/classes/Panel/Cert/CertsDelete.php
Normal file
70
panel/classes/Panel/Cert/CertsDelete.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Cert;
|
||||
|
||||
class CertsDelete extends \Panel\Cert {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
|
||||
if ($f3->exists('PARAMS.cert')) {
|
||||
$domain = $f3->get('PARAMS.cert');
|
||||
if ($f3->call('\Panel::validateDomain', $domain)) {
|
||||
if ($f3->call('\Panel::verifyCertificateExists', $domain)) {
|
||||
|
||||
/* delete the cert */
|
||||
$f3->call('\Panel::vGet', array("letsencrypt-delete.sh -d $domain -r", FALSE));
|
||||
|
||||
/* check for and delete dovecot config */
|
||||
if (preg_match('/^mail\./i', $domain)) {
|
||||
$mxdomain = preg_replace('/^mail\./i', '', $f3->get('HOST'));
|
||||
$f3->call('\Panel::vGet', array("vmail-dovecot-disable.sh -d $mxdomain", FALSE));
|
||||
}
|
||||
|
||||
/* delete apache config (vhost or webmail) */
|
||||
if (is_link("/etc/apache2/sites-enabled/$domain.conf")) {
|
||||
$f3->call('\Panel::vGet', array("vhost-disable.sh -d $domain", FALSE));
|
||||
}
|
||||
|
||||
$messages[] = "The Security Certificate and related configs for $domain have been deleted.";
|
||||
|
||||
} else {
|
||||
|
||||
$messages[] = "Security Certificate for $domain not found.";
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$messages[] = "Invalid domain name ($domain).";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* reroute user to page the originated from */
|
||||
parse_str($f3->get('QUERY'), $output);
|
||||
if (isset($output['r'])) {
|
||||
$f3->reroute($output['r']);
|
||||
} else {
|
||||
/* default reroute as fallback */
|
||||
$f3->reroute('/');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
20
panel/classes/Panel/MySQL.php
Normal file
20
panel/classes/Panel/MySQL.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2023 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel;
|
||||
|
||||
class MySQL extends \Panel {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
}
|
||||
|
||||
}
|
27
panel/classes/Panel/MySQL/Databases.php
Normal file
27
panel/classes/Panel/MySQL/Databases.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\MySQL;
|
||||
|
||||
class Databases extends \Panel\MySQL {
|
||||
|
||||
/* use this to make query */
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
echo \Template::instance()->render('mysql/databases.html');
|
||||
|
||||
}
|
||||
|
||||
}
|
62
panel/classes/Panel/Vhost/Users.php
Normal file
62
panel/classes/Panel/Vhost/Users.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vhost;
|
||||
|
||||
class Users extends \Panel\Vhost {
|
||||
|
||||
/* use this to make query */
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
if ($f3->exists('PARAMS.username')) {
|
||||
$username = $f3->get('PARAMS.username');
|
||||
if ($users_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -u $username -c", FALSE))) {
|
||||
if ($users_array[0]['passwd'] == "") {
|
||||
$users_array[0]['passwd'] = '(unavailable)';
|
||||
}
|
||||
$f3->set('users_array', $users_array[0]);
|
||||
if ($vhosts_array = $f3->call('\Panel::vGet', array("vhost-get.sh -u $username -c", FALSE))) {
|
||||
$f3->set('vhosts_array', $vhosts_array);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($users_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -c", FALSE))) {
|
||||
if (is_array($users_array) && count($users_array) > 0) {
|
||||
foreach ($users_array as $k=>$user_array) {
|
||||
if ($user_array['passwd'] == "") {
|
||||
$users_array[$k]['passwd'] = '(unavailable)';
|
||||
}
|
||||
}
|
||||
$f3->set('users_array', $users_array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
if ($f3->exists('PARAMS.username')) {
|
||||
|
||||
$username = $f3->get('PARAMS.username');
|
||||
$f3->set('page_header', "User Details");
|
||||
echo \Template::instance()->render('vhost/users-user.html');
|
||||
|
||||
} else {
|
||||
|
||||
$f3->set('page_header', "Users");
|
||||
echo \Template::instance()->render('vhost/users.html');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
90
panel/classes/Panel/Vhost/UsersAdd.php
Normal file
90
panel/classes/Panel/Vhost/UsersAdd.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vhost;
|
||||
|
||||
class UsersAdd extends \Panel\Vhost {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
/* get system defaults for new users */
|
||||
$user = array();
|
||||
$user['username'] = '';
|
||||
$user['password'] = '';
|
||||
$user['password_confirm'] = '';
|
||||
if ($f3->get('JAILUSER') == '1') {
|
||||
$user['jailuser'] = 1;
|
||||
} else {
|
||||
$user['jailuser'] = 0;
|
||||
}
|
||||
$user['fpmmax'] = $f3->get('FPMMAX');
|
||||
if ($f3->get('WRITEUSERINFO') == '1') {
|
||||
$user['writeuserinfo'] = 1;
|
||||
} else {
|
||||
$user['writeuserinfo'] = 0;
|
||||
}
|
||||
if ($f3->get('SHOWWRITEINFO') == '1') {
|
||||
$user['showwriteinfo'] = 1;
|
||||
} else {
|
||||
$user['showwriteinfo'] = 0;
|
||||
}
|
||||
$f3->set('user', $user);
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
echo \Template::instance()->render('vhost/users-add.html');
|
||||
|
||||
}
|
||||
|
||||
function post($f3) {
|
||||
|
||||
extract($_POST);
|
||||
|
||||
/* force username to be all lower case */
|
||||
$username = strtolower($username);
|
||||
$f3->call('\Panel::validateUsername', $username);
|
||||
/* only validate password if one was submitted, otherwise script will generate random password */
|
||||
if ($password != '' || $password_confirm != '') {
|
||||
$f3->call('\Panel::validatePassword', array($password, $password_confirm));
|
||||
}
|
||||
|
||||
/* check for validation errors */
|
||||
if ($f3->exists('SESSION.messages')) {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "Please make changes and re-submit the form to try again.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->set('user', $_POST);
|
||||
$f3->call('\Panel\Vhost\UsersAdd::get', $f3);
|
||||
} else {
|
||||
$domain = $f3->get('PARAMS.domain');
|
||||
if ($password != '') {
|
||||
$password = "-p " . escapeshellarg($password);
|
||||
}
|
||||
exec("/usr/local/bin/vhost-user-add.sh -u $username -x $fpmmax $password -w $writeuserinfo", $output, $result_code);
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "Success: User $username added.";
|
||||
if ($jailuser == 1) {
|
||||
exec("/usr/local/bin/vhost-user-jail.sh -u $username >/dev/null 2>/dev/null &", $output, $result_code);
|
||||
$messages[] = "Note: User is being jailed. Setting up the jail environment takes about a minute to complete and is run in the background now.";
|
||||
}
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Users");
|
||||
} else {
|
||||
$messages[] = "Error adding user.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->call('\Panel\Vhost\UsersAdd::get', $f3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
52
panel/classes/Panel/Vhost/UsersDelete.php
Normal file
52
panel/classes/Panel/Vhost/UsersDelete.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vhost;
|
||||
|
||||
class UsersDelete extends \Panel\Vhost {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
/* verify user exists */
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
$f3->set('confirm', 'true');
|
||||
echo \Template::instance()->render('vhost/users-delete.html');
|
||||
|
||||
}
|
||||
|
||||
function post($f3) {
|
||||
|
||||
/* run delete command here */
|
||||
$username = $f3->get('PARAMS.username');
|
||||
$messages = array();
|
||||
$output = system("/usr/local/bin/vhost-user-del.sh -u $username", $result_code);
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "User '$username' has been deleted.";
|
||||
} else {
|
||||
$messages[] = "Error deleting user '$username'.";
|
||||
$messages[] = $output;
|
||||
}
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Users");
|
||||
// $mapping = $f3->get('NAV.mapping');
|
||||
// if ($mapping == 'vmail') {
|
||||
// $f3->reroute("/Users");
|
||||
// } else {
|
||||
// $f3->reroute("/Email/$domain/Accounts");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
150
panel/classes/Panel/Vhost/UsersEdit.php
Normal file
150
panel/classes/Panel/Vhost/UsersEdit.php
Normal file
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vhost;
|
||||
|
||||
class UsersEdit extends \Panel\Vhost {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
$username = $f3->get('PARAMS.username');
|
||||
if ($user_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -u $username -c", FALSE))) {
|
||||
if ($user_array[0]['passwd'] == "") {
|
||||
$user_array[0]['passwd'] = '(unavailable)';
|
||||
}
|
||||
$f3->set('user_array', $user_array[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static public function get($f3) {
|
||||
|
||||
if ($f3->exists('PARAMS.username')) {
|
||||
|
||||
$username = $f3->get('PARAMS.username');
|
||||
$f3->set('page_header', "Edit User: $username");
|
||||
echo \Template::instance()->render('vhost/users-edit.html');
|
||||
|
||||
} else {
|
||||
|
||||
$f3->set('page_header', "Users");
|
||||
echo \Template::instance()->render('vhost/users.html');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function post($f3) {
|
||||
|
||||
$username = $f3->get('PARAMS.username');
|
||||
$action = $_POST['action'];
|
||||
|
||||
if ($action == 'password') {
|
||||
$password = $_POST['password'];
|
||||
$password_confirm = $_POST['password_confirm'];
|
||||
$f3->call('\Panel::validatePassword', array($password, $password_confirm));
|
||||
/* check for validation errors */
|
||||
if ($f3->exists('SESSION.messages')) {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
} else {
|
||||
$password = escapeshellarg($password);
|
||||
if ($f3->get('WRITEUSERINFO') == '1') {
|
||||
exec("/usr/local/bin/vhost-user-mod.sh -u $username -p $password -w", $output, $result_code);
|
||||
} else {
|
||||
exec("/usr/local/bin/vhost-user-mod.sh -u $username -p $password", $output, $result_code);
|
||||
}
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "Success: Password for $username updated.";
|
||||
} else {
|
||||
$messages[] = "Error updating password.";
|
||||
}
|
||||
}
|
||||
} elseif ($action == 'jail') {
|
||||
exec("/usr/local/bin/vhost-user-jail.sh -u $username >/dev/null 2>/dev/null &", $output, $result_code);
|
||||
$messages[] = "User is being jailed. Note: Setting up the jail environment takes about a minute to complete and is run in the background now.";
|
||||
$f3->reroute("/Users/$username");
|
||||
} elseif ($action == 'fpmmax') {
|
||||
$fpmmax = $_POST['fpmmax'];
|
||||
exec("/usr/local/bin/vhost-user-mod.sh -u $username -x $fpmmax", $output, $result_code);
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "Success: PHP Workers updated.";
|
||||
} else {
|
||||
$messages[] = "Error updating PHP Workers.";
|
||||
}
|
||||
} else {
|
||||
$messages[] = "Unkown edit action.";
|
||||
}
|
||||
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Users/$username");
|
||||
|
||||
|
||||
// /* run mod command here */
|
||||
// $mbox = $f3->get('PARAMS.mbox');
|
||||
// $domain = $f3->get('PARAMS.domain');
|
||||
// $mbox_array = $_POST;
|
||||
// $f3->set('mbox_array', $mbox_array);
|
||||
// foreach ($mbox_array as $k=>$v) {
|
||||
// if (strtolower($v) == 'unlimited') {
|
||||
// $mbox_array[$k] = 'NULL';
|
||||
// }
|
||||
// }
|
||||
// extract($mbox_array);
|
||||
//
|
||||
// if ($password != '') {
|
||||
// $f3->call('\Panel::validatePassword', array($password, $password_confirm));
|
||||
// }
|
||||
// settype($status, "integer");
|
||||
// $f3->call('\Panel::validateEmailStatus', $status);
|
||||
// if (strtolower($quota == 'unlimited') || strtolower($quota == 'null')) {
|
||||
// $quota = "NULL";
|
||||
// } else {
|
||||
// settype($quota, "integer");
|
||||
// }
|
||||
// $f3->call('\Panel::validateEmailQuota', $quota);
|
||||
// if (strtolower($ratelimit == 'unlimited') || strtolower($ratelimit == 'null')) {
|
||||
// $ratelimit = "NULL";
|
||||
// }
|
||||
// $f3->call('\Panel::validateEmailRatelimit', $ratelimit);
|
||||
// $f3->call('\Panel::validateEmailFiltering', $filter);
|
||||
//
|
||||
// /* check for validation errors */
|
||||
// if ($f3->exists('SESSION.messages')) {
|
||||
// $messages = $f3->get('SESSION.messages');
|
||||
// $messages[] = "Please make changes and re-submit the form to try again.";
|
||||
// $f3->set('SESSION.messages', $messages);
|
||||
// $f3->call('\Panel\Vmail\MboxesEdit::get', $f3);
|
||||
// } else {
|
||||
// if ($password != '') {
|
||||
// $password = escapeshellarg($password);
|
||||
// $pword_cmd = "-p $password";
|
||||
// } else {
|
||||
// $pword_cmd = '';
|
||||
// }
|
||||
// exec("/usr/local/bin/vmail-mboxes-mod.sh -e $mbox@$domain $pword_cmd -q $quota -r $ratelimit -s $status -j $filter", $output, $result_code);
|
||||
// if ($result_code == 0) {
|
||||
// $messages[] = "Success: Email account $mbox@$domain updated.";
|
||||
// $f3->set('SESSION.messages', $messages);
|
||||
// $mapping = $f3->get('NAV.mapping');
|
||||
// if ($mapping == 'vmail') {
|
||||
// $f3->reroute("/Accounts/$mbox");
|
||||
// } else {
|
||||
// $f3->reroute("/Email/$domain/Accounts/$mbox");
|
||||
// }
|
||||
// } else {
|
||||
// $messages[] = "Error.";
|
||||
// $f3->set('SESSION.messages', $messages);
|
||||
// $f3->call('\Panel\Vmail\MboxesEdit::get', $f3);
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -20,6 +20,39 @@ class Vhosts extends \Panel\Vhost {
|
|||
$vhost = $f3->get('PARAMS.vhost');
|
||||
if ($vhost_array = $f3->call('\Panel::vGet', array("vhost-get.sh -d $vhost -c", FALSE))) {
|
||||
$f3->set('vhost_array', $vhost_array[0]);
|
||||
/* get cert info */
|
||||
if ($f3->call('\Panel::verifyCertificateExists', $vhost)) {
|
||||
if ($cert_array = $f3->call('\Panel::vGet', array("letsencrypt-get.sh -d $vhost -c", FALSE))) {
|
||||
$cert_array = $cert_array[0];
|
||||
/* remove time from expiration date */
|
||||
$end = $cert_array['end'];
|
||||
$end_array = explode(' ', $end);
|
||||
unset($end_array[2]);
|
||||
$end = implode(' ', $end_array);
|
||||
$cert_array['end'] = $end;
|
||||
/* add line breaks */
|
||||
$common = $cert_array['common'];
|
||||
$alternative = $cert_array['alternative'];
|
||||
$alternative = preg_replace('/ /', '<br>', $alternative);
|
||||
$cert_array['alternative'] = $alternative;
|
||||
$f3->set('cert_array', $cert_array);
|
||||
}
|
||||
}
|
||||
/* get user info */
|
||||
$username = $vhost_array[0]['username'];
|
||||
if ($users_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -u $username -c", FALSE))) {
|
||||
if ($users_array[0]['passwd'] == "") {
|
||||
$users_array[0]['passwd'] = '(unavailable)';
|
||||
}
|
||||
$f3->set('users_array', $users_array[0]);
|
||||
}
|
||||
/* get mysql db info */
|
||||
if ($mysqlinfo_array = $f3->call('\Panel::vGet', array("vhost-mysql-db-get.sh -d $vhost -c", FALSE))) {
|
||||
$f3->set('mysqlinfo_array', $mysqlinfo_array[0]);
|
||||
} else {
|
||||
$mysqlinfo_array = array('(unknown)', '(unknown)', '(unknown)', '(unknown)');
|
||||
$f3->set('mysqlinfo_array', $mysqlinfo_array);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($vhosts_array = $f3->call('\Panel::vGet', array("vhost-get.sh -c", FALSE))) {
|
||||
|
@ -41,7 +74,7 @@ class Vhosts extends \Panel\Vhost {
|
|||
$f3->set('vhost_array', $vhost_array);
|
||||
|
||||
$vhost = $f3->get('PARAMS.vhost');
|
||||
$f3->set('page_header', "Website Hosting for $vhost");
|
||||
$f3->set('page_header', "Details for $vhost");
|
||||
echo \Template::instance()->render('vhost/vhosts-vhost.html');
|
||||
|
||||
} else {
|
||||
|
|
|
@ -15,9 +15,26 @@ class VhostsAdd extends \Panel\Vhost {
|
|||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
// /* get vm_domains defaults for "add new" form */
|
||||
// $vm_domains_defaults = $f3->call('\Panel::vGet', array("vmail-defaults-get.sh -c", FALSE));
|
||||
// $f3->set('vm_domains_defaults', $vm_domains_defaults[0]);
|
||||
/* get system defaults for new websites */
|
||||
$deploy = array();
|
||||
$deploy['username'] = '';
|
||||
if ($users_array = $f3->call('\Panel::vGet', array("vhost-user-get.sh -c", FALSE))) {
|
||||
$deploy['users_array'] = $users_array;
|
||||
} else {
|
||||
$deploy['users_array'] = array();
|
||||
}
|
||||
|
||||
if ($f3->get('WRITEUSERINFO') == '1') {
|
||||
$deploy['writeuserinfo'] = 1;
|
||||
} else {
|
||||
$deploy['writeuserinfo'] = 0;
|
||||
}
|
||||
if ($f3->get('SHOWWRITEINFO') == '1') {
|
||||
$deploy['showwriteinfo'] = 1;
|
||||
} else {
|
||||
$deploy['showwriteinfo'] = 0;
|
||||
}
|
||||
$f3->set('deploy', $deploy);
|
||||
|
||||
}
|
||||
|
||||
|
@ -34,93 +51,61 @@ class VhostsAdd extends \Panel\Vhost {
|
|||
$messages = array();
|
||||
|
||||
/* validate domain */
|
||||
if (preg_match('/^[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,24}$/i', strtolower($_POST['domain']))) {
|
||||
// strip www
|
||||
$domain = strtolower($_POST['domain']);
|
||||
} else {
|
||||
$messages[] = "Invalid domain name.";
|
||||
}
|
||||
|
||||
/* validate status */
|
||||
if ($_POST['status'] != 0 && $_POST['status'] != 1) {
|
||||
$messages[] = "Invalid 'Status'.";
|
||||
} else {
|
||||
$status = $_POST['status'];
|
||||
}
|
||||
|
||||
/* validate mbox_limit */
|
||||
if (strtolower($_POST['mbox_limit']) == 'unlimited' || strtolower($_POST['mbox_limit'] == 'null')) {
|
||||
$mbox_limit = "NULL";
|
||||
} elseif (is_numeric($_POST['mbox_limit'])) {
|
||||
/* make sure mbox_limit is a possitive integer */
|
||||
$mbox_limit = abs(intval($_POST['mbox_limit']));
|
||||
if ($mbox_limit < 1) {
|
||||
echo "Mailbox Limit must be a positive number or \"Unlimited\".\n";
|
||||
$messages[] = "Mailbox Limit must be a positive number or \"Unlimited\".";
|
||||
}
|
||||
} else {
|
||||
$messages[] = "Mailbox Limit must be a positive number or \"Unlimited\".";
|
||||
}
|
||||
|
||||
/* validate mbox_quota_default */
|
||||
if (strtolower($_POST['mbox_quota_default']) == 'unlimited' || strtolower($_POST['mbox_quota_default'] == 'null')) {
|
||||
$mbox_quota_default = "NULL";
|
||||
} elseif (is_numeric($_POST['mbox_quota_default'])) {
|
||||
/* make sure mbox_quota_default is a possitive integer */
|
||||
$mbox_quota_default = abs(intval($_POST['mbox_quota_default']));
|
||||
if ($mbox_quota_default < 1) {
|
||||
echo "Default Quota must be a positive number or \"Unlimited\".\n";
|
||||
$messages[] = "Default Quota must be a positive number or \"Unlimited\".";
|
||||
}
|
||||
} else {
|
||||
$messages[] = "Default Quota must be a positive number or \"Unlimited\".";
|
||||
}
|
||||
|
||||
/* validate mbox_ratelimit_default */
|
||||
if (strtolower($_POST['mbox_ratelimit_default']) == 'unlimited' || strtolower($_POST['mbox_ratelimit_default'] == 'null')) {
|
||||
$mbox_ratelimit_default = "NULL";
|
||||
} elseif (is_numeric($_POST['mbox_ratelimit_default'])) {
|
||||
/* make sure mbox_ratelimit_default is a possitive integer */
|
||||
$mbox_ratelimit_default = abs(intval($_POST['mbox_ratelimit_default']));
|
||||
if ($mbox_ratelimit_default < 1) {
|
||||
$messages[] = "Default Rate Limit must be a positive number or \"Unlimited\".";
|
||||
}
|
||||
} else {
|
||||
$messages[] = "Default Rate Limit must be a positive number or \"Unlimited\".";
|
||||
}
|
||||
|
||||
/* check for validation errors */
|
||||
if (count($messages) > 0) {
|
||||
$messages[] = "Please re-submit the form to try again.";
|
||||
$domain = preg_replace('/^www\./', '', $domain);
|
||||
if ($f3->call('\Panel::validateDomain', $domain)) {
|
||||
if ($f3->call('\Panel::verifyVhostDomainExists', $domain)) {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "$domain already exists on this server.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
|
||||
$f3->reroute("/Websites/Add");
|
||||
} else {
|
||||
/* check if vmail domain already exists */
|
||||
$domain_array = $f3->call('\Panel::vGet', array("vmail-domains-get.sh -d $domain -c", FALSE));
|
||||
if (count($domain_array) == 0) {
|
||||
/* add email domain */
|
||||
exec("/usr/local/bin/vmail-domains-add.sh -d $domain -l $mbox_limit -q $mbox_quota_default -r $mbox_ratelimit_default -s $status", $output, $result_code);
|
||||
$cmd = "/usr/local/bin/vhost-deploy.sh -d $domain";
|
||||
}
|
||||
} else {
|
||||
$f3->reroute("/Websites/Add");
|
||||
}
|
||||
|
||||
/* validate username & set related options */
|
||||
$username = strtolower($_POST['username']);
|
||||
if ($f3->get('JAILUSER') == '1') {
|
||||
$jailuser = 1;
|
||||
} else {
|
||||
$jailuser = 0;
|
||||
}
|
||||
if ($username == '') {
|
||||
$cmd = "$cmd -j $jailuser";
|
||||
} else {
|
||||
if ($f3->call('\Panel::vGet', array("vhost-user-get.sh -u $username -c", FALSE))) {
|
||||
$cmd = "$cmd -u $username";
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "Error validating username $username.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Websites/Add");
|
||||
}
|
||||
}
|
||||
|
||||
if ($f3->get('WRITEUSERINFO') == '1') {
|
||||
$writeuserinfo = 1;
|
||||
} else {
|
||||
$writeuserinfo = 0;
|
||||
}
|
||||
$cmd = "$cmd -w $writeuserinfo";
|
||||
exec("$cmd", $output, $result_code);
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "Email Domain $domain has been added.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Email/$domain");
|
||||
} else {
|
||||
if (count($output) > 0) {
|
||||
foreach ($output as $k=>$output_message) {
|
||||
$messages[] = "$output_message";
|
||||
}
|
||||
} else {
|
||||
$messages[] = "Unknown error adding Email Domain $domain.";
|
||||
$messages[] = "Success: Website $domain added.";
|
||||
if ($username == '' && $jailuser == 1) {
|
||||
$messages[] = "Note: New user is being jailed. Setting up the jail environment takes about a minute to complete and is being run in the background now.";
|
||||
}
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
|
||||
}
|
||||
$f3->reroute("/Websites");
|
||||
} else {
|
||||
$messages[] = "Email Domain '$domain' already exists.";
|
||||
$messages[] = "Error adding website.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Email/$domain");
|
||||
}
|
||||
$f3->reroute("/Websites/Add");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
52
panel/classes/Panel/Vhost/VhostsDelete.php
Normal file
52
panel/classes/Panel/Vhost/VhostsDelete.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vhost;
|
||||
|
||||
class VhostsDelete extends \Panel\Vhost {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
/* verify user exists */
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
$f3->set('confirm', 'true');
|
||||
echo \Template::instance()->render('vhost/vhosts-delete.html');
|
||||
|
||||
}
|
||||
|
||||
function post($f3) {
|
||||
|
||||
/* run delete command here */
|
||||
$domain = $f3->get('PARAMS.vhost');
|
||||
$messages = array();
|
||||
$output = system("/usr/local/bin/vhost-destroy.sh -d $domain", $result_code);
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "Website '$domain' has been deleted.";
|
||||
} else {
|
||||
$messages[] = "Error deleting website '$domain'.";
|
||||
$messages[] = $output;
|
||||
}
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Websites");
|
||||
// $mapping = $f3->get('NAV.mapping');
|
||||
// if ($mapping == 'vmail') {
|
||||
// $f3->reroute("/Users");
|
||||
// } else {
|
||||
// $f3->reroute("/Email/$domain/Accounts");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
47
panel/classes/Panel/Vhost/VhostsDisable.php
Normal file
47
panel/classes/Panel/Vhost/VhostsDisable.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vhost;
|
||||
|
||||
class VhostsDisable extends \Panel\Vhost {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
/* verify user exists */
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
/* run delete command here */
|
||||
$domain = $f3->get('PARAMS.vhost');
|
||||
$messages = array();
|
||||
$output = system("/usr/local/bin/vhost-disable.sh -d $domain", $result_code);
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "Website '$domain' has been disabled.";
|
||||
$messages[] = "NOTICE: Nothing has been deleted and the site can be re-enabled at any time.";
|
||||
} else {
|
||||
$messages[] = "Error disabling website '$domain'.";
|
||||
$messages[] = $output;
|
||||
}
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Websites/$domain");
|
||||
// $mapping = $f3->get('NAV.mapping');
|
||||
// if ($mapping == 'vmail') {
|
||||
// $f3->reroute("/Users");
|
||||
// } else {
|
||||
// $f3->reroute("/Email/$domain/Accounts");
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
37
panel/classes/Panel/Vhost/VhostsEnable.php
Normal file
37
panel/classes/Panel/Vhost/VhostsEnable.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vhost;
|
||||
|
||||
class VhostsEnable extends \Panel\Vhost {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
/* run enable command here */
|
||||
$domain = $f3->get('PARAMS.vhost');
|
||||
$messages = array();
|
||||
$output = system("/usr/local/bin/vhost-enable.sh -d $domain", $result_code);
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "Website '$domain' has been enabled.";
|
||||
} else {
|
||||
$messages[] = "Error enabling website '$domain'.";
|
||||
$messages[] = $output;
|
||||
}
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Websites/$domain");
|
||||
|
||||
}
|
||||
|
||||
}
|
66
panel/classes/Panel/Vmail/Dkim.php
Normal file
66
panel/classes/Panel/Vmail/Dkim.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vmail;
|
||||
|
||||
class Dkim extends \Panel\Vmail {
|
||||
|
||||
/* use this to make query */
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
if ($f3->exists('PARAMS.domain')) {
|
||||
$domain = $f3->get('PARAMS.domain');
|
||||
$dkim_array = array();
|
||||
if ($f3->call('\Panel::verifyDkimExists', $domain)) {
|
||||
if ($dkim_array = $f3->call('\Panel::vGet', array("vmail-dkim-get.sh -d $domain -c", FALSE))) {
|
||||
$dkim_array = $dkim_array[0];
|
||||
$dkim_array['dns']['host'] = $dkim_array['selector'] . "._domainkey.$domain";
|
||||
if ($dns_txt_records = dns_get_record($dkim_array['dns']['host'], DNS_TXT)) {
|
||||
$dkim_array['dns']['status'] = "Verified";
|
||||
} else {
|
||||
$dkim_array['dns']['status'] = "Update";
|
||||
}
|
||||
} else {
|
||||
$dkim_array['dns']['status'] = "Error";
|
||||
}
|
||||
} else {
|
||||
$dkim_array['dns']['status'] = "Create";
|
||||
}
|
||||
$f3->set('dkim_array', $dkim_array);
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "Domain not set, must specify domain for DKIM info.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute('/');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
if ($f3->exists('PARAMS.domain')) {
|
||||
|
||||
$domain = $f3->get('PARAMS.domain');
|
||||
$f3->set('page_header', "DKIM Details for $domain");
|
||||
|
||||
} else {
|
||||
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "Domain not set, must specify domain for DKIM info.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
|
||||
}
|
||||
|
||||
echo \Template::instance()->render('vmail/dkim.html');
|
||||
|
||||
}
|
||||
|
||||
}
|
60
panel/classes/Panel/Vmail/DkimAdd.php
Normal file
60
panel/classes/Panel/Vmail/DkimAdd.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vmail;
|
||||
|
||||
class DkimAdd extends \Panel\Vmail {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
if ($f3->exists('PARAMS.domain')) {
|
||||
$domain = $f3->get('PARAMS.domain');
|
||||
if ($f3->call('\Panel::validateDomain', $domain)) {
|
||||
if ($f3->call('\Panel::verifyVmailDomainExists', $domain)) {
|
||||
if ($f3->call('\Panel::verifyDkimExists', $domain)) {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "DKIM for $domain already exists.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
} else {
|
||||
exec("/usr/local/bin/vmail-dkim-add.sh -d $domain", $output, $result_code);
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "DKIM for $domain has been added.";
|
||||
} else {
|
||||
$messages[] = "ERROR: adding DKIM for $domain failed.";
|
||||
}
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
}
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "ERROR: $domain is not configured for email on this server.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
}
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "ERROR: Invalid domain: $domain.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
}
|
||||
}
|
||||
parse_str($f3->get('QUERY'), $output);
|
||||
if (isset($output['r'])) {
|
||||
$f3->reroute($output['r']);
|
||||
} else {
|
||||
$f3->reroute('/');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
61
panel/classes/Panel/Vmail/DkimDelete.php
Normal file
61
panel/classes/Panel/Vmail/DkimDelete.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* vpanel-stack
|
||||
* https://git.stack-source.com/msb/vpanel-stack
|
||||
* Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
||||
* GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
*/
|
||||
|
||||
namespace Panel\Vmail;
|
||||
|
||||
class DkimDelete extends \Panel\Vmail {
|
||||
|
||||
function beforeRoute($f3) {
|
||||
|
||||
parent::beforeRoute($f3);
|
||||
|
||||
}
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
$f3->set('confirm', 'true');
|
||||
echo \Template::instance()->render('vmail/dkim-delete.html');
|
||||
|
||||
}
|
||||
|
||||
static function post($f3) {
|
||||
|
||||
if ($f3->exists('PARAMS.domain')) {
|
||||
$domain = $f3->get('PARAMS.domain');
|
||||
if ($f3->call('\Panel::validateDomain', $domain)) {
|
||||
if ($f3->call('\Panel::verifyDkimExists', $domain)) {
|
||||
/* delete the dkim keys */
|
||||
exec("/usr/local/bin/vmail-dkim-del.sh -d $domain", $output, $result_code);
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
if ($result_code == 0) {
|
||||
$messages[] = "DKIM keys for $domain have been deleted.";
|
||||
$messages[] = "Note that you probably want to delete the associated DNS record now too.";
|
||||
} else {
|
||||
$messages[] = "Error deleting DKIM keys for $domain.";
|
||||
}
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "DKIM keys for $domain not found.";
|
||||
}
|
||||
} else {
|
||||
$messages = $f3->get('SESSION.messages');
|
||||
$messages[] = "Invalid domain name ($domain).";
|
||||
}
|
||||
}
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$mapping = $f3->get('NAV.mapping');
|
||||
if ($mapping == 'vmail') {
|
||||
$f3->reroute("/");
|
||||
} else {
|
||||
$f3->reroute("/Email/$domain");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -19,15 +19,132 @@ class Domains extends \Panel\Vmail {
|
|||
$domain = $f3->get('PARAMS.domain');
|
||||
if ($domain_array = $f3->call('\Panel::vGet', array("vmail-domains-get.sh -d $domain -c", FALSE))) {
|
||||
$f3->set('domain_array', $domain_array[0]);
|
||||
/* get cert info */
|
||||
$mxdomain = "mail.$domain";
|
||||
if ($f3->call('\Panel::verifyCertificateExists', $mxdomain)) {
|
||||
if ($cert_array = $f3->call('\Panel::vGet', array("letsencrypt-get.sh -d $mxdomain -c", FALSE))) {
|
||||
$cert_array = $cert_array[0];
|
||||
/* remove time from expiration date */
|
||||
$end = $cert_array['end'];
|
||||
$end_array = explode(' ', $end);
|
||||
unset($end_array[2]);
|
||||
$end = implode(' ', $end_array);
|
||||
$cert_array['end'] = $end;
|
||||
/* add line breaks */
|
||||
$common = $cert_array['common'];
|
||||
$alternative = $cert_array['alternative'];
|
||||
$alternative = preg_replace('/ /', '<br>', $alternative);
|
||||
$cert_array['alternative'] = $alternative;
|
||||
$f3->set('cert_array', $cert_array);
|
||||
}
|
||||
}
|
||||
/* get dns info */
|
||||
$dnsinfo = array();
|
||||
$dnsinfo['verified_count'] = 0;
|
||||
$dnsinfo['server_addr'] = $_SERVER['SERVER_ADDR'];
|
||||
# A record
|
||||
$dnsinfo['a']['color'] = "red";
|
||||
if ($certdomain_dns = dns_get_record("$mxdomain", DNS_A)) {
|
||||
if ($certdomain_dns[0]['ip'] == $dnsinfo['server_addr']) {
|
||||
$dnsinfo['a']['status'] = "Verified";
|
||||
$dnsinfo['a']['color'] = "black";
|
||||
$dnsinfo['verified_count']++;
|
||||
} else {
|
||||
$dnsinfo['a']['status'] = "Update";
|
||||
}
|
||||
} else {
|
||||
$dnsinfo['a']['status'] = "Create";
|
||||
}
|
||||
# MX record
|
||||
$dnsinfo['mx']['color'] = "red";
|
||||
if (getmxrr($domain, $mx)) {
|
||||
if (in_array($mxdomain, $mx)) {
|
||||
$dnsinfo['mx']['status'] = "Verified";
|
||||
$dnsinfo['mx']['color'] = "black";
|
||||
$dnsinfo['verified_count']++;
|
||||
} else {
|
||||
$dnsinfo['mx']['status'] = "Update";
|
||||
}
|
||||
} else {
|
||||
$dnsinfo['mx']['status'] = "Create";
|
||||
}
|
||||
# SPF (TXT) record
|
||||
$dnsinfo['spf']['status'] = "Create";
|
||||
$dnsinfo['spf']['color'] = "red";
|
||||
if ($dns_txt_records = dns_get_record("$domain", DNS_TXT)) {
|
||||
foreach ($dns_txt_records as $k=>$dns_txt_record) {
|
||||
if (str_starts_with($dns_txt_record['txt'], 'v=spf1')) {
|
||||
$dnsinfo['spf']['status'] = "Update";
|
||||
if (str_contains($dns_txt_record['txt'], ' mx ')) {
|
||||
$dnsinfo['spf']['status'] = "Verified";
|
||||
$dnsinfo['spf']['color'] = "black";
|
||||
$dnsinfo['verified_count']++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# DKIM
|
||||
$dnsinfo['dkim']['color'] = "red";
|
||||
if ($f3->call('\Panel::verifyDkimExists', $domain)) {
|
||||
if ($dkim_array = $f3->call('\Panel::vGet', array("vmail-dkim-get.sh -d $domain -c", FALSE))) {
|
||||
$dkim_hostname = $dkim_array[0]['selector'] . "._domainkey.$domain";
|
||||
if ($dns_txt_records = dns_get_record($dkim_hostname, DNS_TXT)) {
|
||||
$dnsinfo['dkim']['status'] = "Verified";
|
||||
$dnsinfo['dkim']['color'] = "black";
|
||||
$dnsinfo['verified_count']++;
|
||||
} else {
|
||||
$dnsinfo['dkim']['status'] = "Update";
|
||||
$dnsinfo['dkim']['selector'] = $dkim_array[0]['selector'];
|
||||
$dnsinfo['dkim']['dkim'] = $dkim_array[0]['dkim'];
|
||||
}
|
||||
} else {
|
||||
$dnsinfo['dkim']['status'] = "Error";
|
||||
}
|
||||
} else {
|
||||
$dnsinfo['dkim']['status'] = "Create";
|
||||
}
|
||||
|
||||
if ($dnsinfo['verified_count'] == 4) {
|
||||
$dnsinfo['status'] = 'Verified';
|
||||
} else {
|
||||
$dnsinfo['status'] = 'Update';
|
||||
}
|
||||
|
||||
$f3->set('dnsinfo', $dnsinfo);
|
||||
|
||||
}
|
||||
} else {
|
||||
if ($domains_array = $f3->call('\Panel::vGet', array("vmail-domains-get.sh -c", FALSE))) {
|
||||
$f3->set('domains_array', $domains_array);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// $dnsinfo['mx']['status'] = ready/update/none
|
||||
// $dnsinfo['spf']['status'] = ready/update/none
|
||||
// $dnsinfo['spf']['data'] = current_record
|
||||
// $dnsinfo['dkim']['status'] = ready/update/none
|
||||
// $dnsinfo['dkim']['selector'] =
|
||||
// $dnsinfo['dkim']['data'] =
|
||||
|
||||
// dns_a gethostbyname()
|
||||
// dns_mx getmxrr() / dns_get_mx()
|
||||
// dns_spf checkdnsrr() / dns_check_record()
|
||||
// dns_dkim
|
||||
// # domain does not have cert yet, check DNS
|
||||
// $dns_a_record = $_SERVER['SERVER_ADDR'];
|
||||
// if ($certdomain_dns = dns_get_record("$certdomain", DNS_A)) {
|
||||
// if ($certdomain_dns[0]['ip'] == $dns_a_record) {
|
||||
// $dns_status = "ready";
|
||||
// } else {
|
||||
// $dns_status = "update";
|
||||
// }
|
||||
// } else {
|
||||
// $dns_status = "none";
|
||||
// }
|
||||
// $f3->set('dns_a_record', $dns_a_record);
|
||||
// $f3->set('dns_status', $dns_status);
|
||||
|
||||
static function get($f3) {
|
||||
|
||||
if ($f3->exists('PARAMS.domain')) {
|
||||
|
|
|
@ -34,10 +34,13 @@ class DomainsAdd extends \Panel\Vmail {
|
|||
$messages = array();
|
||||
|
||||
/* validate domain */
|
||||
if (preg_match('/^[0-9a-z]([-.]?[0-9a-z])*\.[a-z]{2,24}$/i', strtolower($_POST['domain']))) {
|
||||
$domain = strtolower($_POST['domain']);
|
||||
} else {
|
||||
$messages[] = "Invalid domain name.";
|
||||
$domain = preg_replace('/^mail\./', '', $domain);
|
||||
$domain = preg_replace('/^www\./', '', $domain);
|
||||
if ($f3->call('\Panel::validateDomain', $domain)) {
|
||||
if ($f3->call('\Panel::verifyVmailDomainExists', $domain)) {
|
||||
$messages[] = "Email Domain '$domain' already exists.";
|
||||
}
|
||||
}
|
||||
|
||||
/* validate status */
|
||||
|
@ -94,9 +97,6 @@ class DomainsAdd extends \Panel\Vmail {
|
|||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
|
||||
} else {
|
||||
/* check if vmail domain already exists */
|
||||
$domain_array = $f3->call('\Panel::vGet', array("vmail-domains-get.sh -d $domain -c", FALSE));
|
||||
if (count($domain_array) == 0) {
|
||||
/* add email domain */
|
||||
exec("/usr/local/bin/vmail-domains-add.sh -d $domain -l $mbox_limit -q $mbox_quota_default -r $mbox_ratelimit_default -s $status", $output, $result_code);
|
||||
if ($result_code == 0) {
|
||||
|
@ -114,12 +114,6 @@ class DomainsAdd extends \Panel\Vmail {
|
|||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->call('\Panel\Vmail\DomainsAdd::get', $f3);
|
||||
}
|
||||
} else {
|
||||
$messages[] = "Email Domain '$domain' already exists.";
|
||||
$f3->set('SESSION.messages', $messages);
|
||||
$f3->reroute("/Email/$domain");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class MboxesAdd extends \Panel\Vmail {
|
|||
extract($_POST);
|
||||
|
||||
$f3->call('\Panel::validateEmailLocalpart', $localpart);
|
||||
$f3->call('\Panel::validateEmailPassword', array($password, $password_confirm));
|
||||
$f3->call('\Panel::validatePassword', array($password, $password_confirm));
|
||||
settype($status, "integer");
|
||||
$f3->call('\Panel::validateEmailStatus', $status);
|
||||
if (strtolower($quota == 'unlimited') || strtolower($quota == 'null')) {
|
||||
|
|
|
@ -62,7 +62,7 @@ class MboxesEdit extends \Panel\Vmail {
|
|||
extract($mbox_array);
|
||||
|
||||
if ($password != '') {
|
||||
$f3->call('\Panel::validateEmailPassword', array($password, $password_confirm));
|
||||
$f3->call('\Panel::validatePassword', array($password, $password_confirm));
|
||||
}
|
||||
settype($status, "integer");
|
||||
$f3->call('\Panel::validateEmailStatus', $status);
|
||||
|
|
|
@ -16,6 +16,15 @@ LICENSE=GPL-3.0
|
|||
LICENSEURL=https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
CASELESS=FALSE
|
||||
CACHE=TRUE
|
||||
; session lifetime in seconds
|
||||
; Session lifetime in seconds
|
||||
TIMEOUT=900
|
||||
; Remote IP address that is automatically logged in without auth
|
||||
ADMINIP=
|
||||
; Jail new users by default. 1 = Yes, blank or 0 = No
|
||||
JAILUSER=1
|
||||
; PHP-FPM pm.max_children. Recommended range 2-12 on Shared Server
|
||||
FPMMAX=4
|
||||
; Write user info to /home/username/.passwd. 1 = Yes, blank or 0 = No
|
||||
WRITEUSERINFO=1
|
||||
; Show "Write User Info" & "Write DB Info" options. If no then just use defaults above without giving users the option to change. 1 = Yes, blank or 0 = No
|
||||
SHOWWRITEINFO=0
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
/Email/@domain/Accounts/@mbox/Forwarding/Add [sync] = Panel\Vmail\ForwardsAdd
|
||||
/Email/@domain/Accounts/@mbox/Forwarding/Edit [sync] = Panel\Vmail\ForwardsEdit
|
||||
/Email/@domain/Accounts/@mbox/Forwarding/Delete [sync] = Panel\Vmail\ForwardsDelete
|
||||
/Email/@domain/Dkim [sync] = Panel\Vmail\Dkim
|
||||
/Email/@domain/Dkim/Add [sync] = Panel\Vmail\DkimAdd
|
||||
/Email/@domain/Dkim/Delete [sync] = Panel\Vmail\DkimDelete
|
||||
/Email/@domain/Aliases [sync] = Panel\Vmail\Aliases
|
||||
/Email/@domain/Aliases/@alias [sync] = Panel\Vmail\Aliases
|
||||
/Email/@domain/Autoresponders [sync] = Panel\Vmail\Autoresponders
|
||||
|
@ -38,16 +41,17 @@
|
|||
/Websites [sync] = Panel\Vhost\Vhosts
|
||||
/Websites/Add [sync] = Panel\Vhost\VhostsAdd
|
||||
/Websites/@vhost [sync] = Panel\Vhost\Vhosts
|
||||
/Websites/@vhost/Edit [sync] = Panel\Vhost\VhostsEdit
|
||||
/Websites/@vhost/Disable [sync] = Panel\Vhost\VhostsDisable
|
||||
/Websites/@vhost/Enable [sync] = Panel\Vhost\VhostsEnable
|
||||
/Websites/@vhost/Delete [sync] = Panel\Vhost\VhostsDelete
|
||||
|
||||
/Websites/@vhost/Databases [sync] = Panel\Vhost\Databases
|
||||
/Websites/@vhost/Databases/Add [sync] = Panel\Vhost\DatabasesAdd
|
||||
/Websites/@vhost/Databases/Delete [sync] = Panel\Vhost\DatabasesDelete
|
||||
/Websites/@vhost/Databases/Users [sync] = Panel\Vhost\DatabasesUsers
|
||||
/Websites/@vhost/Databases/Users/Add [sync] = Panel\Vhost\DatabasesUsersAdd
|
||||
/Websites/@vhost/Databases/Users/Edit [sync] = Panel\Vhost\DatabasesUsersEdit
|
||||
/Websites/@vhost/Databases/Users/Delete [sync] = Panel\Vhost\DatabasesUsersDelete
|
||||
; /Websites/@vhost/Databases [sync] = Panel\Vhost\Databases
|
||||
; /Websites/@vhost/Databases/Add [sync] = Panel\Vhost\DatabasesAdd
|
||||
; /Websites/@vhost/Databases/Delete [sync] = Panel\Vhost\DatabasesDelete
|
||||
; /Websites/@vhost/Databases/Users [sync] = Panel\Vhost\DatabasesUsers
|
||||
; /Websites/@vhost/Databases/Users/Add [sync] = Panel\Vhost\DatabasesUsersAdd
|
||||
; /Websites/@vhost/Databases/Users/Edit [sync] = Panel\Vhost\DatabasesUsersEdit
|
||||
; /Websites/@vhost/Databases/Users/Delete [sync] = Panel\Vhost\DatabasesUsersDelete
|
||||
|
||||
/Websites/Redirects [sync] = Panel\Vhost\Redirects
|
||||
/Websites/Redirects/Add [sync] = Panel\Vhost\RedirectsAdd
|
||||
|
@ -70,6 +74,14 @@
|
|||
; System users (ssh, websites)
|
||||
/Users [sync] = Panel\Vhost\Users
|
||||
/Users/Add [sync] = Panel\Vhost\UsersAdd
|
||||
/Users/@user [sync] = Panel\Vhost\Users
|
||||
/Users/@user/Edit [sync] = Panel\Vhost\UsersEdit
|
||||
/Users/@user/Delete [sync] = Panel\Vhost\UsersDelete
|
||||
/Users/@username [sync] = Panel\Vhost\Users
|
||||
/Users/@username/Edit [sync] = Panel\Vhost\UsersEdit
|
||||
/Users/@username/Delete [sync] = Panel\Vhost\UsersDelete
|
||||
|
||||
/Certs [sync] = Panel\Cert\Certs
|
||||
/Certs/@cert [sync] = Panel\Cert\Certs
|
||||
/Certs/@cert/Add [sync] = Panel\Cert\CertsAdd
|
||||
/Certs/@cert/Delete [sync] = Panel\Cert\CertsDelete
|
||||
|
||||
/Databases [sync] = Panel\MySQL\Databases
|
||||
|
||||
|
|
40
panel/ui/cert/certs-cert.html
Normal file
40
panel/ui/cert/certs-cert.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
<include href="header.html" />
|
||||
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th style="white-space: nowrap; text-align: center;">Certificate</th>
|
||||
<th style="white-space: nowrap; text-align: center;">Expiration</th>
|
||||
<th style="white-space: nowrap; text-align: center;">Secured Hostnames</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="white-space: nowrap; text-align: right;">{{ @cert_array.common }}</td>
|
||||
<td style="white-space: nowrap; text-align: center;">{{ @cert_array.end }}</td>
|
||||
<td style="white-space: nowrap; text-align: right;">{{ @cert_array.alternative | raw }}</td>
|
||||
<td style="white-space: nowrap; text-align: right;"><a href="{{@BASE}}/Certs/{{@cert_array.common}}/Delete?r=/Certs">Delete</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<!--
|
||||
<table>
|
||||
<tr>
|
||||
<td style="white-space: nowrap; text-align: right;"><b>Domain Name:</b></td>
|
||||
<td style="white-space: nowrap; text-align: center;">{{ @cert_array.common }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="white-space: nowrap; text-align: right;"><b>Valid From:</b></td>
|
||||
<td style="white-space: nowrap; text-align: center;">{{ @cert_array.start }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="white-space: nowrap; text-align: right;"><b>Valid Until:</b></td>
|
||||
<td style="white-space: nowrap; text-align: center;">{{ @cert_array.end }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="white-space: nowrap; text-align: right;"><b>Additional Names:</b></td>
|
||||
<td style="white-space: nowrap; text-align: right;">{{ @cert_array.alternative | raw }}</td>
|
||||
</tr>
|
||||
</table>-->
|
||||
|
||||
<include href="footer.html" />
|
38
panel/ui/cert/certs.html
Normal file
38
panel/ui/cert/certs.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<check if="isset(@certs_array)">
|
||||
<true>
|
||||
<table>
|
||||
<tr>
|
||||
<th style="white-space: nowrap; text-align: center;">Certificate</th>
|
||||
<th style="white-space: nowrap; text-align: center;">Expiration</th>
|
||||
<th style="white-space: nowrap; text-align: center;">Secured Hostnames</th>
|
||||
</tr>
|
||||
|
||||
<repeat group="{{ @certs_array }}" value="{{ @cert_array }}">
|
||||
|
||||
<tr>
|
||||
<td style="white-space: nowrap; text-align: right;"><a href="{{@BASE}}/Certs/{{ @cert_array.common }}">{{ @cert_array.common }}</a></td>
|
||||
<td style="white-space: nowrap; text-align: center;">{{ @cert_array.end }}</td>
|
||||
<td style="white-space: nowrap; text-align: right;">{{ @cert_array.alternative | raw }}</td>
|
||||
</tr>
|
||||
|
||||
</repeat>
|
||||
|
||||
</table>
|
||||
<p>
|
||||
<b>Certificate</b> is the name of the configuration and is normally the primary domain secured.<br>
|
||||
<b>Expiration</b> is the date the certificate expires. Certificates are automatically renewed 30 days before expiration.<br>
|
||||
<b>Secured Hostnames</b> is the full list of domain names secured by the certificate.<br>
|
||||
</p>
|
||||
</true>
|
||||
<false>
|
||||
<p>There are no security certificates on this server.</p>
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<p>
|
||||
<a href="{{@NAV.fullpath}}/Add">Add new Certificate form</a>
|
||||
</p>
|
||||
|
||||
<include href="footer.html" />
|
|
@ -10,6 +10,17 @@
|
|||
<link rel="icon" href="{{@BASE}}/ui/favicon.ico">
|
||||
<link href="{{@BASE}}/ui/css/awsm.css" type="text/css" rel="stylesheet" />
|
||||
<title>{{@PACKAGE}}</title>
|
||||
|
||||
<style>
|
||||
.hidden {
|
||||
opacity: 0;
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
.hidden:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
|
@ -19,8 +30,9 @@
|
|||
<check if="{{@NAV.mapping=='vpanel'}}">
|
||||
<a href="{{@BASE}}/Websites">Websites</a> |
|
||||
<a href="{{@BASE}}/Email">Email</a> |
|
||||
<a href="{{@BASE}}/mysql/databases">Databases</a> |
|
||||
<a href="{{@BASE}}/letsencrypt/ertificates">Certificates</a> |
|
||||
<a href="{{@BASE}}/Databases">Databases</a> |
|
||||
<a href="{{@BASE}}/Certs">Certificates</a> |
|
||||
<a href="{{@BASE}}/Users">Users</a> |
|
||||
<a href="{{@BASE}}/Logout">Logout</a>
|
||||
</check>
|
||||
|
||||
|
|
8
panel/ui/mysql/databases.html
Normal file
8
panel/ui/mysql/databases.html
Normal file
|
@ -0,0 +1,8 @@
|
|||
<include href="header.html" />
|
||||
|
||||
phpMyAdmin can be reached at <a href="https://{{@HOST}}/phpMyAdmin">https://{{@HOST}}/phpMyAdmin</a>
|
||||
<br>
|
||||
<br>
|
||||
<small>Note that phpMyAdmin requires a two-stage login process.<br>First use the websites "Remote Access" info (SFTP/SSH username & password) for the popup authentication.<br>Then use the MySQL info for the database login page.</small>
|
||||
|
||||
<include href="footer.html" />
|
185
panel/ui/vhost/users-add.html
Normal file
185
panel/ui/vhost/users-add.html
Normal file
|
@ -0,0 +1,185 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<form action="{{@REALM}}" method="POST">
|
||||
<fieldset>
|
||||
<legend>Add New System User</legend>
|
||||
<label for="username">Username <small>(must be between 3 and 16 characters in length)</small></label>
|
||||
<input id="username" name="username" type="text" placeholder="joe" value="{{ @user.username }}" required>
|
||||
|
||||
<label for="password">Password <small>(minimum 8 characters, recommended 12 or more)</small></label>
|
||||
<input id="password" name="password" type="password" value="{{ @user.password }}">
|
||||
|
||||
<label for="password_confirm">Confirm Password <small>(repeat same password)</small></label>
|
||||
<input id="password_confirm" name="password_confirm" type="password" value="{{ @user.password_confirm }}">
|
||||
|
||||
<small>Leave both password fields blank for random password generation.</small>
|
||||
|
||||
<label for="jailuser">Jail User</label>
|
||||
<select id="jailuser" name="jailuser">
|
||||
<check if="{{ @user.jailuser=='1' }}">
|
||||
<true>
|
||||
<option value="1" selected>Yes</option>
|
||||
<option value="0">No</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="1">Yes</option>
|
||||
<option value="0" selected>No</option>
|
||||
</false>
|
||||
</check>
|
||||
</select>
|
||||
|
||||
<check if="{{ @user.showwriteinfo=='1' }}">
|
||||
<true>
|
||||
<label for="writeuserinfo">Write User Info <small>(Writes to /home/username/.passwd)</small></label>
|
||||
<select id="writeuserinfo" name="writeuserinfo">
|
||||
<check if="{{ @user.writeuserinfo=='1' }}">
|
||||
<true>
|
||||
<option value="1" selected>Yes</option>
|
||||
<option value="0">No</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="1">Yes</option>
|
||||
<option value="0" selected>No</option>
|
||||
</false>
|
||||
</check>
|
||||
</select>
|
||||
</true>
|
||||
<false>
|
||||
<input type="hidden" name="writeuserinfo" value="{{ @user.writeuserinfo }}">
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<label for="fpmmax">PHP Workers <small>(Recommended range 2-12 on a Shared Server)</small></label>
|
||||
<select id="fpmmax" name="fpmmax">
|
||||
<check if="{{ @user.fpmmax=='2' }}">
|
||||
<true>
|
||||
<option value="2" selected>2</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="2">2</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='4' }}">
|
||||
<true>
|
||||
<option value="4" selected>4</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="4">4</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='6' }}">
|
||||
<true>
|
||||
<option value="6" selected>6</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="6">6</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='8' }}">
|
||||
<true>
|
||||
<option value="8" selected>8</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="8">8</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='10' }}">
|
||||
<true>
|
||||
<option value="10" selected>10</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="10">10</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='12' }}">
|
||||
<true>
|
||||
<option value="12" selected>12</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="12">12</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='16' }}">
|
||||
<true>
|
||||
<option value="16" selected>16</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="16">16</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='20' }}">
|
||||
<true>
|
||||
<option value="20" selected>20</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="20">20</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='24' }}">
|
||||
<true>
|
||||
<option value="24" selected>24</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="24">24</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='30' }}">
|
||||
<true>
|
||||
<option value="30" selected>30</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="30">30</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='36' }}">
|
||||
<true>
|
||||
<option value="36" selected>36</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="36">36</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='42' }}">
|
||||
<true>
|
||||
<option value="42" selected>42</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="42">42</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user.fpmmax=='48' }}">
|
||||
<true>
|
||||
<option value="48" selected>48</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="48">48</option>
|
||||
</false>
|
||||
</check>
|
||||
</select>
|
||||
|
||||
<input type="submit" value="Submit">
|
||||
<button id="reset" type="reset">Reset</button>
|
||||
|
||||
<check if="{{ @NAV.mapping=='vpanel' }}">
|
||||
<br>
|
||||
<!-- <small>Enter "Unlimited" for no limit on Quota or Rate Limit.</small>-->
|
||||
</check>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<p>
|
||||
<b>Username</b> is the system username that a website can be installed under. It will be used for SFTP & SSH access. Mixed case usernames are converted to all lower case.<br>
|
||||
<b>Password</b> must be at least 8 characters with 12 or more being highly recommended.<br>
|
||||
Passwords under 15 characters must contain characters from at least three of the following four groups:<br>
|
||||
Lower Case Letters, Uppler Case Leters, Numbers, Puncuation/Special Characters.<br>
|
||||
Passwords 15 or more characters long do not have any complexity requirements.<br>
|
||||
<b>Jail</b> determines if the user will be "jailed". This is recommended on a Shared Server. Once a user is Jailed it can't be undone by these admins.<br>
|
||||
<check if="{{ @user.showwriteinfo=='1' }}">
|
||||
<b>Write User Info</b> writes user account information to /home/username/.passwd. Includes encrypted password, which can be unencrypted.<br>
|
||||
</check>
|
||||
<b>PHP Workers</b> is maximum number of PHP processes that this user can have running at one time. Any website(s) installed for this user will be limited by this.<br>
|
||||
</p>
|
||||
|
||||
|
||||
<include href="footer.html" />
|
20
panel/ui/vhost/users-delete.html
Normal file
20
panel/ui/vhost/users-delete.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<check if="isset(@confirm)">
|
||||
<true>
|
||||
<form action="{{@REALM}}" method="POST">
|
||||
<fieldset>
|
||||
<legend>Really Delete User {{ @PARAMS.username }}</legend>
|
||||
<br>
|
||||
<input type="submit" value="Delete {{ @PARAMS.username }}">
|
||||
<br>
|
||||
<small><b>CAUTION:</b> This will permanently remove the user {{ @PARAMS.username }} and any related settings and files from this server. There is no undo after this!</small>
|
||||
</fieldset>
|
||||
</form>
|
||||
</true>
|
||||
<false>
|
||||
Go to <a href="{{@BASE}}/Users">Users</a></br>
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<include href="footer.html" />
|
176
panel/ui/vhost/users-edit.html
Normal file
176
panel/ui/vhost/users-edit.html
Normal file
|
@ -0,0 +1,176 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<!-- password -->
|
||||
<p>
|
||||
<form action="{{@REALM}}" method="POST">
|
||||
<fieldset>
|
||||
<legend>Change Password for {{ @user_array.username }}</legend>
|
||||
<input id="action" name="action" type="hidden" value="password">
|
||||
|
||||
<label for="password">Password <small></small></label>
|
||||
<input id="password" name="password" type="password" value="">
|
||||
|
||||
<label for="password_confirm">Confirm Password <small>(repeat same password)</small></label>
|
||||
<input id="password_confirm" name="password_confirm" type="password" value="">
|
||||
|
||||
<input type="submit" value="Submit">
|
||||
<button id="reset" type="reset">Reset</button>
|
||||
<br>
|
||||
|
||||
<b>Password</b> must be at least 8 characters with 12 or more being highly recommended.<br>
|
||||
Passwords under 15 characters must contain characters from at least three of the following four groups:<br>
|
||||
Lower Case Letters, Uppler Case Leters, Numbers, Puncuation/Special Characters.<br>
|
||||
Passwords 15 or more characters long do not have any complexity requirements.<br>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<!-- jail -->
|
||||
<form action="{{@REALM}}" method="POST">
|
||||
<fieldset>
|
||||
<legend>Jail User {{ @user_array.username }}</legend>
|
||||
<input id="action" name="action" type="hidden" value="jail">
|
||||
<check if="{{ @user_array.jailed=='Yes' }}">
|
||||
<true>
|
||||
User is Jailed. This can not be undone by this admin.
|
||||
</true>
|
||||
<false>
|
||||
<input type="submit" value="Jail User"><br>
|
||||
<b>Jail User</b> puts existing user in a secure jail. This is recommended on a Shared Server. Once a user is Jailed it can't be undone by these admins.<br>
|
||||
</false>
|
||||
</check>
|
||||
</fieldset>
|
||||
</form>
|
||||
</p>
|
||||
|
||||
<!-- php workers -->
|
||||
<p>
|
||||
<form action="{{@REALM}}" method="POST">
|
||||
<fieldset>
|
||||
<legend>Adjust PHP Workers for {{ @user_array.username }}</legend>
|
||||
<input id="action" name="action" type="hidden" value="fpmmax">
|
||||
<check if="{{ @user_array.fpmmax=='0' }}">
|
||||
<true>
|
||||
User {{ @user_array.username }} does not have PHP enabled.
|
||||
</true>
|
||||
<false>
|
||||
<label for="fpmmax">Adjust PHP Workers <small>(Recommended range 2-12 on a Shared Server)</small></label>
|
||||
<select id="fpmmax" name="fpmmax">
|
||||
<check if="{{ @user_array.fpmmax=='2' }}">
|
||||
<true>
|
||||
<option value="2" selected>2</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="2">2</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='4' }}">
|
||||
<true>
|
||||
<option value="4" selected>4</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="4">4</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='6' }}">
|
||||
<true>
|
||||
<option value="6" selected>6</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="6">6</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='8' }}">
|
||||
<true>
|
||||
<option value="8" selected>8</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="8">8</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='10' }}">
|
||||
<true>
|
||||
<option value="10" selected>10</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="10">10</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='12' }}">
|
||||
<true>
|
||||
<option value="12" selected>12</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="12">12</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='16' }}">
|
||||
<true>
|
||||
<option value="16" selected>16</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="16">16</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='20' }}">
|
||||
<true>
|
||||
<option value="20" selected>20</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="20">20</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='24' }}">
|
||||
<true>
|
||||
<option value="24" selected>24</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="24">24</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='30' }}">
|
||||
<true>
|
||||
<option value="30" selected>30</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="30">30</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='36' }}">
|
||||
<true>
|
||||
<option value="36" selected>36</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="36">36</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='42' }}">
|
||||
<true>
|
||||
<option value="42" selected>42</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="42">42</option>
|
||||
</false>
|
||||
</check>
|
||||
<check if="{{ @user_array.fpmmax=='48' }}">
|
||||
<true>
|
||||
<option value="48" selected>48</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="48">48</option>
|
||||
</false>
|
||||
</check>
|
||||
</select>
|
||||
|
||||
<input type="submit" value="Submit">
|
||||
<button id="reset" type="reset">Reset</button><br>
|
||||
<b>PHP Workers</b> is maximum number of PHP processes that this user can have running at one time. Any website(s) installed for this user will be limited by this.<br>
|
||||
</false>
|
||||
</check>
|
||||
</fieldset>
|
||||
</form>
|
||||
</p>
|
||||
|
||||
<include href="footer.html" />
|
54
panel/ui/vhost/users-user.html
Normal file
54
panel/ui/vhost/users-user.html
Normal file
|
@ -0,0 +1,54 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Password</th>
|
||||
<th>Jailed</th>
|
||||
<th>PHP Workers</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ @users_array.username }}</td>
|
||||
<td><span class="hidden">{{ @users_array.passwd }}</span></td>
|
||||
<td>{{ @users_array.jailed }}</td>
|
||||
<td>{{ @users_array.fpmmax }}</td>
|
||||
<td><a href="{{@REALM}}/Edit">Edit</a> <a href="{{@REALM}}/Delete">Delete</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
|
||||
<h3>Websites</h3>
|
||||
|
||||
<br>
|
||||
|
||||
<check if="isset(@vhosts_array)">
|
||||
<true>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Website</th>
|
||||
<th>Username</th>
|
||||
<th>Status</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
|
||||
<repeat group="{{ @vhosts_array }}" value="{{ @vhost_domain }}">
|
||||
|
||||
<tr>
|
||||
<td><a href="{{@BASE}}/Websites/{{ @vhost_domain.virtualhost }}">{{ @vhost_domain.virtualhost }}</a></td>
|
||||
<td>{{ @vhost_domain.username }}</td>
|
||||
<td>{{ @vhost_domain.status }}</td>
|
||||
<td><a href="{{@BASE}}/Websites/{{ @vhost_domain.virtualhost }}/Disable">Disable</a> <a href="{{@BASE}}/Websites/{{ @vhost_domain.virtualhost }}/Delete">Delete</a></td>
|
||||
</tr>
|
||||
|
||||
</repeat>
|
||||
|
||||
</table>
|
||||
</true>
|
||||
<false>
|
||||
There are no websites for this user.
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<include href="footer.html" />
|
43
panel/ui/vhost/users.html
Normal file
43
panel/ui/vhost/users.html
Normal file
|
@ -0,0 +1,43 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<check if="isset(@users_array)">
|
||||
<true>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Username</th>
|
||||
<th>Password</th>
|
||||
<th>Jailed</th>
|
||||
<th>PHP Workers</th>
|
||||
</tr>
|
||||
|
||||
<repeat group="{{ @users_array }}" value="{{ @userinfo }}">
|
||||
|
||||
<tr>
|
||||
<td><a href="{{@BASE}}/Users/{{ @userinfo.username }}">{{ @userinfo.username }}</a></td>
|
||||
<td><span class="hidden">{{ @userinfo.passwd }}</span></td>
|
||||
<td>{{ @userinfo.jailed }}</td>
|
||||
<td>{{ @userinfo.fpmmax }}</td>
|
||||
</tr>
|
||||
|
||||
</repeat>
|
||||
|
||||
</table>
|
||||
<p>
|
||||
Select a <b>Username</b> name above for more details and options.<br>
|
||||
<b>Username</b> is the system username that owns the website files.<br>
|
||||
<!--<b>uid</b> is the system User ID assigned to this user on this server.<br>-->
|
||||
<b>Password</b> is the unencrypted password for the user, if available. Scroll over field to reveal password.<br>
|
||||
<b>Jailed</b> is a flag indicating if the user is jailed.<br>
|
||||
<b>PHP Workers</b> is maximum number of PHP processes that this user can have running at one time.<br>
|
||||
</p>
|
||||
</true>
|
||||
<false>
|
||||
<p>There are no website system users on this server.</p>
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<p>
|
||||
<a href="{{@NAV.fullpath}}/Add">Add new User form</a>
|
||||
</p>
|
||||
|
||||
<include href="footer.html" />
|
|
@ -7,22 +7,31 @@
|
|||
<label for="domain">Domain Name <small>(Do not include 'www', that will be aliased to the main domain)</small></label>
|
||||
<input id="domain" name="domain" type="text" placeholder="example.com" value="" required>
|
||||
|
||||
<label for="username">Username <small>(System username, leave empty for auto-creation)</small></label>
|
||||
<input id="username" name="username" type="text" placeholder="examplec" value="" required>
|
||||
<label for="username">Username <small>(Used for SSH & SFTP access, leave empty to auto-create new user)</small></label>
|
||||
<select id="username" name="username">
|
||||
<check if="{{ @deploy.username=='' }}">
|
||||
<true>
|
||||
<option value="" selected></option>
|
||||
</true>
|
||||
<false>
|
||||
<option value=""></option>
|
||||
</false>
|
||||
</check>
|
||||
<repeat group="{{ @deploy.users_array }}" value="{{ @user_array }}">
|
||||
<check if="{{ @deploy.username==@user_array.username }}">
|
||||
<true>
|
||||
<option value="{{ @user_array.username }}" selected>{{ @user_array.username }}</option>
|
||||
</true>
|
||||
<false>
|
||||
<option value="{{ @user_array.username }}">{{ @user_array.username }}</option>
|
||||
</false>
|
||||
</check>
|
||||
</repeat>
|
||||
|
||||
Check to jail user: <input type="checkbox" id="jail" name="jail" value="yes" checked>
|
||||
|
||||
<label for="macro">Config <small>(A valid Let's Encrypt certificate is required for VHostHTTPS)</small></label>
|
||||
<select id="macro" name="macro">
|
||||
<option value="VHostHTTP" selected>VHostHTTP</option>
|
||||
<option value="VHostHTTPS">VHostHTTPS</option>
|
||||
</select>
|
||||
<small><a href="{{@BASE}}/Users/Add">Add user here</a> first if you want to create a specific username for this site.</small>
|
||||
|
||||
<label for="status">Status</label>
|
||||
<select id="status" name="status">
|
||||
<option value="1" selected>Enabled</option>
|
||||
<option value="0">Disabled</option>
|
||||
</select>
|
||||
<br><br>
|
||||
|
||||
<input type="submit" value="Submit">
|
||||
<button id="reset" type="reset" disabled>Reset</button>
|
||||
|
@ -34,10 +43,8 @@
|
|||
</form>
|
||||
|
||||
<p>
|
||||
<b>Username</b><br>
|
||||
<b>Jail</b><br>
|
||||
<b>Config</b><br>
|
||||
<b>Status</b> can be used to temporarily disable the website domain without deleting any settings or files.<br>
|
||||
<b>Domain Name</b> Enter the website domain name without the leading www.<br>
|
||||
<b>Username</b> By default this should be left blank which will create a new (unique) username just for this site. Optionally you can pick from a list of existing users, or first go to the User admin and create a specific username & password.<br>
|
||||
</p>
|
||||
|
||||
|
||||
|
|
20
panel/ui/vhost/vhosts-delete.html
Normal file
20
panel/ui/vhost/vhosts-delete.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<check if="isset(@confirm)">
|
||||
<true>
|
||||
<form action="{{@REALM}}" method="POST">
|
||||
<fieldset>
|
||||
<legend>Really Delete Website {{ @PARAMS.vhost }}</legend>
|
||||
<br>
|
||||
<input type="submit" value="Delete {{ @PARAMS.vhost }}">
|
||||
<br>
|
||||
<small><b>CAUTION:</b> This will permanently remove the {{ @PARAMS.vhost }} website and any related databases and username from this server. There is no undo after this!</small>
|
||||
</fieldset>
|
||||
</form>
|
||||
</true>
|
||||
<false>
|
||||
Go to <a href="{{@BASE}}/Websites">Websites</a></br>
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<include href="footer.html" />
|
|
@ -2,35 +2,97 @@
|
|||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Domain</th>
|
||||
<th>Website</th>
|
||||
<th>Status</th>
|
||||
<th>Mailbox Limit</th>
|
||||
<th>Default Quota</th>
|
||||
<th>Default Rate Limit</th>
|
||||
<check if="{{ @NAV.mapping=='vpanel' }}">
|
||||
<th>Action</th>
|
||||
</check>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ @vhost_array.domain }}</td>
|
||||
<td>{{ @vhost_array.virtualhost }}</td>
|
||||
<td>{{ @vhost_array.status }}</td>
|
||||
<td>{{ @vhost_array.mbox_limit }}</td>
|
||||
<td>{{ @vhost_array.mbox_quota_default }}</td>
|
||||
<td>{{ @vhost_array.mbox_ratelimit_default }}</td>
|
||||
<check if="{{ @NAV.mapping=='vpanel' }}">
|
||||
<td><a href="{{@NAV.vhostbase}}/Edit">Edit</a> <a href="{{@NAV.vhostbase}}/Delete">Delete</a></td>
|
||||
<td>
|
||||
<check if="{{ @vhost_array.status=='Enabled' }}">
|
||||
<true><a href="{{@REALM}}/Disable">Disable</a></true>
|
||||
<false><a href="{{@REALM}}/Enable">Enable</a></false>
|
||||
</check>
|
||||
<a href="{{@REALM}}/Delete">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="{{@NAV.vhostbase}}/Databases">Databases</a></li>
|
||||
<li><a href="{{@NAV.vhostbase}}/Certificates">Let's Encrypt</a></li>
|
||||
<li><a href="{{@BASE}}/Users/{{@vhost_domain.username}}">System User</a></li>
|
||||
<!-- <li><a href="{{@NAV.vhostbase}}/Forwards">Forwards</a></li> -->
|
||||
</ul>
|
||||
</nav>
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>System User</th>
|
||||
<th>PHP Workers</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ @vhost_array.username }}</td>
|
||||
<td>{{ @users_array.fpmmax }}</td>
|
||||
<td><a href="{{@BASE}}/Users/{{ @users_array.username }}/Edit">Edit</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
|
||||
<check if="isset(@cert_array)">
|
||||
<true>
|
||||
<table>
|
||||
<tr>
|
||||
<th style="white-space: nowrap;">Certificate</th>
|
||||
<th style="white-space: nowrap;">Expiration</th>
|
||||
<th style="white-space: nowrap;">Secured Hostnames</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="white-space: nowrap;">{{ @cert_array.common }}</td>
|
||||
<td style="white-space: nowrap;">{{ @cert_array.end }}</td>
|
||||
<td style="white-space: nowrap; text-align: right;">{{ @cert_array.alternative | raw }}</td>
|
||||
<td style="white-space: nowrap;"><a href="{{@BASE}}/Certs/{{@vhost_array.virtualhost}}/Delete?r={{@PATH}}">Delete</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</true>
|
||||
<false>
|
||||
<a href="{{@BASE}}/Certs/{{@vhost_array.virtualhost}}/Add?r={{@PATH}}">Add Security Certificate</a>
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr><th colspan="2">Remote Access</th></tr>
|
||||
<tr><td style="text-align: right;">Protocol:</td><td>SFTP (SSH File Transfer Protocol)</td></tr>
|
||||
<tr><td style="text-align: right;">Hostname:</td><td>{{ @vhost_array.virtualhost }}</td></tr>
|
||||
<tr><td style="text-align: right;">Username:</td><td>{{ @vhost_array.username }}</td></tr>
|
||||
<tr><td style="text-align: right;">Password:</td><td><span class="hidden">{{ @users_array.passwd }}</span> <small>← hover mouse here to reveal</small></td></tr>
|
||||
<tr><td style="text-align: right;">User Home Directory:</td><td>/home/{{ @vhost_array.username }}/</td></tr>
|
||||
<tr><td style="text-align: right;">Website Files Directory:</td><td>/srv/www/{{ @vhost_array.username }}/html/</td></tr>
|
||||
<tr><td style="text-align: right;">User Jailed:</td><td>{{ @users_array.jailed }}</td></tr>
|
||||
<tr><td style="text-align: right;">Action:</td><td><a href="{{@BASE}}/Users/{{ @users_array.username }}/Edit">Edit User</a></td></tr>
|
||||
<tr><td style="text-align: right;"><small>Notes:</small></td><td><small>The above information can also be used for SSH access.</small></td></tr>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr><th colspan="2">MySQL Database Info</th></tr>
|
||||
<tr><td style="text-align: right;">Hostname:</td><td>{{ @mysqlinfo_array.hostname }}</td></tr>
|
||||
<tr><td style="text-align: right;">Database:</td><td>{{ @mysqlinfo_array.database }}</td></tr>
|
||||
<tr><td style="text-align: right;">Username:</td><td>{{ @mysqlinfo_array.username }}</td></tr>
|
||||
<tr><td style="text-align: right;">Password:</td><td><span class="hidden">{{ @mysqlinfo_array.password }}</span> <small>← hover mouse here to reveal</small></td></tr>
|
||||
<tr><td style="text-align: right;">phpMyAdmin:</td><td>
|
||||
<check if="isset(@cert_array)">
|
||||
<true>
|
||||
<a href="https://{{ @vhost_array.virtualhost }}/phpMyAdmin">https://{{ @vhost_array.virtualhost }}/phpMyAdmin</a>
|
||||
</true>
|
||||
<false>
|
||||
<a href="https://{{ @HOST }}/phpMyAdmin">https://{{ @HOST }}/phpMyAdmin</a>
|
||||
</false>
|
||||
</check>
|
||||
</td></tr>
|
||||
<tr><td style="text-align: right;"><small>Notes:</small></td><td><small>phpMyAdmin requires a two-stage login process.<br>First use the "Remote Access" info for the popup authentication.<br>Then use the MySQL info for the database login page.</small></td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
<include href="footer.html" />
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<tr>
|
||||
<th>Website</th>
|
||||
<th>Username</th>
|
||||
<th>Config</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
|
||||
|
@ -14,8 +13,7 @@
|
|||
|
||||
<tr>
|
||||
<td><a href="{{@BASE}}/Websites/{{ @vhost_domain.virtualhost }}">{{ @vhost_domain.virtualhost }}</a></td>
|
||||
<td>{{ @vhost_domain.username }}</td>
|
||||
<td>{{ @vhost_domain.config }}</td>
|
||||
<td><a href="{{@BASE}}/Users/{{ @vhost_domain.username }}">{{ @vhost_domain.username }}</a></td>
|
||||
<td>{{ @vhost_domain.status }}</td>
|
||||
</tr>
|
||||
|
||||
|
|
20
panel/ui/vmail/dkim-delete.html
Normal file
20
panel/ui/vmail/dkim-delete.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<check if="isset(@confirm)">
|
||||
<true>
|
||||
<form action="{{@REALM}}" method="POST">
|
||||
<fieldset>
|
||||
<legend>Really Delete DKIM {{ @PARAMS.domain }}</legend>
|
||||
<br>
|
||||
<input type="submit" value="Delete DKIM for {{ @PARAMS.domain }}">
|
||||
<br>
|
||||
<small><b>CAUTION:</b> This will permanently remove the DKIM keys for {{ @PARAMS.domain }}.<br>You probably want to delete the associated DNS entry too.</small>
|
||||
</fieldset>
|
||||
</form>
|
||||
</true>
|
||||
<false>
|
||||
Go to <a href="{{@NAV.vmailbase}}">{{ @PARAMS.domain }}</a></br>
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<include href="footer.html" />
|
44
panel/ui/vmail/dkim.html
Normal file
44
panel/ui/vmail/dkim.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
<include href="header.html" />
|
||||
|
||||
<check if="isset(@dkim_array)">
|
||||
<true>
|
||||
<check if="{{@dkim_array.dns.status == 'Create'}}">
|
||||
<true>
|
||||
DKIM for {{@PARAMS.domain}} does not exist.<br>
|
||||
<a href="{{@NAV.vmailbase}}/Dkim/Add?r={{@PATH}}">Click here to add a DKIM Key now.</a>
|
||||
</true>
|
||||
<false>
|
||||
<check if="{{@dkim_array.dns.status == 'Error'}}">
|
||||
<true>
|
||||
Error checking for DKIM for {{@PARAMS.domain}}. Try again later.
|
||||
</true>
|
||||
<false>
|
||||
<table>
|
||||
<tr><th colspan="2">DKIM (TXT) Record for {{ @PARAMS.domain }}</th></tr>
|
||||
<check if="{{ @dkim_array.dns.status=='Verified' }}">
|
||||
<true>
|
||||
<tr><td colspan="2">This DNS record is all set, nothing to do.</td></tr>
|
||||
</true>
|
||||
<false>
|
||||
<tr><td style="color:red" colspan="2">Please update DNS with the following info.</td></tr>
|
||||
</false>
|
||||
</check>
|
||||
<tr><td style="text-align: right;">Type:</td><td>TXT</td></tr>
|
||||
<tr><td style="text-align: right;">Host:</td><td>{{ @dkim_array.dns.host }}</td></tr>
|
||||
<tr><td style="text-align: right;">Value:</td><td style="width: 650px; overflow-wrap: anywhere;">"k=rsa; p={{ @dkim_array.dkim }}"</td></tr>
|
||||
<tr><td style="text-align: right;">TTL:</td><td>3600 (or default)</td></tr>
|
||||
<tr><td></td><td><small>This should be the only record for this specific Host value listed above.</small></td></tr>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
<a href="{{@NAV.vmailbase}}/Dkim/Delete">Click here to delete this DKIM Key.</a>
|
||||
|
||||
</false>
|
||||
</check>
|
||||
</false>
|
||||
</check>
|
||||
</true>
|
||||
</check>
|
||||
|
||||
|
||||
<include href="footer.html" />
|
|
@ -32,29 +32,171 @@
|
|||
</ul>
|
||||
</nav>
|
||||
|
||||
<hr>
|
||||
|
||||
<check if="isset(@cert_array)">
|
||||
<true>
|
||||
<table>
|
||||
<tr>
|
||||
<th style="white-space: nowrap;">Certificate</th>
|
||||
<th style="white-space: nowrap;">Expiration</th>
|
||||
<th style="white-space: nowrap;">Secured Hostnames</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="white-space: nowrap;">{{ @cert_array.common }}</td>
|
||||
<td style="white-space: nowrap;">{{ @cert_array.end }}</td>
|
||||
<td style="white-space: nowrap; text-align: right;">{{ @cert_array.alternative | raw }}</td>
|
||||
<td style="white-space: nowrap;"><a href="{{@BASE}}/Certs/mail.{{@domain_array.domain}}/Delete?r={{@PATH}}">Delete</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</true>
|
||||
<false>
|
||||
<check if="{{ @dnsinfo.a.status=='Verified' }}">
|
||||
<true>
|
||||
You need a Security Certificate. <a href="{{@BASE}}/Certs/mail.{{@domain_array.domain}}/Add?r={{@PATH}}">Click Here</a> to add one now.
|
||||
</true>
|
||||
<false>
|
||||
<span style="color:red">You need a Security Certificate for {{ @domain_array.domain }}.</span> Before you can add one you must create the DNS "A" record below. Once that's completed come back here and this message will change to an option to create a Security Certificate.
|
||||
</false>
|
||||
</check>
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<!--<br><br>
|
||||
<b>DNS:</b> <br>
|
||||
<b>SPF:</b> <br>
|
||||
<b>DKIM:</b> <br>
|
||||
<b>Let's Encrypt:</b><br>
|
||||
<br><br>
|
||||
Email Application Settings:<br>
|
||||
|
||||
mail.example.com etc etc.<br>
|
||||
webmail<br>
|
||||
<br>
|
||||
POP<br>
|
||||
Port 110 with or without STARTTLS<br>
|
||||
Port 995 SSL/TLS<br>
|
||||
<br>
|
||||
IMAP<br>
|
||||
Port 143 with or without STARTTLS<br>
|
||||
Port 993 SSL/TLS<br>
|
||||
<br>
|
||||
SMTP<br>
|
||||
Port 25 plain, no security<br>
|
||||
Port 587 with or without STARTTLS<br>
|
||||
Port 465 SSL/TLS<br>
|
||||
<br>-->
|
||||
<check if="{{ @dnsinfo.status=='Verified' }}">
|
||||
<true>
|
||||
✓ All email related DNS settings for {{ @domain_array.domain }} have been verified.
|
||||
<br><br>
|
||||
Webmail is available at: <a href="https://mail.{{ @domain_array.domain }}">https://mail.{{ @domain_array.domain }}</a>
|
||||
</true>
|
||||
<false>
|
||||
<h3 style="color:red">NOTICE: You need to update the DNS settings for {{ @domain_array.domain }}:</h3>
|
||||
<small>Note that after you add DNS records it can take some time for the changes to propagate and show up here.</small>
|
||||
<br><br>
|
||||
<table>
|
||||
<tr><th style="color:{{ @dnsinfo.a.color }}" colspan="2">{{ @dnsinfo.a.status }} A Record for mail.{{ @domain_array.domain }}</th></tr>
|
||||
<check if="{{ @dnsinfo.a.status=='Verified' }}">
|
||||
<true>
|
||||
<tr><td colspan="2">This DNS record is all set, nothing to do.</td></tr>
|
||||
</true>
|
||||
<false>
|
||||
<tr><td style="text-align: right;">Type:</td><td>A</td></tr>
|
||||
<tr><td style="text-align: right;">Host:</td><td>mail.{{ @domain_array.domain }}</td></tr>
|
||||
<tr><td style="text-align: right;">Value:</td><td>{{ @dnsinfo.server_addr }}</td></tr>
|
||||
<tr><td style="text-align: right;">TTL:</td><td>3600 (or default)</td></tr>
|
||||
<tr><td></td><td><small>This should be the only A record for mail.{{ @domain_array.domain }}.</small></td></tr>
|
||||
</false>
|
||||
</check>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr><th style="color:{{ @dnsinfo.mx.color }}" colspan="2">{{ @dnsinfo.mx.status }} MX Record for {{ @domain_array.domain }}</th></tr>
|
||||
<check if="{{ @dnsinfo.mx.status=='Verified' }}">
|
||||
<true>
|
||||
<tr><td colspan="2">This DNS record is all set, nothing to do.</td></tr>
|
||||
</true>
|
||||
<false>
|
||||
<tr><td style="text-align: right;">Type:</td><td>MX</td></tr>
|
||||
<tr><td style="text-align: right;">Host:</td><td>{{ @domain_array.domain }}</td></tr>
|
||||
<tr><td style="text-align: right;">Value:</td><td>mail.{{ @domain_array.domain }}</td></tr>
|
||||
<tr><td style="text-align: right;">TTL:</td><td>3600 (or default)</td></tr>
|
||||
<tr><td style="text-align: right;">Priority:</td><td>10 (or default)</td></tr>
|
||||
<tr><td></td><td><small>This should be the only MX record for {{ @domain_array.domain }}<br>unless you have a backup MX system.</small></td></tr>
|
||||
</false>
|
||||
</check>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr><th style="color:{{ @dnsinfo.spf.color }}" colspan="2">{{ @dnsinfo.spf.status }} SPF (TXT) Record for {{ @domain_array.domain }}</th></tr>
|
||||
<check if="{{ @dnsinfo.spf.status=='Verified' }}">
|
||||
<true>
|
||||
<tr><td colspan="2">This DNS record is all set, nothing to do.</td></tr>
|
||||
</true>
|
||||
<false>
|
||||
<tr><td style="text-align: right;">Type:</td><td>TXT</td></tr>
|
||||
<tr><td style="text-align: right;">Host:</td><td>{{ @domain_array.domain }}</td></tr>
|
||||
<tr><td style="text-align: right;">Value:</td><td>"v=spf1 a mx -all"</td></tr>
|
||||
<tr><td style="text-align: right;">TTL:</td><td>3600 (or default)</td></tr>
|
||||
<tr><td></td><td><small>There may be other TXT records for {{ @domain_array.domain }}.</small></td></tr>
|
||||
</check>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr><th style="color:{{ @dnsinfo.dkim.color }}" colspan="2">{{ @dnsinfo.dkim.status }} DKIM (TXT) Record for {{ @domain_array.domain }}</th></tr>
|
||||
<check if="{{ @dnsinfo.dkim.status=='Verified' }}">
|
||||
<true>
|
||||
<tr><td colspan="2">DKIM is all set, nothing to do.</td></tr>
|
||||
</true>
|
||||
</check>
|
||||
<check if="{{ @dnsinfo.dkim.status=='Update' }}">
|
||||
<true>
|
||||
<tr><td style="text-align: right;">Type:</td><td>TXT</td></tr>
|
||||
<tr><td style="text-align: right;">Host:</td><td>{{ @dnsinfo.dkim.selector }}._domainkey.{{ @domain_array.domain }}</td></tr>
|
||||
<tr><td style="text-align: right;">Value:</td><td style="width: 650px; overflow-wrap: anywhere;">"k=rsa; p={{ @dnsinfo.dkim.dkim }}"</td></tr>
|
||||
<tr><td style="text-align: right;">TTL:</td><td>3600 (or default)</td></tr>
|
||||
<tr><td></td><td><small>This should be the only TXT record for this specific Host name.</small></td></tr>
|
||||
</true>
|
||||
</check>
|
||||
<check if="{{ @dnsinfo.dkim.status=='Create' }}">
|
||||
<true>
|
||||
<tr><td colspan="2"><a href="{{@NAV.vmailbase}}/Dkim/Add?r={{@PATH}}">Add DKIM Key</a><br>Use the link above to create a DKIM configuration. Once that's completed come back here and this message will change to instructions on adding an associated DNS record.</td></tr>
|
||||
</true>
|
||||
</check>
|
||||
</table>
|
||||
</false>
|
||||
</check>
|
||||
|
||||
<!-- https://www.w3docs.com/snippets/css/how-to-wrap-a-long-string-without-any-whitespace-character.html -->
|
||||
|
||||
<hr>
|
||||
<h3>Email Client Configuration Options</h3>
|
||||
<small>Use the settings below to configure email clients like<br>Mozilla Thunderbird, Apple Mail, Microsoft Outlook, et cetera.</small>
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr><th colspan="2">Incoming Server Settings</th></tr>
|
||||
<tr><td style="text-align: right;">Protocol:</td><td>IMAP</td></tr>
|
||||
<tr><td style="text-align: right;">Hostname:</td><td>mail.{{ @domain_array.domain }}</td></tr>
|
||||
<tr><td style="text-align: right;">Port</td><td>143</td></tr>
|
||||
<tr><td style="text-align: right;">Connection Security:</td><td>STARTTLS</td></tr>
|
||||
<tr><td style="text-align: right;">Authentication Method:</td><td>Normal password</td></tr>
|
||||
<tr><td style="text-align: right;">Username:</td><td>(full email address)</td></tr>
|
||||
<tr><td style="text-align: right;"><small>Notes:</small></td><td><small>Alternative options that work:<br>Connection Security: SSL/TLS<br>Port: 993</small></td></tr>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr><th colspan="2">Outgoing Server Settings</th></tr>
|
||||
<tr><td style="text-align: right;">Protocol:</td><td>SMTP</td></tr>
|
||||
<tr><td style="text-align: right;">Hostname:</td><td>mail.{{ @domain_array.domain }}</td></tr>
|
||||
<tr><td style="text-align: right;">Port</td><td>587</td></tr>
|
||||
<tr><td style="text-align: right;">Connection Security:</td><td>STARTTLS</td></tr>
|
||||
<tr><td style="text-align: right;">Authentication Method:</td><td>Normal password</td></tr>
|
||||
<tr><td style="text-align: right;">Username:</td><td>(full email address)</td></tr>
|
||||
<tr><td style="text-align: right;"><small>Notes:</small></td><td><small>Alternative options that work:<br>Connection Security: SSL/TLS<br>Port: 465</small></td></tr>
|
||||
</table>
|
||||
|
||||
<br><br>
|
||||
|
||||
<table>
|
||||
<tr><th colspan="2">Alternative Incoming Server Settings</th></tr>
|
||||
<tr><td style="text-align: right;">Protocol:</td><td>POP3</td></tr>
|
||||
<tr><td style="text-align: right;">Hostname:</td><td>mail.{{ @domain_array.domain }}</td></tr>
|
||||
<tr><td style="text-align: right;">Port</td><td>110</td></tr>
|
||||
<tr><td style="text-align: right;">Connection Security:</td><td>STARTTLS</td></tr>
|
||||
<tr><td style="text-align: right;">Authentication Method:</td><td>Normal password</td></tr>
|
||||
<tr><td style="text-align: right;">Username:</td><td>(full email address)</td></tr>
|
||||
<tr><td style="text-align: right;"><small>Notes:</small></td><td><small>Alternative options that work:<br>Connection Security: SSL/TLS<br>Port: 995</small></td></tr>
|
||||
<tr><td colspan="2" style="text-align: left;"><small>IMAP (listed above) keeps your folders and emails synced on your<br>server and is the recommended default.<br>POP3 listed here keeps your folders and emails on your local<br>computer and can sometimes be a prefered configuration.</small></td></tr>
|
||||
</table>
|
||||
|
||||
<include href="footer.html" />
|
||||
|
|
Loading…
Reference in New Issue
Block a user