diff --git a/api_keys.php b/api_keys.php index d57fa51b..0c1e0835 100644 --- a/api_keys.php +++ b/api_keys.php @@ -32,36 +32,43 @@ $success_message = ""; $id = (int) Request::get('id'); // do the delete and then just show a success-message and the apikeys list again -if ($action == 'delete') { - if ($id > 0) { - $chk = (AREA == 'admin' && $userinfo['customers_see_all'] == '1') ? true : false; - if (AREA == 'customer') { - $chk_stmt = Database::prepare(" +if ($action == 'delete' && $id > 0) { + \Froxlor\UI\HTML::askYesNo('apikey_reallydelete', $filename, array( + 'id' => $id, + 'page' => $page, + 'action' => 'deletesure' + ), '', [ + 'section' => 'index', + 'page' => $page + ]); +} elseif ($action == 'deletesure' && $id > 0) { + $chk = (AREA == 'admin' && $userinfo['customers_see_all'] == '1') ? true : false; + if (AREA == 'customer') { + $chk_stmt = Database::prepare(" SELECT c.customerid FROM `" . TABLE_PANEL_CUSTOMERS . "` c LEFT JOIN `" . TABLE_API_KEYS . "` ak ON ak.customerid = c.customerid WHERE ak.`id` = :id AND c.`customerid` = :cid "); - $chk = Database::pexecute_first($chk_stmt, array( - 'id' => $id, - 'cid' => $userinfo['customerid'] - )); - } elseif (AREA == 'admin' && $userinfo['customers_see_all'] == '0') { - $chk_stmt = Database::prepare(" + $chk = Database::pexecute_first($chk_stmt, array( + 'id' => $id, + 'cid' => $userinfo['customerid'] + )); + } elseif (AREA == 'admin' && $userinfo['customers_see_all'] == '0') { + $chk_stmt = Database::prepare(" SELECT a.adminid FROM `" . TABLE_PANEL_ADMINS . "` a LEFT JOIN `" . TABLE_API_KEYS . "` ak ON ak.adminid = a.adminid WHERE ak.`id` = :id AND a.`adminid` = :aid "); - $chk = Database::pexecute_first($chk_stmt, array( - 'id' => $id, - 'aid' => $userinfo['adminid'] - )); - } - if ($chk !== false) { - Database::pexecute($del_stmt, array( - 'id' => $id - )); - $success_message = sprintf($lng['apikeys']['apikey_removed'], $id); - } + $chk = Database::pexecute_first($chk_stmt, array( + 'id' => $id, + 'aid' => $userinfo['adminid'] + )); + } + if ($chk !== false) { + Database::pexecute($del_stmt, array( + 'id' => $id + )); + $success_message = sprintf($lng['apikeys']['apikey_removed'], $id); } } elseif ($action == 'add') { $ins_stmt = Database::prepare(" @@ -83,47 +90,6 @@ if ($action == 'delete') { 'cid' => $cid )); $success_message = $lng['apikeys']['apikey_added']; -} elseif ($action == 'jqEditApiKey') { - $keyid = isset($_POST['id']) ? (int) $_POST['id'] : 0; - $allowed_from = isset($_POST['allowed_from']) ? $_POST['allowed_from'] : ""; - $valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : -1; - - // validate allowed_from - if (!empty($allowed_from)) { - $ip_list = array_map('trim', explode(",", $allowed_from)); - $_check_list = $ip_list; - foreach ($_check_list as $idx => $ip) { - if (\Froxlor\Validate\Validate::validate_ip2($ip, true, 'invalidip', true, true) == false) { - unset($ip_list[$idx]); - } - } - $ip_list = array_map('inet_ntop', array_map('inet_pton', $ip_list)); - $allowed_from = implode(",", array_unique($ip_list)); - } - - if ($valid_until <= 0 || !is_numeric($valid_until)) { - $valid_until = -1; - } - - $upd_stmt = Database::prepare(" - UPDATE `" . TABLE_API_KEYS . "` SET - `valid_until` = :vu, `allowed_from` = :af - WHERE `id` = :keyid AND `adminid` = :aid AND `customerid` = :cid - "); - if (AREA == 'admin') { - $cid = 0; - } elseif (AREA == 'customer') { - $cid = $userinfo['customerid']; - } - Database::pexecute($upd_stmt, array( - 'keyid' => $keyid, - 'af' => $allowed_from, - 'vu' => $valid_until, - 'aid' => $userinfo['adminid'], - 'cid' => $cid - )); - echo json_encode(true); - exit(); } $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed api::api_keys"); diff --git a/install/lib/class.FroxlorInstall.php b/install/lib/class.FroxlorInstall.php index 89d8d8bc..8469718d 100644 --- a/install/lib/class.FroxlorInstall.php +++ b/install/lib/class.FroxlorInstall.php @@ -444,7 +444,7 @@ class FroxlorInstall `vhostcontainer` = '1', `vhostcontainer_servername_statement` = '1' "); - $nvh = $this->_data['webserver'] == 'apache2' ? '1' : '0'; + $nvh = $this->_data['webserver'] == 'apache2' ? '1' : '0'; $stmt->execute(array( 'nvh' => $nvh, 'serverip' => $this->_data['serverip'], @@ -1193,6 +1193,9 @@ class FroxlorInstall // check for json extension $this->_requirementCheckFor($content, $_die, 'json', false, 'phpjson'); + // check for gmp extension + $this->_requirementCheckFor($content, $_die, 'gmp', false, 'phpgmp'); + // check for bcmath extension $this->_requirementCheckFor($content, $_die, 'bcmath', true, 'phpbcmath', 'bcmathdescription'); diff --git a/install/lng/english.lng.php b/install/lng/english.lng.php index 73ef9d4e..031c6ff8 100644 --- a/install/lng/english.lng.php +++ b/install/lng/english.lng.php @@ -36,6 +36,7 @@ $lng['requirements']['phpcurl'] = 'PHP curl-extension...'; $lng['requirements']['phpmbstring'] = 'PHP mbstring-extension...'; $lng['requirements']['phpzip'] = 'PHP zip-extension...'; $lng['requirements']['phpjson'] = 'PHP json-extension...'; +$lng['requirements']['phpgmp'] = 'PHP gmp-extension...'; $lng['requirements']['bcmathdescription'] = 'Traffic-calculation related functions will not work correctly!'; $lng['requirements']['zipdescription'] = 'The auto-update feature requires the zip extension.'; $lng['requirements']['openbasedir'] = 'open_basedir...'; diff --git a/install/lng/german.lng.php b/install/lng/german.lng.php index a3ac7c6a..0a1226ed 100644 --- a/install/lng/german.lng.php +++ b/install/lng/german.lng.php @@ -36,6 +36,7 @@ $lng['requirements']['phpcurl'] = 'PHP curl-Erweiterung...'; $lng['requirements']['phpmbstring'] = 'PHP mbstring-Erweiterung...'; $lng['requirements']['phpzip'] = 'PHP zip-Erweiterung...'; $lng['requirements']['phpjson'] = 'PHP json-Erweiterung...'; +$lng['requirements']['phpgmp'] = 'PHP gmp-Erweiterung...'; $lng['requirements']['bcmathdescription'] = 'Traffic-Berechnungs bezogene Funktionen stehen nicht vollständig zur Verfügung!'; $lng['requirements']['zipdescription'] = 'Die Auto-Update Funktion benötigt die zip Erweiterung.'; $lng['requirements']['openbasedir'] = 'open_basedir genutzt wird...'; diff --git a/lib/Froxlor/Ajax/Ajax.php b/lib/Froxlor/Ajax/Ajax.php index de9123a5..9af17e2d 100644 --- a/lib/Froxlor/Ajax/Ajax.php +++ b/lib/Froxlor/Ajax/Ajax.php @@ -3,7 +3,9 @@ namespace Froxlor\Ajax; use Exception; +use Froxlor\Database\Database; use Froxlor\Http\HttpClient; +use Froxlor\Validate\Validate; use Froxlor\Settings; use Froxlor\UI\Listing; use Froxlor\UI\Panel\UI; @@ -52,7 +54,7 @@ class Ajax global $lng; // query the whole table - $result_stmt = \Froxlor\Database\Database::query("SELECT * FROM `" . TABLE_PANEL_LANGUAGE . "`"); + $result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_LANGUAGE . "`"); $langs = array(); // presort languages @@ -110,6 +112,8 @@ class Ajax return $this->searchGlobal(); case 'tablelisting': return $this->updateTablelisting(); + case 'editapikey': + return $this->editApiKey(); default: return $this->errorResponse('Action not found!'); } @@ -117,11 +121,13 @@ class Ajax public function errorResponse($message, int $response_code = 500) { + header("Content-Type: application/json"); return \Froxlor\Api\Response::jsonErrorResponse($message, $response_code); } public function jsonResponse($value, int $response_code = 200) { + header("Content-Type: application/json"); return \Froxlor\Api\Response::jsonResponse($value, $response_code); } @@ -193,7 +199,7 @@ class Ajax ]); } - return $items; + return $this->jsonResponse($items); } else { return $this->errorResponse('No Newsfeeds available at the moment.'); } @@ -206,8 +212,8 @@ class Ajax try { $json_result = \Froxlor\Api\Commands\Froxlor::getLocal($this->userinfo)->checkUpdate(); $result = json_decode($json_result, true)['data']; - echo UI::twig()->render($this->theme . '/misc/version_top.html.twig', $result); - exit; + $result = UI::twig()->render($this->theme . '/misc/version_top.html.twig', $result); + return $this->jsonResponse($result); } catch (Exception $e) { // don't display anything if just not allowed due to permissions if ($e->getCode() != 403) { @@ -236,8 +242,7 @@ class Ajax $result = array_merge($result_settings, $result_entities); - header("Content-type: application/json"); - echo json_encode($result); + return $this->jsonResponse($result); } private function updateTablelisting() @@ -249,6 +254,61 @@ class Ajax Listing::storeColumnListingForUser([Request::get('listing') => $columns]); - return json_encode($columns); + return $this->jsonResponse($columns); + } + + private function editApiKey() + { + $keyid = isset($_POST['id']) ? (int) $_POST['id'] : 0; + $allowed_from = isset($_POST['allowed_from']) ? $_POST['allowed_from'] : ""; + $valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : -1; + + // validate allowed_from + if (!empty($allowed_from)) { + $ip_list = array_map('trim', explode(",", $allowed_from)); + $_check_list = $ip_list; + foreach ($_check_list as $idx => $ip) { + if (Validate::validate_ip2($ip, true, 'invalidip', true, true, true) == false) { + unset($ip_list[$idx]); + continue; + } + // check for cidr + if (strpos($ip, '/') !== false) { + $ipparts = explode("/", $ip); + // shorten IP + $ip = inet_ntop(inet_pton($ipparts[0])); + // re-add cidr + $ip .= '/' . $ipparts[1]; + } else { + // shorten IP + $ip = inet_ntop(inet_pton($ip)); + } + $ip_list[$idx] = $ip; + } + $allowed_from = implode(",", array_unique($ip_list)); + } + + if ($valid_until <= 0 || !is_numeric($valid_until)) { + $valid_until = -1; + } + + $upd_stmt = Database::prepare(" + UPDATE `" . TABLE_API_KEYS . "` SET + `valid_until` = :vu, `allowed_from` = :af + WHERE `id` = :keyid AND `adminid` = :aid AND `customerid` = :cid + "); + if ((int) $this->userinfo['adminsession'] == 1) { + $cid = 0; + } else { + $cid = $this->userinfo['customerid']; + } + Database::pexecute($upd_stmt, array( + 'keyid' => $keyid, + 'af' => $allowed_from, + 'vu' => $valid_until, + 'aid' => $this->userinfo['adminid'], + 'cid' => $cid + )); + return $this->jsonResponse(['allowed_from' => $allowed_from, 'valid_until' => $valid_until]); } } diff --git a/lib/Froxlor/Api/Response.php b/lib/Froxlor/Api/Response.php index a88cb795..1ebae861 100644 --- a/lib/Froxlor/Api/Response.php +++ b/lib/Froxlor/Api/Response.php @@ -1,4 +1,5 @@ $data], $response_code); - } + public static function jsonDataResponse($data = null, int $response_code = 200) + { + return self::jsonResponse(['data' => $data], $response_code); + } - public static function jsonErrorResponse($message = null, int $response_code = 400) - { - return self::jsonResponse(['message' => $message], $response_code); - } + public static function jsonErrorResponse($message = null, int $response_code = 400) + { + return self::jsonResponse(['message' => $message], $response_code); + } } diff --git a/lib/Froxlor/UI/Callbacks/Domain.php b/lib/Froxlor/UI/Callbacks/Domain.php index 42c9e4c9..713b255b 100644 --- a/lib/Froxlor/UI/Callbacks/Domain.php +++ b/lib/Froxlor/UI/Callbacks/Domain.php @@ -61,9 +61,24 @@ class Domain return UI::getLng('domains.aliasdomain') . ' ' . $attributes['fields']['aliasdomain']; } - public static function domainExternalLink(array $attributes) + public static function domainExternalLinkInfo(array $attributes) { - return '' . $attributes['data'] . ''; + $result = '' . $attributes['data'] . ''; + // check for statistics if parentdomainid==0 to show stats-link for customers + if ((int) UI::getCurrentUser()['adminsession'] == 0 && $attributes['fields']['parentdomainid'] == 0) { + $statsapp = 'webalizer'; + if (Settings::Get('system.awstats_enabled') == '1') { + $statsapp = 'awstats'; + } + $result .= ' '; + } + if ($attributes['fields']['registration_date'] != '') { + $result .= '
' . UI::getLng('domains.registration_date') . ': ' . $attributes['fields']['registration_date'] . ''; + } + if ($attributes['fields']['termination_date'] != '') { + $result .= '
' . UI::getLng('domains.termination_date_overview') . ': ' . $attributes['fields']['termination_date'] . ''; + } + return $result; } public static function canEdit(array $attributes): bool diff --git a/lib/Froxlor/UI/Callbacks/Style.php b/lib/Froxlor/UI/Callbacks/Style.php index d34b521e..6ff1ea9a 100644 --- a/lib/Froxlor/UI/Callbacks/Style.php +++ b/lib/Froxlor/UI/Callbacks/Style.php @@ -46,6 +46,21 @@ class Style return $isValid ? '' : 'bg-danger'; } + public static function resultDomainTerminatedOrDeactivated(array $attributes): string + { + $termination_date = str_replace("0000-00-00", "", $attributes['fields']['termination_date'] ?? ''); + $termination_css = ''; + if (!empty($termination_date)) { + $cdate = strtotime($termination_date . " 23:59:59"); + $today = time(); + $termination_css = 'bg-warning'; + if ($cdate < $today) { + $termination_css = 'bg-danger'; + } + } + return $attributes['fields']['deactivated'] ? 'bg-info' : $termination_css; + } + public static function diskspaceWarning(array $attributes): string { return self::getWarningStyle('diskspace', $attributes['fields'], (int)Settings::Get('system.report_webmax')); diff --git a/lib/Froxlor/UI/Callbacks/Text.php b/lib/Froxlor/UI/Callbacks/Text.php index 12e6ead0..6f1c3156 100644 --- a/lib/Froxlor/UI/Callbacks/Text.php +++ b/lib/Froxlor/UI/Callbacks/Text.php @@ -79,6 +79,7 @@ class Text 'editid' => $attributes['fields']['id'] ]); return [ + 'entry' => $attributes['fields']['id'], 'id' => 'akModal' . $attributes['fields']['id'], 'title' => 'API-key ' . ($attributes['fields']['loginname'] ?? $attributes['fields']['adminname']), 'body' => $body diff --git a/lib/Froxlor/UI/HTML.php b/lib/Froxlor/UI/HTML.php index 6d9cf22a..5f6af921 100644 --- a/lib/Froxlor/UI/HTML.php +++ b/lib/Froxlor/UI/HTML.php @@ -169,12 +169,13 @@ class HTML * Values which will be given to $yesfile. Format: array(variable1=>value1, variable2=>value2, variable3=>value3) * @param string $replacer * value of a possible existing string-replacer in the question + * @param array $back_link * * @author Froxlor team (2010-) * * @return string */ - public static function askYesNo(string $text, string $yesfile, array $params = [], string $replacer = '') + public static function askYesNo(string $text, string $yesfile, array $params = [], string $replacer = '', array $back_link = []) { global $lng; @@ -189,7 +190,8 @@ class HTML Panel\UI::view('form/yesnoquestion.html.twig', [ 'action' => $yesfile, 'url_params' => $params, - 'question' => $text + 'question' => $text, + 'back_link' => $back_link ]); exit(); } diff --git a/lib/formfields/formfield.api_key.php b/lib/formfields/formfield.api_key.php index 2bff23a4..3e96fe33 100644 --- a/lib/formfields/formfield.api_key.php +++ b/lib/formfields/formfield.api_key.php @@ -40,15 +40,15 @@ return [ 'value' => $result['secret'] ], 'allowed_from' => [ - 'label' => UI::getLng('apikeys.allowed_from'), + 'label' => ['title' => UI::getLng('apikeys.allowed_from'), 'description' => UI::getLng('apikeys.allowed_from_help')], 'type' => 'text', 'value' => $result['allowed_from'], ], 'valid_until' => [ - 'label' => UI::getLng('apikeys.valid_until'), + 'label' => ['title' => UI::getLng('apikeys.valid_until'), 'description' => UI::getLng('apikeys.valid_until_help')], + /** @TODO datetime-picker */ 'type' => 'text', - 'value' => $result['valid_until'], - 'format_callback' => [Text::class, 'timestampUntil'], + 'value' => $result['valid_until'] < 0 ? "" : $result['valid_until'] ] ] ] diff --git a/lib/tablelisting/admin/tablelisting.domains.php b/lib/tablelisting/admin/tablelisting.domains.php index 2590d6c0..2ca442aa 100644 --- a/lib/tablelisting/admin/tablelisting.domains.php +++ b/lib/tablelisting/admin/tablelisting.domains.php @@ -16,6 +16,7 @@ * */ +use Froxlor\UI\Callbacks\Style; use Froxlor\UI\Callbacks\Domain; use Froxlor\UI\Callbacks\Impersonate; use Froxlor\UI\Callbacks\Text; @@ -117,6 +118,9 @@ return [ ], 'visible' => [Domain::class, 'adminCanDelete'] ] + ], + 'format_callback' => [ + [Style::class, 'resultDomainTerminatedOrDeactivated'] ] ] ]; diff --git a/lib/tablelisting/customer/tablelisting.domains.php b/lib/tablelisting/customer/tablelisting.domains.php index 8088058a..0946a6df 100644 --- a/lib/tablelisting/customer/tablelisting.domains.php +++ b/lib/tablelisting/customer/tablelisting.domains.php @@ -16,6 +16,8 @@ * */ + +use Froxlor\UI\Callbacks\Style; use Froxlor\UI\Callbacks\Domain; use Froxlor\UI\Listing; @@ -31,7 +33,7 @@ return [ 'd.domain_ace' => [ 'label' => $lng['domains']['domainname'], 'field' => 'domain_ace', - 'callback' => [Domain::class, 'domainExternalLink'], + 'callback' => [Domain::class, 'domainExternalLinkInfo'], ], 'd.documentroot' => [ 'label' => $lng['panel']['path'], @@ -119,6 +121,9 @@ return [ ], 'visible' => [Domain::class, 'canDelete'] ] + ], + 'format_callback' => [ + [Style::class, 'resultDomainTerminatedOrDeactivated'] ] ] ]; diff --git a/lng/english.lng.php b/lng/english.lng.php index 43fb1ca1..ae5254ca 100644 --- a/lng/english.lng.php +++ b/lng/english.lng.php @@ -2041,7 +2041,7 @@ $lng['apikeys']['apikey_removed'] = 'The api key with the id #%s has been remove $lng['apikeys']['apikey_added'] = 'A new api key has been generated successfully'; $lng['apikeys']['clicktoview'] = 'Click to view'; $lng['apikeys']['allowed_from'] = 'Allowed from'; -$lng['apikeys']['allowed_from_help'] = 'Comma separated list of ip addresses. Default empty.
Specifying a subnet e.g. 192.168.1.1/24 is currently not supported.'; +$lng['apikeys']['allowed_from_help'] = 'Comma separated list of ip addresses / networks.
Default is empty (allow from all).'; $lng['apikeys']['valid_until'] = 'Valid until'; $lng['apikeys']['valid_until_help'] = 'Date until valid, format YYYY-MM-DD'; $lng['serversettings']['enable_api']['title'] = 'Enable external API usage'; @@ -2167,5 +2167,6 @@ $lng['panel']['settingsmodebasic'] = 'Basic'; $lng['panel']['settingsmodeadvanced'] = 'Advanced'; $lng['panel']['settingsmodetoggle'] = 'Click to toggle mode'; $lng['panel']['modalclose'] = 'Close'; -$lng['panel']['managetablecolumnsmodal']['title'] = 'Manage Table columns'; -$lng['panel']['managetablecolumnsmodal']['description'] = 'Here you can individualise the table columns for yourself.'; +$lng['panel']['managetablecolumnsmodal']['title'] = 'Manage table columns'; +$lng['panel']['managetablecolumnsmodal']['description'] = 'Here you can customize the visible columns'; +$lng['question']['apikey_reallydelete'] = 'Do you really want to delete this api-key?'; diff --git a/lng/german.lng.php b/lng/german.lng.php index f9720c73..722ddc1e 100644 --- a/lng/german.lng.php +++ b/lng/german.lng.php @@ -1683,7 +1683,7 @@ $lng['apikeys']['no_api_keys'] = 'Keine API Keys gefunden'; $lng['apikeys']['key_add'] = 'API Key hinzufügen'; $lng['apikeys']['apikey_removed'] = 'Der API Key mit der ID #%s wurde erfolgreich gelöscht.'; $lng['apikeys']['allowed_from'] = 'Erlaube Zugriff von'; -$lng['apikeys']['allowed_from_help'] = 'Komma getrennte Liste von IPs. Standard ist leer.
Angabe von Subnetzen z.B. 192.168.1.1/24 wird derzeit nicht unterstützt.'; +$lng['apikeys']['allowed_from_help'] = 'Komma getrennte Liste von IPs oder Netzen.
Standard ist leer (von überall erlaubt).'; $lng['apikeys']['valid_until'] = 'Gültig bis'; $lng['apikeys']['valid_until_help'] = 'Datum Gültigkeitsende, Format JJJJ-MM-TT'; $lng['serversettings']['enable_api']['title'] = 'Aktiviere externe API Nutzung'; @@ -1806,4 +1806,5 @@ $lng['panel']['settingsmodeadvanced'] = 'Erweitert'; $lng['panel']['settingsmodetoggle'] = 'Modus umschalten'; $lng['panel']['modalclose'] = 'Schließen'; $lng['panel']['managetablecolumnsmodal']['title'] = 'Tabellenspalten verwalten'; -$lng['panel']['managetablecolumnsmodal']['description'] = 'Hier kannst du die Tabellenspalten für dich selbst individualisieren.'; +$lng['panel']['managetablecolumnsmodal']['description'] = 'Hier können die angezeigten Tabellenspalten angepasst werden'; +$lng['question']['plan_reallydelete'] = 'Wollen Sie den Api-Key wirklich löschen?'; diff --git a/templates/Froxlor/form/yesnoquestion.html.twig b/templates/Froxlor/form/yesnoquestion.html.twig index 22036cec..73dfec30 100644 --- a/templates/Froxlor/form/yesnoquestion.html.twig +++ b/templates/Froxlor/form/yesnoquestion.html.twig @@ -23,7 +23,11 @@ {% endfor %}   - {{ lng('panel.no') }} + {% if back_link is defined and back_link is iterable %} + {{ lng('panel.no') }} + {% else %} + {{ lng('panel.no') }} + {% endif %}

