Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1467dab58f | ||
|
|
3a8f48de35 | ||
|
|
46391c06ec | ||
|
|
7103f7dd51 | ||
|
|
9fc1dfee41 | ||
|
|
82dc76fdc6 | ||
|
|
02ae52e3df | ||
|
|
5c06683e27 | ||
|
|
2684372156 | ||
|
|
d80c6d5714 | ||
|
|
1ae5311b81 | ||
|
|
e1e7555cce | ||
|
|
4f79d7cf4b | ||
|
|
b13b1e8ac7 | ||
|
|
6a1e7cc539 | ||
|
|
2e87633ef7 | ||
|
|
8a23d0b72c | ||
|
|
735ef85088 | ||
|
|
75cf44a6d2 | ||
|
|
7e0073f4a3 | ||
|
|
c9291df345 | ||
|
|
fd5e97d48c | ||
|
|
64a9fb163a | ||
|
|
b0256ffb7d | ||
|
|
e606bdc97f | ||
|
|
b53b3a924a | ||
|
|
539ea7c8fc | ||
|
|
5e8763e160 |
5
.github/workflows/build-docs.yml
vendored
5
.github/workflows/build-docs.yml
vendored
@@ -2,7 +2,8 @@ name: build-documentation
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
# only run for stable releases
|
||||
types: [released]
|
||||
|
||||
jobs:
|
||||
build_docs:
|
||||
@@ -11,4 +12,4 @@ jobs:
|
||||
- env:
|
||||
GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh workflow run --repo Froxlor/Documentation build-and-deploy.yml -f type=tags ref=${{github.ref_name}}
|
||||
gh workflow run --repo Froxlor/Documentation build-and-deploy.yml -f type=tags -f ref=${{github.ref_name}}
|
||||
|
||||
110
.github/workflows/build-mariadb.yml
vendored
110
.github/workflows/build-mariadb.yml
vendored
@@ -1,5 +1,5 @@
|
||||
name: Froxlor-CI-MariaDB
|
||||
on: ['push', 'pull_request', 'create']
|
||||
on: [ 'push', 'pull_request', 'create' ]
|
||||
|
||||
jobs:
|
||||
froxlor:
|
||||
@@ -8,8 +8,8 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.2']
|
||||
mariadb-version: [10.11, 10.5]
|
||||
php-versions: [ '7.4', '8.2' ]
|
||||
mariadb-version: [ 10.11, 10.5 ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -49,33 +49,81 @@ jobs:
|
||||
- name: Run testing
|
||||
run: ant quick-build
|
||||
|
||||
# - name: irc push
|
||||
# uses: rectalogic/notify-irc@v1
|
||||
# if: github.event_name == 'push'
|
||||
# with:
|
||||
# channel: "#froxlor"
|
||||
# server: "irc.libera.chat"
|
||||
# nickname: froxlor-ci
|
||||
# message: |
|
||||
# ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }}
|
||||
# ${{ join(github.event.commits.*.message) }}
|
||||
nightly:
|
||||
name: Create nightly/testing tarball
|
||||
runs-on: ubuntu-latest
|
||||
needs: froxlor
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
|
||||
# - name: irc pull request
|
||||
# uses: rectalogic/notify-irc@v1
|
||||
# if: github.event_name == 'pull_request'
|
||||
# with:
|
||||
# channel: "#froxlor"
|
||||
# server: "irc.libera.chat"
|
||||
# nickname: froxlor-ci
|
||||
# message: |
|
||||
# ${{ github.actor }} opened PR ${{ github.event.pull_request.html_url }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# - name: irc tag created
|
||||
# uses: rectalogic/notify-irc@v1
|
||||
# if: github.event_name == 'create' && github.event.ref_type == 'tag'
|
||||
# with:
|
||||
# channel: "#froxlor"
|
||||
# server: "irc.libera.chat"
|
||||
# nickname: froxlor-ci
|
||||
# message: |
|
||||
# ${{ github.actor }} tagged ${{ github.repository }} ${{ github.event.ref }}
|
||||
- name: Setup PHP with PECL extension
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '7.4'
|
||||
tools: composer:v2
|
||||
extensions: mbstring, xml, ctype, pdo_mysql, mysql, curl, json, zip, session, filter, posix, openssl, fileinfo, bcmath, gmp, gnupg
|
||||
|
||||
- name: Install composer dependencies
|
||||
run: composer install --no-dev
|
||||
|
||||
- name: Install Node.js
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20.x'
|
||||
|
||||
- name: Install npm dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build assets
|
||||
run: npm run build
|
||||
working-directory: .
|
||||
|
||||
- name: Setting file/directory permissions
|
||||
run: |
|
||||
find -exec chmod ugo+r,u+w,go-w {} \;
|
||||
find -type f -exec chmod ugo-x {} \;
|
||||
find -type d -exec chmod ugo+x {} \;
|
||||
chmod 0755 bin/froxlor-cli
|
||||
|
||||
- name: Remove vcs and unneeded files
|
||||
run: |
|
||||
rm .gitignore
|
||||
rm .editorconfig
|
||||
rm -rf node_modules
|
||||
rm composer.json
|
||||
rm composer.lock
|
||||
rm package.json
|
||||
rm package-lock.json
|
||||
rm *.xml
|
||||
rm vite.config.js
|
||||
|
||||
- name: Create empty index.html in built assets directory
|
||||
run: |
|
||||
touch templates/Froxlor/build/index.html
|
||||
touch templates/Froxlor/build/assets/index.html
|
||||
|
||||
- name: Set outputs
|
||||
id: vars
|
||||
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set nightly branding
|
||||
run: |
|
||||
sed -i "s/const BRANDING = '';/const BRANDING = '+nightly.${{steps.vars.outputs.sha_short}}';/" lib/Froxlor/Froxlor.php
|
||||
zip -r froxlor-nightly.${{steps.vars.outputs.sha_short}}.zip . -x "*.git*"
|
||||
sha256sum froxlor-nightly.${{steps.vars.outputs.sha_short}}.zip > froxlor-nightly.${{steps.vars.outputs.sha_short}}.zip.sha256
|
||||
mkdir dist
|
||||
mv froxlor-nightly.${{steps.vars.outputs.sha_short}}.zip dist/
|
||||
mv froxlor-nightly.${{steps.vars.outputs.sha_short}}.zip.sha256 dist/
|
||||
|
||||
- name: Deploy nightly to server
|
||||
uses: easingthemes/ssh-deploy@v3.4.3
|
||||
env:
|
||||
ARGS: "-rltDzvO --chown=${{ secrets.WEB_USER }}:${{ secrets.WEB_USER }}"
|
||||
SOURCE: "dist/"
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }}
|
||||
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
|
||||
REMOTE_USER: ${{ secrets.REMOTE_USER }}
|
||||
TARGET: "${{ secrets.REMOTE_TARGET }}"
|
||||
|
||||
@@ -130,7 +130,8 @@ return [
|
||||
'default' => 'stable',
|
||||
'select_var' => [
|
||||
'stable' => lng('serversettings.uc_stable'),
|
||||
'testing' => lng('serversettings.uc_testing')
|
||||
'testing' => lng('serversettings.uc_testing'),
|
||||
'nightly' => lng('serversettings.uc_nightly')
|
||||
],
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
@@ -171,16 +172,6 @@ return [
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
],
|
||||
'system_index_file_extension' => [
|
||||
'label' => lng('serversettings.index_file_extension'),
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'index_file_extension',
|
||||
'type' => 'text',
|
||||
'string_regexp' => '/^[a-zA-Z0-9]{1,6}$/',
|
||||
'default' => 'html',
|
||||
'save_method' => 'storeSettingField',
|
||||
'advanced_mode' => true
|
||||
],
|
||||
'system_store_index_file_subs' => [
|
||||
'label' => lng('serversettings.system_store_index_file_subs'),
|
||||
'settinggroup' => 'system',
|
||||
|
||||
@@ -60,7 +60,8 @@ if (Settings::Get('panel.sendalternativemail') == 1) {
|
||||
}
|
||||
|
||||
$file_templates = [
|
||||
'index_html'
|
||||
'index_html',
|
||||
'unconfigured_html'
|
||||
];
|
||||
|
||||
$languages = Language::getLanguages();
|
||||
|
||||
@@ -24,20 +24,8 @@
|
||||
* @license https://files.froxlor.org/misc/COPYING.txt GPLv2
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Froxlor\Cli\ConfigDiff;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Froxlor\Cli\RunApiCommand;
|
||||
use Froxlor\Cli\ConfigServices;
|
||||
use Froxlor\Cli\PhpSessionclean;
|
||||
use Froxlor\Cli\SwitchServerIp;
|
||||
use Froxlor\Cli\UpdateCommand;
|
||||
use Froxlor\Cli\InstallCommand;
|
||||
use Froxlor\Cli\MasterCron;
|
||||
use Froxlor\Cli\UserCommand;
|
||||
use Froxlor\Cli\ValidateAcmeWebroot;
|
||||
use Froxlor\Froxlor;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
// validate correct php version
|
||||
if (version_compare("7.4.0", PHP_VERSION, ">=")) {
|
||||
@@ -53,14 +41,31 @@ require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
require dirname(__DIR__) . '/lib/tables.inc.php';
|
||||
|
||||
$application = new Application('froxlor-cli', Froxlor::getFullVersion());
|
||||
$application->add(new RunApiCommand());
|
||||
$application->add(new ConfigServices());
|
||||
$application->add(new PhpSessionclean());
|
||||
$application->add(new SwitchServerIp());
|
||||
$application->add(new UpdateCommand());
|
||||
$application->add(new InstallCommand());
|
||||
$application->add(new MasterCron());
|
||||
$application->add(new UserCommand());
|
||||
$application->add(new ValidateAcmeWebroot());
|
||||
$application->add(new ConfigDiff());
|
||||
|
||||
// files that are no commands
|
||||
$fileIgnoreList = [
|
||||
// Current non-command files
|
||||
'CliCommand.php',
|
||||
'index.html',
|
||||
'install.functions.php',
|
||||
];
|
||||
// directory of commands to include
|
||||
$cmd_files = glob(Froxlor::getInstallDir() . '/lib/Froxlor/Cli/*.php');
|
||||
|
||||
// include and add commands
|
||||
foreach ($cmd_files as $cmdFile) {
|
||||
// check ignore-list
|
||||
if (!in_array(basename($cmdFile), $fileIgnoreList)) {
|
||||
// include class-file
|
||||
require $cmdFile;
|
||||
// create class-name including namespace
|
||||
$cmdClass = "\\Froxlor\\Cli\\" . substr(basename($cmdFile), 0, -4);
|
||||
// check whether it exists
|
||||
if (class_exists($cmdClass) && is_subclass_of($cmdClass, '\Symfony\Component\Console\Command\Command')) {
|
||||
// add to cli application
|
||||
$application->add(new $cmdClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$application->run();
|
||||
|
||||
144
composer.lock
generated
144
composer.lock
generated
@@ -8,16 +8,16 @@
|
||||
"packages": [
|
||||
{
|
||||
"name": "amnuts/opcache-gui",
|
||||
"version": "3.5.2",
|
||||
"version": "3.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/amnuts/opcache-gui.git",
|
||||
"reference": "db9df06889067f99d95bb9f226ec99e663aed196"
|
||||
"reference": "f3a8fe44c0a4c69dd69b9999d68f9097ee362946"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/amnuts/opcache-gui/zipball/db9df06889067f99d95bb9f226ec99e663aed196",
|
||||
"reference": "db9df06889067f99d95bb9f226ec99e663aed196",
|
||||
"url": "https://api.github.com/repos/amnuts/opcache-gui/zipball/f3a8fe44c0a4c69dd69b9999d68f9097ee362946",
|
||||
"reference": "f3a8fe44c0a4c69dd69b9999d68f9097ee362946",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -58,7 +58,7 @@
|
||||
"support": {
|
||||
"email": "andy@amnuts.com",
|
||||
"issues": "https://github.com/amnuts/opcache-gui/issues",
|
||||
"source": "https://github.com/amnuts/opcache-gui/tree/3.5.2"
|
||||
"source": "https://github.com/amnuts/opcache-gui/tree/3.5.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -66,7 +66,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-10-02T10:23:26+00:00"
|
||||
"time": "2023-10-25T19:09:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
@@ -674,16 +674,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.8.1",
|
||||
"version": "v6.9.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "e88da8d679acc3824ff231fdc553565b802ac016"
|
||||
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/e88da8d679acc3824ff231fdc553565b802ac016",
|
||||
"reference": "e88da8d679acc3824ff231fdc553565b802ac016",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/039de174cd9c17a8389754d3b877a2ed22743e18",
|
||||
"reference": "039de174cd9c17a8389754d3b877a2ed22743e18",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -703,6 +703,7 @@
|
||||
"yoast/phpunit-polyfills": "^1.0.4"
|
||||
},
|
||||
"suggest": {
|
||||
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
|
||||
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
|
||||
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
|
||||
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
|
||||
@@ -742,7 +743,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.8.1"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.9.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -750,7 +751,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-08-29T08:26:30+00:00"
|
||||
"time": "2023-11-25T22:23:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
@@ -972,16 +973,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v5.4.28",
|
||||
"version": "v5.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "f4f71842f24c2023b91237c72a365306f3c58827"
|
||||
"reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/f4f71842f24c2023b91237c72a365306f3c58827",
|
||||
"reference": "f4f71842f24c2023b91237c72a365306f3c58827",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/c70df1ffaf23a8d340bded3cfab1b86752ad6ed7",
|
||||
"reference": "c70df1ffaf23a8d340bded3cfab1b86752ad6ed7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1051,7 +1052,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v5.4.28"
|
||||
"source": "https://github.com/symfony/console/tree/v5.4.32"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1067,7 +1068,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-08-07T06:12:30+00:00"
|
||||
"time": "2023-11-18T18:23:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@@ -1872,16 +1873,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v5.4.29",
|
||||
"version": "v5.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "e41bdc93def20eaf3bfc1537c4e0a2b0680a152d"
|
||||
"reference": "91bf4453d65d8231688a04376c3a40efe0770f04"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/e41bdc93def20eaf3bfc1537c4e0a2b0680a152d",
|
||||
"reference": "e41bdc93def20eaf3bfc1537c4e0a2b0680a152d",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/91bf4453d65d8231688a04376c3a40efe0770f04",
|
||||
"reference": "91bf4453d65d8231688a04376c3a40efe0770f04",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1938,7 +1939,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v5.4.29"
|
||||
"source": "https://github.com/symfony/string/tree/v5.4.32"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -1954,30 +1955,31 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-09-13T11:47:41+00:00"
|
||||
"time": "2023-11-26T13:43:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.7.1",
|
||||
"version": "v3.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554"
|
||||
"reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
|
||||
"reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
|
||||
"reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "^1.3"
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php80": "^1.22"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/container": "^1.0|^2.0",
|
||||
"symfony/phpunit-bridge": "^5.4.9|^6.3"
|
||||
"symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -2013,7 +2015,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.7.1"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.8.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2025,7 +2027,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-08-28T11:09:02+00:00"
|
||||
"time": "2023-11-21T18:54:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "voku/anti-xss",
|
||||
@@ -2291,16 +2293,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/pcre.git",
|
||||
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
|
||||
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
|
||||
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9",
|
||||
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2342,7 +2344,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/pcre/issues",
|
||||
"source": "https://github.com/composer/pcre/tree/3.1.0"
|
||||
"source": "https://github.com/composer/pcre/tree/3.1.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2358,7 +2360,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-17T09:50:14+00:00"
|
||||
"time": "2023-10-11T07:11:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
@@ -2613,23 +2615,24 @@
|
||||
},
|
||||
{
|
||||
"name": "pdepend/pdepend",
|
||||
"version": "2.15.1",
|
||||
"version": "2.16.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/pdepend/pdepend.git",
|
||||
"reference": "d12f25bcdfb7754bea458a4a5cb159d55e9950d0"
|
||||
"reference": "8dfc0c46529e2073fa97986552f80646eedac562"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/d12f25bcdfb7754bea458a4a5cb159d55e9950d0",
|
||||
"reference": "d12f25bcdfb7754bea458a4a5cb159d55e9950d0",
|
||||
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/8dfc0c46529e2073fa97986552f80646eedac562",
|
||||
"reference": "8dfc0c46529e2073fa97986552f80646eedac562",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.7",
|
||||
"symfony/config": "^2.3.0|^3|^4|^5|^6.0",
|
||||
"symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0",
|
||||
"symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0"
|
||||
"symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||
"symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||
"symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0",
|
||||
"symfony/polyfill-mbstring": "^1.19"
|
||||
},
|
||||
"require-dev": {
|
||||
"easy-doc/easy-doc": "0.0.0|^1.2.3",
|
||||
@@ -2664,7 +2667,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/pdepend/pdepend/issues",
|
||||
"source": "https://github.com/pdepend/pdepend/tree/2.15.1"
|
||||
"source": "https://github.com/pdepend/pdepend/tree/2.16.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -2672,7 +2675,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-09-28T12:00:56+00:00"
|
||||
"time": "2023-11-29T08:52:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@@ -2906,7 +2909,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"abandoned": true,
|
||||
"time": "2020-12-07T05:51:20+00:00"
|
||||
},
|
||||
{
|
||||
@@ -2995,16 +2997,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpstan",
|
||||
"version": "1.10.38",
|
||||
"version": "1.10.46",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpstan.git",
|
||||
"reference": "5302bb402c57f00fb3c2c015bac86e0827e4b691"
|
||||
"reference": "90d3d25c5b98b8068916bbf08ce42d5cb6c54e70"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/5302bb402c57f00fb3c2c015bac86e0827e4b691",
|
||||
"reference": "5302bb402c57f00fb3c2c015bac86e0827e4b691",
|
||||
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/90d3d25c5b98b8068916bbf08ce42d5cb6c54e70",
|
||||
"reference": "90d3d25c5b98b8068916bbf08ce42d5cb6c54e70",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3053,7 +3055,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-10-06T14:19:14+00:00"
|
||||
"time": "2023-11-28T14:57:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@@ -4562,16 +4564,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/config",
|
||||
"version": "v5.4.26",
|
||||
"version": "v5.4.31",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/config.git",
|
||||
"reference": "8109892f27beed9252bd1f1c1880aeb4ad842650"
|
||||
"reference": "dd5ea39de228813aba0c23c3a4153da2a4cf3cd9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/8109892f27beed9252bd1f1c1880aeb4ad842650",
|
||||
"reference": "8109892f27beed9252bd1f1c1880aeb4ad842650",
|
||||
"url": "https://api.github.com/repos/symfony/config/zipball/dd5ea39de228813aba0c23c3a4153da2a4cf3cd9",
|
||||
"reference": "dd5ea39de228813aba0c23c3a4153da2a4cf3cd9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4621,7 +4623,7 @@
|
||||
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/config/tree/v5.4.26"
|
||||
"source": "https://github.com/symfony/config/tree/v5.4.31"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4637,20 +4639,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-07-19T20:21:11+00:00"
|
||||
"time": "2023-11-09T08:22:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dependency-injection",
|
||||
"version": "v5.4.29",
|
||||
"version": "v5.4.32",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dependency-injection.git",
|
||||
"reference": "338638ed8c9d5c7fcb136a73f5c7043465ae2f05"
|
||||
"reference": "d5d48f215ed73f7973d01256b9a2fac729bef759"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/338638ed8c9d5c7fcb136a73f5c7043465ae2f05",
|
||||
"reference": "338638ed8c9d5c7fcb136a73f5c7043465ae2f05",
|
||||
"url": "https://api.github.com/repos/symfony/dependency-injection/zipball/d5d48f215ed73f7973d01256b9a2fac729bef759",
|
||||
"reference": "d5d48f215ed73f7973d01256b9a2fac729bef759",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4710,7 +4712,7 @@
|
||||
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.29"
|
||||
"source": "https://github.com/symfony/dependency-injection/tree/v5.4.32"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4726,7 +4728,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-09-20T06:23:43+00:00"
|
||||
"time": "2023-11-29T06:58:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
@@ -4873,16 +4875,16 @@
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/theseer/tokenizer.git",
|
||||
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
|
||||
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
|
||||
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
|
||||
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
|
||||
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4911,7 +4913,7 @@
|
||||
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
|
||||
"support": {
|
||||
"issues": "https://github.com/theseer/tokenizer/issues",
|
||||
"source": "https://github.com/theseer/tokenizer/tree/1.2.1"
|
||||
"source": "https://github.com/theseer/tokenizer/tree/1.2.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4919,7 +4921,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-28T10:34:58+00:00"
|
||||
"time": "2023-11-20T00:12:19+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
||||
@@ -72,7 +72,7 @@ if ($page == 'overview' || $page == 'domains') {
|
||||
}
|
||||
|
||||
$actions_links[] = [
|
||||
'href' => 'https://docs.froxlor.org/v2/user-guide/domains/',
|
||||
'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/domains/',
|
||||
'target' => '_blank',
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'class' => 'btn-outline-secondary'
|
||||
|
||||
@@ -76,7 +76,7 @@ if ($page == 'overview' || $page == 'emails') {
|
||||
}
|
||||
|
||||
$actions_links[] = [
|
||||
'href' => 'https://docs.froxlor.org/v2/user-guide/emails/',
|
||||
'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/emails/',
|
||||
'target' => '_blank',
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'class' => 'btn-outline-secondary'
|
||||
@@ -138,7 +138,7 @@ if ($page == 'email_domain') {
|
||||
];
|
||||
}
|
||||
$actions_links[] = [
|
||||
'href' => 'https://docs.froxlor.org/v2/user-guide/emails/',
|
||||
'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/emails/',
|
||||
'target' => '_blank',
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'class' => 'btn-outline-secondary'
|
||||
|
||||
@@ -75,7 +75,7 @@ if ($page == 'overview' || $page == 'htpasswds') {
|
||||
];
|
||||
|
||||
$actions_links[] = [
|
||||
'href' => 'https://docs.froxlor.org/v2/user-guide/extras/',
|
||||
'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/extras/',
|
||||
'target' => '_blank',
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'class' => 'btn-outline-secondary'
|
||||
@@ -200,7 +200,7 @@ if ($page == 'overview' || $page == 'htpasswds') {
|
||||
];
|
||||
|
||||
$actions_links[] = [
|
||||
'href' => 'https://docs.froxlor.org/v2/user-guide/extras/',
|
||||
'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/extras/',
|
||||
'target' => '_blank',
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'class' => 'btn-outline-secondary'
|
||||
@@ -349,7 +349,7 @@ if ($page == 'overview' || $page == 'htpasswds') {
|
||||
|
||||
$actions_links = [
|
||||
[
|
||||
'href' => 'https://docs.froxlor.org/v2/user-guide/extras/',
|
||||
'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/extras/',
|
||||
'target' => '_blank',
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'class' => 'btn-outline-secondary'
|
||||
|
||||
@@ -65,7 +65,7 @@ if ($page == 'overview' || $page == 'accounts') {
|
||||
];
|
||||
}
|
||||
$actions_links[] = [
|
||||
'href' => 'https://docs.froxlor.org/v2/user-guide/ftp-accounts/',
|
||||
'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/ftp-accounts/',
|
||||
'target' => '_blank',
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'class' => 'btn-outline-secondary'
|
||||
|
||||
@@ -75,7 +75,7 @@ if ($page == 'overview' || $page == 'mysqls') {
|
||||
}
|
||||
|
||||
$actions_links[] = [
|
||||
'href' => 'https://docs.froxlor.org/v2/user-guide/databases/',
|
||||
'href' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/databases/',
|
||||
'target' => '_blank',
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'class' => 'btn-outline-secondary'
|
||||
|
||||
@@ -562,7 +562,6 @@ opcache.validate_timestamps'),
|
||||
('system', 'mod_fcgid_wrapper', '1'),
|
||||
('system', 'mod_fcgid_starter', '0'),
|
||||
('system', 'mod_fcgid_peardir', '/usr/share/php/:/usr/share/php5/'),
|
||||
('system', 'index_file_extension', 'html'),
|
||||
('system', 'mod_fcgid_maxrequests', '250'),
|
||||
('system', 'ssl_key_file','/etc/ssl/froxlor_selfsigned.key'),
|
||||
('system', 'ssl_ca_file', ''),
|
||||
@@ -679,7 +678,7 @@ opcache.validate_timestamps'),
|
||||
('system', 'distribution', ''),
|
||||
('system', 'update_channel', 'stable'),
|
||||
('system', 'updatecheck_data', ''),
|
||||
('system', 'update_notify_last', '2.1.0-rc2'),
|
||||
('system', 'update_notify_last', '2.1.0'),
|
||||
('system', 'traffictool', 'goaccess'),
|
||||
('system', 'req_limit_per_interval', 60),
|
||||
('system', 'req_limit_interval', 60),
|
||||
@@ -727,8 +726,8 @@ opcache.validate_timestamps'),
|
||||
('panel', 'logo_overridecustom', '0'),
|
||||
('panel', 'settings_mode', '0'),
|
||||
('panel', 'menu_collapsed', '1'),
|
||||
('panel', 'version', '2.1.0-rc2'),
|
||||
('panel', 'db_version', '202305240');
|
||||
('panel', 'version', '2.1.0-rc3'),
|
||||
('panel', 'db_version', '202312050');
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_tasks`;
|
||||
@@ -751,6 +750,7 @@ CREATE TABLE `panel_templates` (
|
||||
`templategroup` varchar(255) NOT NULL default '',
|
||||
`varname` varchar(255) NOT NULL default '',
|
||||
`value` longtext NOT NULL,
|
||||
`file_extension` varchar(50) NOT NULL default 'html',
|
||||
PRIMARY KEY (id),
|
||||
KEY adminid (adminid)
|
||||
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
@@ -67,15 +67,18 @@ if (Froxlor::isFroxlorVersion('2.0.24')) {
|
||||
}
|
||||
|
||||
Update::showUpdateStep("Adjusting cronjobs");
|
||||
Database::query("
|
||||
$cfupd_stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET
|
||||
`module`= 'froxlor/export',
|
||||
`cronfile` = 'export',
|
||||
`cronclass` = '\\Froxlor\\Cron\\System\\ExportCron',
|
||||
`cronclass` = :cc,
|
||||
`interval` = '1 HOUR',
|
||||
`desc_lng_key` = 'cron_export'
|
||||
WHERE `module` = 'froxlor/backup'
|
||||
");
|
||||
Database::pexecute($cfupd_stmt, [
|
||||
'cc' => '\\Froxlor\\Cron\\System\\ExportCron'
|
||||
]);
|
||||
Update::lastStepStatus(0);
|
||||
|
||||
Update::showUpdateStep("Adjusting system for data-export function");
|
||||
@@ -123,3 +126,85 @@ if (Froxlor::isFroxlorVersion('2.1.0-rc1')) {
|
||||
|
||||
Froxlor::updateToVersion('2.1.0-rc2');
|
||||
}
|
||||
|
||||
if (Froxlor::isDatabaseVersion('202305240')) {
|
||||
|
||||
Update::showUpdateStep("Adjusting file-template file extension setttings");
|
||||
$current_fileextension = Settings::Get('system.index_file_extension');
|
||||
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup`= 'system' AND `varname`= 'index_file_extension'");
|
||||
Database::query("ALTER TABLE `" . TABLE_PANEL_TEMPLATES . "` ADD `file_extension` varchar(50) NOT NULL default 'html';");
|
||||
if (!empty(trim($current_fileextension)) && strtolower(trim($current_fileextension)) != 'html') {
|
||||
$stmt = Database::prepare("UPDATE `" . TABLE_PANEL_TEMPLATES . "` SET `file_extension` = :ext WHERE `templategroup` = 'files'");
|
||||
Database::pexecute($stmt, ['ext' => strtolower(trim($current_fileextension))]);
|
||||
}
|
||||
Update::lastStepStatus(0);
|
||||
|
||||
Froxlor::updateToDbVersion('202311260');
|
||||
}
|
||||
|
||||
if (Froxlor::isFroxlorVersion('2.1.0-rc2')) {
|
||||
Update::showUpdateStep("Updating from 2.1.0-rc2 to 2.1.0-rc3", false);
|
||||
Froxlor::updateToVersion('2.1.0-rc3');
|
||||
}
|
||||
|
||||
if (Froxlor::isDatabaseVersion('202311260')) {
|
||||
Update::showUpdateStep("Cleaning up old files");
|
||||
$to_clean = array(
|
||||
"install/updates/froxlor/update_2.x.inc.php",
|
||||
"install/updates/preconfig/preconfig_2.x.inc.php",
|
||||
"lib/Froxlor/Api/Commands/CustomerBackups.php",
|
||||
"lib/Froxlor/Cli/Action",
|
||||
"lib/Froxlor/Cli/Action.php",
|
||||
"lib/Froxlor/Cli/CmdLineHandler.php",
|
||||
"lib/Froxlor/Cli/ConfigServicesCmd.php",
|
||||
"lib/Froxlor/Cli/PhpSessioncleanCmd.php",
|
||||
"lib/Froxlor/Cli/SwitchServerIpCmd.php",
|
||||
"lib/Froxlor/Cli/UpdateCliCmd.php",
|
||||
"lib/Froxlor/Cron/System/BackupCron.php",
|
||||
"lib/formfields/customer/extras/formfield.backup.php",
|
||||
"lib/tablelisting/customer/tablelisting.backups.php",
|
||||
"templates/Froxlor/assets/mix-manifest.json",
|
||||
"templates/Froxlor/assets/css",
|
||||
"templates/Froxlor/assets/webfonts",
|
||||
"templates/Froxlor/assets/js/main.js",
|
||||
"templates/Froxlor/assets/js/main.js.LICENSE.txt",
|
||||
"templates/Froxlor/src",
|
||||
"templates/Froxlor/user/change_language.html.twig",
|
||||
"templates/Froxlor/user/change_password.html.twig",
|
||||
"templates/Froxlor/user/change_theme.html.twig",
|
||||
"tests/Backup/CustomerBackupsTest.php"
|
||||
);
|
||||
$disabled = explode(',', ini_get('disable_functions'));
|
||||
$exec_allowed = !in_array('exec', $disabled);
|
||||
$del_list = "";
|
||||
foreach ($to_clean as $filedir) {
|
||||
$complete_filedir = Froxlor::getInstallDir() . $filedir;
|
||||
if (file_exists($complete_filedir)) {
|
||||
if ($exec_allowed) {
|
||||
FileDir::safe_exec("rm -rf " . escapeshellarg($complete_filedir));
|
||||
} else {
|
||||
$del_list .= "rm -rf " . escapeshellarg($complete_filedir) . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($exec_allowed) {
|
||||
Update::lastStepStatus(0);
|
||||
} else {
|
||||
if (empty($del_list)) {
|
||||
// none of the files existed
|
||||
Update::lastStepStatus(0);
|
||||
} else {
|
||||
Update::lastStepStatus(
|
||||
1,
|
||||
'manual commands needed',
|
||||
'Please run the following commands manually:<br><pre>' . $del_list . '</pre>'
|
||||
);
|
||||
}
|
||||
}
|
||||
Froxlor::updateToDbVersion('202312050');
|
||||
}
|
||||
|
||||
if (Froxlor::isFroxlorVersion('2.1.0-rc3')) {
|
||||
Update::showUpdateStep("Updating from 2.1.0-rc3 to 2.1.0 stable", false);
|
||||
Froxlor::updateToVersion('2.1.0');
|
||||
}
|
||||
|
||||
@@ -1652,6 +1652,7 @@ class Domains extends ApiCommand implements ResourceEntity
|
||||
|| $iswildcarddomain != $result['iswildcarddomain']
|
||||
|| $phpenabled != $result['phpenabled']
|
||||
|| $openbasedir != $result['openbasedir']
|
||||
|| $openbasedir_path != $result['openbasedir_path']
|
||||
|| $phpsettingid != $result['phpsettingid']
|
||||
|| $mod_fcgid_starter != $result['mod_fcgid_starter']
|
||||
|| $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests']
|
||||
|
||||
@@ -82,7 +82,7 @@ class Froxlor extends ApiCommand
|
||||
if ($aucheck == 1) {
|
||||
// anzeige über version-status mit ggfls. formular
|
||||
// zum update schritt #1 -> download
|
||||
$text = lng('update.uc_newinfo', [(Settings::Get('system.update_channel') == 'testing' ? 'testing ' : ''), AutoUpdate::getFromResult('version'), $this->version]);
|
||||
$text = lng('update.uc_newinfo', [(Settings::Get('system.update_channel') != 'stable' ? Settings::Get('system.update_channel').' ' : ''), AutoUpdate::getFromResult('version'), $this->version]);
|
||||
$response = [
|
||||
'isnewerversion' => (int) !AutoUpdate::getFromResult('has_latest'),
|
||||
'version' => $this->version,
|
||||
@@ -91,7 +91,7 @@ class Froxlor extends ApiCommand
|
||||
'additional_info' => AutoUpdate::getFromResult('info'),
|
||||
'aucheck' => $aucheck
|
||||
];
|
||||
} else if ($aucheck < 0 || $aucheck > 1) {
|
||||
} elseif ($aucheck < 0 || $aucheck > 1) {
|
||||
// errors
|
||||
if ($aucheck < 0) {
|
||||
$errmsg = AutoUpdate::getLastError();
|
||||
|
||||
@@ -100,7 +100,7 @@ final class UpdateCommand extends CliCommand
|
||||
}
|
||||
// there is a new version
|
||||
if ($input->getOption('check-only')) {
|
||||
$text = lng('update.uc_newinfo', [(Settings::Get('system.update_channel') == 'testing' ? 'testing ' : ''), AutoUpdate::getFromResult('version'), Froxlor::VERSION]);
|
||||
$text = lng('update.uc_newinfo', [(Settings::Get('system.update_channel') != 'stable' ? Settings::Get('system.update_channel').' ' : ''), AutoUpdate::getFromResult('version'), Froxlor::VERSION]);
|
||||
} else {
|
||||
$text = lng('admin.newerversionavailable') . ' ' . lng('admin.newerversiondetails', [AutoUpdate::getFromResult('version'), Froxlor::VERSION]);
|
||||
}
|
||||
@@ -175,7 +175,7 @@ final class UpdateCommand extends CliCommand
|
||||
$result = self::SUCCESS;
|
||||
$question = new ConfirmationQuestion('Update database? [no] ', false, '/^(y|j)/i');
|
||||
if ($yestoall || $helper->ask($input, $output, $question)) {
|
||||
$result = $this->updateDatabase();
|
||||
$result = $this->runUpdate($output, true);
|
||||
}
|
||||
} else {
|
||||
$errmsg = 'error.autoupdate_' . $auex;
|
||||
@@ -199,7 +199,7 @@ final class UpdateCommand extends CliCommand
|
||||
if ($input->getOption('mail-notify')) {
|
||||
$last_check_version = Settings::Get('system.update_notify_last');
|
||||
if (Update::versionInUpdate($last_check_version, AutoUpdate::getFromResult('version'))) {
|
||||
$text = lng('update.uc_newinfo', [(Settings::Get('system.update_channel') == 'testing' ? 'testing ' : ''), AutoUpdate::getFromResult('version'), Froxlor::VERSION]);
|
||||
$text = lng('update.uc_newinfo', [(Settings::Get('system.update_channel') != 'stable' ? Settings::Get('system.update_channel').' ' : ''), AutoUpdate::getFromResult('version'), Froxlor::VERSION]);
|
||||
$mail = new Mailer(true);
|
||||
$mail->Body = $text;
|
||||
$mail->Subject = "[froxlor] " . lng('update.notify_subject');
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
namespace Froxlor\Cron\Http\LetsEncrypt;
|
||||
|
||||
use Froxlor\Cron\FroxlorCron;
|
||||
use Froxlor\Cron\TaskId;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\FileDir;
|
||||
@@ -83,7 +84,7 @@ class AcmeSh extends FroxlorCron
|
||||
$renew_domains = self::renewDomains(true);
|
||||
if ($issue_froxlor || !empty($issue_domains) || !empty($renew_froxlor) || $renew_domains) {
|
||||
// insert task to generate certificates and vhost-configs
|
||||
Cronjob::inserttask(1);
|
||||
Cronjob::inserttask(TaskId::REBUILD_VHOST);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -203,7 +204,7 @@ class AcmeSh extends FroxlorCron
|
||||
// This is easiest done by just creating a new task ;)
|
||||
if ($changedetected) {
|
||||
if (self::$no_inserttask == false) {
|
||||
Cronjob::inserttask(1);
|
||||
Cronjob::inserttask(TaskId::REBUILD_VHOST);
|
||||
}
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Let's Encrypt certificates have been updated");
|
||||
} else {
|
||||
|
||||
@@ -257,6 +257,41 @@ class FileDir
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read unconfigured-domain template from database if exists or fallback to default
|
||||
*
|
||||
* @param string $servername
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function getUnknownDomainTemplate(string $servername = "")
|
||||
{
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_TEMPLATES . "` WHERE `templategroup` = 'files' AND `varname` = 'unconfigured_html'
|
||||
");
|
||||
Database::pexecute($result_stmt);
|
||||
if (Database::num_rows() > 0) {
|
||||
$template = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$replace_arr = [
|
||||
'SERVERNAME' => $servername,
|
||||
];
|
||||
$tpl_content = PhpHelper::replaceVariables($template['value'], $replace_arr);
|
||||
$tpl_ext = $template['file_extension'];
|
||||
} else {
|
||||
$tpl_ext = 'html';
|
||||
$unconfiguredPath = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/templates/misc/unconfigured/index.html');
|
||||
if (file_exists($unconfiguredPath)) {
|
||||
$tpl_content = file_get_contents($unconfiguredPath);
|
||||
} else {
|
||||
$tpl_content = lng('admin.templates.unconfigured_content_fallback');
|
||||
}
|
||||
}
|
||||
$redirect_file = FileDir::makeCorrectFile(Froxlor::getInstallDir().'/notice.'.$tpl_ext);
|
||||
file_put_contents($redirect_file, $tpl_content);
|
||||
return basename($redirect_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* store the default index-file in a given destination folder
|
||||
*
|
||||
@@ -277,7 +312,7 @@ class FileDir
|
||||
{
|
||||
if ($force || (int)Settings::Get('system.store_index_file_subs') == 1) {
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `t`.`value`, `c`.`email` AS `customer_email`, `a`.`email` AS `admin_email`, `c`.`loginname` AS `customer_login`, `a`.`loginname` AS `admin_login`
|
||||
SELECT `t`.`value`, `t`.`file_extension`, `c`.`email` AS `customer_email`, `a`.`email` AS `admin_email`, `c`.`loginname` AS `customer_login`, `a`.`loginname` AS `admin_login`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` AS `c` INNER JOIN `" . TABLE_PANEL_ADMINS . "` AS `a`
|
||||
ON `c`.`adminid` = `a`.`adminid`
|
||||
INNER JOIN `" . TABLE_PANEL_TEMPLATES . "` AS `t`
|
||||
@@ -300,7 +335,7 @@ class FileDir
|
||||
|
||||
// replaceVariables
|
||||
$htmlcontent = PhpHelper::replaceVariables($template['value'], $replace_arr);
|
||||
$indexhtmlpath = self::makeCorrectFile($destination . '/index.' . Settings::Get('system.index_file_extension'));
|
||||
$indexhtmlpath = self::makeCorrectFile($destination . '/index.' . $template['file_extension']);
|
||||
$index_html_handler = fopen($indexhtmlpath, 'w');
|
||||
fwrite($index_html_handler, $htmlcontent);
|
||||
fclose($index_html_handler);
|
||||
@@ -308,7 +343,7 @@ class FileDir
|
||||
$logger->logAction(
|
||||
FroxlorLogger::CRON_ACTION,
|
||||
LOG_NOTICE,
|
||||
'Creating \'index.' . Settings::Get('system.index_file_extension') . '\' for Customer \'' . $template['customer_login'] . '\' based on template in directory ' . escapeshellarg($indexhtmlpath)
|
||||
'Creating \'index.' . $template['file_extension'] . '\' for Customer \'' . $template['customer_login'] . '\' based on template in directory ' . escapeshellarg($indexhtmlpath)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -31,14 +31,16 @@ final class Froxlor
|
||||
{
|
||||
|
||||
// Main version variable
|
||||
const VERSION = '2.1.0-rc2';
|
||||
const VERSION = '2.1.0';
|
||||
|
||||
// Database version (YYYYMMDDC where C is a daily counter)
|
||||
const DBVERSION = '202305240';
|
||||
const DBVERSION = '202312050';
|
||||
|
||||
// Distribution branding-tag (used for Debian etc.)
|
||||
const BRANDING = '';
|
||||
|
||||
const DOCS_URL = 'https://docs.froxlor.org/v2.1/';
|
||||
|
||||
/**
|
||||
* return path to where froxlor is installed, e.g.
|
||||
* /var/www/froxlor/
|
||||
|
||||
@@ -104,17 +104,15 @@ class FroxlorLogger
|
||||
self::$ml->pushHandler(new SyslogHandler('froxlor', LOG_USER, Logger::DEBUG));
|
||||
break;
|
||||
case 'file':
|
||||
$setings_logfile = Settings::Get('logger.logfile');
|
||||
if (empty($setings_logfile)) {
|
||||
Settings::Set('logger.logfile', 'froxlor.log');
|
||||
}
|
||||
$logger_logfile = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/logs/' . Settings::Get('logger.logfile'));
|
||||
// is_writable needs an existing file to check if it's actually writable
|
||||
@touch($logger_logfile);
|
||||
if (empty($logger_logfile) || !is_writable($logger_logfile)) {
|
||||
Settings::Set('logger.logfile', 'froxlor.log');
|
||||
$logger_logfile = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/logs/froxlor.log');
|
||||
@touch($logger_logfile);
|
||||
if (empty($logger_logfile) || !is_writable($logger_logfile)) {
|
||||
// not writable in our own directory? Skip
|
||||
break;
|
||||
}
|
||||
if (!@touch($logger_logfile) || !is_writable($logger_logfile)) {
|
||||
// not writable in our own directory? Skip
|
||||
break;
|
||||
}
|
||||
self::$ml->pushHandler(new StreamHandler($logger_logfile, Logger::DEBUG));
|
||||
break;
|
||||
|
||||
@@ -68,6 +68,12 @@ class AutoUpdate
|
||||
$channel = '';
|
||||
if (Settings::Get('system.update_channel') == 'testing') {
|
||||
$channel = '/testing';
|
||||
} elseif (Settings::Get('system.update_channel') == 'nightly') {
|
||||
if (empty(Froxlor::BRANDING)) {
|
||||
$channel = '/nightly.0000000';
|
||||
} else {
|
||||
$channel = '/' . substr(Froxlor::BRANDING, 1);
|
||||
}
|
||||
}
|
||||
$latestversion = HttpClient::urlGet(self::UPDATE_URI . Froxlor::VERSION . $channel, true, 3);
|
||||
} catch (Exception $e) {
|
||||
@@ -81,7 +87,7 @@ class AutoUpdate
|
||||
if (!empty(self::$latestversion['error']) && self::$latestversion['error']) {
|
||||
$result = -1;
|
||||
self::$lasterror = self::$latestversion['message'];
|
||||
} else if (isset(self::$latestversion['has_latest']) && self::$latestversion['has_latest'] == false) {
|
||||
} elseif (isset(self::$latestversion['has_latest']) && self::$latestversion['has_latest'] == false) {
|
||||
$result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +26,14 @@
|
||||
namespace Froxlor\Install;
|
||||
|
||||
use Exception;
|
||||
use PDO;
|
||||
use Froxlor\Config\ConfigParser;
|
||||
use Froxlor\Froxlor;
|
||||
use Froxlor\Install\Install\Core;
|
||||
use Froxlor\System\IPTools;
|
||||
use Froxlor\UI\Panel\UI;
|
||||
use Froxlor\UI\Request;
|
||||
use Froxlor\Config\ConfigParser;
|
||||
use Froxlor\Validate\Validate;
|
||||
use Froxlor\System\IPTools;
|
||||
use PDO;
|
||||
|
||||
class Install
|
||||
{
|
||||
@@ -41,34 +42,37 @@ class Install
|
||||
public $maxSteps;
|
||||
public $phpVersion;
|
||||
public $formfield;
|
||||
public string $requiredVersion = '7.4.0';
|
||||
public array $requiredExtensions = ['session', 'ctype', 'xml', 'filter', 'posix', 'mbstring', 'curl', 'gmp', 'json', 'gd'];
|
||||
public array $suggestedExtensions = ['bcmath', 'zip', 'gnupg'];
|
||||
public array $suggestions = [];
|
||||
public array $criticals = [];
|
||||
public array $loadedExtensions;
|
||||
public array $supportedOS = [];
|
||||
public array $webserverBackend = [
|
||||
'php-fpm' => 'PHP-FPM',
|
||||
'fcgid' => 'FCGID',
|
||||
'fcgid' => 'FCGID (apache2 only)',
|
||||
'mod_php' => 'mod_php (not recommended)',
|
||||
];
|
||||
|
||||
public function __construct(array $cliData = [])
|
||||
{
|
||||
// set actual php version and extensions
|
||||
$this->phpVersion = phpversion();
|
||||
$this->loadedExtensions = get_loaded_extensions();
|
||||
|
||||
// get all supported OS
|
||||
// show list of available distro's
|
||||
$distros = glob(dirname(__DIR__, 3) . '/lib/configfiles/*.xml');
|
||||
$distributions_select[''] = '-';
|
||||
// read in all the distros
|
||||
foreach ($distros as $distribution) {
|
||||
// get configparser object
|
||||
$dist = new ConfigParser($distribution);
|
||||
// store in tmp array
|
||||
$this->supportedOS[str_replace(".xml", "", strtolower(basename($distribution)))] = $dist->getCompleteDistroName();
|
||||
if (in_array('xml', $this->loadedExtensions)) {
|
||||
// read in all the distros
|
||||
foreach ($distros as $distribution) {
|
||||
// get configparser object
|
||||
$dist = new ConfigParser($distribution);
|
||||
// store in tmp array
|
||||
$this->supportedOS[str_replace(".xml", "", strtolower(basename($distribution)))] = $dist->getCompleteDistroName();
|
||||
}
|
||||
// sort by distribution name
|
||||
asort($this->supportedOS);
|
||||
}
|
||||
// sort by distribution name
|
||||
asort($this->supportedOS);
|
||||
|
||||
// guess distribution and webserver to preselect in formfield
|
||||
$webserverBackend = $this->webserverBackend;
|
||||
@@ -84,10 +88,6 @@ class Install
|
||||
$this->extendedView = $cliData['extended'] ?? Request::any('extended', 0);
|
||||
$this->maxSteps = count($this->formfield['install']['sections']);
|
||||
|
||||
// set actual php version and extensions
|
||||
$this->phpVersion = phpversion();
|
||||
$this->loadedExtensions = get_loaded_extensions();
|
||||
|
||||
if (empty($cliData)) {
|
||||
// set global variables
|
||||
UI::twig()->addGlobal('install_mode', true);
|
||||
@@ -99,7 +99,7 @@ class Install
|
||||
}
|
||||
|
||||
// check for url manipulation or wrong step
|
||||
if ((isset($_SESSION['installation']['stepCompleted']) && ($this->currentStep + 1) > ($_SESSION['installation']['stepCompleted'] ?? 0))
|
||||
if ((isset($_SESSION['installation']['stepCompleted']) && ($this->currentStep + 1) > $_SESSION['installation']['stepCompleted'])
|
||||
|| (!isset($_SESSION['installation']['stepCompleted']) && $this->currentStep > 0)
|
||||
) {
|
||||
$this->currentStep = isset($_SESSION['installation']['stepCompleted']) ? $_SESSION['installation']['stepCompleted'] + 1 : 1;
|
||||
@@ -136,6 +136,7 @@ class Install
|
||||
'section' => $this->formfield['install']['sections']['step' . $this->currentStep] ?? [],
|
||||
'error' => $error ?? null,
|
||||
'extended' => $this->extendedView,
|
||||
'csrf_token' => Froxlor::genSessionId(20),
|
||||
]);
|
||||
|
||||
// output view
|
||||
@@ -151,16 +152,14 @@ class Install
|
||||
if ($this->currentStep <= $this->maxSteps) {
|
||||
// Validate user data
|
||||
$validatedData = $this->validateRequest($formfield['sections']['step' . $this->currentStep]['fields']);
|
||||
// Check database connection (
|
||||
if ($this->currentStep == 1) {
|
||||
// Check database connection
|
||||
$this->checkDatabase($validatedData);
|
||||
}
|
||||
// Check validity of admin user data
|
||||
elseif ($this->currentStep == 2) {
|
||||
} elseif ($this->currentStep == 2) {
|
||||
// Check validity of admin user data
|
||||
$this->checkAdminUser($validatedData);
|
||||
}
|
||||
// Check validity of system data
|
||||
elseif ($this->currentStep == 3) {
|
||||
} elseif ($this->currentStep == 3) {
|
||||
// Check validity of system data
|
||||
$this->checkSystem($validatedData);
|
||||
}
|
||||
$validatedData['stepCompleted'] = ($this->currentStep < $this->maxSteps) ? $this->currentStep : ($this->maxSteps - 1);
|
||||
@@ -192,7 +191,7 @@ class Install
|
||||
private function checkInstallStateFinished(): bool
|
||||
{
|
||||
$core = new Core($_SESSION['installation']);
|
||||
if (isset($_SESSION['installation']['manual_config']) && (int) $_SESSION['installation']['manual_config'] == 1) {
|
||||
if (isset($_SESSION['installation']['manual_config']) && (int)$_SESSION['installation']['manual_config'] == 1) {
|
||||
$core->createUserdataConf();
|
||||
return true;
|
||||
}
|
||||
@@ -200,7 +199,7 @@ class Install
|
||||
$stmt = $pdo->prepare("SELECT `value` FROM `panel_settings` WHERE `settinggroup` = 'panel' AND `varname` = 'is_configured'");
|
||||
$stmt->execute();
|
||||
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($result && (int) $result['value'] == 1) {
|
||||
if ($result && (int)$result['value'] == 1) {
|
||||
$core->createUserdataConf();
|
||||
return true;
|
||||
}
|
||||
@@ -223,7 +222,7 @@ class Install
|
||||
}
|
||||
|
||||
// check for required extensions
|
||||
foreach ($this->requiredExtensions as $requiredExtension) {
|
||||
foreach (Requirements::REQUIRED_EXTENSIONS as $requiredExtension) {
|
||||
if (in_array($requiredExtension, $this->loadedExtensions)) {
|
||||
continue;
|
||||
}
|
||||
@@ -231,7 +230,7 @@ class Install
|
||||
}
|
||||
|
||||
// check for suggested extensions
|
||||
foreach ($this->suggestedExtensions as $suggestedExtension) {
|
||||
foreach (Requirements::SUGGESTED_EXTENSIONS as $suggestedExtension) {
|
||||
if (in_array($suggestedExtension, $this->loadedExtensions)) {
|
||||
continue;
|
||||
}
|
||||
@@ -250,11 +249,11 @@ class Install
|
||||
*/
|
||||
private function getInformationText(): string
|
||||
{
|
||||
if (version_compare($this->requiredVersion, PHP_VERSION, "<")) {
|
||||
if (version_compare(Requirements::REQUIRED_VERSION, PHP_VERSION, "<")) {
|
||||
$text = lng('install.phpinfosuccess', [$this->phpVersion]);
|
||||
} else {
|
||||
$text = lng('install.phpinfowarn', [$this->requiredVersion]);
|
||||
$this->criticals[] = lng('install.phpinfoupdate', [$this->phpVersion, $this->requiredVersion]);
|
||||
$text = lng('install.phpinfowarn', [Requirements::REQUIRED_VERSION]);
|
||||
$this->criticals[] = lng('install.phpinfoupdate', [$this->phpVersion, Requirements::REQUIRED_VERSION]);
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
@@ -302,7 +301,7 @@ class Install
|
||||
throw new Exception(lng('install.errors.nov4andnov6ip'));
|
||||
} elseif (!empty($serveripv4) && (!Validate::validate_ip2($serveripv4, true, '', false, true) || IPTools::is_ipv6($serveripv4))) {
|
||||
throw new Exception(lng('error.invalidip', [$serveripv4]));
|
||||
} elseif (!empty($serveripv6) && (!Validate::validate_ip2($serveripv6, true, '', false, true) || IPTools::is_ipv6($serveripv6) == false)) {
|
||||
} elseif (!empty($serveripv6) && (!Validate::validate_ip2($serveripv6, true, '', false, true) || !IPTools::is_ipv6($serveripv6))) {
|
||||
throw new Exception(lng('error.invalidip', [$serveripv6]));
|
||||
} elseif (!Validate::validateDomain($servername)) {
|
||||
throw new Exception(lng('install.errors.servernameneedstobevalid'));
|
||||
@@ -410,7 +409,7 @@ class Install
|
||||
} else {
|
||||
$osrf = explode("\n", file_get_contents('/etc/os-release'));
|
||||
foreach ($osrf as $line) {
|
||||
$osrfline = explode("\n", $line);
|
||||
$osrfline = explode("=", $line);
|
||||
if ($osrfline[0] == 'VERSION_CODENAME') {
|
||||
$os_dist['VERSION_CODENAME'] = $osrfline[1];
|
||||
} else if ($osrfline[0] == 'ID') {
|
||||
|
||||
10
lib/Froxlor/Install/Requirements.php
Normal file
10
lib/Froxlor/Install/Requirements.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Install;
|
||||
|
||||
class Requirements
|
||||
{
|
||||
const REQUIRED_VERSION = '7.4.0';
|
||||
const REQUIRED_EXTENSIONS = ['session', 'ctype', 'xml', 'filter', 'posix', 'mbstring', 'pdo_mysql', 'curl', 'gmp', 'json', 'gd'];
|
||||
const SUGGESTED_EXTENSIONS = ['bcmath', 'zip', 'gnupg'];
|
||||
}
|
||||
@@ -321,6 +321,10 @@ class UI
|
||||
}
|
||||
}
|
||||
}
|
||||
// check for template-variant
|
||||
if (preg_match("/([a-z0-9.\-]+)_([a-z0-9.\-]+)/i", $theme, $matches)) {
|
||||
$theme = $matches[1];
|
||||
}
|
||||
if (!file_exists(Froxlor::getInstallDir() . '/templates/' . $theme)) {
|
||||
PhpHelper::phpErrHandler(E_USER_WARNING, "Theme '" . $theme . "' could not be found.", __FILE__, __LINE__);
|
||||
$theme = self::$default_theme;
|
||||
|
||||
@@ -35,6 +35,11 @@ class Data
|
||||
return self::validateFormFieldString($fieldname, $fielddata, $newfieldvalue);
|
||||
}
|
||||
|
||||
public static function validateFormFieldPassword($fieldname, $fielddata, $newfieldvalue)
|
||||
{
|
||||
return self::validateFormFieldString($fieldname, $fielddata, $newfieldvalue);
|
||||
}
|
||||
|
||||
public static function validateFormFieldString($fieldname, $fielddata, $newfieldvalue)
|
||||
{
|
||||
if (isset($fielddata['string_delimiter']) && $fielddata['string_delimiter'] != '') {
|
||||
@@ -210,75 +215,6 @@ class Data
|
||||
}
|
||||
}
|
||||
|
||||
public static function validateFormFieldHiddenString($fieldname, $fielddata, $newfieldvalue)
|
||||
{
|
||||
if (isset($fielddata['string_delimiter']) && $fielddata['string_delimiter'] != '') {
|
||||
$newfieldvalues = explode($fielddata['string_delimiter'], $newfieldvalue);
|
||||
unset($fielddata['string_delimiter']);
|
||||
|
||||
$returnvalue = true;
|
||||
foreach ($newfieldvalues as $single_newfieldvalue) {
|
||||
/**
|
||||
* don't use tabs in value-fields, #81
|
||||
*/
|
||||
$single_newfieldvalue = str_replace("\t", " ", $single_newfieldvalue);
|
||||
$single_returnvalue = Data::validateFormFieldString($fieldname, $fielddata, $single_newfieldvalue);
|
||||
if ($single_returnvalue !== true) {
|
||||
$returnvalue = $single_returnvalue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$returnvalue = false;
|
||||
|
||||
/**
|
||||
* don't use tabs in value-fields, #81
|
||||
*/
|
||||
$newfieldvalue = str_replace("\t", " ", $newfieldvalue);
|
||||
|
||||
if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') {
|
||||
$returnvalue = Validate::validateEmail($newfieldvalue);
|
||||
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') {
|
||||
$returnvalue = Validate::validateUrl($newfieldvalue);
|
||||
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') {
|
||||
// add trailing slash to validate path if needed
|
||||
// refs #331
|
||||
if (substr($newfieldvalue, -1) != '/') {
|
||||
$newfieldvalue .= '/';
|
||||
}
|
||||
$returnvalue = ($newfieldvalue == FileDir::makeCorrectDir($newfieldvalue));
|
||||
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'file') {
|
||||
$returnvalue = ($newfieldvalue == FileDir::makeCorrectFile($newfieldvalue));
|
||||
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'filedir') {
|
||||
$returnvalue = (($newfieldvalue == FileDir::makeCorrectDir($newfieldvalue)) || ($newfieldvalue == FileDir::makeCorrectFile($newfieldvalue)));
|
||||
} elseif (preg_match('/^[^\r\n\t\f\0]*$/D', $newfieldvalue)) {
|
||||
$returnvalue = true;
|
||||
}
|
||||
|
||||
if (isset($fielddata['string_regexp']) && $fielddata['string_regexp'] != '') {
|
||||
if (preg_match($fielddata['string_regexp'], $newfieldvalue)) {
|
||||
$returnvalue = true;
|
||||
} else {
|
||||
$returnvalue = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($fielddata['string_emptyallowed']) && $fielddata['string_emptyallowed'] === true && $newfieldvalue === '') {
|
||||
$returnvalue = true;
|
||||
} elseif (isset($fielddata['string_emptyallowed']) && $fielddata['string_emptyallowed'] === false && $newfieldvalue === '') {
|
||||
$returnvalue = 'stringmustntbeempty';
|
||||
}
|
||||
}
|
||||
|
||||
if ($returnvalue === true) {
|
||||
return true;
|
||||
} elseif ($returnvalue === false) {
|
||||
return 'stringformaterror';
|
||||
} else {
|
||||
return $returnvalue;
|
||||
}
|
||||
}
|
||||
|
||||
public static function validateFormFieldNumber($fieldname, $fielddata, $newfieldvalue)
|
||||
{
|
||||
if (isset($fielddata['min']) && (int)$newfieldvalue < (int)$fielddata['min']) {
|
||||
@@ -323,10 +259,16 @@ class Data
|
||||
if (preg_match($fielddata['string_regexp'], $newfieldvalue)) {
|
||||
$returnvalue = true;
|
||||
}
|
||||
} else if (preg_match('/^[^\0]*$/', $newfieldvalue)) {
|
||||
} elseif (preg_match('/^[^\0]*$/', $newfieldvalue)) {
|
||||
$returnvalue = true;
|
||||
}
|
||||
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
public static function validateFormFieldImage($fieldname, $fielddata, $newfieldvalue)
|
||||
{
|
||||
// validation is handled in \Froxlor\Settings\Store::storeSettingImage()
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3383,6 +3383,11 @@ aliases: files
|
||||
</visibility>
|
||||
<command><![CDATA[a2dismod php8.2]]></command>
|
||||
</commands>
|
||||
<commands index="5">
|
||||
<visibility mode="equals" value="apache2">{{settings.system.webserver}}
|
||||
</visibility>
|
||||
<command><![CDATA[a2disconf php8.2-fpm]]></command>
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
|
||||
@@ -4172,6 +4172,11 @@ aliases: files
|
||||
</visibility>
|
||||
<command><![CDATA[a2dismod php8.1]]></command>
|
||||
</commands>
|
||||
<commands index="5">
|
||||
<visibility mode="equals" value="apache2">{{settings.system.webserver}}
|
||||
</visibility>
|
||||
<command><![CDATA[a2disconf php8.1-fpm]]></command>
|
||||
</commands>
|
||||
<!-- instead of just restarting apache, we let the cronjob do all the
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}bin/froxlor-cli froxlor:cron --force]]></command>
|
||||
|
||||
@@ -38,11 +38,20 @@ return [
|
||||
'type' => 'select',
|
||||
'select_var' => $free_templates
|
||||
],
|
||||
'file_extension' => [
|
||||
'label' => lng('admin.templates.file_extension'),
|
||||
'type' => 'text',
|
||||
'string_regexp' => '/^[a-zA-Z0-9]{1,6}$/',
|
||||
'default' => 'html',
|
||||
'value' => 'html',
|
||||
'mandatory' => true
|
||||
],
|
||||
'filecontent' => [
|
||||
'label' => lng('admin.templates.filecontent'),
|
||||
'type' => 'textarea',
|
||||
'cols' => 60,
|
||||
'rows' => 12
|
||||
'rows' => 12,
|
||||
'mandatory' => true
|
||||
],
|
||||
'filesend' => [
|
||||
'type' => 'hidden',
|
||||
|
||||
@@ -39,12 +39,21 @@ return [
|
||||
'value' => lng('admin.templates.' . $row['varname']),
|
||||
'display' => lng('admin.templates.' . $row['varname'])
|
||||
],
|
||||
'file_extension' => [
|
||||
'label' => lng('admin.templates.file_extension'),
|
||||
'type' => 'text',
|
||||
'string_regexp' => '/^[a-zA-Z0-9]{1,6}$/',
|
||||
'value' => $row['file_extension'],
|
||||
'default' => 'html',
|
||||
'mandatory' => true
|
||||
],
|
||||
'filecontent' => [
|
||||
'label' => lng('admin.templates.filecontent'),
|
||||
'type' => 'textarea',
|
||||
'cols' => 60,
|
||||
'rows' => 12,
|
||||
'value' => $row['value']
|
||||
'value' => $row['value'],
|
||||
'mandatory' => true
|
||||
],
|
||||
'filesend' => [
|
||||
'type' => 'hidden',
|
||||
|
||||
37
lib/init.php
37
lib/init.php
@@ -65,6 +65,7 @@ use Froxlor\UI\Linker;
|
||||
use Froxlor\UI\Panel\UI;
|
||||
use Froxlor\UI\Request;
|
||||
use Froxlor\UI\Response;
|
||||
use Froxlor\Install\Requirements;
|
||||
|
||||
// include MySQL-tabledefinitions
|
||||
require Froxlor::getInstallDir() . '/lib/tables.inc.php';
|
||||
@@ -114,18 +115,34 @@ if (!isset($sql) || !is_array($sql)) {
|
||||
/**
|
||||
* Show nice note if requested domain is "unknown" to froxlor and thus is being lead to its vhost
|
||||
*/
|
||||
if ($_SERVER['SERVER_NAME'] != Settings::Get('system.hostname') &&
|
||||
!filter_var($_SERVER['SERVER_NAME'], FILTER_VALIDATE_IP) && (
|
||||
$req_host = UI::getCookieHost();
|
||||
if ($req_host != Settings::Get('system.hostname') &&
|
||||
Settings::Get('panel.is_configured') == 1 &&
|
||||
!filter_var($req_host, FILTER_VALIDATE_IP) && (
|
||||
empty(Settings::Get('system.froxloraliases')) ||
|
||||
(!empty(Settings::Get('system.froxloraliases')) && !in_array($_SERVER['SERVER_NAME'], array_map('trim', explode(',', Settings::Get('system.froxloraliases')))))
|
||||
(!empty(Settings::Get('system.froxloraliases')) && !in_array($req_host, array_map('trim', explode(',', Settings::Get('system.froxloraliases')))))
|
||||
)) {
|
||||
// not the froxlor system-hostname, show info page for domains not configured in froxlor
|
||||
$unconfiguredPath = FileDir::makeCorrectFile(Froxlor::getInstallDir() . '/templates/misc/unconfigured/index.html');
|
||||
if (file_exists($unconfiguredPath)) {
|
||||
echo file_get_contents($unconfiguredPath);
|
||||
} else {
|
||||
echo "This domain requires configuration via the froxlor server management panel, as it is currently not assigned to any customer.";
|
||||
$redirect_file = FileDir::getUnknownDomainTemplate($req_host);
|
||||
header('Location: '.$redirect_file);
|
||||
die();
|
||||
}
|
||||
|
||||
// validate php-extensions requirements
|
||||
$loadedExtensions = get_loaded_extensions();
|
||||
$missingExtensions = [];
|
||||
foreach (Requirements::REQUIRED_EXTENSIONS as $requiredExtension) {
|
||||
if (in_array($requiredExtension, $loadedExtensions)) {
|
||||
continue;
|
||||
}
|
||||
$missingExtensions[] = $requiredExtension;
|
||||
}
|
||||
if (!empty($missingExtensions)) {
|
||||
UI::twig()->addGlobal('install_mode', '1');
|
||||
echo UI::twig()->render($_deftheme . '/misc/missingextensionhint.html.twig', [
|
||||
'phpversion' => phpversion(),
|
||||
'missing_extensions' => implode(", ", $missingExtensions),
|
||||
]);
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -187,7 +204,7 @@ if (Update::versionInUpdate(Settings::Get('panel.version'), '2.0.0-beta1')) {
|
||||
|
||||
// Check if a different variant of the theme is used
|
||||
$themevariant = "default";
|
||||
if (preg_match("/([a-z0-9\.\-]+)_([a-z0-9\.\-]+)/i", $theme, $matches)) {
|
||||
if (preg_match("/([a-z0-9.\-]+)_([a-z0-9.\-]+)/i", $theme, $matches)) {
|
||||
$theme = $matches[1];
|
||||
$themevariant = $matches[2];
|
||||
}
|
||||
@@ -360,4 +377,6 @@ if (CurrentUser::hasSession()) {
|
||||
'samesite' => 'Strict'
|
||||
];
|
||||
setcookie(session_name(), $_COOKIE[session_name()], $cookie_params);
|
||||
} else {
|
||||
UI::twig()->addGlobal('csrf_token', Froxlor::genSessionId(20));
|
||||
}
|
||||
|
||||
@@ -161,13 +161,13 @@ return [
|
||||
'show_element' => (!Settings::IsInList('panel.customer_hide_options', 'misc.documentation')),
|
||||
'elements' => [
|
||||
[
|
||||
'url' => 'https://docs.froxlor.org/v2/user-guide/',
|
||||
'url' => \Froxlor\Froxlor::DOCS_URL . 'user-guide/',
|
||||
'label' => lng('admin.userguide'),
|
||||
'new_window' => true,
|
||||
'is_external' => true,
|
||||
],
|
||||
[
|
||||
'url' => 'https://docs.froxlor.org/v2/api-guide/',
|
||||
'url' => \Froxlor\Froxlor::DOCS_URL . 'api-guide/',
|
||||
'label' => lng('admin.apiguide'),
|
||||
'new_window' => true,
|
||||
'show_element' => Settings::Get('api.enabled') == 1 && CurrentUser::getField('api_allowed') == 1,
|
||||
@@ -348,13 +348,13 @@ return [
|
||||
'icon' => 'fa-solid fa-circle-info',
|
||||
'elements' => [
|
||||
[
|
||||
'url' => 'https://docs.froxlor.org/v2/admin-guide/',
|
||||
'url' => \Froxlor\Froxlor::DOCS_URL . 'admin-guide/',
|
||||
'label' => lng('admin.adminguide'),
|
||||
'new_window' => true,
|
||||
'is_external' => true,
|
||||
],
|
||||
[
|
||||
'url' => 'https://docs.froxlor.org/v2/api-guide/',
|
||||
'url' => \Froxlor\Froxlor::DOCS_URL . 'api-guide/',
|
||||
'label' => lng('admin.apiguide'),
|
||||
'new_window' => true,
|
||||
'show_element' => Settings::Get('api.enabled') == 1,
|
||||
|
||||
@@ -140,12 +140,18 @@ return [
|
||||
'TRAFFICUSED' => 'Wird mit Traffic, der vom Kunden bereits verbraucht wurde, ersetzt.',
|
||||
'pop_success_alternative' => 'Willkommensmail für neue E-Mail-Konten für die alternative E-Mail-Adresse',
|
||||
'EMAIL_PASSWORD' => 'Wird mit dem Passwort des neuen POP3/IMAP Kontos ersetzt.',
|
||||
'index_html' => 'index.html Datei für neu erzeugte Kundenverzeichnisse',
|
||||
'index_html' => 'index Datei für neu erzeugte Kundenverzeichnisse',
|
||||
'unconfigured_html' => 'index Datei für unkonfigurierte/unbekannte Domains',
|
||||
'unconfigured_content_fallback' => 'Diese Domain muss über das Froxlor-Serververwaltungspanel konfiguriert werden, da sie derzeit keinem Kunden zugewiesen ist.',
|
||||
'file_extension' => [
|
||||
'description' => 'Die Dateiendung für die index Datei muss zwischen 1 und 6 Zeichen lang sein und darf nur aus den Zeichen a-z, A-Z und 0-9 bestehen<br><br>Standard: html',
|
||||
'title' => 'Dateiendung für Datei Vorlage',
|
||||
],
|
||||
'SERVERNAME' => 'Wird mit dem Servernamen ersetzt.',
|
||||
'CUSTOMER' => 'Wird mit dem Loginnamen des Kunden ersetzt.',
|
||||
'ADMIN' => 'Wird mit dem Loginnamen des Admins ersetzt.',
|
||||
'CUSTOMER_EMAIL' => 'Wird mit der E-Mail-Adresse des Kunden ersetzt.',
|
||||
'ADMIN_EMAIL' => 'Wird mit der E-Mail-Adresse des Admin ersetzt.',
|
||||
'CUSTOMER' => 'Wird mit dem Loginnamen des Kunden ersetzt. Nur für "index Datei für neu erzeugte Kundenverzeichnisse".',
|
||||
'ADMIN' => 'Wird mit dem Loginnamen des Admins ersetzt. Nur für "index Datei für neu erzeugte Kundenverzeichnisse".',
|
||||
'CUSTOMER_EMAIL' => 'Wird mit der E-Mail-Adresse des Kunden ersetzt. Nur für "index Datei für neu erzeugte Kundenverzeichnisse".',
|
||||
'ADMIN_EMAIL' => 'Wird mit der E-Mail-Adresse des Admin ersetzt. Nur für "index Datei für neu erzeugte Kundenverzeichnisse".',
|
||||
'filetemplates' => 'Dateivorlagen',
|
||||
'filecontent' => 'Dateiinhalt',
|
||||
'new_database_by_customer' => 'Kunden-Benachrichtigungs nach Erstellung einer neuen Datenbank',
|
||||
@@ -831,7 +837,6 @@ return [
|
||||
'descriptioninvalid' => 'Der Beschreibungstext ist zu kurz, zu lang oder enthält ungültige Zeichen',
|
||||
'info' => 'Info',
|
||||
'filecontentnotset' => 'Diese Datei darf nicht leer sein!',
|
||||
'index_file_extension' => 'Die Dateiendung für die index Datei muss zwischen 1 und 6 Zeichen lang sein und darf nur aus den Zeichen a-z, A-Z und 0-9 bestehen',
|
||||
'customerdoesntexist' => 'Der ausgewählte Kunde existiert nicht.',
|
||||
'admindoesntexist' => 'Der ausgewählte Admin existiert nicht.',
|
||||
'ipportdoesntexist' => 'Die gewählte IP/Port-Kombination existiert nicht.',
|
||||
@@ -1610,10 +1615,6 @@ Vielen Dank, Ihr Administrator',
|
||||
'removelink' => 'Hier klicken, um alle E-Mail-Kontingente zu entfernen',
|
||||
'enforcelink' => 'Hier klicken, um allen Benutzern das Standard-Kontingent zu zuweisen.',
|
||||
],
|
||||
'index_file_extension' => [
|
||||
'description' => 'Welche Dateiendung soll die index Datei in neu erstellten Kundenverzeichnissen haben? Diese Dateiendung wird dann verwendet, wenn Sie bzw. einer Ihrer Admins eigene index Dateivorlagen erstellt haben.',
|
||||
'title' => 'Dateiendung für index Datei in neu erstellen Kundenverzeichnissen',
|
||||
],
|
||||
'session_allow_multiple_login' => [
|
||||
'title' => 'Erlaube gleichzeitigen Login',
|
||||
'description' => 'Wenn diese Option aktiviert ist, können sich Nutzer mehrmals gleichzeitig anmelden.',
|
||||
@@ -2242,7 +2243,7 @@ Vielen Dank, Ihr Administrator',
|
||||
'database' => [
|
||||
'top' => 'Datenbank',
|
||||
'title' => 'Datenbank und Benutzer erstellen',
|
||||
'description' => 'Froxlor benötigt eine Datenbank und zusätzlich einen Benutzer mit privilegierten Rechten, welcher Benutzer und Datenbanken erstellen darf (GRANT Option). Die angegebene Datenbank und der unprivilegierte Benutzer werden automatisch in diesem Prozess erstellt. Der privilegierte Benutzer muss existieren.',
|
||||
'description' => 'Froxlor benötigt eine Datenbank und zusätzlich <a href="https://docs.froxlor.org/latest/general/installation/tarball.html#_3-create-privileged-database-user" target="_blank">einen Benutzer mit privilegierten Rechten</a>, welcher Benutzer und Datenbanken erstellen darf (GRANT Option). Die angegebene Datenbank und der unprivilegierte Benutzer werden automatisch in diesem Prozess erstellt. Der privilegierte Benutzer muss existieren.',
|
||||
'user' => 'Unprivilegierter Datenbank Benutzer',
|
||||
'dbname' => 'Datenbank Name',
|
||||
'force_create' => 'Sichern und überschreiben, sofern Datenbank existiert?',
|
||||
|
||||
@@ -144,11 +144,17 @@ return [
|
||||
'pop_success_alternative' => 'Welcome mail for new email accounts sent to alternative address',
|
||||
'EMAIL_PASSWORD' => 'Replaced with the POP3/IMAP account password.',
|
||||
'index_html' => 'index file for newly created customer directories',
|
||||
'unconfigured_html' => 'index file for unconfigured/unknown domains',
|
||||
'unconfigured_content_fallback' => 'This domain requires configuration via the froxlor server management panel, as it is currently not assigned to any customer.',
|
||||
'file_extension' => [
|
||||
'description' => 'The file extension for the index file must be between 1 and 6 characters long. The extension can only contain characters like a-z, A-Z and 0-9<br><br>Default: html',
|
||||
'title' => 'File extension for the file template',
|
||||
],
|
||||
'SERVERNAME' => 'Replaced with the servername.',
|
||||
'CUSTOMER' => 'Replaced with the loginname of the customer.',
|
||||
'ADMIN' => 'Replaced with the loginname of the admin.',
|
||||
'CUSTOMER_EMAIL' => 'Replaced with the e-mail address of the customer.',
|
||||
'ADMIN_EMAIL' => 'Replaced with the e-mail address of the admin.',
|
||||
'CUSTOMER' => 'Replaced with the loginname of the customer. Only for "index file for newly created customer directories"',
|
||||
'ADMIN' => 'Replaced with the loginname of the admin. Only for "index file for newly created customer directories"',
|
||||
'CUSTOMER_EMAIL' => 'Replaced with the e-mail address of the customer. Only for "index file for newly created customer directories"',
|
||||
'ADMIN_EMAIL' => 'Replaced with the e-mail address of the admin. Only for "index file for newly created customer directories"',
|
||||
'filetemplates' => 'File templates',
|
||||
'filecontent' => 'File content',
|
||||
'new_database_by_customer' => 'Customer-notification when a database has been created',
|
||||
@@ -903,7 +909,6 @@ return [
|
||||
'descriptioninvalid' => 'The description is too short, too long or contains illegal characters.',
|
||||
'info' => 'Info',
|
||||
'filecontentnotset' => 'The file cannot be empty!',
|
||||
'index_file_extension' => 'The file extension for the index file must be between 1 and 6 characters long. The extension can only contain characters like a-z, A-Z and 0-9',
|
||||
'customerdoesntexist' => 'The customer you have chosen doesn\'t exist.',
|
||||
'admindoesntexist' => 'The admin you have chosen doesn\'t exist.',
|
||||
'ipportdoesntexist' => 'The ip/port combination you have chosen doesn\'t exist.',
|
||||
@@ -1732,10 +1737,6 @@ Yours sincerely, your administrator',
|
||||
'removelink' => 'Click here to wipe all quotas for mail accounts.',
|
||||
'enforcelink' => 'Click here to enforce default quota to all User mail accounts.',
|
||||
],
|
||||
'index_file_extension' => [
|
||||
'description' => 'Which file extension should be used for the index file in newly created customer directories? This file extension will be used, if you or one of your admins has created its own index file template.',
|
||||
'title' => 'File extension for index file in newly created customer directories',
|
||||
],
|
||||
'session_allow_multiple_login' => [
|
||||
'title' => 'Allow multiple login',
|
||||
'description' => 'If activated a user could login multiple times.',
|
||||
@@ -2210,6 +2211,7 @@ Yours sincerely, your administrator',
|
||||
],
|
||||
'uc_stable' => 'stable',
|
||||
'uc_testing' => 'testing',
|
||||
'uc_nightly' => 'nightly',
|
||||
'traffictool' => [
|
||||
'toolselect' => 'Traffic analyzer',
|
||||
'webalizer' => 'Webalizer',
|
||||
@@ -2377,7 +2379,7 @@ Yours sincerely, your administrator',
|
||||
'database' => [
|
||||
'top' => 'Database',
|
||||
'title' => 'Create database and user',
|
||||
'description' => 'Froxlor requires a database and additionally a privileged user to be able to create users and databases (GRANT option). The given database and unprivileged database-user will be created in this process. The privileged user must exist.',
|
||||
'description' => 'Froxlor requires a database and additionally <a href="https://docs.froxlor.org/latest/general/installation/tarball.html#_3-create-privileged-database-user" target="_blank">a privileged user</a> to be able to create users and databases (GRANT option). The given database and unprivileged database-user will be created in this process. The privileged user must exist.',
|
||||
'user' => 'Unprivileged database user',
|
||||
'dbname' => 'Database name',
|
||||
'force_create' => 'Backup and overwrite database if exists?',
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -19,7 +19,7 @@
|
||||
"postcss": "^8.1.14",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"sass": "^1.69.3",
|
||||
"vite": "^4.0.0",
|
||||
"vite": "^4.4.12",
|
||||
"vue": "^3.2.37"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1156,9 +1156,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "4.4.11",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz",
|
||||
"integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==",
|
||||
"version": "4.4.12",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.12.tgz",
|
||||
"integrity": "sha512-KtPlUbWfxzGVul8Nut8Gw2Qe8sBzWY+8QVc5SL8iRFnpnrcoCaNlzO40c1R6hPmcdTwIPEDkq0Y9+27a5tVbdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.18.10",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"postcss": "^8.1.14",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"sass": "^1.69.3",
|
||||
"vite": "^4.0.0",
|
||||
"vite": "^4.4.12",
|
||||
"vue": "^3.2.37"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-group-item {
|
||||
background: $white;
|
||||
}
|
||||
|
||||
@include color-mode(dark) {
|
||||
.card, .list-group-item {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{{ call_static('\\Froxlor\\Froxlor', 'getFullVersion') }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
© 2009-{{ "now"|date("Y") }} by <a href="https://www.froxlor.org/" rel="external" target="_blank">the Froxlor Team</a><br>
|
||||
© 2009-{{ "now"|date("Y") }} by <a href="https://www.froxlor.org/" rel="external" target="_blank">the froxlor team</a><br>
|
||||
{% if install_mode is not defined %}
|
||||
{% if (get_setting('panel.imprint_url') != '') %}<a href="{{ get_setting('panel.imprint_url') }}" target="_blank" class="footer-link">{{ lng('imprint') }}</a>{% endif %}
|
||||
{% if (get_setting('panel.terms_url') != '') %}<a href="{{ get_setting('panel.terms_url') }}" target="_blank" class="footer-link">{{ lng('terms') }}</a>{% endif %}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
<div class="row gx-0 rounded shadow bg-primary text-white mt-5">
|
||||
<div class="col p-5 rounded-start">
|
||||
<h2 class="card-title">Welcome to Froxlor</h2>
|
||||
<p class="lead mt-5">It seems that Froxlor has not been installed yet.</p>
|
||||
<h2 class="card-title">Welcome to froxlor</h2>
|
||||
<p class="lead mt-5">It seems that froxlor has not been installed yet.</p>
|
||||
<p class="lead">Click on the button below to start the installation.</p>
|
||||
</div>
|
||||
|
||||
|
||||
18
templates/Froxlor/misc/missingextensionhint.html.twig
Normal file
18
templates/Froxlor/misc/missingextensionhint.html.twig
Normal file
@@ -0,0 +1,18 @@
|
||||
{% extends "Froxlor/base.html.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container my-auto">
|
||||
<div class="alert alert-warning fade show" role="alert">
|
||||
<h4 class="alert-heading">
|
||||
Whoops!
|
||||
</h4>
|
||||
<p>It looks like you are missing some of the required php requirements.</p>
|
||||
<p>Please ensure that the following extension for the currently used php version ({{ phpversion }}) are installed:</p>
|
||||
<pre>{{ missing_extensions }}</pre>
|
||||
<hr>
|
||||
<p class="mt-1 text-center">
|
||||
<a href="" class="btn btn-primary" title="Reload page">Reload</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -35,7 +35,7 @@
|
||||
<footer class="pý-5 text-center">
|
||||
<span>
|
||||
<img src="{{ basehref }}templates/Froxlor/assets/img/logo_grey.png" alt="Froxlor" />
|
||||
© 2009-{{ current_year }} by <a href="https://www.froxlor.org/" rel="external">the Froxlor Team</a>
|
||||
© 2009-{{ current_year }} by <a href="https://www.froxlor.org/" rel="external">the froxlor team</a>
|
||||
</span>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<footer class="py-5 text-center">
|
||||
<span>
|
||||
<img src="{{ basehref }}templates/Froxlor/assets/img/logo_grey.png" alt="Froxlor" />
|
||||
© 2009-{{ current_year }} by <a href="https://www.froxlor.org/" rel="external">the Froxlor Team</a>
|
||||
© 2009-{{ current_year }} by <a href="https://www.froxlor.org/" rel="external">the froxlor team</a>
|
||||
</span>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -51,8 +51,16 @@
|
||||
|
||||
<div class="row">
|
||||
{% if userinfo.adminsession == 1 %}
|
||||
<div
|
||||
class="col-12 col-lg-6">
|
||||
<div class="col-12 col-lg-6">
|
||||
|
||||
{% if userinfo.custom_notes|markdown is not empty and userinfo.custom_notes_show == 1 %}
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
{{ userinfo.custom_notes|markdown|raw }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# system infos #}
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
@@ -135,22 +143,9 @@
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{% if userinfo.custom_notes|markdown is not empty and userinfo.custom_notes_show == 1 %}
|
||||
<div class="card mb-3">
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item list-group-item-info d-flex justify-content-between align-items-start">
|
||||
<div class="ms-2 me-auto">
|
||||
{{ userinfo.custom_notes|markdown|raw }}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div
|
||||
class="col-12 col-md-6 col-lg-4">
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
{# account info #}
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
@@ -174,16 +169,16 @@
|
||||
<div class="ms-2 me-auto">
|
||||
<div class="fw-bold">{{ lng('customer.services') }}</div>
|
||||
{% if userinfo.imap == 1 %}
|
||||
<span class="badge bg-success">IMAP</span>
|
||||
<span class="badge bg-success me-1">IMAP</span>
|
||||
{% endif %}
|
||||
{% if userinfo.pop3 == 1 %}
|
||||
<span class="badge bg-success">POP3</span>
|
||||
<span class="badge bg-success me-1">POP3</span>
|
||||
{% endif %}
|
||||
{% if userinfo.phpenabled == 1 %}
|
||||
<span class="badge bg-success">PHP</span>
|
||||
<span class="badge bg-success me-1">PHP</span>
|
||||
{% endif %}
|
||||
{% if userinfo.perlenabled == 1 %}
|
||||
<span class="badge bg-success">Perl/CGI</span>
|
||||
<span class="badge bg-success me-1">Perl/CGI</span>
|
||||
{% endif %}
|
||||
{% if userinfo.api_allowed == 1 %}
|
||||
<a href="{{ linker({'section':'index','page':'apikeys'}) }}">
|
||||
@@ -212,8 +207,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="col-12 col-md-6 col-lg-4">
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
{# customer details #}
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
|
||||
Reference in New Issue
Block a user