diff --git a/templates/Froxlor/src/js/components/apikeys.js b/templates/Froxlor/src/js/components/apikeys.js new file mode 100644 index 00000000..41db9028 --- /dev/null +++ b/templates/Froxlor/src/js/components/apikeys.js @@ -0,0 +1,57 @@ +$(function () { + + var timer, delay = 500; + $('div[data-action="apikeys"] #allowed_from').on('keyup change', function () { + var _this = $(this); + clearTimeout(timer); + timer = setTimeout(function () { + var akid = $('div[data-action="apikeys"]').data('entry'); + $.ajax({ + url: "lib/ajax.php?action=editapikey", + type: "POST", + dataType: "json", + data: { id: akid, allowed_from: _this.val(), valid_until: $('div[data-action="apikeys"] #valid_until').val() }, + success: function (data) { + if (data.message) { + _this.removeClass('is-valid'); + _this.addClass('is-invalid'); + } else { + _this.removeClass('is-invalid'); + _this.addClass('is-valid'); + _this.val(data.allowed_from); + } + }, + error: function (request, status, error) { + console.log(request, status, error) + } + }); + }, delay); + }); + + $('div[data-action="apikeys"] #valid_until').on('keyup change', function () { + var _this = $(this); + clearTimeout(timer); + timer = setTimeout(function () { + var akid = $('div[data-action="apikeys"]').data('entry'); + $.ajax({ + url: "lib/ajax.php?action=editapikey", + type: "POST", + dataType: "json", + data: { id: akid, valid_until: _this.val(), allowed_from: $('div[data-action="apikeys"] #allowed_from').val() }, + success: function (data) { + if (data.message) { + _this.removeClass('is-valid'); + _this.addClass('is-invalid'); + } else { + _this.removeClass('is-invalid'); + _this.addClass('is-valid'); + _this.val(data.valid_until); + } + }, + error: function (request, status, error) { + console.log(request, status, error) + } + }); + }, delay); + }); +}); diff --git a/templates/Froxlor/src/js/components/configfiles.js b/templates/Froxlor/src/js/components/configfiles.js index 6ea59352..2a7f97b4 100644 --- a/templates/Froxlor/src/js/components/configfiles.js +++ b/templates/Froxlor/src/js/components/configfiles.js @@ -1,8 +1,8 @@ -$(document).ready(function () { +$(function() { /* * config files - select all recommended */ - $('#selectRecommendedConfig').click(function () { + $('#selectRecommendedConfig').on('click', function () { $('input[data-recommended]').each(function () { if ($(this).data('recommended') == 1) { $(this).prop('checked', true); diff --git a/templates/Froxlor/src/js/components/customer.js b/templates/Froxlor/src/js/components/customer.js index f04e1e0f..eefe02af 100644 --- a/templates/Froxlor/src/js/components/customer.js +++ b/templates/Froxlor/src/js/components/customer.js @@ -1,4 +1,4 @@ -$(document).ready(function () { +$(function() { // Make inputs with enabled unlimited checked disabled $("input[name$='_ul']").each(function () { @@ -9,7 +9,7 @@ $(document).ready(function () { }); }); // change state when unlimited checkboxes are clicked - $("input[name$='_ul']").change(function () { + $("input[name$='_ul']").on('change', function () { var fieldname = $(this).attr("name").substring(0, $(this).attr("name").length - 3); $("input[name='" + fieldname + "']").prop({ readonly: $(this).is(":checked"), @@ -21,7 +21,7 @@ $(document).ready(function () { }); // set values from hosting plan when adding/editing a customer according to the plan's values - $('#use_plan').change(function () { + $('#use_plan').on('change', function () { var pid = $(this).val(); if (pid > 0) { $.ajax({ diff --git a/templates/Froxlor/src/js/components/domains.js b/templates/Froxlor/src/js/components/domains.js index cd083411..67817d54 100644 --- a/templates/Froxlor/src/js/components/domains.js +++ b/templates/Froxlor/src/js/components/domains.js @@ -1,7 +1,7 @@ -$(document).ready(function () { +$(function() { // disable unusable php-configuration by customer settings - $('#customerid').change(function () { + $('#customerid').on('change', function () { var cid = $(this).val(); $.ajax({ url: "admin_domains.php?page=domains&action=jqGetCustomerPHPConfigs", @@ -31,7 +31,7 @@ $(document).ready(function () { // show warning if speciallogfile option is toggled if ($('input[name=speciallogverified]')) { - $('input[name=speciallogfile]').click(function () { + $('input[name=speciallogfile]').on('click', function () { $('#speciallogfilenote').remove(); $('#speciallogfile').removeClass('is-invalid'); $('#speciallogverified').val(0); @@ -64,7 +64,7 @@ $(document).ready(function () { $('#section_d').hide(); } - $('#email_only').click(function () { + $('#email_only').on('click', function () { if ($(this).is(':checked')) { // hide unnecessary sections $('#section_b').hide(); diff --git a/templates/Froxlor/src/js/components/ipsandports.js b/templates/Froxlor/src/js/components/ipsandports.js index 50c40a7a..c42b6da4 100644 --- a/templates/Froxlor/src/js/components/ipsandports.js +++ b/templates/Froxlor/src/js/components/ipsandports.js @@ -1,7 +1,7 @@ -$(document).ready(function () { +$(function() { // check for internal ip and output a notice if private-range ip is given - $('#ip').change(function () { + $('#ip').on('change', function () { var ipval = $(this).val(); if (ipval.length > 0) { $('#ipnote').remove(); diff --git a/templates/Froxlor/src/js/components/newsfeed.js b/templates/Froxlor/src/js/components/newsfeed.js index 8e4fb8c2..2776eeb3 100644 --- a/templates/Froxlor/src/js/components/newsfeed.js +++ b/templates/Froxlor/src/js/components/newsfeed.js @@ -1,4 +1,4 @@ -$(document).ready(function () { +$(function() { /* * newsfeed */ diff --git a/templates/Froxlor/src/js/components/search.js b/templates/Froxlor/src/js/components/search.js index 40dd2c06..92115aab 100644 --- a/templates/Froxlor/src/js/components/search.js +++ b/templates/Froxlor/src/js/components/search.js @@ -1,7 +1,7 @@ -$(document).ready(function () { +$(function() { let search = $('#search') - search.submit(function (e) { + search.on('submit', function (e) { e.preventDefault(); }); diff --git a/templates/Froxlor/src/js/components/updatecheck.js b/templates/Froxlor/src/js/components/updatecheck.js index e5da6103..9a7cae69 100644 --- a/templates/Froxlor/src/js/components/updatecheck.js +++ b/templates/Froxlor/src/js/components/updatecheck.js @@ -1,4 +1,4 @@ -$(document).ready(function () { +$(function() { /* * updatecheck */ diff --git a/templates/Froxlor/src/js/main.js b/templates/Froxlor/src/js/main.js index 578e2655..fd3e3e78 100644 --- a/templates/Froxlor/src/js/main.js +++ b/templates/Froxlor/src/js/main.js @@ -7,7 +7,7 @@ import 'chart.js/dist/chart'; global.$ = require('jquery'); global.bootstrap = require('bootstrap'); -$(document).ready(function () { +$(function() { window.$theme = 'Froxlor'; }); @@ -20,3 +20,4 @@ require('./components/tablecolumns') require('./components/ipsandports') require('./components/domains') require('./components/configfiles') +require('./components/apikeys') diff --git a/templates/Froxlor/table/macros.html.twig b/templates/Froxlor/table/macros.html.twig index 3944e548..0908277a 100644 --- a/templates/Froxlor/table/macros.html.twig +++ b/templates/Froxlor/table/macros.html.twig @@ -53,7 +53,7 @@ {% endif %} {% if data.modal is defined and data.modal is iterable %} -