Compare commits
314 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4dd13200d0 | |||
| 77d399a645 | |||
| c3186e9803 | |||
| 92824194fb | |||
| 3b42d5832b | |||
| 9be43e98fa | |||
| 59ce699440 | |||
| 9dbb5322f2 | |||
| b3290085c0 | |||
| 0e75f74eb8 | |||
| 91d2f2da8a | |||
| 638b153969 | |||
|
|
fbac2f2bbc | ||
|
|
e10f77e219 | ||
|
|
83ff0f5b00 | ||
|
|
0562d248b5 | ||
|
|
3fda5be5a3 | ||
|
|
4d454a3903 | ||
|
|
0e703a4199 | ||
|
|
47c71f6035 | ||
|
|
5923cbb1d5 | ||
|
|
3f10a4aded | ||
|
|
eaea93296d | ||
|
|
1182453c18 | ||
|
|
2c8bdfbbbc | ||
|
|
bbe82286aa | ||
|
|
13571f1f16 | ||
| d82e9b1e81 | |||
| 992ebebf89 | |||
|
|
d6b34cc8f8 | ||
|
|
cfda35a36b | ||
|
|
57ae625d38 | ||
|
|
65ab064289 | ||
|
|
e6a6f6f9de | ||
|
|
a7b91eb1ed | ||
|
|
a2342ad1d2 | ||
|
|
add1818723 | ||
|
|
51c1d648b2 | ||
| 2cb06be3d6 | |||
| 93c72e6754 | |||
|
|
0fca98c652 | ||
|
|
3682116ba2 | ||
|
|
3b99070496 | ||
|
|
25f20e4a7d | ||
|
|
d46b2d1d80 | ||
|
|
4750dad9e2 | ||
|
|
c6830d8e7a | ||
|
|
10b4de4cf9 | ||
|
|
ae39a1759a | ||
|
|
989b4fee0e | ||
|
|
7f6810c5bd | ||
|
|
3fbc9815ea | ||
|
|
11533c2d75 | ||
|
|
652a998188 | ||
|
|
4546c00adb | ||
|
|
3c16fab92c | ||
|
|
c8c1f7e691 | ||
|
|
02d0194b9f | ||
|
|
54876efc8c | ||
|
|
a2f8d02b16 | ||
|
|
0d45e03f19 | ||
|
|
ae74cdda53 | ||
| b118883013 | |||
|
|
84f5de42a9 | ||
|
|
1d7d32130a | ||
|
|
9babcde3e5 | ||
|
|
9ec76c9fd6 | ||
|
|
61dfeb947f | ||
|
|
6fdf2636fc | ||
|
|
0a38d1ab5f | ||
|
|
7c80dc3d1d | ||
|
|
5ab49e3f50 | ||
|
|
06849133a8 | ||
|
|
4a912e3902 | ||
|
|
bcb95e9b7d | ||
|
|
c97f5f1e29 | ||
|
|
4d289e2a7f | ||
|
|
c491f2c03e | ||
|
|
5832346f75 | ||
|
|
4b4770ab36 | ||
|
|
8c998dd6f2 | ||
|
|
965359ec79 | ||
|
|
d1d42f2055 | ||
|
|
5f41b37770 | ||
|
|
61265778a5 | ||
|
|
8f0f890145 | ||
|
|
5ccae3f9bb | ||
|
|
f4d9e64804 | ||
|
|
149c0935fa | ||
|
|
cb0b537f6c | ||
|
|
b54c012579 | ||
|
|
389d83f5a3 | ||
|
|
00771381e8 | ||
|
|
46df429909 | ||
|
|
eb841da007 | ||
|
|
c4a2db03be | ||
|
|
e5838f00cf | ||
|
|
bcde7e93df | ||
|
|
bd8327afbe | ||
|
|
b961eba382 | ||
|
|
a552ea878e | ||
|
|
4ad2a1da1c | ||
|
|
37ae69f07a | ||
|
|
9870db2560 | ||
|
|
724a5e172a | ||
|
|
8e166cb842 | ||
|
|
5e281cf486 | ||
|
|
5d2f44ecd8 | ||
|
|
5009c625d8 | ||
|
|
eb592340b0 | ||
|
|
c6f556c8d9 | ||
|
|
db1df84ef1 | ||
|
|
52135a1d3a | ||
|
|
7f13bd09da | ||
|
|
7ccbb37c4e | ||
|
|
7feddf0aec | ||
|
|
e73523531a | ||
|
|
a47b790e19 | ||
|
|
319eec6124 | ||
|
|
21983f27b6 | ||
|
|
5d375b784d | ||
|
|
4b22470872 | ||
|
|
ec1c37aa06 | ||
|
|
67351ec3c2 | ||
|
|
f1887aaaf2 | ||
|
|
afd2d7b5e9 | ||
|
|
c967e585b5 | ||
|
|
73e364d4ba | ||
|
|
eb49331b21 | ||
|
|
0a1a3e023f | ||
|
|
bef5cedcd0 | ||
|
|
f8e2bc7bff | ||
|
|
09038ac7aa | ||
|
|
4c507232c7 | ||
|
|
86939a64da | ||
|
|
926ce427fc | ||
|
|
53401eebfb | ||
|
|
bef580929e | ||
|
|
c7b7c67ff4 | ||
|
|
ed42d4e3df | ||
|
|
69a2ebce36 | ||
|
|
15f08739fa | ||
|
|
571690c8c5 | ||
|
|
b2005d7f29 | ||
|
|
4354598c64 | ||
|
|
05d4bdc499 | ||
|
|
25c6a37df2 | ||
|
|
41a470fe36 | ||
|
|
8a4aa2a721 | ||
|
|
1d903770fc | ||
|
|
934be5a238 | ||
|
|
5608f0407f | ||
|
|
ce9d8dad7f | ||
|
|
d6fe263e68 | ||
|
|
156846a845 | ||
|
|
abe00b79a7 | ||
|
|
26ab659c6a | ||
|
|
b0273c68d2 | ||
|
|
720cf9d74f | ||
|
|
35cd567c48 | ||
|
|
2332d5be7b | ||
|
|
14cdc3801a | ||
|
|
d85efe480e | ||
|
|
4f2ceaa3ab | ||
|
|
3b6792d548 | ||
|
|
36de6e09d4 | ||
|
|
300c410b18 | ||
|
|
282d7d9101 | ||
|
|
48f6601003 | ||
|
|
c4c4279171 | ||
|
|
b88f9c1f18 | ||
|
|
0dac045dc9 | ||
|
|
80b5f97367 | ||
|
|
7a8b39fad0 | ||
|
|
9f5978e875 | ||
|
|
155fd757bf | ||
|
|
518ec202ab | ||
|
|
871083d613 | ||
|
|
79f0c8d28f | ||
|
|
dfbb4127e2 | ||
|
|
b9b2f00f30 | ||
|
|
6923f9d926 | ||
|
|
cacbf7fec7 | ||
|
|
73991e855c | ||
|
|
0208812013 | ||
|
|
48bd2561f7 | ||
|
|
af12c4102b | ||
|
|
d2efa3ecc4 | ||
|
|
acb04566f5 | ||
|
|
abb98ae960 | ||
|
|
0d202a7e4d | ||
|
|
c69ef20b17 | ||
|
|
5872d0682a | ||
|
|
c4fa8feb8c | ||
|
|
61a50cc657 | ||
|
|
3df3261ac0 | ||
|
|
f2636e14f0 | ||
|
|
a23f22f561 | ||
|
|
8cf3f4ee24 | ||
|
|
e83f7634f8 | ||
|
|
6eb6595a46 | ||
|
|
bd48fb7328 | ||
|
|
769525bb56 | ||
|
|
9195fb3c98 | ||
|
|
82922f7aea | ||
|
|
db1a39b6d9 | ||
|
|
7fbbc2ea0b | ||
|
|
91d4432108 | ||
|
|
c8914312aa | ||
|
|
3fd89c48e8 | ||
|
|
eceb144a77 | ||
|
|
1d9651b18a | ||
|
|
49db4e60cb | ||
|
|
53e8ccbccb | ||
|
|
6d8fc215f1 | ||
|
|
f94c303cb3 | ||
|
|
2be1873354 | ||
|
|
d1d36c32fe | ||
|
|
3b3527348f | ||
|
|
036d5f0713 | ||
|
|
a1b8807b0f | ||
|
|
356a087b6a | ||
|
|
0a77fd7150 | ||
|
|
67d67a287f | ||
|
|
1f792466bf | ||
|
|
5a6343b47c | ||
|
|
841c529107 | ||
|
|
41c3f21f0b | ||
|
|
b8c0688ba0 | ||
|
|
24e02e99fb | ||
|
|
97bb7b6227 | ||
|
|
5ceddc8c65 | ||
|
|
3a17d03796 | ||
|
|
57ae195930 | ||
|
|
9b86d576fa | ||
|
|
02a12eda13 | ||
|
|
a31da97d66 | ||
|
|
9f13aa9a12 | ||
|
|
2841051649 | ||
|
|
acfbf55d15 | ||
|
|
5848df28fd | ||
|
|
21925f48c3 | ||
|
|
17a64c58c2 | ||
|
|
0ca38cff31 | ||
|
|
5efc1849b4 | ||
|
|
f213d666e2 | ||
|
|
78495b6487 | ||
| 2e81445a4e | |||
| 5821f4a0e5 | |||
| a9c258105a | |||
| 34fd64e5b9 | |||
| 0adc511d07 | |||
| 6f32d810c1 | |||
| 70faf0cf2a | |||
| 11b589c399 | |||
| c8e5668852 | |||
| 1eb0f698c0 | |||
| d4d98122bf | |||
| 44d430950c | |||
| 4ac5e2439c | |||
| 99f7fc14de | |||
| 3dcd109ee2 | |||
| 2ab6b9f6f3 | |||
| 2c7502485b | |||
| 581e4deca1 | |||
| 92f8986477 | |||
| 1f800f5298 | |||
| cb582a2947 | |||
| caf2c21ae9 | |||
| 18998d40c0 | |||
| e2380284e8 | |||
| dce20e55b8 | |||
| 8bd32821dd | |||
| fe5072d0a2 | |||
| 6ca2292820 | |||
| a51ff99ec2 | |||
| 57464ba8c4 | |||
| 924f93435f | |||
| c141868fd4 | |||
| 3154914532 | |||
| f6e3779728 | |||
| c7e0fe57d1 | |||
| 57aacd96e4 | |||
| 27be204c96 | |||
| b7ab10665a | |||
| 8bc1a5be69 | |||
| 832799942e | |||
| 081858d7bb | |||
| 88791d3d4a | |||
| 1f0b90ceef | |||
| 8f295f1b5d | |||
| 9abe4415af | |||
| d25dd58f7b | |||
| 9d363c5eb0 | |||
| acd357f561 | |||
| 660272b64b | |||
| e2209f53d1 | |||
| 7a7f131861 | |||
| 67803ff106 | |||
| 03bafc9540 | |||
| 8fbc3acba6 | |||
| 0e9dad1b71 | |||
| 3542e85195 | |||
| b4829b521b | |||
| 46bf7005e6 | |||
| 924731d54d | |||
| bc550e086f | |||
| 3167df9947 | |||
| 8686b54fb8 | |||
| 480afb0ccd | |||
| b52364a873 | |||
| ccc95b638b | |||
| 2365d3eae3 | |||
| 2e0ee3d683 |
40
.drone.yml
Normal file
40
.drone.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
kind: pipeline
|
||||
name: deploy-froxlor
|
||||
type: docker
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm64
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- live
|
||||
event:
|
||||
include:
|
||||
- push
|
||||
|
||||
steps:
|
||||
- name: deploy
|
||||
image: cr.wks/drone/drone-rsync:latest
|
||||
settings:
|
||||
hosts: ["rechner02.maketank.net"]
|
||||
source: ./
|
||||
target: ~/froxlor-test
|
||||
user: www-data
|
||||
exclude: ['vendor', '.git*', '*drone.yml', '.settings', '.buildpath', '.editorconfig', '.project', '.travis.yml']
|
||||
args: '-v --delete'
|
||||
log_level: quiet
|
||||
key:
|
||||
from_secret: ssh-www-data-maketank-rsa
|
||||
command_timeout: 10m
|
||||
- name: compose-install
|
||||
image: appleboy/drone-ssh
|
||||
settings:
|
||||
host:
|
||||
- rechner02.maketank.net
|
||||
username: www-data
|
||||
key:
|
||||
from_secret: ssh-www-data-maketank-rsa
|
||||
script:
|
||||
- cd ~/froxlor-test && composer install --no-dev
|
||||
|
||||
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,6 +1,6 @@
|
||||
# Bug report vs. support request
|
||||
If you're unsure of whether your problem is a bug or a configuration error
|
||||
* contact us via IRC in #froxlor on freenode
|
||||
* contact us via IRC in #froxlor on irc.libera.chat
|
||||
* or post a thread in our forum at https://forum.froxlor.org
|
||||
|
||||
As a rule of thumb: before reporting an issue
|
||||
|
||||
40
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
40
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**As a rule of thumb: before reporting an issue**
|
||||
* see if it hasn't been [reported](https://github.com/Froxlor/froxlor/issues) (and possibly already been [fixed](https://github.com/Froxlor/froxlor/issues?utf8=✓&q=is:issue%20is:closed)) first
|
||||
* try with the git master
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**System information**
|
||||
* Froxlor version: $version/$gitSHA1
|
||||
* Web server: apache2/nginx/lighttpd
|
||||
* DNS server: Bind/PowerDNS (standalone)/PowerDNS (Bind-backend)
|
||||
* POP/IMAP server: Courier/Dovecot
|
||||
* SMTP server: postfix/exim
|
||||
* FTP server: proftpd/pureftpd
|
||||
* OS/Version: ...
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Logfiles**
|
||||
If applicable, add log-entries to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
14
.github/workflows/build-apidocs.yml
vendored
Normal file
14
.github/workflows/build-apidocs.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: build-docs
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build_docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- env:
|
||||
GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh workflow run --repo Froxlor/Documentation build-docs -f ref=${{github.ref_name}}
|
||||
80
.github/workflows/build-mariadb.yml
vendored
Normal file
80
.github/workflows/build-mariadb.yml
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
name: Froxlor-CI-MariaDB
|
||||
on: ['push', 'pull_request', 'create']
|
||||
|
||||
jobs:
|
||||
froxlor:
|
||||
name: Froxlor (PHP ${{ matrix.php-versions }}, MariaDB ${{ matrix.mariadb-version }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.0']
|
||||
mariadb-version: [10.5, 10.4]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP, with composer and extensions
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: composer:v2
|
||||
extensions: mbstring, xml, ctype, pdo_mysql, mysql, curl, json, zip, session, filter, posix, openssl, fileinfo, bcmath
|
||||
|
||||
- name: Install tools
|
||||
run: sudo apt-get install -y ant
|
||||
|
||||
- name: Adjust firewall
|
||||
run: |
|
||||
sudo ufw allow out 3306/tcp
|
||||
sudo ufw allow in 3306/tcp
|
||||
|
||||
- name: Setup MariaDB
|
||||
uses: getong/mariadb-action@v1.1
|
||||
with:
|
||||
mariadb version: ${{ matrix.mariadb-version }}
|
||||
mysql database: 'froxlor010'
|
||||
mysql root password: 'fr0xl0r.TravisCI'
|
||||
|
||||
- name: Wait for database
|
||||
run: sleep 15
|
||||
|
||||
- name: Setup databases
|
||||
run: |
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED BY 'fr0xl0r.TravisCI';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
|
||||
|
||||
- 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) }}
|
||||
|
||||
# - 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 }}
|
||||
|
||||
# - 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 }}
|
||||
57
.github/workflows/build-mysql.yml
vendored
Normal file
57
.github/workflows/build-mysql.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Froxlor-CI-MySQL
|
||||
on: ['push', 'pull_request', 'create']
|
||||
|
||||
jobs:
|
||||
froxlor:
|
||||
name: Froxlor (PHP ${{ matrix.php-versions }}, MySQL ${{ matrix.mysql-version }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.0']
|
||||
mysql-version: [8.0, 5.7]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP, with composer and extensions
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: composer:v2
|
||||
extensions: mbstring, xml, ctype, pdo_mysql, mysql, curl, json, zip, session, filter, posix, openssl, fileinfo, bcmath
|
||||
|
||||
- name: Install tools
|
||||
run: sudo apt-get install -y ant
|
||||
|
||||
- name: Adjust firewall
|
||||
run: |
|
||||
sudo ufw allow out 3306/tcp
|
||||
sudo ufw allow in 3306/tcp
|
||||
|
||||
- name: Setup MySQL
|
||||
uses: samin/mysql-action@v1.3
|
||||
with:
|
||||
mysql version: ${{ matrix.mysql-version }}
|
||||
mysql database: 'froxlor010'
|
||||
mysql root password: 'fr0xl0r.TravisCI'
|
||||
|
||||
- name: Wait for database
|
||||
run: sleep 15
|
||||
|
||||
- name: Setup database (8.0)
|
||||
if: matrix.mysql-version == '8.0'
|
||||
run: |
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED WITH mysql_native_password BY 'fr0xl0r.TravisCI';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
|
||||
|
||||
- name: Setup database (5.7)
|
||||
if: matrix.mysql-version == '5.7'
|
||||
run: |
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED BY 'fr0xl0r.TravisCI';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
|
||||
|
||||
- name: Run testing
|
||||
run: ant quick-build
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -12,9 +12,11 @@ logs/*
|
||||
.well-known
|
||||
.idea
|
||||
*.iml
|
||||
img/
|
||||
|
||||
!templates/Maketank/
|
||||
!templates/Froxlor/
|
||||
!templates/Sparkle/
|
||||
!templates/misc/
|
||||
templates/Froxlor/assets/img/logo_custom.png
|
||||
templates/Sparkle/assets/css/custom.css
|
||||
vendor/
|
||||
|
||||
@@ -55,7 +55,7 @@ script:
|
||||
- ant phpunit-no-coverage
|
||||
|
||||
notifications:
|
||||
irc: "chat.freenode.net#froxlor"
|
||||
irc: "irc.libera.chat#froxlor"
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/bdf91d1c3f745e51f796
|
||||
|
||||
43
README.md
43
README.md
@@ -1,5 +1,6 @@
|
||||
[](https://travis-ci.com/Froxlor/Froxlor)
|
||||
[](https://gitter.im/Froxlor/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml)
|
||||
[](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml)
|
||||
[](https://discord.froxlor.org)
|
||||
|
||||
# Froxlor
|
||||
|
||||
@@ -20,16 +21,20 @@ Developed by experienced server administrators, this panel simplifies the effort
|
||||
9. Have fun!
|
||||
|
||||
### Detailed installation
|
||||
https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-from-tarball
|
||||
https://docs.froxlor.org/general/installation/index.html
|
||||
|
||||
## Help
|
||||
|
||||
You may find help in the following places:
|
||||
|
||||
### Discord
|
||||
|
||||
The froxlor community discord server can be found here: https://discord.froxlor.org
|
||||
|
||||
### IRC
|
||||
|
||||
froxlor may be found on freenode.net, channel #froxlor:
|
||||
irc://chat.freenode.net/froxlor
|
||||
froxlor may be found on libera.chat, channel #froxlor:
|
||||
irc://irc.libera.chat/froxlor
|
||||
|
||||
### Forum
|
||||
|
||||
@@ -37,36 +42,36 @@ The community is located on https://forum.froxlor.org/
|
||||
|
||||
### Wiki
|
||||
|
||||
More documentation may be found in the froxlor - wiki:
|
||||
https://github.com/Froxlor/Froxlor/wiki
|
||||
More documentation may be found in the froxlor - documentation:
|
||||
https://docs.froxlor.org/
|
||||
|
||||
## License
|
||||
|
||||
May be found in COPYING
|
||||
May be found in [COPYING](COPYING)
|
||||
|
||||
## Downloads
|
||||
|
||||
### Tarball
|
||||
https://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](https://files.froxlor.org/releases/froxlor-latest.tar.gz.md5) [SHA1](https://files.froxlor.org/releases/froxlor-latest.tar.gz.sha1)
|
||||
|
||||
### Debian repository
|
||||
### Debian / Ubutnu repository
|
||||
|
||||
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-debian)
|
||||
[HowTo](https://docs.froxlor.org/general/installation/aptpackage.html)
|
||||
|
||||
#### Debian
|
||||
|
||||
```
|
||||
apt-get -y install apt-transport-https lsb-release ca-certificates
|
||||
wget -O - https://deb.froxlor.org/froxlor.gpg | apt-key add -
|
||||
echo "deb https://deb.froxlor.org/debian $(lsb_release -sc) main" > /etc/apt/sources.list.d/froxlor.list
|
||||
apt-get -y install apt-transport-https lsb-release ca-certificates curl
|
||||
curl -sSLo /usr/share/keyrings/deb.froxlor.org-froxlor.gpg https://deb.froxlor.org/froxlor.gpg
|
||||
sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.froxlor.org-froxlor.gpg] https://deb.froxlor.org/debian $(lsb_release -sc) main" > /etc/apt/sources.list.d/froxlor.list'
|
||||
```
|
||||
|
||||
### Ubuntu repository
|
||||
|
||||
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-ubuntu)
|
||||
#### Ubuntu
|
||||
|
||||
```
|
||||
apt-get -y install apt-transport-https lsb-release ca-certificates
|
||||
wget -O - https://deb.froxlor.org/froxlor.gpg | apt-key add -
|
||||
echo "deb https://deb.froxlor.org/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/froxlor.list
|
||||
apt-get -y install apt-transport-https lsb-release ca-certificates curl
|
||||
curl -sSLo /usr/share/keyrings/deb.froxlor.org-froxlor.gpg https://deb.froxlor.org/froxlor.gpg
|
||||
sh -c 'echo "deb [signed-by=/usr/share/keyrings/deb.froxlor.org-froxlor.gpg] https://deb.froxlor.org/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/froxlor.list'
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
0
actions/admin/index.html
Normal file
0
actions/admin/index.html
Normal file
@@ -77,14 +77,6 @@ return array(
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_no_robots' => array(
|
||||
'label' => $lng['serversettings']['no_robots'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'no_robots',
|
||||
'type' => 'bool',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_paging' => array(
|
||||
'label' => $lng['serversettings']['paging'],
|
||||
'settinggroup' => 'panel',
|
||||
@@ -257,7 +249,7 @@ return array(
|
||||
'extras' => $lng['menue']['extras']['extras'],
|
||||
'extras.directoryprotection' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['directoryprotection'],
|
||||
'extras.pathoptions' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['pathoptions'],
|
||||
'extras.logger' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['logger']['logger'],
|
||||
'extras.logger' => $lng['menue']['extras']['extras'] . " / " . $lng['admin']['loggersystem'],
|
||||
'extras.backup' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['backup'],
|
||||
'traffic' => $lng['menue']['traffic']['traffic'],
|
||||
'traffic.http' => $lng['menue']['traffic']['traffic'] . " / HTTP",
|
||||
@@ -265,7 +257,71 @@ return array(
|
||||
'traffic.mail' => $lng['menue']['traffic']['traffic'] . " / Mail"
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
)
|
||||
),
|
||||
'panel_imprint_url' => array(
|
||||
'label' => $lng['serversettings']['imprint_url'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'imprint_url',
|
||||
'type' => 'string',
|
||||
'string_type' => 'url',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_terms_url' => array(
|
||||
'label' => $lng['serversettings']['terms_url'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'terms_url',
|
||||
'type' => 'string',
|
||||
'string_type' => 'url',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_privacy_url' => array(
|
||||
'label' => $lng['serversettings']['privacy_url'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'privacy_url',
|
||||
'type' => 'string',
|
||||
'string_type' => 'url',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_logo_overridetheme' => array(
|
||||
'label' => $lng['serversettings']['logo_overridetheme'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'logo_overridetheme',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_logo_overridecustom' => array(
|
||||
'label' => $lng['serversettings']['logo_overridecustom'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'logo_overridecustom',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_logo_image_header' => array(
|
||||
'label' => $lng['serversettings']['logo_image_header'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'logo_image_header',
|
||||
'type' => 'image',
|
||||
'image_name' => 'logo_header',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingImage'
|
||||
),
|
||||
'panel_logo_image_login' => array(
|
||||
'label' => $lng['serversettings']['logo_image_login'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'logo_image_login',
|
||||
'type' => 'image',
|
||||
'image_name' => 'logo_login',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingImage'
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -205,9 +205,21 @@ return array(
|
||||
'default' => false,
|
||||
'cronmodule' => 'froxlor/backup',
|
||||
'save_method' => 'storeSettingField'
|
||||
)
|
||||
),
|
||||
'system_createstdsubdom_default' => array(
|
||||
'label' => $lng['serversettings']['createstdsubdom_default'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'createstdsubdom_default',
|
||||
'type' => 'option',
|
||||
'default' => '1',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(
|
||||
'0' => $lng['panel']['no'],
|
||||
'1' => $lng['panel']['yes']
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -270,6 +270,28 @@ return array(
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_domaindefaultalias' => array(
|
||||
'label' => $lng['admin']['domaindefaultalias'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'domaindefaultalias',
|
||||
'type' => 'option',
|
||||
'default' => '0',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(
|
||||
'0' => $lng['domains']['serveraliasoption_wildcard'],
|
||||
'1' => $lng['domains']['serveraliasoption_www'],
|
||||
'2' => $lng['domains']['serveraliasoption_none']
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'hide_incompatible_settings' => array(
|
||||
'label' => $lng['serversettings']['hide_incompatible_settings'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'hide_incompatible_settings',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -133,6 +133,15 @@ return array(
|
||||
'cronmodule' => 'froxlor/letsencrypt',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_acmeshpath' => array(
|
||||
'label' => $lng['serversettings']['acmeshpath'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'acmeshpath',
|
||||
'type' => 'string',
|
||||
'string_type' => 'file',
|
||||
'default' => '/root/.acme.sh/acme.sh',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_letsencryptacmeconf' => array(
|
||||
'label' => $lng['serversettings']['letsencryptacmeconf'],
|
||||
'settinggroup' => 'system',
|
||||
@@ -142,6 +151,9 @@ return array(
|
||||
'default' => '/etc/apache2/conf-enabled/acme.conf',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
/**
|
||||
* currently the only option anyway
|
||||
*
|
||||
'system_leapiversion' => array(
|
||||
'label' => $lng['serversettings']['leapiversion'],
|
||||
'settinggroup' => 'system',
|
||||
@@ -154,16 +166,20 @@ return array(
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
*/
|
||||
'system_letsencryptca' => array(
|
||||
'label' => $lng['serversettings']['letsencryptca'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'letsencryptca',
|
||||
'type' => 'option',
|
||||
'default' => 'production',
|
||||
'default' => 'letsencrypt',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(
|
||||
'testing' => 'https://acme-staging-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Test)',
|
||||
'production' => 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Live)'
|
||||
'letsencrypt_test' => 'Let\'s Encrypt (Test / Staging)',
|
||||
'letsencrypt' => 'Let\'s Encrypt (Live)',
|
||||
'buypass_test' => 'Buypass (Test / Staging)',
|
||||
'buypass' => 'Buypass (Live)',
|
||||
'zerossl' => 'ZeroSSL (Live)'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
@@ -213,7 +229,7 @@ return array(
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_disable_le_selfcheck' => array(
|
||||
'system_le_domain_dnscheck' => array(
|
||||
'label' => $lng['serversettings']['le_domain_dnscheck'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'le_domain_dnscheck',
|
||||
|
||||
@@ -90,7 +90,23 @@ return array(
|
||||
'varname' => 'catchall_enabled',
|
||||
'type' => 'bool',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingResetCatchall'
|
||||
'save_method' => 'storeSettingResetCatchall',
|
||||
),
|
||||
'mail_greylist_enabled' => array(
|
||||
'label' => $lng['serversettings']['greylist_enabled'],
|
||||
'settinggroup' => 'mail',
|
||||
'varname' => 'greylist_enabled',
|
||||
'type' => 'bool',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'mail_greylist_disabled_default' => array(
|
||||
'label' => $lng['serversettings']['greylist_disabled_default'],
|
||||
'settinggroup' => 'mail',
|
||||
'varname' => 'greylist_disabled_default',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField',
|
||||
),
|
||||
'system_mailtraffic_enabled' => array(
|
||||
'label' => $lng['serversettings']['mailtraffic_enabled'],
|
||||
|
||||
@@ -99,6 +99,19 @@ return array(
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_powerdns_mode' => array(
|
||||
'label' => $lng['serversettings']['powerdns_mode'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'powerdns_mode',
|
||||
'type' => 'option',
|
||||
'default' => 'Native',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(
|
||||
'Native' => 'Native',
|
||||
'Master' => 'Master'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_dns_createmailentry' => array(
|
||||
'label' => $lng['serversettings']['mail_also_with_mxservers'],
|
||||
'settinggroup' => 'system',
|
||||
@@ -132,6 +145,16 @@ return array(
|
||||
'int_min' => 3600, /* 1 hour */
|
||||
'int_max' => 2147483647, /* integer max */
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_soaemail' => array(
|
||||
'label' => $lng['serversettings']['soaemail'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'soaemail',
|
||||
'type' => 'string',
|
||||
'string_type' => 'mail',
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -39,6 +39,15 @@ return array(
|
||||
'default' => '/etc/postfix/dkim/',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'dkim_privkeysuffix' => array(
|
||||
'label' => $lng['dkim']['privkeysuffix'],
|
||||
'settinggroup' => 'dkim',
|
||||
'varname' => 'privkeysuffix',
|
||||
'type' => 'string',
|
||||
'string_regexp' => '/^[a-z0-9\._]+$/i',
|
||||
'default' => '.priv',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'dkim_domains' => array(
|
||||
'label' => $lng['dkim']['dkim_domains'],
|
||||
'settinggroup' => 'dkim',
|
||||
|
||||
@@ -82,7 +82,20 @@ return array(
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
)
|
||||
),
|
||||
'system_froxlorusergroup' => array(
|
||||
'label' => $lng['serversettings']['froxlorusergroup'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'froxlorusergroup',
|
||||
'type' => 'string',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField',
|
||||
'plausibility_check_method' => array(
|
||||
'\\Froxlor\\Validate\\Check',
|
||||
'checkLocalGroup'
|
||||
),
|
||||
'visible' => \Froxlor\Settings::Get('system.nssextrausers')
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
0
actions/admin/settings/index.html
Normal file
0
actions/admin/settings/index.html
Normal file
0
actions/index.html
Normal file
0
actions/index.html
Normal file
@@ -129,7 +129,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
|
||||
'userid' => $userinfo['userid']
|
||||
));
|
||||
|
||||
$s = md5(uniqid(microtime(), 1));
|
||||
$s = \Froxlor\Froxlor::genSessionId();
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET
|
||||
`hash` = :hash, `userid` = :userid, `ipaddress` = :ip,
|
||||
@@ -260,7 +260,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
|
||||
$dec_places = Settings::Get('panel.decimal_places');
|
||||
$result['traffic'] = round($result['traffic'] / (1024 * 1024), $dec_places);
|
||||
$result['diskspace'] = round($result['diskspace'] / 1024, $dec_places);
|
||||
$result['email'] = $idna_convert->decode($result['email']);
|
||||
$result['email'] = $idna_convert->decode($result['email'] ?? '');
|
||||
|
||||
$customers_ul = \Froxlor\UI\HTML::makecheckbox('customers_ul', $lng['customer']['unlimited'], '-1', false, $result['customers'], true, true);
|
||||
if ($result['customers'] == '-1') {
|
||||
|
||||
@@ -67,6 +67,9 @@ if ($page == 'showinfo') {
|
||||
$uptime_duration = duration($cache['start_time']);
|
||||
$size_vars = bsize($cache['mem_size']);
|
||||
|
||||
$num_hits_and_misses = $cache['num_hits'] + $cache['num_misses'];
|
||||
$num_hits_and_misses = 0 >= $num_hits_and_misses ? 1 : $num_hits_and_misses;
|
||||
|
||||
// check for possible empty values that are used in the templates
|
||||
if (! isset($cache['file_upload_progress'])) {
|
||||
$cache['file_upload_progress'] = $lng['logger']['unknown'];
|
||||
@@ -84,10 +87,10 @@ if ($page == 'showinfo') {
|
||||
|
||||
$freemem = bsize($mem_avail) . sprintf(" (%.1f%%)", $mem_avail * 100 / $mem_size);
|
||||
$usedmem = bsize($mem_used) . sprintf(" (%.1f%%)", $mem_used * 100 / $mem_size);
|
||||
$hits = $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / ($cache['num_hits'] + $cache['num_misses']));
|
||||
$misses = $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / ($cache['num_hits'] + $cache['num_misses']));
|
||||
$hits = $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / $num_hits_and_misses);
|
||||
$misses = $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / $num_hits_and_misses);
|
||||
|
||||
// Fragementation: (freeseg - 1) / total_seg
|
||||
// Fragmentation: (freeseg - 1) / total_seg
|
||||
$nseg = $freeseg = $fragsize = $freetotal = 0;
|
||||
for ($i = 0; $i < $mem['num_seg']; $i ++) {
|
||||
$ptr = 0;
|
||||
|
||||
@@ -38,13 +38,43 @@ if ($userinfo['change_serversettings'] == '1') {
|
||||
|
||||
// try to convert namserver hosts to ip's
|
||||
$ns_ips = "";
|
||||
$known_ns_ips = [];
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
// DNS servers might be multi homed; allow transfer from all ip
|
||||
// addresses of the DNS server
|
||||
$nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
|
||||
if (is_array($nameserver_ips) && count($nameserver_ips) > 0) {
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
// append dot to hostname
|
||||
if (substr($nameserver, - 1, 1) != '.') {
|
||||
$nameserver .= '.';
|
||||
}
|
||||
// ignore invalid responses
|
||||
if (! is_array($nameserver_ips)) {
|
||||
// act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error
|
||||
$nameserver_ips = array(
|
||||
$nameserver
|
||||
);
|
||||
} else {
|
||||
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
|
||||
}
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
}
|
||||
}
|
||||
|
||||
// AXFR server
|
||||
if (Settings::Get('system.axfrservers') != '') {
|
||||
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
|
||||
foreach ($axfrservers as $axfrserver) {
|
||||
if (!in_array(trim($axfrserver), $known_ns_ips)) {
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= trim($axfrserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +89,6 @@ if ($userinfo['change_serversettings'] == '1') {
|
||||
'<SERVERIP>' => Settings::Get('system.ipaddress'),
|
||||
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
|
||||
'<NAMESERVERS_IP>' => $ns_ips,
|
||||
'<AXFRSERVERS>' => Settings::Get('system.axfrservers'),
|
||||
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
|
||||
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
|
||||
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
|
||||
|
||||
@@ -178,7 +178,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
|
||||
'hash' => $s
|
||||
));
|
||||
|
||||
$s = md5(uniqid(microtime(), 1));
|
||||
$s = \Froxlor\Froxlor::genSessionId();
|
||||
$insert = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET
|
||||
`hash` = :hash,
|
||||
@@ -298,6 +298,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
|
||||
$email_quota_ul = \Froxlor\UI\HTML::makecheckbox('email_quota_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true);
|
||||
$ftps_ul = \Froxlor\UI\HTML::makecheckbox('ftps_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true);
|
||||
$mysqls_ul = \Froxlor\UI\HTML::makecheckbox('mysqls_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true);
|
||||
$nextcloud_quota_ul = \Froxlor\UI\HTML::makecheckbox('nextcloud_quota_ul', $lng['customer']['unlimited'], '-1', false, '0', true, true);
|
||||
|
||||
$gender_options = \Froxlor\UI\HTML::makeoption($lng['gender']['undef'], 0, true, true, true);
|
||||
$gender_options .= \Froxlor\UI\HTML::makeoption($lng['gender']['male'], 1, null, true, true);
|
||||
@@ -395,13 +396,18 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
|
||||
$dec_places = Settings::Get('panel.decimal_places');
|
||||
$result['traffic'] = round($result['traffic'] / (1024 * 1024), $dec_places);
|
||||
$result['diskspace'] = round($result['diskspace'] / 1024, $dec_places);
|
||||
$result['email'] = $idna_convert->decode($result['email']);
|
||||
$result['email'] = $idna_convert->decode($result['email'] ?? '');
|
||||
|
||||
$nextcloud_quota_ul = \Froxlor\UI\HTML::makecheckbox('nextcloud_quota_ul', $lng['customer']['unlimited'], '-1', false, $result['nextcloud_quota'], true, true);
|
||||
if ($result['nextcloud_quota'] == '-1') {
|
||||
$result['nextcloud_quota'] = '';
|
||||
}
|
||||
|
||||
$diskspace_ul = \Froxlor\UI\HTML::makecheckbox('diskspace_ul', $lng['customer']['unlimited'], '-1', false, $result['diskspace'], true, true);
|
||||
if ($result['diskspace'] == '-1') {
|
||||
$result['diskspace'] = '';
|
||||
}
|
||||
|
||||
|
||||
$traffic_ul = \Froxlor\UI\HTML::makecheckbox('traffic_ul', $lng['customer']['unlimited'], '-1', false, $result['traffic'], true, true);
|
||||
if ($result['traffic'] == '-1') {
|
||||
$result['traffic'] = '';
|
||||
|
||||
@@ -148,7 +148,7 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
$customers = \Froxlor\UI\HTML::makeoption($lng['panel']['please_choose'], 0, 0, true);
|
||||
$result_customers_stmt = Database::prepare("
|
||||
SELECT `customerid`, `loginname`, `name`, `firstname`, `company`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` " . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = '" . (int) $userinfo['adminid'] . "' ") . " ORDER BY COALESCE(NULLIF(`name`,''), `company`) ASC");
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "` " . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid ") . " ORDER BY COALESCE(NULLIF(`name`,''), `company`) ASC");
|
||||
$params = array();
|
||||
if ($userinfo['customers_see_all'] == '0') {
|
||||
$params['adminid'] = $userinfo['adminid'];
|
||||
@@ -290,9 +290,9 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
|
||||
// create serveralias options
|
||||
$serveraliasoptions = "";
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', '0', true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_www'], '1', '0', true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_none'], '2', '0', true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', Settings::Get('system.domaindefaultalias'), true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_www'], '1', Settings::Get('system.domaindefaultalias'), true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_none'], '2', Settings::Get('system.domaindefaultalias'), true, true);
|
||||
|
||||
$subcanemaildomain = \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['never'], '0', '0', true, true);
|
||||
$subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['choosableno'], '1', '0', true, true);
|
||||
@@ -428,7 +428,7 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
$customer = Database::pexecute_first($customer_stmt, array(
|
||||
'customerid' => $result['customerid']
|
||||
));
|
||||
$result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer) . ' (' . $customer['loginname'] . ')';
|
||||
$result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer);
|
||||
}
|
||||
|
||||
if ($userinfo['customers_see_all'] == '1') {
|
||||
@@ -594,6 +594,10 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
}
|
||||
|
||||
$result = \Froxlor\PhpHelper::htmlentitiesArray($result);
|
||||
if (Settings::Get('panel.allow_domain_change_customer') != '1') {
|
||||
$result['customername'] .= ' (<a href="' . $linker->getLink(array('section' => 'customers', 'page' => 'customers',
|
||||
'action' => 'su', 'id' => $customer['customerid'])) . '" rel="external">' . $customer['loginname'] . '</a>)';
|
||||
}
|
||||
|
||||
$domain_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_edit.php';
|
||||
$domain_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_edit_data);
|
||||
@@ -636,8 +640,8 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
|
||||
// update customer/admin counters
|
||||
\Froxlor\User::updateCounters(false);
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$result_str = $result['imported'] . ' / ' . $result['all'] . (! empty($result['note']) ? ' (' . $result['note'] . ')' : '');
|
||||
\Froxlor\UI\Response::standard_success('domain_import_successfully', $result_str, array(
|
||||
@@ -670,7 +674,7 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
function formatDomainEntry(&$row, &$idna_convert)
|
||||
{
|
||||
$row['domain'] = $idna_convert->decode($row['domain']);
|
||||
$row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']);
|
||||
$row['aliasdomain'] = $idna_convert->decode($row['aliasdomain'] ?? '');
|
||||
|
||||
$row['ipandport'] = '';
|
||||
foreach ($row['ipsandports'] as $rowip) {
|
||||
@@ -681,7 +685,7 @@ function formatDomainEntry(&$row, &$idna_convert)
|
||||
}
|
||||
}
|
||||
$row['ipandport'] = substr($row['ipandport'], 0, - 1);
|
||||
$row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date']);
|
||||
$row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date'] ?? '');
|
||||
|
||||
$row['termination_css'] = "";
|
||||
if ($row['termination_date'] != "") {
|
||||
|
||||
@@ -57,6 +57,12 @@ if (isset($_POST['id'])) {
|
||||
if ($page == 'overview') {
|
||||
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_index");
|
||||
$params = [];
|
||||
if ($userinfo['customers_see_all'] == '0') {
|
||||
$params = [
|
||||
'adminid' => $userinfo['adminid']
|
||||
];
|
||||
}
|
||||
$overview_stmt = Database::prepare("SELECT COUNT(*) AS `number_customers`,
|
||||
SUM(`diskspace_used`) AS `diskspace_used`,
|
||||
SUM(`mysqls_used`) AS `mysqls_used`,
|
||||
@@ -68,20 +74,18 @@ if ($page == 'overview') {
|
||||
SUM(`subdomains_used`) AS `subdomains_used`,
|
||||
SUM(`traffic_used`) AS `traffic_used`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "`" . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid "));
|
||||
$overview = Database::pexecute_first($overview_stmt, array(
|
||||
'adminid' => $userinfo['adminid']
|
||||
));
|
||||
$overview = Database::pexecute_first($overview_stmt, $params);
|
||||
|
||||
$dec_places = Settings::Get('panel.decimal_places');
|
||||
$overview['traffic_used'] = round($overview['traffic_used'] / (1024 * 1024), $dec_places);
|
||||
$overview['diskspace_used'] = round($overview['diskspace_used'] / 1024, $dec_places);
|
||||
$overview['traffic_bytes_used'] = $overview['traffic_used'] * 1024;
|
||||
$overview['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($overview['traffic_used'] * 1024, null, 'bi');
|
||||
$overview['diskspace_bytes_used'] = $overview['diskspace_used'] * 1024;
|
||||
$overview['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($overview['diskspace_used'] * 1024, null, 'bi');
|
||||
|
||||
$number_domains_stmt = Database::prepare("
|
||||
SELECT COUNT(*) AS `number_domains` FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
WHERE `parentdomainid`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid"));
|
||||
$number_domains = Database::pexecute_first($number_domains_stmt, array(
|
||||
'adminid' => $userinfo['adminid']
|
||||
));
|
||||
$number_domains = Database::pexecute_first($number_domains_stmt, $params);
|
||||
|
||||
$overview['number_domains'] = $number_domains['number_domains'];
|
||||
|
||||
@@ -111,11 +115,17 @@ if ($page == 'overview') {
|
||||
}
|
||||
|
||||
$dec_places = Settings::Get('panel.decimal_places');
|
||||
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, $dec_places);
|
||||
$userinfo['diskspace_used'] = round($userinfo['diskspace_used'] / 1024, $dec_places);
|
||||
$userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), $dec_places);
|
||||
$userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), $dec_places);
|
||||
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
|
||||
// get everything in bytes for the percentage calculation on the dashboard
|
||||
$userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1;
|
||||
$userinfo['diskspace_bytes_used'] = $userinfo['diskspace_used'] * 1024;
|
||||
$userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1;
|
||||
$userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024;
|
||||
|
||||
$userinfo['diskspace'] = ($userinfo['diskspace'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace'] * 1024, null, 'bi') : - 1;
|
||||
$userinfo['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace_used'] * 1024, null, 'bi');
|
||||
$userinfo['traffic'] = ($userinfo['traffic'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['traffic'] * 1024, null, 'bi') : - 1;
|
||||
$userinfo['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['traffic_used'] * 1024, null, 'bi');
|
||||
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace diskspace_bytes traffic traffic_bytes mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
|
||||
|
||||
$userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : '';
|
||||
|
||||
@@ -183,8 +193,12 @@ if ($page == 'overview') {
|
||||
\Froxlor\UI\Response::standard_error('oldpasswordnotcorrect');
|
||||
}
|
||||
|
||||
$new_password = \Froxlor\Validate\Validate::validate($_POST['new_password'], 'new password');
|
||||
$new_password_confirm = \Froxlor\Validate\Validate::validate($_POST['new_password_confirm'], 'new password confirm');
|
||||
try {
|
||||
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
|
||||
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\UI\Response::dynamic_error($e->getMessage());
|
||||
}
|
||||
|
||||
if ($old_password == '') {
|
||||
\Froxlor\UI\Response::standard_error(array(
|
||||
|
||||
@@ -32,10 +32,10 @@ if ($page == 'message') {
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed panel_message');
|
||||
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
if ($_POST['receipient'] == 0 && $userinfo['customers_see_all'] == '1') {
|
||||
if ($_POST['recipient'] == 0 && $userinfo['customers_see_all'] == '1') {
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to admins');
|
||||
$result = Database::query('SELECT `name`, `email` FROM `' . TABLE_PANEL_ADMINS . "`");
|
||||
} elseif ($_POST['receipient'] == 1) {
|
||||
} elseif ($_POST['recipient'] == 1) {
|
||||
if ($userinfo['customers_see_all'] == '1') {
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to ALL customers');
|
||||
$result = Database::query('SELECT `firstname`, `name`, `company`, `email` FROM `' . TABLE_PANEL_CUSTOMERS . "`");
|
||||
@@ -49,7 +49,7 @@ if ($page == 'message') {
|
||||
));
|
||||
}
|
||||
} else {
|
||||
\Froxlor\UI\Response::standard_error('noreceipientsgiven');
|
||||
\Froxlor\UI\Response::standard_error('norecipientsgiven');
|
||||
}
|
||||
|
||||
$subject = $_POST['subject'];
|
||||
@@ -105,7 +105,7 @@ if ($page == 'message') {
|
||||
$sentitems = isset($_GET['sentitems']) ? (int) $_GET['sentitems'] : 0;
|
||||
|
||||
if ($sentitems == 0) {
|
||||
$successmessage = $lng['message']['noreceipients'];
|
||||
$successmessage = $lng['message']['norecipients'];
|
||||
} else {
|
||||
$successmessage = str_replace('%s', $sentitems, $lng['message']['success']);
|
||||
}
|
||||
@@ -116,12 +116,12 @@ if ($page == 'message') {
|
||||
}
|
||||
|
||||
$action = '';
|
||||
$receipients = '';
|
||||
$recipients = '';
|
||||
|
||||
if ($userinfo['customers_see_all'] == '1') {
|
||||
$receipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['reseller'], 0);
|
||||
$recipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['reseller'], 0);
|
||||
}
|
||||
|
||||
$receipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['customer'], 1);
|
||||
$recipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['customer'], 1);
|
||||
eval("echo \"" . \Froxlor\UI\Template::getTemplate('message/message') . "\";");
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ require './lib/init.php';
|
||||
|
||||
if ($action == 'reset' && function_exists('opcache_reset') && $userinfo['change_serversettings'] == '1') {
|
||||
opcache_reset();
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "reseted OPcache");
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "reset OPcache");
|
||||
header('Location: ' . $linker->getLink(array(
|
||||
'section' => 'opcacheinfo',
|
||||
'page' => 'showinfo'
|
||||
|
||||
@@ -66,11 +66,11 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') {
|
||||
'page' => $page
|
||||
), $_part, $settings_all, $settings_part, $only_enabledisable)) {
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles due to changed setting");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// cron.d file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
|
||||
\Froxlor\UI\Response::standard_success('settingssaved', '', array(
|
||||
'filename' => $filename,
|
||||
@@ -146,12 +146,12 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') {
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// cron.d file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
|
||||
\Froxlor\UI\Response::standard_success('rebuildingconfigs', '', array(
|
||||
'filename' => 'admin_index.php'
|
||||
|
||||
@@ -56,6 +56,26 @@ if ($page == 'overview' || $page == 'customers') {
|
||||
$maxyears = date("Y") - $minyear['year'];
|
||||
}
|
||||
|
||||
$params = [];
|
||||
if ($userinfo['customers_see_all'] == '0') {
|
||||
$params = [
|
||||
'id' => $userinfo['adminid']
|
||||
];
|
||||
}
|
||||
$customer_name_list_stmt = Database::prepare("
|
||||
SELECT `customerid`,`company`,`name`,`firstname`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "`
|
||||
WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . "
|
||||
ORDER BY name"
|
||||
);
|
||||
|
||||
$traffic_list_stmt = Database::prepare("
|
||||
SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE year = :year AND `customerid` = :id
|
||||
GROUP BY month ORDER BY month"
|
||||
);
|
||||
|
||||
for ($years = 0; $years <= $maxyears; $years ++) {
|
||||
|
||||
$overview['year'] = date("Y") - $years;
|
||||
@@ -76,14 +96,7 @@ if ($page == 'overview' || $page == 'customers') {
|
||||
'dec' => 0
|
||||
);
|
||||
|
||||
$customer_name_list_stmt = Database::prepare("
|
||||
SELECT `customerid`,`company`,`name`,`firstname`
|
||||
FROM `" . TABLE_PANEL_CUSTOMERS . "`
|
||||
WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . "
|
||||
ORDER BY name");
|
||||
Database::pexecute($customer_name_list_stmt, array(
|
||||
'id' => $userinfo['adminid']
|
||||
));
|
||||
Database::pexecute($customer_name_list_stmt, $params);
|
||||
|
||||
while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
@@ -104,11 +117,6 @@ if ($page == 'overview' || $page == 'customers') {
|
||||
'dec' => '-'
|
||||
);
|
||||
|
||||
$traffic_list_stmt = Database::prepare("
|
||||
SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic
|
||||
FROM `" . TABLE_PANEL_TRAFFIC . "`
|
||||
WHERE year = :year AND `customerid` = :id
|
||||
GROUP BY month ORDER BY month");
|
||||
Database::pexecute($traffic_list_stmt, array(
|
||||
'year' => (date("Y") - $years),
|
||||
'id' => $customer_name['customerid']
|
||||
|
||||
@@ -65,7 +65,7 @@ if ($page == 'overview') {
|
||||
eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/update_end') . "\";");
|
||||
|
||||
\Froxlor\User::updateCounters();
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
@chmod(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php', 0440);
|
||||
|
||||
$successful_update = true;
|
||||
|
||||
122
api_keys.php
122
api_keys.php
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
if (! defined('AREA')) {
|
||||
if (!defined('AREA')) {
|
||||
header("Location: index.php");
|
||||
exit();
|
||||
}
|
||||
@@ -27,68 +27,88 @@ use Froxlor\Database\Database;
|
||||
|
||||
$del_stmt = Database::prepare("DELETE FROM `" . TABLE_API_KEYS . "` WHERE id = :id");
|
||||
$success_message = "";
|
||||
$id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
|
||||
$id = isset($_POST['id']) ? (int) $_POST['id'] : (isset($_GET['id']) ? (int) $_GET['id'] : 0);
|
||||
$area = AREA;
|
||||
|
||||
// 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("
|
||||
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("
|
||||
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(
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
$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("
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
\Froxlor\UI\HTML::askYesNo('api_reallydelete', $filename, array(
|
||||
'page' => $page,
|
||||
'action' => $action,
|
||||
'id' => $id
|
||||
));
|
||||
$success_message = sprintf($lng['apikeys']['apikey_removed'], $id);
|
||||
), $id);
|
||||
}
|
||||
}
|
||||
} elseif ($action == 'add') {
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_API_KEYS . "` SET
|
||||
`apikey` = :key, `secret` = :secret, `adminid` = :aid, `customerid` = :cid, `valid_until` = '-1', `allowed_from` = ''
|
||||
");
|
||||
// customer generates for himself, admins will see a customer-select-box later
|
||||
if (AREA == 'admin') {
|
||||
$cid = 0;
|
||||
} elseif (AREA == 'customer') {
|
||||
$cid = $userinfo['customerid'];
|
||||
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_API_KEYS . "` SET
|
||||
`apikey` = :key, `secret` = :secret, `adminid` = :aid, `customerid` = :cid, `valid_until` = '-1', `allowed_from` = ''
|
||||
");
|
||||
// customer generates for himself, admins will see a customer-select-box later
|
||||
if (AREA == 'admin') {
|
||||
$cid = 0;
|
||||
} elseif (AREA == 'customer') {
|
||||
$cid = $userinfo['customerid'];
|
||||
}
|
||||
$key = hash('sha256', openssl_random_pseudo_bytes(64 * 64));
|
||||
$secret = hash('sha512', openssl_random_pseudo_bytes(64 * 64 * 4));
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'key' => $key,
|
||||
'secret' => $secret,
|
||||
'aid' => $userinfo['adminid'],
|
||||
'cid' => $cid
|
||||
));
|
||||
$success_message = $lng['apikeys']['apikey_added'];
|
||||
} else {
|
||||
\Froxlor\UI\HTML::askYesNo('api_reallyadd', $filename, array(
|
||||
'page' => $page,
|
||||
'action' => $action
|
||||
), $id);
|
||||
}
|
||||
$key = hash('sha256', openssl_random_pseudo_bytes(64 * 64));
|
||||
$secret = hash('sha512', openssl_random_pseudo_bytes(64 * 64 * 4));
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'key' => $key,
|
||||
'secret' => $secret,
|
||||
'aid' => $userinfo['adminid'],
|
||||
'cid' => $cid
|
||||
));
|
||||
$success_message = $lng['apikeys']['apikey_added'];
|
||||
} elseif ($action == 'jqEditApiKey') {
|
||||
$keyid = isset($_POST['id']) ? (int) $_POST['id'] : 0;
|
||||
if (empty($keyid)) {
|
||||
echo json_encode(false);
|
||||
exit;
|
||||
}
|
||||
$allowed_from = isset($_POST['allowed_from']) ? $_POST['allowed_from'] : "";
|
||||
$valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : - 1;
|
||||
$valid_until = isset($_POST['valid_until']) ? (int) $_POST['valid_until'] : -1;
|
||||
|
||||
// validate allowed_from
|
||||
if (! empty($allowed_from)) {
|
||||
if (!empty($allowed_from)) {
|
||||
$ip_list = array_map('trim', explode(",", $allowed_from));
|
||||
$_check_list = $ip_list;
|
||||
foreach ($_check_list as $idx => $ip) {
|
||||
@@ -100,8 +120,8 @@ if ($action == 'delete') {
|
||||
$allowed_from = implode(",", array_unique($ip_list));
|
||||
}
|
||||
|
||||
if ($valid_until <= 0 || ! is_numeric($valid_until)) {
|
||||
$valid_until = - 1;
|
||||
if ($valid_until <= 0 || !is_numeric($valid_until)) {
|
||||
$valid_until = -1;
|
||||
}
|
||||
|
||||
$upd_stmt = Database::prepare("
|
||||
@@ -127,7 +147,7 @@ if ($action == 'delete') {
|
||||
|
||||
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed api::api_keys");
|
||||
|
||||
// select all my (accessable) certificates
|
||||
// select all my (accessible) certificates
|
||||
$keys_stmt_query = "SELECT ak.*, c.loginname, a.loginname as adminname
|
||||
FROM `" . TABLE_API_KEYS . "` ak
|
||||
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `ak`.`customerid`
|
||||
|
||||
23
build.xml
23
build.xml
@@ -6,21 +6,20 @@
|
||||
<property name="pdepend" value="${basedir}/vendor/bin/pdepend" />
|
||||
<property name="phpcpd" value="${basedir}/vendor/bin/phpcpd" />
|
||||
<property name="phpcs" value="${basedir}/vendor/bin/phpcs" />
|
||||
<property name="phpdox" value="${basedir}/vendor/bin/phpdox" />
|
||||
<property name="phploc" value="${basedir}/vendor/bin/phploc" />
|
||||
<property name="phpmd" value="${basedir}/vendor/bin/phpmd" />
|
||||
<property name="phpunit" value="${basedir}/vendor/bin/phpunit" />
|
||||
|
||||
<target name="full-build"
|
||||
depends="prepare,composer,static-analysis,phpunit,phpdox,-check-failure"
|
||||
depends="prepare,composer,static-analysis,phpunit,-check-failure"
|
||||
description="Performs static analysis, runs the tests, and generates project documentation" />
|
||||
|
||||
<target name="full-build-parallel"
|
||||
depends="prepare,composer,static-analysis-parallel,phpunit,phpdox,-check-failure"
|
||||
depends="prepare,composer,static-analysis-parallel,phpunit,-check-failure"
|
||||
description="Performs static analysis (executing the tools in parallel), runs the tests, and generates project documentation" />
|
||||
|
||||
<target name="quick-build"
|
||||
depends="prepare,composer,lint,phpunit-no-coverage"
|
||||
depends="prepare,composer,lint,phpunit-no-coverage,-check-failure"
|
||||
description="Performs a lint check and runs the tests (without generating code coverage reports)" />
|
||||
|
||||
<target name="static-analysis"
|
||||
@@ -49,7 +48,6 @@
|
||||
<delete dir="${basedir}/build/coverage" />
|
||||
<delete dir="${basedir}/build/logs" />
|
||||
<delete dir="${basedir}/build/pdepend" />
|
||||
<delete dir="${basedir}/build/phpdox" />
|
||||
<property name="clean.done" value="true" />
|
||||
</target>
|
||||
|
||||
@@ -59,7 +57,6 @@
|
||||
<mkdir dir="${basedir}/build/coverage" />
|
||||
<mkdir dir="${basedir}/build/logs" />
|
||||
<mkdir dir="${basedir}/build/pdepend" />
|
||||
<mkdir dir="${basedir}/build/phpdox" />
|
||||
|
||||
<property name="prepare.done" value="true" />
|
||||
</target>
|
||||
@@ -257,7 +254,7 @@
|
||||
<target name="phpunit-no-coverage" unless="phpunit.done"
|
||||
depends="composer"
|
||||
description="Run unit tests with PHPUnit (without generating code coverage reports)">
|
||||
<exec executable="${phpunit}" failonerror="true"
|
||||
<exec executable="${phpunit}" failonerror="true" resultproperty="result.phpunit"
|
||||
taskname="phpunit">
|
||||
<arg value="--configuration" />
|
||||
<arg path="${basedir}/phpunit.xml" />
|
||||
@@ -269,18 +266,6 @@
|
||||
<property name="phpunit.done" value="true" />
|
||||
</target>
|
||||
|
||||
<target name="phpdox" unless="phpdox.done"
|
||||
depends="phploc-ci,phpcs-ci,phpcompat-ci,phpmd-ci"
|
||||
description="Generate project documentation using phpDox">
|
||||
<exec executable="${phpdox}" dir="${basedir}/build"
|
||||
taskname="phpdox">
|
||||
<arg value="--file" />
|
||||
<arg path="${basedir}/phpdox.xml" />
|
||||
</exec>
|
||||
|
||||
<property name="phpdox.done" value="true" />
|
||||
</target>
|
||||
|
||||
<target name="-check-failure">
|
||||
<fail message="PHPUnit did not finish successfully">
|
||||
<condition>
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
"issues": "https://github.com/Froxlor/Froxlor/issues",
|
||||
"forum": "https://forum.froxlor.org/",
|
||||
"wiki": "https://github.com/Froxlor/Froxlor/wiki",
|
||||
"irc": "irc://chat.freenode.net/froxlor",
|
||||
"irc": "irc://irc.libera.chat/froxlor",
|
||||
"source": "https://github.com/Froxlor/Froxlor",
|
||||
"docs": "https://github.com/Froxlor/Froxlor/wiki"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"ext-session": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-pdo": "*",
|
||||
@@ -43,23 +43,23 @@
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"phpmailer/phpmailer": "~6.0",
|
||||
"monolog/monolog": "^1.24",
|
||||
"robthree/twofactorauth": "^1.6",
|
||||
"froxlor/idna-convert-legacy": "^2.1",
|
||||
"voku/anti-xss": "^4.1"
|
||||
},
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "8.4.1",
|
||||
"php": ">=7.3",
|
||||
"phpunit/phpunit": "^9",
|
||||
"ext-pcntl": "*",
|
||||
"phpcompatibility/php-compatibility": "*",
|
||||
"squizlabs/php_codesniffer": "*",
|
||||
"pdepend/pdepend": "^2.5",
|
||||
"sebastian/phpcpd": "^4.1",
|
||||
"theseer/phpdox": "^0.12.0",
|
||||
"phploc/phploc": "^5.0",
|
||||
"phpmd/phpmd": "^2.6"
|
||||
"pdepend/pdepend": "^2.9",
|
||||
"sebastian/phpcpd": "^6.0",
|
||||
"phploc/phploc": "^7.0",
|
||||
"phpmd/phpmd": "^2.10",
|
||||
"phpunit/php-timer" : "^5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "*",
|
||||
|
||||
2036
composer.lock
generated
2036
composer.lock
generated
File diff suppressed because it is too large
Load Diff
0
css/images/index.html
Normal file
0
css/images/index.html
Normal file
0
css/index.html
Normal file
0
css/index.html
Normal file
@@ -83,7 +83,7 @@ if ($page == 'overview') {
|
||||
$statsapp = 'webalizer';
|
||||
}
|
||||
$row = [
|
||||
'domain' => $idna_convert->decode($parentdomain)
|
||||
'domain' => $idna_convert->decode($parentdomain ?? '')
|
||||
];
|
||||
eval("\$domains.=\"" . \Froxlor\UI\Template::getTemplate("domains/domains_delimiter") . "\";");
|
||||
|
||||
@@ -472,8 +472,8 @@ if ($page == 'overview') {
|
||||
function formatDomainEntry(&$row, &$idna_convert)
|
||||
{
|
||||
$row['domain'] = $idna_convert->decode($row['domain']);
|
||||
$row['aliasdomain'] = $idna_convert->decode($row['aliasdomain']);
|
||||
$row['domainalias'] = $idna_convert->decode($row['domainalias']);
|
||||
$row['aliasdomain'] = $idna_convert->decode($row['aliasdomain'] ?? '');
|
||||
$row['domainalias'] = $idna_convert->decode($row['domainalias'] ?? '');
|
||||
|
||||
/**
|
||||
* check for set ssl-certs to show different state-icons
|
||||
@@ -503,7 +503,7 @@ function formatDomainEntry(&$row, &$idna_convert)
|
||||
}
|
||||
}
|
||||
|
||||
$row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date']);
|
||||
$row['termination_date'] = str_replace("0000-00-00", "", $row['termination_date'] ?? '');
|
||||
|
||||
$row['termination_css'] = "";
|
||||
if ($row['termination_date'] != "") {
|
||||
|
||||
@@ -212,7 +212,9 @@ if ($page == 'overview') {
|
||||
if (Settings::Get('catchall.catchall_enabled') != '1') {
|
||||
unset($email_add_data['emails_add']['sections']['section_a']['fields']['iscatchall']);
|
||||
}
|
||||
|
||||
if (Settings::Get('mail.greylist_enabled') != '1') {
|
||||
unset($email_edit_data['emails_edit']['sections']['section_a']['fields']['mail_greylist']);
|
||||
}
|
||||
$email_add_form = \Froxlor\UI\HtmlForm::genHTMLForm($email_add_data);
|
||||
|
||||
$title = $email_add_data['emails_add']['title'];
|
||||
@@ -232,7 +234,7 @@ if ($page == 'overview') {
|
||||
\Froxlor\UI\Response::dynamic_error($e->getMessage());
|
||||
}
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
|
||||
|
||||
if (isset($result['email']) && $result['email'] != '') {
|
||||
$result['email'] = $idna_convert->decode($result['email']);
|
||||
$result['email_full'] = $idna_convert->decode($result['email_full']);
|
||||
@@ -260,7 +262,9 @@ if ($page == 'overview') {
|
||||
if (Settings::Get('catchall.catchall_enabled') != '1') {
|
||||
unset($email_edit_data['emails_edit']['sections']['section_a']['fields']['mail_catchall']);
|
||||
}
|
||||
|
||||
if (Settings::Get('mail.greylist_enabled') != '1') {
|
||||
unset($email_edit_data['emails_edit']['sections']['section_a']['fields']['mail_greylist']);
|
||||
}
|
||||
$email_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($email_edit_data);
|
||||
|
||||
$title = $email_edit_data['emails_edit']['title'];
|
||||
@@ -281,7 +285,7 @@ if ($page == 'overview') {
|
||||
try {
|
||||
Emails::getLocal($userinfo, array(
|
||||
'id' => $id,
|
||||
'iscatchall' => ($result['iscatchall'] == '1' ? 0 : 1)
|
||||
'iscatchall' => ($result['iscatchall'] == '1' ? 0 : 1),
|
||||
))->update();
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\UI\Response::dynamic_error($e->getMessage());
|
||||
@@ -292,6 +296,30 @@ if ($page == 'overview') {
|
||||
'id' => $id,
|
||||
's' => $s
|
||||
));
|
||||
} elseif ($action == 'togglegreylist' && $id != 0) {
|
||||
try {
|
||||
$json_result = Emails::getLocal($userinfo, array(
|
||||
'id' => $id
|
||||
))->get();
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\UI\Response::dynamic_error($e->getMessage());
|
||||
}
|
||||
$result = json_decode($json_result, true)['data'];
|
||||
|
||||
try {
|
||||
Emails::getLocal($userinfo, array(
|
||||
'id' => $id,
|
||||
'disablegreylist' => ($result['disablegreylist'] == '1' ? 0 : 1)
|
||||
))->update_greylist();
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\UI\Response::dynamic_error($e->getMessage());
|
||||
}
|
||||
\Froxlor\UI\Response::redirectTo($filename, array(
|
||||
'page' => $page,
|
||||
'action' => 'edit',
|
||||
'id' => $id,
|
||||
's' => $s
|
||||
));
|
||||
}
|
||||
} elseif ($page == 'accounts') {
|
||||
if ($action == 'add' && $id != 0) {
|
||||
|
||||
@@ -93,22 +93,30 @@ if ($page == 'overview') {
|
||||
'cid' => $userinfo['customerid']
|
||||
));
|
||||
|
||||
if ($usages)
|
||||
{
|
||||
$userinfo['diskspace_used'] = round($usages['webspace'] / 1024, Settings::Get('panel.decimal_places'));
|
||||
$userinfo['mailspace_used'] = round($usages['mail'] / 1024, Settings::Get('panel.decimal_places'));
|
||||
$userinfo['dbspace_used'] = round($usages['mysql'] / 1024, Settings::Get('panel.decimal_places'));
|
||||
$userinfo['total_used'] = round(($usages['webspace'] + $usages['mail'] + $usages['mysql']) / 1024, Settings::Get('panel.decimal_places'));
|
||||
// get everything in bytes for the percentage calculation on the dashboard
|
||||
$userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1;
|
||||
$userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1;
|
||||
$userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024;
|
||||
|
||||
if ($usages) {
|
||||
$userinfo['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['webspace'] * 1024, null, 'bi');
|
||||
$userinfo['mailspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['mail'] * 1024, null, 'bi');
|
||||
$userinfo['dbspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['mysql'] * 1024, null, 'bi');
|
||||
$userinfo['total_used'] = \Froxlor\PhpHelper::sizeReadable(($usages['webspace'] + $usages['mail'] + $usages['mysql']) * 1024, null, 'bi');
|
||||
$userinfo['diskspace_bytes_used'] = $usages['webspace'] * 1024;
|
||||
$userinfo['total_bytes_used'] = ($usages['webspace'] + $usages['mail'] + $usages['mysql']) * 1024;
|
||||
} else {
|
||||
$userinfo['diskspace_used'] = 0;
|
||||
$userinfo['mailspace_used'] = 0;
|
||||
$userinfo['dbspace_used'] = 0;
|
||||
$userinfo['total_used'] = 0;
|
||||
$userinfo['diskspace_bytes_used'] = 0;
|
||||
$userinfo['total_bytes_used'] = 0;
|
||||
}
|
||||
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places'));
|
||||
$userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
|
||||
$userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
|
||||
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
|
||||
$userinfo['diskspace'] = ($userinfo['diskspace'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace'] * 1024, null, 'bi') : - 1;
|
||||
$userinfo['traffic'] = ($userinfo['traffic'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['traffic'] * 1024, null, 'bi') : - 1;
|
||||
$userinfo['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['traffic_used'] * 1024, null, 'bi');
|
||||
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace diskspace_bytes traffic traffic_bytes mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
|
||||
|
||||
$userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : '';
|
||||
|
||||
@@ -123,19 +131,25 @@ if ($page == 'overview') {
|
||||
if ($userinfo['perlenabled'] == '1')
|
||||
$se[] = "Perl/CGI";
|
||||
if ($userinfo['api_allowed'] == '1')
|
||||
$se[] = '<a href="customer_index.php?s='.$s.'&page=apikeys">API</a>';
|
||||
$se[] = '<a href="customer_index.php?s=' . $s . '&page=apikeys">API</a>';
|
||||
$services_enabled = implode(", ", $se);
|
||||
|
||||
eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";");
|
||||
} elseif ($page == 'change_password') {
|
||||
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
$old_password = \Froxlor\Validate\Validate::validate($_POST['old_password'], 'old password');
|
||||
|
||||
if (! \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_CUSTOMERS, 'customerid')) {
|
||||
\Froxlor\UI\Response::standard_error('oldpasswordnotcorrect');
|
||||
}
|
||||
|
||||
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
|
||||
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
|
||||
try {
|
||||
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
|
||||
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\UI\Response::dynamic_error($e->getMessage());
|
||||
}
|
||||
|
||||
if ($old_password == '') {
|
||||
\Froxlor\UI\Response::standard_error(array(
|
||||
|
||||
@@ -24,7 +24,7 @@ use Froxlor\Api\Commands\DomainZones as DomainZones;
|
||||
// This file is being included in admin_domains and customer_domains
|
||||
// and therefore does not need to require lib/init.php
|
||||
|
||||
$domain_id = isset($_GET['domain_id']) ? (int) $_GET['domain_id'] : null;
|
||||
$domain_id = isset($_GET['domain_id']) ? (int) $_GET['domain_id'] : (isset($_POST['domain_id']) ? (int)$_POST['domain_id'] : null);
|
||||
|
||||
$record = isset($_POST['record']['record']) ? trim($_POST['record']['record']) : null;
|
||||
$type = isset($_POST['record']['type']) ? $_POST['record']['type'] : 'A';
|
||||
@@ -56,17 +56,25 @@ if ($action == 'add_record' && ! empty($_POST)) {
|
||||
}
|
||||
} elseif ($action == 'delete') {
|
||||
// remove entry
|
||||
$entry_id = isset($_GET['id']) ? (int) $_GET['id'] : 0;
|
||||
if ($entry_id > 0) {
|
||||
try {
|
||||
DomainZones::getLocal($userinfo, array(
|
||||
'entry_id' => $entry_id,
|
||||
'id' => $domain_id
|
||||
))->delete();
|
||||
// success message (inline)
|
||||
$success_message = $lng['success']['dns_record_deleted'];
|
||||
} catch (Exception $e) {
|
||||
$errors = str_replace("\n", "<br>", $e->getMessage());
|
||||
if ($id > 0) {
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
try {
|
||||
DomainZones::getLocal($userinfo, array(
|
||||
'entry_id' => $id,
|
||||
'id' => $domain_id
|
||||
))->delete();
|
||||
// success message (inline)
|
||||
$success_message = $lng['success']['dns_record_deleted'];
|
||||
} catch (Exception $e) {
|
||||
$errors = str_replace("\n", "<br>", $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
\Froxlor\UI\HTML::askYesNo('dnsentry_reallydelete', $filename, array(
|
||||
'page' => $page,
|
||||
'action' => $action,
|
||||
'id' => $id,
|
||||
'domain_id' => $domain_id
|
||||
), $id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
doc/example/index.html
Normal file
0
doc/example/index.html
Normal file
0
doc/index.html
Normal file
0
doc/index.html
Normal file
293
index.php
293
index.php
@@ -22,12 +22,19 @@ require './lib/init.php';
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\FroxlorLogger;
|
||||
use Froxlor\Validate\Validate;
|
||||
|
||||
if ($action == '') {
|
||||
$action = 'login';
|
||||
}
|
||||
|
||||
if (session_status() == PHP_SESSION_NONE) {
|
||||
ini_set("session.name", "s");
|
||||
ini_set("url_rewriter.tags", "");
|
||||
ini_set("session.use_cookies", false);
|
||||
ini_set("session.cookie_httponly", true);
|
||||
ini_set("session.cookie_secure", $is_ssl);
|
||||
session_id('login');
|
||||
session_start();
|
||||
}
|
||||
|
||||
@@ -114,7 +121,7 @@ if ($action == '2fa_entercode') {
|
||||
));
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($row['customer'] == $loginname) {
|
||||
if ($row && $row['customer'] == $loginname) {
|
||||
$table = "`" . TABLE_PANEL_CUSTOMERS . "`";
|
||||
$uid = 'customerid';
|
||||
$adminsession = '0';
|
||||
@@ -142,7 +149,7 @@ if ($action == '2fa_entercode') {
|
||||
"loginname" => $loginname
|
||||
));
|
||||
$row3 = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if ($row3['customer'] == $loginname) {
|
||||
if ($row3 && $row3['customer'] == $loginname) {
|
||||
$table = "`" . TABLE_PANEL_CUSTOMERS . "`";
|
||||
$uid = 'customerid';
|
||||
$adminsession = '0';
|
||||
@@ -181,7 +188,7 @@ if ($action == '2fa_entercode') {
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
if ($row['admin'] == $loginname) {
|
||||
if ($row && $row['admin'] == $loginname) {
|
||||
$table = "`" . TABLE_PANEL_ADMINS . "`";
|
||||
$uid = 'adminid';
|
||||
$adminsession = '1';
|
||||
@@ -346,8 +353,7 @@ if ($action == '2fa_entercode') {
|
||||
$message = sprintf($lng['error']['login_blocked'], Settings::Get('login.deactivatetime'));
|
||||
break;
|
||||
case 4:
|
||||
$cmail = isset($_GET['customermail']) ? $_GET['customermail'] : 'unknown';
|
||||
$message = str_replace('%s', $cmail, $lng['error']['errorsendingmail']);
|
||||
$message = $lng['error']['errorsendingmailpub'];
|
||||
break;
|
||||
case 5:
|
||||
$message = $lng['error']['user_banned'];
|
||||
@@ -372,6 +378,8 @@ if ($action == '2fa_entercode') {
|
||||
$lastscript = "";
|
||||
if (isset($_REQUEST['script']) && $_REQUEST['script'] != "") {
|
||||
$lastscript = $_REQUEST['script'];
|
||||
$lastscript = str_replace("..", "", $lastscript);
|
||||
$lastscript = htmlspecialchars($lastscript, ENT_QUOTES);
|
||||
|
||||
if (! file_exists(__DIR__ . "/" . $lastscript)) {
|
||||
$lastscript = "";
|
||||
@@ -417,159 +425,162 @@ if ($action == 'forgotpwd') {
|
||||
}
|
||||
}
|
||||
|
||||
if ($result_stmt !== null) {
|
||||
$user = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
/* Check whether user is banned */
|
||||
if ($user['deactivated']) {
|
||||
\Froxlor\UI\Response::redirectTo('index.php', array(
|
||||
'showmessage' => '8'
|
||||
));
|
||||
exit();
|
||||
$no_action = false;
|
||||
if ($adminchecked) {
|
||||
if (Settings::Get('panel.allow_preset_admin') != '1') {
|
||||
$message = $lng['pwdreminder']['notallowed'];
|
||||
unset($adminchecked);
|
||||
}
|
||||
} else {
|
||||
if (Settings::Get('panel.allow_preset') != '1') {
|
||||
$message = $lng['pwdreminder']['notallowed'];
|
||||
}
|
||||
}
|
||||
|
||||
if (($adminchecked && Settings::Get('panel.allow_preset_admin') == '1') || $adminchecked == false) {
|
||||
if ($user !== false) {
|
||||
// build a activation code
|
||||
$timestamp = time();
|
||||
$first = substr(md5($user['loginname'] . $timestamp . \Froxlor\PhpHelper::randomStr(16)), 0, 15);
|
||||
$third = substr(md5($user['email'] . $timestamp . \Froxlor\PhpHelper::randomStr(16)), - 15);
|
||||
$activationcode = $first . $timestamp . $third . substr(md5($third . $timestamp), 0, 10);
|
||||
if (empty($message)) {
|
||||
if ($result_stmt !== null) {
|
||||
$user = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// Drop all existing activation codes for this user
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_ACTIVATION . "`
|
||||
WHERE `userid` = :userid
|
||||
AND `admin` = :admin");
|
||||
$params = array(
|
||||
"userid" => $adminchecked ? $user['adminid'] : $user['customerid'],
|
||||
"admin" => $adminchecked ? 1 : 0
|
||||
);
|
||||
Database::pexecute($stmt, $params);
|
||||
|
||||
// Add new activation code to database
|
||||
$stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_ACTIVATION . "`
|
||||
(userid, admin, creation, activationcode)
|
||||
VALUES (:userid, :admin, :creation, :activationcode)");
|
||||
$params = array(
|
||||
"userid" => $adminchecked ? $user['adminid'] : $user['customerid'],
|
||||
"admin" => $adminchecked ? 1 : 0,
|
||||
"creation" => $timestamp,
|
||||
"activationcode" => $activationcode
|
||||
);
|
||||
Database::pexecute($stmt, $params);
|
||||
|
||||
$rstlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'password_reset'
|
||||
/* Check whether user is banned */
|
||||
if ($user['deactivated']) {
|
||||
\Froxlor\UI\Response::redirectTo('index.php', array(
|
||||
'showmessage' => '8'
|
||||
));
|
||||
$rstlog->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "User '" . $user['loginname'] . "' requested a link for setting a new password.");
|
||||
exit();
|
||||
}
|
||||
|
||||
// Set together our activation link
|
||||
$protocol = empty($_SERVER['HTTPS']) ? 'http' : 'https';
|
||||
// this can be a fixed value to avoid potential exploiting by modifying headers
|
||||
$host = Settings::Get('system.hostname'); // $_SERVER['HTTP_HOST'];
|
||||
$port = $_SERVER['SERVER_PORT'] != 80 ? ':' . $_SERVER['SERVER_PORT'] : '';
|
||||
// don't add :443 when https is used, as it is default (and just looks weird!)
|
||||
if ($protocol == 'https' && $_SERVER['SERVER_PORT'] == '443') {
|
||||
$port = '';
|
||||
}
|
||||
// there can be only one script to handle this so we can use a fixed value here
|
||||
$script = "/index.php"; // $_SERVER['SCRIPT_NAME'];
|
||||
if (Settings::Get('system.froxlordirectlyviahostname') == 0) {
|
||||
$script = \Froxlor\FileDir::makeCorrectFile("/" . basename(__DIR__) . "/" . $script);
|
||||
}
|
||||
$activationlink = $protocol . '://' . $host . $port . $script . '?action=resetpwd&resetcode=' . $activationcode;
|
||||
if (($adminchecked && Settings::Get('panel.allow_preset_admin') == '1') || $adminchecked == false) {
|
||||
if ($user !== false) {
|
||||
// build a activation code
|
||||
$timestamp = time();
|
||||
$first = substr(md5($user['loginname'] . $timestamp . \Froxlor\PhpHelper::randomStr(16)), 0, 15);
|
||||
$third = substr(md5($user['email'] . $timestamp . \Froxlor\PhpHelper::randomStr(16)), - 15);
|
||||
$activationcode = $first . $timestamp . $third . substr(md5($third . $timestamp), 0, 10);
|
||||
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($user),
|
||||
'NAME' => $user['name'],
|
||||
'FIRSTNAME' => $user['firstname'] ?? "",
|
||||
'COMPANY' => $user['company'] ?? "",
|
||||
'CUSTOMER_NO' => $user['customernumber'] ?? 0,
|
||||
'USERNAME' => $loginname,
|
||||
'LINK' => $activationlink
|
||||
);
|
||||
// Drop all existing activation codes for this user
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_ACTIVATION . "`
|
||||
WHERE `userid` = :userid
|
||||
AND `admin` = :admin");
|
||||
$params = array(
|
||||
"userid" => $adminchecked ? $user['adminid'] : $user['customerid'],
|
||||
"admin" => $adminchecked ? 1 : 0
|
||||
);
|
||||
Database::pexecute($stmt, $params);
|
||||
|
||||
$def_language = ($user['def_language'] != '') ? $user['def_language'] : Settings::Get('panel.standardlanguage');
|
||||
$result_stmt = Database::prepare('SELECT `value` FROM `' . TABLE_PANEL_TEMPLATES . '`
|
||||
WHERE `adminid`= :adminid
|
||||
AND `language`= :lang
|
||||
AND `templategroup`=\'mails\'
|
||||
AND `varname`=\'password_reset_subject\'');
|
||||
Database::pexecute($result_stmt, array(
|
||||
"adminid" => $user['adminid'],
|
||||
"lang" => $def_language
|
||||
));
|
||||
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result['value'] != '') ? $result['value'] : $lng['mails']['password_reset']['subject']), $replace_arr));
|
||||
// Add new activation code to database
|
||||
$stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_ACTIVATION . "`
|
||||
(userid, admin, creation, activationcode)
|
||||
VALUES (:userid, :admin, :creation, :activationcode)");
|
||||
$params = array(
|
||||
"userid" => $adminchecked ? $user['adminid'] : $user['customerid'],
|
||||
"admin" => $adminchecked ? 1 : 0,
|
||||
"creation" => $timestamp,
|
||||
"activationcode" => $activationcode
|
||||
);
|
||||
Database::pexecute($stmt, $params);
|
||||
|
||||
$result_stmt = Database::prepare('SELECT `value` FROM `' . TABLE_PANEL_TEMPLATES . '`
|
||||
WHERE `adminid`= :adminid
|
||||
AND `language`= :lang
|
||||
AND `templategroup`=\'mails\'
|
||||
AND `varname`=\'password_reset_mailbody\'');
|
||||
Database::pexecute($result_stmt, array(
|
||||
"adminid" => $user['adminid'],
|
||||
"lang" => $def_language
|
||||
));
|
||||
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result['value'] != '') ? $result['value'] : $lng['mails']['password_reset']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->AltBody = $mail_body;
|
||||
$mail->MsgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$mail->AddAddress($user['email'], \Froxlor\User::getCorrectUserSalutation($user));
|
||||
$mail->Send();
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$rstlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'password_reset'
|
||||
));
|
||||
$rstlog->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
$rstlog->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "User '" . $user['loginname'] . "' requested a link for setting a new password.");
|
||||
|
||||
// Set together our activation link
|
||||
$protocol = empty($_SERVER['HTTPS']) ? 'http' : 'https';
|
||||
// this can be a fixed value to avoid potential exploiting by modifying headers
|
||||
$host = Settings::Get('system.hostname'); // $_SERVER['HTTP_HOST'];
|
||||
$port = $_SERVER['SERVER_PORT'] != 80 ? ':' . $_SERVER['SERVER_PORT'] : '';
|
||||
// don't add :443 when https is used, as it is default (and just looks weird!)
|
||||
if ($protocol == 'https' && $_SERVER['SERVER_PORT'] == '443') {
|
||||
$port = '';
|
||||
}
|
||||
// there can be only one script to handle this so we can use a fixed value here
|
||||
$script = "/index.php"; // $_SERVER['SCRIPT_NAME'];
|
||||
if (Settings::Get('system.froxlordirectlyviahostname') == 0) {
|
||||
$script = \Froxlor\FileDir::makeCorrectFile("/" . basename(__DIR__) . "/" . $script);
|
||||
}
|
||||
$activationlink = $protocol . '://' . $host . $port . $script . '?action=resetpwd&resetcode=' . $activationcode;
|
||||
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($user),
|
||||
'NAME' => $user['name'],
|
||||
'FIRSTNAME' => $user['firstname'] ?? "",
|
||||
'COMPANY' => $user['company'] ?? "",
|
||||
'CUSTOMER_NO' => $user['customernumber'] ?? 0,
|
||||
'USERNAME' => $loginname,
|
||||
'LINK' => $activationlink
|
||||
);
|
||||
|
||||
$def_language = ($user['def_language'] != '') ? $user['def_language'] : Settings::Get('panel.standardlanguage');
|
||||
$result_stmt = Database::prepare('SELECT `value` FROM `' . TABLE_PANEL_TEMPLATES . '`
|
||||
WHERE `adminid`= :adminid
|
||||
AND `language`= :lang
|
||||
AND `templategroup`=\'mails\'
|
||||
AND `varname`=\'password_reset_subject\'');
|
||||
Database::pexecute($result_stmt, array(
|
||||
"adminid" => $user['adminid'],
|
||||
"lang" => $def_language
|
||||
));
|
||||
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result['value'] != '') ? $result['value'] : $lng['mails']['password_reset']['subject']), $replace_arr));
|
||||
|
||||
$result_stmt = Database::prepare('SELECT `value` FROM `' . TABLE_PANEL_TEMPLATES . '`
|
||||
WHERE `adminid`= :adminid
|
||||
AND `language`= :lang
|
||||
AND `templategroup`=\'mails\'
|
||||
AND `varname`=\'password_reset_mailbody\'');
|
||||
Database::pexecute($result_stmt, array(
|
||||
"adminid" => $user['adminid'],
|
||||
"lang" => $def_language
|
||||
));
|
||||
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result['value'] != '') ? $result['value'] : $lng['mails']['password_reset']['mailbody']), $replace_arr));
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$mail->Subject = $mail_subject;
|
||||
$mail->AltBody = $mail_body;
|
||||
$mail->MsgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$mail->AddAddress($user['email'], \Froxlor\User::getCorrectUserSalutation($user));
|
||||
$mail->Send();
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$rstlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'password_reset'
|
||||
));
|
||||
$rstlog->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
|
||||
\Froxlor\UI\Response::redirectTo('index.php', array(
|
||||
'showmessage' => '4',
|
||||
'customermail' => $user['email']
|
||||
));
|
||||
exit();
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
\Froxlor\UI\Response::redirectTo('index.php', array(
|
||||
'showmessage' => '4',
|
||||
'customermail' => $user['email']
|
||||
'showmessage' => '1'
|
||||
));
|
||||
exit();
|
||||
} else {
|
||||
$rstlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'password_reset'
|
||||
));
|
||||
$rstlog->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "User '" . $loginname . "' requested to set a new password, but was not found in database!");
|
||||
$message = $lng['login']['combination_not_found'];
|
||||
}
|
||||
|
||||
$mail->ClearAddresses();
|
||||
\Froxlor\UI\Response::redirectTo('index.php', array(
|
||||
'showmessage' => '1'
|
||||
));
|
||||
exit();
|
||||
} else {
|
||||
$rstlog = FroxlorLogger::getInstanceOf(array(
|
||||
'loginname' => 'password_reset'
|
||||
));
|
||||
$rstlog->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "User '" . $loginname . "' requested to set a new password, but was not found in database!");
|
||||
$message = $lng['login']['combination_not_found'];
|
||||
unset($user);
|
||||
}
|
||||
|
||||
unset($user);
|
||||
} else {
|
||||
$message = $lng['pwdreminder']['notallowed'];
|
||||
}
|
||||
} else {
|
||||
$message = $lng['login']['usernotfound'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($adminchecked) {
|
||||
if (Settings::Get('panel.allow_preset_admin') != '1') {
|
||||
$message = $lng['pwdreminder']['notallowed'];
|
||||
unset($adminchecked);
|
||||
}
|
||||
} else {
|
||||
if (Settings::Get('panel.allow_preset') != '1') {
|
||||
$message = $lng['pwdreminder']['notallowed'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -669,7 +680,7 @@ function finishLogin($userinfo)
|
||||
global $version, $dbversion, $remote_addr, $http_user_agent, $languages;
|
||||
|
||||
if (isset($userinfo['userid']) && $userinfo['userid'] != '') {
|
||||
$s = md5(uniqid(microtime(), 1));
|
||||
$s = \Froxlor\Froxlor::genSessionId();
|
||||
|
||||
if (isset($_POST['language'])) {
|
||||
$language = \Froxlor\Validate\Validate::validate($_POST['language'], 'language');
|
||||
|
||||
@@ -71,6 +71,7 @@ CREATE TABLE `mail_virtual` (
|
||||
`customerid` int(11) NOT NULL default '0',
|
||||
`popaccountid` int(11) NOT NULL default '0',
|
||||
`iscatchall` tinyint(1) unsigned NOT NULL default '0',
|
||||
`description` varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `email` (`email`)
|
||||
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
@@ -269,12 +270,13 @@ CREATE TABLE `panel_domains` (
|
||||
`writeaccesslog` tinyint(1) DEFAULT '1',
|
||||
`writeerrorlog` tinyint(1) DEFAULT '1',
|
||||
`override_tls` tinyint(1) DEFAULT '0',
|
||||
`ssl_protocols` text,
|
||||
`ssl_cipher_list` text,
|
||||
`tlsv13_cipher_list` text,
|
||||
`ssl_protocols` varchar(255) NOT NULL DEFAULT '',
|
||||
`ssl_cipher_list` varchar(500) NOT NULL DEFAULT '',
|
||||
`tlsv13_cipher_list` varchar(500) NOT NULL DEFAULT '',
|
||||
`ssl_enabled` tinyint(1) DEFAULT '1',
|
||||
`ssl_honorcipherorder` tinyint(1) DEFAULT '0',
|
||||
`ssl_sessiontickets` tinyint(1) DEFAULT '1',
|
||||
`description` varchar(255) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `customerid` (`customerid`),
|
||||
KEY `parentdomain` (`parentdomainid`),
|
||||
@@ -387,6 +389,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
|
||||
('dkim', 'dkim_domains', 'domains'),
|
||||
('dkim', 'dkim_dkimkeys', 'dkim-keys.conf'),
|
||||
('dkim', 'dkimrestart_command', '/etc/init.d/dkim-filter restart'),
|
||||
('dkim', 'privkeysuffix', '.priv'),
|
||||
('admin', 'show_news_feed', '0'),
|
||||
('admin', 'show_version_login', '0'),
|
||||
('admin', 'show_version_footer', '0'),
|
||||
@@ -492,7 +495,6 @@ opcache.load_comments
|
||||
opcache.revalidate_path
|
||||
opcache.save_comments
|
||||
opcache.use_cwd
|
||||
opcache.validate_timestamps
|
||||
opcache.fast_shutdown'),
|
||||
('phpfpm', 'ini_admin_values', 'cgi.redirect_status_env
|
||||
date.timezone
|
||||
@@ -516,7 +518,8 @@ opcache.restrict_api
|
||||
opcache.revalidate_freq
|
||||
opcache.max_accelerated_files
|
||||
opcache.memory_consumption
|
||||
opcache.interned_strings_buffer'),
|
||||
opcache.interned_strings_buffer
|
||||
opcache.validate_timestamps'),
|
||||
('nginx', 'fastcgiparams', '/etc/nginx/fastcgi_params'),
|
||||
('system', 'lastaccountnumber', '0'),
|
||||
('system', 'lastguid', '9999'),
|
||||
@@ -529,7 +532,7 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'vmail_gid', '2000'),
|
||||
('system', 'vmail_homedir', '/var/customers/mail/'),
|
||||
('system', 'vmail_maildirname', 'Maildir'),
|
||||
('system', 'bind_enable', '1'),
|
||||
('system', 'bind_enable', '0'),
|
||||
('system', 'bindconf_directory', '/etc/bind/'),
|
||||
('system', 'bindreload_command', '/etc/init.d/bind9 reload'),
|
||||
('system', 'hostname', 'SERVERNAME'),
|
||||
@@ -608,6 +611,7 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'documentroot_use_default_value', '0'),
|
||||
('system', 'passwordcryptfunc', '3'),
|
||||
('system', 'axfrservers', ''),
|
||||
('system', 'powerdns_mode', 'Native'),
|
||||
('system', 'customer_ssl_path', '/etc/ssl/froxlor-custom/'),
|
||||
('system', 'allow_error_report_admin', '1'),
|
||||
('system', 'allow_error_report_customer', '0'),
|
||||
@@ -625,7 +629,7 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'apacheitksupport', '0'),
|
||||
('system', 'leprivatekey', 'unset'),
|
||||
('system', 'lepublickey', 'unset'),
|
||||
('system', 'letsencryptca', 'production'),
|
||||
('system', 'letsencryptca', 'letsencrypt'),
|
||||
('system', 'letsencryptcountrycode', 'DE'),
|
||||
('system', 'letsencryptstate', 'Hessen'),
|
||||
('system', 'letsencryptchallengepath', '/var/www/froxlor'),
|
||||
@@ -671,6 +675,14 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'froxloraliases', ''),
|
||||
('system', 'apply_specialsettings_default', '1'),
|
||||
('system', 'apply_phpconfigs_default', '1'),
|
||||
('system', 'hide_incompatible_settings', '0'),
|
||||
('system', 'include_default_vhostconf', '0'),
|
||||
('system', 'soaemail', ''),
|
||||
('system', 'domaindefaultalias', '0'),
|
||||
('system', 'createstdsubdom_default', '1'),
|
||||
('system', 'froxlorusergroup', ''),
|
||||
('system', 'froxlorusergroup_gid', ''),
|
||||
('system', 'acmeshpath', '/root/.acme.sh/acme.sh'),
|
||||
('api', 'enabled', '0'),
|
||||
('2fa', 'enabled', '1'),
|
||||
('panel', 'decimal_places', '4'),
|
||||
@@ -683,7 +695,6 @@ opcache.interned_strings_buffer'),
|
||||
('panel', 'paging', '20'),
|
||||
('panel', 'natsorting', '1'),
|
||||
('panel', 'sendalternativemail', '0'),
|
||||
('panel', 'no_robots', '1'),
|
||||
('panel', 'allow_domain_change_admin', '0'),
|
||||
('panel', 'allow_domain_change_customer', '0'),
|
||||
('panel', 'frontend', 'froxlor'),
|
||||
@@ -705,8 +716,15 @@ opcache.interned_strings_buffer'),
|
||||
('panel', 'password_special_char', '!?<>§$%+#=@'),
|
||||
('panel', 'customer_hide_options', ''),
|
||||
('panel', 'is_configured', '0'),
|
||||
('panel', 'version', '0.10.23.1'),
|
||||
('panel', 'db_version', '202009070');
|
||||
('panel', 'imprint_url', ''),
|
||||
('panel', 'terms_url', ''),
|
||||
('panel', 'privacy_url', ''),
|
||||
('panel', 'logo_image_header', ''),
|
||||
('panel', 'logo_image_login', ''),
|
||||
('panel', 'logo_overridetheme', '0'),
|
||||
('panel', 'logo_overridecustom', '0'),
|
||||
('panel', 'version', '0.10.38.3'),
|
||||
('panel', 'db_version', '202112310');
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_tasks`;
|
||||
@@ -805,7 +823,8 @@ INSERT INTO `panel_languages` (`id`, `language`, `iso`, `file`) VALUES
|
||||
(4, 'Português', 'pt', 'lng/portugues.lng.php'),
|
||||
(5, 'Italiano', 'it', 'lng/italian.lng.php'),
|
||||
(6, 'Nederlands', 'nl', 'lng/dutch.lng.php'),
|
||||
(7, 'Svenska', 'sv', 'lng/swedish.lng.php');
|
||||
(7, 'Svenska', 'sv', 'lng/swedish.lng.php'),
|
||||
(8, 'Česká republika', 'cs', 'lng/czech.lng.php');
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_syslog`;
|
||||
@@ -923,7 +942,7 @@ CREATE TABLE IF NOT EXISTS `ftp_quotalimits` (
|
||||
|
||||
|
||||
|
||||
INSERT INTO `ftp_quotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES
|
||||
INSERT INTO `ftp_quotalimits` (`name`, `quota_type`, `per_session`, `limit_type`, `bytes_in_avail`, `bytes_out_avail`, `bytes_xfer_avail`, `files_in_avail`, `files_out_avail`, `files_xfer_avail`) VALUES
|
||||
('froxlor', 'user', 'false', 'hard', 0, 0, 0, 0, 0, 0);
|
||||
|
||||
|
||||
|
||||
0
install/index.html
Normal file
0
install/index.html
Normal file
@@ -28,7 +28,7 @@
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Install
|
||||
*
|
||||
*
|
||||
*/
|
||||
class FroxlorInstall
|
||||
{
|
||||
@@ -123,7 +123,7 @@ class FroxlorInstall
|
||||
if ((isset($_POST['installstep']) && $_POST['installstep'] == '1') || (isset($_GET['check']) && $_GET['check'] == '1')) {
|
||||
$pagetitle = $this->_lng['install']['title'];
|
||||
if ($this->_checkPostData()) {
|
||||
// ceck data and create userdata etc.etc.etc.
|
||||
// check data and create userdata etc.etc.etc.
|
||||
$result = $this->_doInstall();
|
||||
} elseif (isset($_GET['check']) && $_GET['check'] == '1') {
|
||||
// gather data
|
||||
@@ -163,10 +163,13 @@ class FroxlorInstall
|
||||
|
||||
$this->_getPostField('mysql_host', '127.0.0.1');
|
||||
$this->_getPostField('mysql_database', 'froxlor');
|
||||
$this->_getPostField('mysql_forcecreate', '0');
|
||||
$this->_getPostField('mysql_unpriv_user', 'froxlor');
|
||||
$this->_getPostField('mysql_unpriv_pass');
|
||||
$this->_getPostField('mysql_root_user', 'root');
|
||||
$this->_getPostField('mysql_root_pass');
|
||||
$this->_getPostField('mysql_ssl_ca_file');
|
||||
$this->_getPostField('mysql_ssl_verify_server_certificate', 0);
|
||||
$this->_getPostField('admin_user', 'admin');
|
||||
$this->_getPostField('admin_pass1');
|
||||
$this->_getPostField('admin_pass2');
|
||||
@@ -212,6 +215,12 @@ class FroxlorInstall
|
||||
$options = array(
|
||||
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
|
||||
);
|
||||
|
||||
if (!empty($this->_data['mysql_ssl_ca_file'])) {
|
||||
$options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file'];
|
||||
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate'];
|
||||
}
|
||||
|
||||
$dsn = "mysql:host=" . $this->_data['mysql_host'] . ";";
|
||||
$fatal_fail = false;
|
||||
try {
|
||||
@@ -246,15 +255,23 @@ class FroxlorInstall
|
||||
$content .= $this->_status_message('green', "OK");
|
||||
// check for existing db and create backup if so
|
||||
$content .= $this->_backupExistingDatabase($db_root);
|
||||
// create unprivileged user and the database itself
|
||||
$content .= $this->_createDatabaseAndUser($db_root);
|
||||
// importing data to new database
|
||||
$content .= $this->_importDatabaseData();
|
||||
if (!$this->_abort) {
|
||||
// create unprivileged user and the database itself
|
||||
$content .= $this->_createDatabaseAndUser($db_root);
|
||||
// importing data to new database
|
||||
$content .= $this->_importDatabaseData();
|
||||
}
|
||||
if (! $this->_abort) {
|
||||
// create DB object for new database
|
||||
$options = array(
|
||||
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
|
||||
);
|
||||
|
||||
if (!empty($this->_data['mysql_ssl_ca_file'])) {
|
||||
$options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file'];
|
||||
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate'];
|
||||
}
|
||||
|
||||
$dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";";
|
||||
$another_fail = false;
|
||||
try {
|
||||
@@ -324,10 +341,14 @@ class FroxlorInstall
|
||||
$userdata .= "\$sql['user']='" . addcslashes($this->_data['mysql_unpriv_user'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql['password']='" . addcslashes($this->_data['mysql_unpriv_pass'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql['db']='" . addcslashes($this->_data['mysql_database'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql['ssl']['caFile']='" . addcslashes($this->_data['mysql_ssl_ca_file'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql['ssl']['verifyServerCertificate']='" . addcslashes($this->_data['mysql_ssl_verify_server_certificate'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['caption']='Default';\n";
|
||||
$userdata .= "\$sql_root[0]['host']='" . addcslashes($this->_data['mysql_host'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['user']='" . addcslashes($this->_data['mysql_root_user'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['password']='" . addcslashes($this->_data['mysql_root_pass'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['ssl']['caFile']='" . addcslashes($this->_data['mysql_ssl_ca_file'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['ssl']['verifyServerCertificate']='" . addcslashes($this->_data['mysql_ssl_verify_server_certificate'], "'\\") . "';\n";
|
||||
$userdata .= "// enable debugging to browser in case of SQL errors\n";
|
||||
$userdata .= "\$sql['debug'] = false;\n";
|
||||
$userdata .= "?>";
|
||||
@@ -360,6 +381,30 @@ class FroxlorInstall
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate safe unique token
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
private function genUniqueToken(int $length = 16)
|
||||
{
|
||||
if(!isset($length) || intval($length) <= 8 ){
|
||||
$length = 16;
|
||||
}
|
||||
if (function_exists('random_bytes')) {
|
||||
return bin2hex(random_bytes($length));
|
||||
}
|
||||
if (function_exists('mcrypt_create_iv')) {
|
||||
return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
|
||||
}
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
return bin2hex(openssl_random_pseudo_bytes($length));
|
||||
}
|
||||
// if everything else fails, use unsafe fallback
|
||||
return md5(uniqid(microtime(), 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* create corresponding entries in froxlor database
|
||||
*
|
||||
@@ -403,8 +448,8 @@ class FroxlorInstall
|
||||
$content .= $this->_status_message('begin', $this->_lng['install']['adding_admin_user']);
|
||||
$ins_data = array(
|
||||
'loginname' => $this->_data['admin_user'],
|
||||
/* use SHA256 default crypt */
|
||||
'password' => crypt($this->_data['admin_pass1'], '$5$' . md5(uniqid(microtime(), 1)) . md5(uniqid(microtime(), 1))),
|
||||
/* use SHA256 default crypt */
|
||||
'password' => crypt($this->_data['admin_pass1'], '$5$' . $this->genUniqueToken() . $this->genUniqueToken()),
|
||||
'email' => 'admin@' . $this->_data['servername'],
|
||||
'deflang' => $this->_languages[$this->_activelng]
|
||||
);
|
||||
@@ -505,16 +550,23 @@ class FroxlorInstall
|
||||
$this->_updateSetting($upd_stmt, 'error', 'system', 'errorlog_level');
|
||||
}
|
||||
|
||||
/*
|
||||
* not yet used in configfiles
|
||||
* -> 0.11.x
|
||||
*
|
||||
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
|
||||
foreach ($distros as $_distribution) {
|
||||
if ($this->_data['distribution'] == str_replace(".xml", "", strtolower(basename($_distribution)))) {
|
||||
$dist = new \Froxlor\Config\ConfigParser($_distribution);
|
||||
$defaults = $dist->getDefaults();
|
||||
foreach ($defaults->property as $property) {
|
||||
$this->_updateSetting($upd_stmt, $property->value, $property->settinggroup, $property->varname);
|
||||
if (!empty($defaults)) {
|
||||
foreach ($defaults as $property) {
|
||||
$this->_updateSetting($upd_stmt, $property->attributes()->value, $property->attributes()->settinggroup, $property->attributes()->varname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
$this->_updateSetting($upd_stmt, $this->_data['activate_newsfeed'], 'admin', 'show_news_feed');
|
||||
$this->_updateSetting($upd_stmt, dirname(dirname(dirname(__FILE__))), 'system', 'letsencryptchallengepath');
|
||||
@@ -555,6 +607,12 @@ class FroxlorInstall
|
||||
$options = array(
|
||||
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
|
||||
);
|
||||
|
||||
if (!empty($this->_data['mysql_ssl_ca_file'])) {
|
||||
$options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file'];
|
||||
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate'];
|
||||
}
|
||||
|
||||
$dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";";
|
||||
$fatal_fail = false;
|
||||
try {
|
||||
@@ -683,8 +741,8 @@ class FroxlorInstall
|
||||
|
||||
private function _grantDbPrivilegesTo(&$db_root, $database, $username, $password, $access_host)
|
||||
{
|
||||
// mysql8 compatibility
|
||||
if (version_compare($db_root->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) {
|
||||
// mariadb
|
||||
if (version_compare($db_root->getAttribute(\PDO::ATTR_SERVER_VERSION), '10.0.0', '>=')) {
|
||||
// create user
|
||||
$stmt = $db_root->prepare("
|
||||
CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED BY :password
|
||||
@@ -700,6 +758,24 @@ class FroxlorInstall
|
||||
"username" => $username,
|
||||
"host" => $access_host
|
||||
));
|
||||
}
|
||||
// mysql8 compatibility
|
||||
elseif (version_compare($db_root->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) {
|
||||
// create user
|
||||
$stmt = $db_root->prepare("
|
||||
CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED WITH mysql_native_password BY :password
|
||||
");
|
||||
$stmt->execute(array(
|
||||
"password" => $password
|
||||
));
|
||||
// grant privileges
|
||||
$stmt = $db_root->prepare("
|
||||
GRANT ALL ON `" . $database . "`.* TO :username@:host
|
||||
");
|
||||
$stmt->execute(array(
|
||||
"username" => $username,
|
||||
"host" => $access_host
|
||||
));
|
||||
} else {
|
||||
// grant privileges
|
||||
$stmt = $db_root->prepare("
|
||||
@@ -733,39 +809,59 @@ class FroxlorInstall
|
||||
));
|
||||
$rows = $db_root->query("SELECT FOUND_ROWS()")->fetchColumn();
|
||||
|
||||
$content .= $this->_status_message('begin', $this->_lng['install']['check_db_exists']);
|
||||
|
||||
// check result
|
||||
if ($result_stmt !== false && $rows > 0) {
|
||||
$tables_exist = true;
|
||||
}
|
||||
|
||||
if ($tables_exist) {
|
||||
// tell whats going on
|
||||
$content .= $this->_status_message('begin', $this->_lng['install']['backup_old_db']);
|
||||
if ((int)$this->_data['mysql_forcecreate'] > 0) {
|
||||
// set status
|
||||
$content .= $this->_status_message('orange', 'exists (' . $this->_data['mysql_database'] . ')');
|
||||
// tell what's going on
|
||||
$content .= $this->_status_message('begin', $this->_lng['install']['backup_old_db']);
|
||||
|
||||
// create temporary backup-filename
|
||||
$filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql";
|
||||
// create temporary backup-filename
|
||||
$filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql";
|
||||
|
||||
// look for mysqldump
|
||||
$do_backup = false;
|
||||
if (file_exists("/usr/bin/mysqldump")) {
|
||||
$do_backup = true;
|
||||
$mysql_dump = '/usr/bin/mysqldump';
|
||||
} elseif (file_exists("/usr/local/bin/mysqldump")) {
|
||||
$do_backup = true;
|
||||
$mysql_dump = '/usr/local/bin/mysqldump';
|
||||
}
|
||||
// look for mysqldump
|
||||
$do_backup = false;
|
||||
if (file_exists("/usr/bin/mysqldump")) {
|
||||
$do_backup = true;
|
||||
$mysql_dump = '/usr/bin/mysqldump';
|
||||
} elseif (file_exists("/usr/local/bin/mysqldump")) {
|
||||
$do_backup = true;
|
||||
$mysql_dump = '/usr/local/bin/mysqldump';
|
||||
}
|
||||
|
||||
if ($do_backup) {
|
||||
$command = $mysql_dump . " " . escapeshellarg($this->_data['mysql_database']) . " -u " . escapeshellarg($this->_data['mysql_root_user']) . " --password='" . escapeshellarg($this->_data['mysql_root_pass']) . "' --result-file=" . $filename;
|
||||
$output = exec($command);
|
||||
if (stristr($output, "error")) {
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['backup_failed']);
|
||||
// create temporary .cnf file
|
||||
$cnffilename = "/tmp/froxlor_dump.cnf";
|
||||
$dumpcnf = "[mysqldump]" . PHP_EOL . "password=\"" . $this->_data['mysql_root_pass'] . "\"" . PHP_EOL;
|
||||
file_put_contents($cnffilename, $dumpcnf);
|
||||
|
||||
if ($do_backup) {
|
||||
$command = $mysql_dump . " --defaults-extra-file=" . $cnffilename . " " . escapeshellarg($this->_data['mysql_database']) . " -u " . escapeshellarg($this->_data['mysql_root_user']) . " --result-file=" . $filename;
|
||||
$output = [];
|
||||
exec($command, $output);
|
||||
@unlink($cnffilename);
|
||||
if (stristr(implode(" ", $output), "error") || ! file_exists($filename)) {
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['backup_failed']);
|
||||
$this->_abort = true;
|
||||
} else {
|
||||
$content .= $this->_status_message('green', 'OK (' . $filename . ')');
|
||||
}
|
||||
} else {
|
||||
$content .= $this->_status_message('green', 'OK (' . $filename . ')');
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['backup_binary_missing']);
|
||||
$this->_abort = true;
|
||||
}
|
||||
} else {
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['backup_binary_missing']);
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['db_exists']);
|
||||
$this->_abort = true;
|
||||
}
|
||||
} else {
|
||||
$content .= $content .= $this->_status_message('green', 'OK');
|
||||
}
|
||||
|
||||
return $content;
|
||||
@@ -784,7 +880,7 @@ class FroxlorInstall
|
||||
}
|
||||
// language selection
|
||||
$language_options = '';
|
||||
foreach ($this->_languages as $language_name => $language_file) {
|
||||
foreach ($this->_languages as $language_file => $language_name) {
|
||||
$language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $this->_activelng, true, true);
|
||||
}
|
||||
// get language-form-template
|
||||
@@ -801,6 +897,8 @@ class FroxlorInstall
|
||||
$formdata .= $this->_getSectionItemString('mysql_host', true);
|
||||
// database
|
||||
$formdata .= $this->_getSectionItemString('mysql_database', true);
|
||||
// database overwrite if exists?
|
||||
$formdata .= $this->_getSectionItemYesNo('mysql_forcecreate', false);
|
||||
// unpriv-user has to be different from root
|
||||
if ($this->_data['mysql_unpriv_user'] == $this->_data['mysql_root_user']) {
|
||||
$style = 'blue';
|
||||
@@ -830,6 +928,9 @@ class FroxlorInstall
|
||||
}
|
||||
$formdata .= $this->_getSectionItemString('mysql_root_pass', true, $style, 'password');
|
||||
|
||||
$formdata .= $this->_getSectionItemString('mysql_ssl_ca_file', false, $style);
|
||||
$formdata .= $this->_getSectionItemYesNo('mysql_ssl_verify_server_certificate', false, $style);
|
||||
|
||||
/**
|
||||
* admin data
|
||||
*/
|
||||
@@ -867,19 +968,24 @@ class FroxlorInstall
|
||||
}
|
||||
|
||||
// show list of available distro's
|
||||
$distributions_select_data = [];
|
||||
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
|
||||
foreach ($distros as $_distribution) {
|
||||
$dist = new \Froxlor\Config\ConfigParser($_distribution);
|
||||
$dist_display = $dist->distributionName . " " . $dist->distributionCodename . " (" . $dist->distributionVersion . ")";
|
||||
if (!array_key_exists($dist_display, $distributions_select_data)) {
|
||||
$distributions_select_data[$dist_display] = '';
|
||||
}
|
||||
$distributions_select_data[$dist_display] .= str_replace(".xml", "", strtolower(basename($_distribution)));
|
||||
}
|
||||
|
||||
// sort by distribution name
|
||||
ksort($distributions_select_data);
|
||||
|
||||
$distributions_select = '';
|
||||
foreach ($distributions_select_data as $dist_display => $dist_index) {
|
||||
// create select-box-option
|
||||
$distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index, $this->_data['distribution']);
|
||||
$distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index, $this->_data['distribution'] ?? '');
|
||||
// $this->_data['distribution']
|
||||
}
|
||||
|
||||
@@ -947,7 +1053,7 @@ class FroxlorInstall
|
||||
* optional css
|
||||
* @param string $type
|
||||
* optional type of input-box (default: text)
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function _getSectionItemString($fieldname = null, $required = false, $style = "", $type = 'text')
|
||||
@@ -994,7 +1100,6 @@ class FroxlorInstall
|
||||
*/
|
||||
private function _getSectionItemSelectbox($fieldname = null, $options = null, $style = "")
|
||||
{
|
||||
$groupname = $this->_lng['install'][$groupname];
|
||||
$fieldlabel = $this->_lng['install'][$fieldname];
|
||||
|
||||
$sectionitem = "";
|
||||
@@ -1036,11 +1141,11 @@ class FroxlorInstall
|
||||
// check for correct php version
|
||||
$content .= $this->_status_message('begin', $this->_lng['requirements']['phpversion']);
|
||||
|
||||
if (version_compare("7.0.0", PHP_VERSION, ">=")) {
|
||||
if (version_compare("7.1.0", PHP_VERSION, ">=")) {
|
||||
$content .= $this->_status_message('red', $this->_lng['requirements']['notfound'] . ' (' . PHP_VERSION . ')');
|
||||
$_die = true;
|
||||
} else {
|
||||
if (version_compare("7.1.0", PHP_VERSION, ">=")) {
|
||||
if (version_compare("7.4.0", PHP_VERSION, ">=")) {
|
||||
$content .= $this->_status_message('orange', $this->_lng['requirements']['newerphpprefered'] . ' (' . PHP_VERSION . ')');
|
||||
} else {
|
||||
$content .= $this->_status_message('green', PHP_VERSION);
|
||||
@@ -1239,7 +1344,7 @@ class FroxlorInstall
|
||||
*
|
||||
* @param string $template
|
||||
* name of the template including subdirectory
|
||||
*
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function _getTemplate($template = null)
|
||||
@@ -1306,10 +1411,12 @@ class FroxlorInstall
|
||||
// from form
|
||||
if (! empty($_POST['serverip'])) {
|
||||
$this->_data['serverip'] = $_POST['serverip'];
|
||||
$this->_data['serverip'] = inet_ntop(inet_pton($this->_data['serverip']));
|
||||
return;
|
||||
// from $_SERVER
|
||||
} elseif (! empty($_SERVER['SERVER_ADDR'])) {
|
||||
$this->_data['serverip'] = $_SERVER['SERVER_ADDR'];
|
||||
$this->_data['serverip'] = inet_ntop(inet_pton($this->_data['serverip']));
|
||||
return;
|
||||
}
|
||||
// empty
|
||||
@@ -1357,7 +1464,14 @@ class FroxlorInstall
|
||||
|
||||
// read os-release
|
||||
if (file_exists('/etc/os-release')) {
|
||||
$os_dist = parse_ini_file('/etc/os-release', false);
|
||||
$os_dist_content = file_get_contents('/etc/os-release');
|
||||
$os_dist_arr = explode("\n", $os_dist_content);
|
||||
$os_dist = [];
|
||||
foreach ($os_dist_arr as $os_dist_line) {
|
||||
if (empty(trim($os_dist_line))) continue;
|
||||
$tmp = explode("=", $os_dist_line);
|
||||
$os_dist[$tmp[0]] = str_replace('"', "", trim($tmp[1]));
|
||||
}
|
||||
if (is_array($os_dist) && array_key_exists('ID', $os_dist) && array_key_exists('VERSION_ID', $os_dist)) {
|
||||
$os_version = explode('.', $os_dist['VERSION_ID'])[0];
|
||||
}
|
||||
|
||||
0
install/lib/index.html
Normal file
0
install/lib/index.html
Normal file
@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'no';
|
||||
$lng['requirements']['notfound'] = 'not found';
|
||||
$lng['requirements']['notinstalled'] = 'not installed';
|
||||
$lng['requirements']['activated'] = 'enabled';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.0';
|
||||
$lng['requirements']['newerphpprefered'] = 'Good, but php-7.1 is prefered.';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.1';
|
||||
$lng['requirements']['newerphpprefered'] = 'Good, but php-7.4 is preferred.';
|
||||
$lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...';
|
||||
$lng['requirements']['phpsession'] = 'PHP session-extension...';
|
||||
$lng['requirements']['phpctype'] = 'PHP ctype-extension...';
|
||||
@@ -39,7 +39,7 @@ $lng['requirements']['phpjson'] = 'PHP json-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...';
|
||||
$lng['requirements']['openbasedirenabled'] = 'Froxlor will not work properly with open_basedir enabled. Please disable open_basedir for Froxlor in the coresponding php.ini';
|
||||
$lng['requirements']['openbasedirenabled'] = 'Froxlor will not work properly with open_basedir enabled. Please disable open_basedir for Froxlor in the corresponding php.ini';
|
||||
$lng['requirements']['mysqldump'] = 'MySQL dump tool';
|
||||
$lng['requirements']['mysqldumpmissing'] = 'Automatic backup of possible existing database is not possible. Please install mysql-client tools';
|
||||
$lng['requirements']['diedbecauseofrequirements'] = 'Cannot install Froxlor without these requirements! Try to fix them and retry.';
|
||||
@@ -53,10 +53,13 @@ $lng['install']['welcometext'] = 'Thank you for choosing Froxlor. Please fill ou
|
||||
$lng['install']['database'] = 'Database connection';
|
||||
$lng['install']['mysql_host'] = 'MySQL-Hostname';
|
||||
$lng['install']['mysql_database'] = 'Database name';
|
||||
$lng['install']['mysql_forcecreate'] = 'Backup and overwrite database if exists?';
|
||||
$lng['install']['mysql_unpriv_user'] = 'Username for the unprivileged MySQL-account';
|
||||
$lng['install']['mysql_unpriv_pass'] = 'Password for the unprivileged MySQL-account';
|
||||
$lng['install']['mysql_root_user'] = 'Username for the MySQL-root-account';
|
||||
$lng['install']['mysql_root_pass'] = 'Password for the MySQL-root-account';
|
||||
$lng['install']['mysql_ssl_ca_file'] = 'MySQL server certificate file path';
|
||||
$lng['install']['mysql_ssl_verify_server_certificate'] = 'Verify MySQL TLS certificate';
|
||||
$lng['install']['admin_account'] = 'Administrator Account';
|
||||
$lng['install']['admin_user'] = 'Administrator Username';
|
||||
$lng['install']['admin_pass1'] = 'Administrator Password';
|
||||
@@ -79,6 +82,8 @@ $lng['install']['testing_mysql_fail'] = 'There seems to be a problem with the da
|
||||
$lng['install']['backup_old_db'] = 'Creating backup of old database...';
|
||||
$lng['install']['backup_binary_missing'] = 'Could not find mysqldump';
|
||||
$lng['install']['backup_failed'] = 'Could not backup database';
|
||||
$lng['install']['check_db_exists'] = 'Checking database...';
|
||||
$lng['install']['db_exists'] = 'Unable to create database. A database with the same name exists and should not be overwritten';
|
||||
$lng['install']['prepare_db'] = 'Preparing database...';
|
||||
$lng['install']['create_mysqluser_and_db'] = 'Creating database and username...';
|
||||
$lng['install']['testing_new_db'] = 'Testing if database and user have been created correctly...';
|
||||
|
||||
@@ -22,7 +22,7 @@ $lng['requirements']['not_true'] = 'non';
|
||||
$lng['requirements']['notfound'] = 'introuvable';
|
||||
$lng['requirements']['notinstalled'] = 'non installé';
|
||||
$lng['requirements']['activated'] = 'activé';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.0';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.1';
|
||||
$lng['requirements']['phppdo'] = 'extension PHP PDO et pilote PDO-MySQL ...';
|
||||
$lng['requirements']['phpxml'] = 'extension PHP XML...';
|
||||
$lng['requirements']['phpfilter'] = 'extension PHP filter ...';
|
||||
|
||||
@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'nein';
|
||||
$lng['requirements']['notfound'] = 'nicht gefunden';
|
||||
$lng['requirements']['notinstalled'] = 'nicht installiert';
|
||||
$lng['requirements']['activated'] = 'ist aktiviert.';
|
||||
$lng['requirements']['phpversion'] = 'PHP Version >= 7.0';
|
||||
$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.1 wird bevorzugt.';
|
||||
$lng['requirements']['phpversion'] = 'PHP Version >= 7.1';
|
||||
$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.4 wird bevorzugt.';
|
||||
$lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...';
|
||||
$lng['requirements']['phpsession'] = 'PHP session-Erweiterung...';
|
||||
$lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...';
|
||||
@@ -53,10 +53,13 @@ $lng['install']['welcometext'] = 'Vielen Dank dass Sie sich für Froxlor entschi
|
||||
$lng['install']['database'] = 'Datenbankverbindung';
|
||||
$lng['install']['mysql_host'] = 'MySQL-Hostname';
|
||||
$lng['install']['mysql_database'] = 'Datenbank Name';
|
||||
$lng['install']['mysql_forcecreate'] = 'Datenbank sichern und überschreiben wenn vorhanden?';
|
||||
$lng['install']['mysql_unpriv_user'] = 'Benutzername für den unprivilegierten MySQL-Account';
|
||||
$lng['install']['mysql_unpriv_pass'] = 'Passwort für den unprivilegierten MySQL-Account';
|
||||
$lng['install']['mysql_root_user'] = 'Benutzername für den MySQL-Root-Account';
|
||||
$lng['install']['mysql_root_pass'] = 'Passwort für den MySQL-Root-Account';
|
||||
$lng['install']['mysql_ssl_ca_file'] = 'MySQL-Server Zertifikatspfad';
|
||||
$lng['install']['mysql_ssl_verify_server_certificate'] = 'Validieren des MySQL-Server Zertifikats';
|
||||
$lng['install']['admin_account'] = 'Admin-Zugang';
|
||||
$lng['install']['admin_user'] = 'Administrator-Benutzername';
|
||||
$lng['install']['admin_pass1'] = 'Administrator-Passwort';
|
||||
@@ -79,6 +82,8 @@ $lng['install']['testing_mysql_fail'] = 'Bei der Verwendung der Datenbank gibt e
|
||||
$lng['install']['backup_old_db'] = 'Sicherung vorheriger Datenbank...';
|
||||
$lng['install']['backup_binary_missing'] = 'Konnte mysqldump nicht finden';
|
||||
$lng['install']['backup_failed'] = 'Sicherung fehlgeschlagen';
|
||||
$lng['install']['check_db_exists'] = 'Databenbank wird geprüft...';
|
||||
$lng['install']['db_exists'] = 'Datenbank kann nicht erstellt werden. Eine Datenbank mit dem selben Namen existiert bereits und soll nicht überschrieben werden.';
|
||||
$lng['install']['prepare_db'] = 'Datenbank wird vorbereitet...';
|
||||
$lng['install']['create_mysqluser_and_db'] = 'Erstelle Datenbank und Benutzer...';
|
||||
$lng['install']['testing_new_db'] = 'Teste, ob Datenbank und Benutzer korrekt angelegt wurden...';
|
||||
|
||||
0
install/lng/index.html
Normal file
0
install/lng/index.html
Normal file
@@ -28,4 +28,5 @@ try {
|
||||
\Froxlor\Cli\ConfigServicesCmd::processParameters($argc, $argv);
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\Cli\ConfigServicesCmd::printerr($e->getMessage());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
0
install/scripts/index.html
Normal file
0
install/scripts/index.html
Normal file
@@ -28,4 +28,5 @@ try {
|
||||
\Froxlor\Cli\SwitchServerIpCmd::processParameters($argc, $argv);
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\Cli\SwitchServerIpCmd::printerr($e->getMessage());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
0
install/templates/assets/css/index.html
Normal file
0
install/templates/assets/css/index.html
Normal file
0
install/templates/assets/index.html
Normal file
0
install/templates/assets/index.html
Normal file
0
install/templates/index.html
Normal file
0
install/templates/index.html
Normal file
0
install/updates/froxlor/0.10/index.html
Normal file
0
install/updates/froxlor/0.10/index.html
Normal file
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Validate\Validate;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -14,7 +15,7 @@ use Froxlor\Settings;
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Install
|
||||
*
|
||||
*
|
||||
*/
|
||||
if (! defined('_CRON_UPDATE')) {
|
||||
if (! defined('AREA') || (defined('AREA') && AREA != 'admin') || ! isset($userinfo['loginname']) || (isset($userinfo['loginname']) && $userinfo['loginname'] == '')) {
|
||||
@@ -699,6 +700,324 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.22')) {
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23')) {
|
||||
showUpdateStep("Updating from 0.10.23 to 0.10.23.1", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.23.1');
|
||||
showUpdateStep("Updating from 0.10.23 to 0.10.23.1", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.23.1');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202009070')) {
|
||||
|
||||
showUpdateStep("Adding setting to hide incompatible settings", true);
|
||||
Settings::AddNew("system.hide_incompatible_settings", '0');
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202012300');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202012300')) {
|
||||
|
||||
showUpdateStep("Adding setting for DKIM private key extension/suffix", true);
|
||||
Settings::AddNew("dkim.privkeysuffix", '.priv');
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202101200');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23.1')) {
|
||||
showUpdateStep("Updating from 0.10.23.1 to 0.10.24", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.24');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202101200')) {
|
||||
|
||||
showUpdateStep("Adding setting for mail address used in SOA records", true);
|
||||
Settings::AddNew("system.soaemail", '');
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202102200');
|
||||
}
|
||||
|
||||
/*
|
||||
* skip due to potential "1118 Row size too large" error
|
||||
*
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202102200')) {
|
||||
|
||||
showUpdateStep("Add new description fields to mail and domain table", true);
|
||||
Database::query("ALTER TABLE panel_domains ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `ssl_sessiontickets`;");
|
||||
Database::query("ALTER TABLE mail_virtual ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `iscatchall`");
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202103030');
|
||||
}
|
||||
*/
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.24')) {
|
||||
showUpdateStep("Updating from 0.10.24 to 0.10.25", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.25');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202102200') || \Froxlor\Froxlor::isDatabaseVersion('202103030')) {
|
||||
|
||||
showUpdateStep("Refactoring columns from large tables", true);
|
||||
Database::query("ALTER TABLE panel_domains CHANGE `ssl_protocols` `ssl_protocols` varchar(255) NOT NULL DEFAULT '';");
|
||||
Database::query("ALTER TABLE panel_domains CHANGE `ssl_cipher_list` `ssl_cipher_list` varchar(500) NOT NULL DEFAULT '';");
|
||||
Database::query("ALTER TABLE panel_domains CHANGE `tlsv13_cipher_list` `tlsv13_cipher_list` varchar(500) NOT NULL DEFAULT '';");
|
||||
lastStepStatus(0);
|
||||
|
||||
showUpdateStep("Add new description fields to mail and domain table", true);
|
||||
$result = Database::query("DESCRIBE `panel_domains`");
|
||||
$columnfound = 0;
|
||||
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
|
||||
if ($row['Field'] == 'description') {
|
||||
$columnfound = 1;
|
||||
}
|
||||
}
|
||||
if (! $columnfound) {
|
||||
Database::query("ALTER TABLE panel_domains ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `ssl_sessiontickets`;");
|
||||
}
|
||||
$result = Database::query("DESCRIBE `mail_virtual`");
|
||||
$columnfound = 0;
|
||||
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
|
||||
if ($row['Field'] == 'description') {
|
||||
$columnfound = 1;
|
||||
}
|
||||
}
|
||||
if (! $columnfound) {
|
||||
Database::query("ALTER TABLE mail_virtual ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `iscatchall`");
|
||||
}
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202103110');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202103110')) {
|
||||
|
||||
showUpdateStep("Adding settings for imprint, terms of use and privacy policy URLs", true);
|
||||
Settings::AddNew("panel.imprint_url", '');
|
||||
Settings::AddNew("panel.terms_url", '');
|
||||
Settings::AddNew("panel.privacy_url", '');
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202103240');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.25')) {
|
||||
showUpdateStep("Updating from 0.10.25 to 0.10.26", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.26');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202103240')) {
|
||||
|
||||
showUpdateStep("Adding setting for default serveralias value for new domains", true);
|
||||
Settings::AddNew("system.domaindefaultalias", '0');
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202106160');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202106160')) {
|
||||
|
||||
showUpdateStep("Adjusting Let's Encrypt endpoint configuration to support ZeroSSL", true);
|
||||
if (Settings::Get('system.letsencryptca') == 'testing') {
|
||||
Settings::Set("system.letsencryptca", 'letsencrypt_test');
|
||||
} else {
|
||||
Settings::Set("system.letsencryptca", 'letsencrypt');
|
||||
}
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202106270');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202106270')) {
|
||||
showUpdateStep("Adding custom logo image settings", true);
|
||||
Settings::AddNew("panel.logo_image_header", '');
|
||||
Settings::AddNew("panel.logo_image_login", '');
|
||||
lastStepStatus(0);
|
||||
|
||||
// Migrating old custom logo over, if exists
|
||||
$custom_logo_file_old = \Froxlor\Froxlor::getInstallDir() . '/templates/Sparkle/assets/img/logo_custom.png';
|
||||
if (file_exists($custom_logo_file_old)) {
|
||||
showUpdateStep("Migrating existing custom logo to new settings", true);
|
||||
|
||||
$path = \Froxlor\Froxlor::getInstallDir().'/img/';
|
||||
if (!is_dir($path) && !mkdir($path, 0775)) {
|
||||
throw new \Exception("img directory does not exist and cannot be created");
|
||||
}
|
||||
if (!is_writable($path)) {
|
||||
if (!chmod($path, 0775)) {
|
||||
throw new \Exception("Cannot write to img directory");
|
||||
}
|
||||
}
|
||||
|
||||
// Save as new custom logo header
|
||||
$save_to = 'logo_header.png';
|
||||
copy($custom_logo_file_old, $path.$save_to);
|
||||
Settings::Set("panel.logo_image_header", "img/{$save_to}?v=".time());
|
||||
|
||||
// Save as new custom logo login
|
||||
$save_to = 'logo_login.png';
|
||||
copy($custom_logo_file_old, $path.$save_to);
|
||||
Settings::Set("panel.logo_image_login", "img/{$save_to}?v=".time());
|
||||
|
||||
lastStepStatus(0);
|
||||
}
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107070');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.26')) {
|
||||
showUpdateStep("Updating from 0.10.26 to 0.10.27", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.27');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107070')) {
|
||||
showUpdateStep("Adding settings to overwrite theme- or custom theme-logo with the new logo settings", true);
|
||||
Settings::AddNew("panel.logo_overridetheme", '0');
|
||||
Settings::AddNew("panel.logo_overridecustom", '0');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107200');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107200')) {
|
||||
showUpdateStep("Adding settings to define default value of 'create std-subdomain' when creating a customer", true);
|
||||
Settings::AddNew("system.createstdsubdom_default", '1');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107210');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107210')) {
|
||||
showUpdateStep("Normalizing ipv6 for correct comparison", true);
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `id`, `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "`"
|
||||
);
|
||||
Database::pexecute($result_stmt);
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_IPSANDPORTS . "` SET `ip` = :ip WHERE `id` = :id");
|
||||
while ($iprow = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if (Validate::is_ipv6($iprow['ip'])) {
|
||||
$ip = inet_ntop(inet_pton($iprow['ip']));
|
||||
Database::pexecute($upd_stmt, [
|
||||
'ip' => $ip,
|
||||
'id' => $iprow['id']
|
||||
]);
|
||||
}
|
||||
}
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107260');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107260')) {
|
||||
showUpdateStep("Removing setting for search-engine allow yes/no", true);
|
||||
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'panel' AND `varname` = 'no_robots'");
|
||||
lastStepStatus(0);
|
||||
showUpdateStep("Adding setting to have all froxlor customers in a local group", true);
|
||||
Settings::AddNew("system.froxlorusergroup", '');
|
||||
Settings::AddNew("system.froxlorusergroup_gid", '');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107300');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107300')) {
|
||||
showUpdateStep("Adds the possibility to select the PowerDNS Operation Mode", true);
|
||||
Settings::AddNew("system.powerdns_mode", 'Native');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202108180');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.27')) {
|
||||
showUpdateStep("Updating from 0.10.27 to 0.10.28", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.28');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202108180')) {
|
||||
showUpdateStep("Adding czech language file", true);
|
||||
Database::query("INSERT INTO `" . TABLE_PANEL_LANGUAGE . "` SET `language` = 'Česká republika', `iso` = 'cs', `file` = 'lng/czech.lng.php'");
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202109040');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.28')) {
|
||||
showUpdateStep("Updating from 0.10.28 to 0.10.29", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.29');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.29')) {
|
||||
showUpdateStep("Updating from 0.10.29 to 0.10.29.1", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.29.1');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.29.1')) {
|
||||
showUpdateStep("Updating from 0.10.29.1 to 0.10.30", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.30');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.30')) {
|
||||
showUpdateStep("Updating from 0.10.30 to 0.10.31", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.31');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202109040')) {
|
||||
showUpdateStep("Add setting for acme.sh install location", true);
|
||||
Settings::AddNew("system.acmeshpath", '/root/.acme.sh/acme.sh');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202112310');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.31')) {
|
||||
showUpdateStep("Updating from 0.10.31 to 0.10.32", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.32');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.32')) {
|
||||
showUpdateStep("Updating from 0.10.32 to 0.10.33", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.33');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.33')) {
|
||||
showUpdateStep("Updating from 0.10.33 to 0.10.34", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.34');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.34')) {
|
||||
showUpdateStep("Updating from 0.10.34 to 0.10.34.1", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.34.1');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.34.1')) {
|
||||
showUpdateStep("Updating from 0.10.34.1 to 0.10.35", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.35');
|
||||
}
|
||||
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.35')) {
|
||||
showUpdateStep("Updating from 0.10.35 to 0.10.35.1", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.35.1');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.35.1')) {
|
||||
showUpdateStep("Updating from 0.10.35.1 to 0.10.36", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.36');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.36')) {
|
||||
showUpdateStep("Updating from 0.10.36 to 0.10.37", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.37');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.37')) {
|
||||
showUpdateStep("Updating from 0.10.37 to 0.10.38", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.38');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.38')) {
|
||||
showUpdateStep("Updating from 0.10.38 to 0.10.38.1", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.38.1');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.38.1')) {
|
||||
showUpdateStep("Updating from 0.10.38.1 to 0.10.38.2", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.38.2');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.38.2')) {
|
||||
showUpdateStep("Updating from 0.10.38.2 to 0.10.38.3", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.38.3');
|
||||
}
|
||||
|
||||
0
install/updates/froxlor/0.9/index.html
Normal file
0
install/updates/froxlor/0.9/index.html
Normal file
@@ -2505,7 +2505,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.9.30')) {
|
||||
showUpdateStep("Updating from 0.9.30 to 0.9.31-dev1", true);
|
||||
lastStepStatus(0);
|
||||
|
||||
showUpdateStep("Removing unsused tables");
|
||||
showUpdateStep("Removing unused tables");
|
||||
Database::query("DROP TABLE IF EXISTS `ipsandports_docrootsettings`;");
|
||||
Database::query("DROP TABLE IF EXISTS `domain_docrootsettings`;");
|
||||
lastStepStatus(0);
|
||||
@@ -2856,7 +2856,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-rc1')) {
|
||||
Settings::AddNew("system.croncmdline", $croncmdline);
|
||||
// add task to generate cron.d-file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
// silenty add the auto-update setting - we do not want everybody to know and use this
|
||||
// silently add the auto-update setting - we do not want everybody to know and use this
|
||||
// as it is a very dangerous setting
|
||||
Settings::AddNew("system.cron_allowautoupdate", 0);
|
||||
lastStepStatus(0);
|
||||
@@ -3872,7 +3872,7 @@ opcache.interned_strings_buffer');
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('201801110')) {
|
||||
|
||||
showUpdateStep("Adding php-fpm php PATH setting for envrironment");
|
||||
showUpdateStep("Adding php-fpm php PATH setting for environment");
|
||||
Settings::AddNew("phpfpm.envpath", '/usr/local/bin:/usr/bin:/bin');
|
||||
lastStepStatus(0);
|
||||
|
||||
|
||||
0
install/updates/froxlor/index.html
Normal file
0
install/updates/froxlor/index.html
Normal file
0
install/updates/index.html
Normal file
0
install/updates/index.html
Normal file
@@ -19,7 +19,7 @@
|
||||
* Function getPreConfig
|
||||
*
|
||||
* outputs various content before the update process
|
||||
* can be continued (askes for agreement whatever is being asked)
|
||||
* can be continued (asks for agreement whatever is being asked)
|
||||
*
|
||||
* @param string $current_version
|
||||
* @param int $current_db_version
|
||||
|
||||
0
install/updates/preconfig/0.10/index.html
Normal file
0
install/updates/preconfig/0.10/index.html
Normal file
0
install/updates/preconfig/0.9/index.html
Normal file
0
install/updates/preconfig/0.9/index.html
Normal file
@@ -414,7 +414,7 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c
|
||||
|
||||
if (Settings::Get('system.webserver') == 'apache2') {
|
||||
$has_preconfig = true;
|
||||
$description = 'Froxlor now supports the new Apache 2.4. Please be aware that you need to load additional apache-modules in ordner to use it.<br />';
|
||||
$description = 'Froxlor now supports the new Apache 2.4. Please be aware that you need to load additional apache-modules in order to use it.<br />';
|
||||
$description .= '<pre>LoadModule authz_core_module modules/mod_authz_core.so
|
||||
LoadModule authz_host_module modules/mod_authz_host.so</pre><br />';
|
||||
$question = '<strong>Do you want to enable the Apache-2.4 modification?:</strong> ';
|
||||
|
||||
0
install/updates/preconfig/index.html
Normal file
0
install/updates/preconfig/index.html
Normal file
0
js/index.html
Normal file
0
js/index.html
Normal file
0
js/plugins/index.html
Normal file
0
js/plugins/index.html
Normal file
@@ -297,6 +297,10 @@ abstract class ApiCommand extends ApiParameter
|
||||
$sortfield[$id] = $sfield;
|
||||
}
|
||||
$field = implode('.', $sortfield);
|
||||
if (preg_match('/^([a-z0-9\-\._`]+)$/i', $field) == false) {
|
||||
// skip
|
||||
continue;
|
||||
}
|
||||
if (! $first) {
|
||||
$condition .= ' AND ';
|
||||
}
|
||||
@@ -310,6 +314,21 @@ abstract class ApiCommand extends ApiParameter
|
||||
} elseif (in_array($valoper['op'], $ops)) {
|
||||
$condition .= $field . ' ' . $valoper['op'] . ':' . $cleanfield;
|
||||
$query_fields[':' . $cleanfield] = $valoper['value'] ?? '';
|
||||
} elseif (strtolower($valoper['op']) == 'in' && is_array($valoper['value']) && count($valoper['value']) > 0) {
|
||||
$condition .= $field . ' ' . $valoper['op'] . ' (';
|
||||
foreach ($valoper['value'] as $incnt => $invalue) {
|
||||
if (!is_numeric($incnt)) {
|
||||
// skip
|
||||
continue;
|
||||
}
|
||||
if (!empty($invalue) && preg_match('/^([a-z0-9\-\._`]+)$/i', $invalue) == false) {
|
||||
// skip
|
||||
continue;
|
||||
}
|
||||
$condition .= ":" . $cleanfield . $incnt . ", ";
|
||||
$query_fields[':' . $cleanfield . $incnt] = $invalue ?? '';
|
||||
}
|
||||
$condition = substr($condition, 0, - 2) . ')';
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
@@ -391,6 +410,10 @@ abstract class ApiCommand extends ApiParameter
|
||||
$sortfield[$id] = $sfield;
|
||||
}
|
||||
$field = implode('.', $sortfield);
|
||||
if (preg_match('/^([a-z0-9\-\._`]+)$/i', $field) == false) {
|
||||
// skip
|
||||
continue;
|
||||
}
|
||||
$by = strtoupper($by);
|
||||
if (! in_array($by, [
|
||||
'ASC',
|
||||
@@ -416,6 +439,7 @@ abstract class ApiCommand extends ApiParameter
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return logger instance
|
||||
*
|
||||
@@ -518,7 +542,7 @@ abstract class ApiCommand extends ApiParameter
|
||||
$customer_ids[] = $customer['customerid'];
|
||||
}
|
||||
} else {
|
||||
if (!$this->isInternal() && ! empty($customer_hide_option) && \Froxlor\Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) {
|
||||
if (! $this->isInternal() && ! empty($customer_hide_option) && \Froxlor\Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) {
|
||||
throw new \Exception("You cannot access this resource", 405);
|
||||
}
|
||||
$customer_ids = array(
|
||||
|
||||
@@ -180,12 +180,18 @@ abstract class ApiParameter
|
||||
*/
|
||||
private function trimArray($input)
|
||||
{
|
||||
if (! is_array($input)) {
|
||||
if ($input === '') {
|
||||
return "";
|
||||
}
|
||||
if (is_numeric($input) || is_null($input)) {
|
||||
return $input;
|
||||
}
|
||||
if (!is_array($input)) {
|
||||
return trim($input);
|
||||
}
|
||||
return array_map(array(
|
||||
return array_map([
|
||||
$this,
|
||||
'trimArray'
|
||||
), $input);
|
||||
], $input);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$ipaddress = $this->getParam('ipaddress', true, - 1);
|
||||
|
||||
// validation
|
||||
$name = \Froxlor\Validate\Validate::validate($name, 'name', '', '', array(), true);
|
||||
$name = \Froxlor\Validate\Validate::validate($name, 'name', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
|
||||
$def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true);
|
||||
@@ -472,10 +472,10 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
// parameters
|
||||
$name = $this->getParam('name', true, $result['name']);
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
$email = $this->getParam('email', true, $idna_convert->decode($result['email']));
|
||||
$email = $this->getParam('email', true, $idna_convert->decode($result['email'] ?? ''));
|
||||
$password = $this->getParam('admin_password', true, '');
|
||||
$def_language = $this->getParam('def_language', true, $result['def_language']);
|
||||
$custom_notes = $this->getParam('custom_notes', true, $result['custom_notes']);
|
||||
$custom_notes = $this->getParam('custom_notes', true, ($result['custom_notes'] ?? ""));
|
||||
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, $result['custom_notes_show']);
|
||||
$theme = $this->getParam('theme', true, $result['theme']);
|
||||
|
||||
@@ -527,7 +527,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
}
|
||||
|
||||
// validation
|
||||
$name = \Froxlor\Validate\Validate::validate($name, 'name', '', '', array(), true);
|
||||
$name = \Froxlor\Validate\Validate::validate($name, 'name', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
|
||||
$def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true);
|
||||
|
||||
@@ -189,7 +189,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
// select all my (accessable) certificates
|
||||
// select all my (accessible) certificates
|
||||
$certs_stmt_query = "SELECT s.*, d.domain, d.letsencrypt, c.customerid, c.loginname
|
||||
FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid`
|
||||
@@ -237,7 +237,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
*/
|
||||
public function listingCount()
|
||||
{
|
||||
// select all my (accessable) certificates
|
||||
// select all my (accessible) certificates
|
||||
$certs_stmt_query = "SELECT COUNT(*) as num_certs
|
||||
FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid`
|
||||
@@ -323,7 +323,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
));
|
||||
// trigger removing of certificate from acme.sh if let's encrypt
|
||||
if ($chk['letsencrypt'] == '1') {
|
||||
\Froxlor\System\Cronjob::inserttask('12', $chk['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $chk['domain']);
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] removed ssl-certificate for '" . $chk['domain'] . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
@@ -421,7 +421,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
// insert task to re-generate webserver-configs (#1260)
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
|
||||
), true, true);
|
||||
|
||||
// insert task to re-generate the cron.d-file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] cronjob with description '" . $result['module'] . '/' . $result['cronfile'] . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('Cronjobs.get', array(
|
||||
'id' => $id
|
||||
|
||||
@@ -23,7 +23,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
|
||||
{
|
||||
|
||||
/**
|
||||
* check whether backup is enabled systemwide and if accessable for customer (hide_options)
|
||||
* check whether backup is enabled systemwide and if accessible for customer (hide_options)
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
@@ -108,7 +108,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
|
||||
'backup_web' => $backup_web
|
||||
);
|
||||
// schedule backup job
|
||||
\Froxlor\System\Cronjob::inserttask('20', $task_data);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_CUSTOMER_BACKUP, $task_data);
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] added customer-backup job for '" . $customer['loginname'] . "'. Target directory: " . $userpath);
|
||||
return $this->response(200, "successful", $task_data);
|
||||
|
||||
@@ -33,7 +33,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* optional specify offset for resultset
|
||||
* @param array $sql_orderby
|
||||
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
|
||||
*
|
||||
* @param bool $show_usages
|
||||
* optional, default false
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array count|list
|
||||
@@ -41,6 +43,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
public function listing()
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$show_usages = $this->getBoolParam('show_usages', true, false);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list customers");
|
||||
$query_fields = array();
|
||||
$result_stmt = Database::prepare("
|
||||
@@ -57,7 +60,47 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$params = array_merge($params, $query_fields);
|
||||
Database::pexecute($result_stmt, $params, true, true);
|
||||
$result = array();
|
||||
|
||||
$domains_stmt = null;
|
||||
$usages_stmt = null;
|
||||
if ($show_usages) {
|
||||
$domains_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) AS `domains`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
WHERE `customerid` = :cid
|
||||
AND `parentdomainid` = '0'
|
||||
AND `id`<> :stdd
|
||||
");
|
||||
$usages_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "`
|
||||
WHERE `customerid` = :cid
|
||||
ORDER BY `stamp` DESC LIMIT 1
|
||||
");
|
||||
}
|
||||
|
||||
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if ($show_usages) {
|
||||
// get number of domains
|
||||
Database::pexecute($domains_stmt, array(
|
||||
'cid' => $row['customerid'],
|
||||
'stdd' => $row['standardsubdomain']
|
||||
));
|
||||
$domains = $domains_stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$row['domains'] = intval($domains['domains']);
|
||||
// get disk-space usages for web, mysql and mail
|
||||
$usages = Database::pexecute_first($usages_stmt, array(
|
||||
'cid' => $row['customerid']
|
||||
));
|
||||
if ($usages) {
|
||||
$row['webspace_used'] = $usages['webspace'];
|
||||
$row['mailspace_used'] = $usages['mail'];
|
||||
$row['dbspace_used'] = $usages['mysql'];
|
||||
} else {
|
||||
$row['webspace_used'] = 0;
|
||||
$row['mailspace_used'] = 0;
|
||||
$row['dbspace_used'] = 0;
|
||||
}
|
||||
}
|
||||
$result[] = $row;
|
||||
}
|
||||
return $this->response(200, "successful", array(
|
||||
@@ -103,6 +146,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* optional, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, the loginname
|
||||
* @param bool $show_usages
|
||||
* optional, default false
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
@@ -113,6 +158,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ln_optional = ($id <= 0 ? false : true);
|
||||
$loginname = $this->getParam('loginname', $ln_optional, '');
|
||||
$show_usages = $this->getBoolParam('show_usages', true, false);
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
$result_stmt = Database::prepare("
|
||||
@@ -142,6 +188,40 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
if (! $this->isAdmin() && $result['custom_notes_show'] != 1) {
|
||||
$result['custom_notes'] = "";
|
||||
}
|
||||
if ($show_usages) {
|
||||
// get number of domains
|
||||
$domains_stmt = Database::prepare("
|
||||
SELECT COUNT(`id`) AS `domains`
|
||||
FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
WHERE `customerid` = :cid
|
||||
AND `parentdomainid` = '0'
|
||||
AND `id`<> :stdd
|
||||
");
|
||||
Database::pexecute($domains_stmt, array(
|
||||
'cid' => $result['customerid'],
|
||||
'stdd' => $result['standardsubdomain']
|
||||
));
|
||||
$domains = $domains_stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$result['domains'] = intval($domains['domains']);
|
||||
// get disk-space usages for web, mysql and mail
|
||||
$usages_stmt = Database::prepare("
|
||||
SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "`
|
||||
WHERE `customerid` = :cid
|
||||
ORDER BY `stamp` DESC LIMIT 1
|
||||
");
|
||||
$usages = Database::pexecute_first($usages_stmt, array(
|
||||
'cid' => $result['customerid']
|
||||
));
|
||||
if ($usages) {
|
||||
$result['webspace_used'] = $usages['webspace'];
|
||||
$result['mailspace_used'] = $usages['mail'];
|
||||
$result['dbspace_used'] = $usages['mysql'];
|
||||
} else {
|
||||
$result['webspace_used'] = 0;
|
||||
$result['mailspace_used'] = 0;
|
||||
$result['dbspace_used'] = 0;
|
||||
}
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get customer '" . $result['loginname'] . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
@@ -228,7 +308,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $mysqls_ul
|
||||
* optional, whether customer should have unlimited mysql-databases, default 0 (false)
|
||||
* @param bool $createstdsubdomain
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 0 (false)
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default [system.createstdsubdom_default]
|
||||
* @param bool $phpenabled
|
||||
* optional, whether to allow usage of PHP, default 0 (false)
|
||||
* @param array $allowed_phpconfigs
|
||||
@@ -236,9 +316,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $perlenabled
|
||||
* optional, whether to allow usage of Perl/CGI, default 0 (false)
|
||||
* @param bool $dnsenabled
|
||||
* optional, wether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* optional, whether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* @param bool $logviewenabled
|
||||
* optional, wether to allow acccess to webserver access/error-logs, default 0 (false)
|
||||
* optional, whether to allow access to webserver access/error-logs, default 0 (false)
|
||||
* @param bool $store_defaultindex
|
||||
* optional, whether to store the default index file to customers homedir
|
||||
* @param int $hosting_plan_id
|
||||
@@ -272,7 +352,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$gender = (int) $this->getParam('gender', true, 0);
|
||||
$custom_notes = $this->getParam('custom_notes', true, '');
|
||||
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, Settings::Get('system.createstdsubdom_default'));
|
||||
$password = $this->getParam('new_customer_password', true, '');
|
||||
$sendpassword = $this->getBoolParam('sendpassword', true, 0);
|
||||
$store_defaultindex = $this->getBoolParam('store_defaultindex', true, 0);
|
||||
@@ -288,6 +368,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
foreach ($hp_result['value'] as $index => $value) {
|
||||
$hp_result[$index] = $value;
|
||||
}
|
||||
$nextcloud_quota = $hp_result['nextcloud_quota'] ?? 0;
|
||||
$diskspace = $hp_result['diskspace'] ?? 0;
|
||||
$traffic = $hp_result['traffic'] ?? 0;
|
||||
$subdomains = $hp_result['subdomains'] ?? 0;
|
||||
@@ -305,6 +386,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$dnsenabled = $hp_result['dnsenabled'] ?? 0;
|
||||
$logviewenabled = $hp_result['logviewenabled'] ?? 0;
|
||||
} else {
|
||||
$nextcloud_quota = $this->getUlParam('nextcloud_quota', 'nextcloud_quota_ul', true, 0);
|
||||
$diskspace = $this->getUlParam('diskspace', 'diskspace_ul', true, 0);
|
||||
$traffic = $this->getUlParam('traffic', 'traffic_ul', true, 0);
|
||||
$subdomains = $this->getUlParam('subdomains', 'subdomains_ul', true, 0);
|
||||
@@ -324,12 +406,12 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
}
|
||||
|
||||
// validation
|
||||
$name = \Froxlor\Validate\Validate::validate($name, 'name', '', '', array(), true);
|
||||
$firstname = \Froxlor\Validate\Validate::validate($firstname, 'first name', '', '', array(), true);
|
||||
$company = \Froxlor\Validate\Validate::validate($company, 'company', '', '', array(), true);
|
||||
$street = \Froxlor\Validate\Validate::validate($street, 'street', '', '', array(), true);
|
||||
$name = \Froxlor\Validate\Validate::validate($name, 'name', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$firstname = \Froxlor\Validate\Validate::validate($firstname, 'first name', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$company = \Froxlor\Validate\Validate::validate($company, 'company', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$street = \Froxlor\Validate\Validate::validate($street, 'street', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$zipcode = \Froxlor\Validate\Validate::validate($zipcode, 'zipcode', '/^[0-9 \-A-Z]*$/', '', array(), true);
|
||||
$city = \Froxlor\Validate\Validate::validate($city, 'city', '', '', array(), true);
|
||||
$city = \Froxlor\Validate\Validate::validate($city, 'city', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$phone = \Froxlor\Validate\Validate::validate($phone, 'phone', '/^[0-9\- \+\(\)\/]*$/', '', array(), true);
|
||||
$fax = \Froxlor\Validate\Validate::validate($fax, 'fax', '/^[0-9\- \+\(\)\/]*$/', '', array(), true);
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
@@ -453,6 +535,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'api_allowed' => $api_allowed,
|
||||
'docroot' => $documentroot,
|
||||
'guid' => $guid,
|
||||
'nextcloud_quota' => $nextcloud_quota,
|
||||
'diskspace' => $diskspace,
|
||||
'traffic' => $traffic,
|
||||
'subdomains' => $subdomains,
|
||||
@@ -494,6 +577,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
`api_allowed` = :api_allowed,
|
||||
`documentroot` = :docroot,
|
||||
`guid` = :guid,
|
||||
`nextcloud_quota` = :nextcloud_quota,
|
||||
`diskspace` = :diskspace,
|
||||
`traffic` = :traffic,
|
||||
`subdomains` = :subdomains,
|
||||
@@ -565,10 +649,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
unset($ins_data);
|
||||
|
||||
// insert task to create homedir etc.
|
||||
\Froxlor\System\Cronjob::inserttask('2', $loginname, $guid, $guid, $store_defaultindex);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_HOME, $loginname, $guid, $guid, $store_defaultindex);
|
||||
|
||||
// Using filesystem - quota, insert a task which cleans the filesystem - quota
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
|
||||
// Add htpasswd for the stats-pages
|
||||
$htpasswdPassword = \Froxlor\System\Crypt::makeCryptPassword($password, true);
|
||||
@@ -594,7 +678,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added " . $stats_folder . " htpasswd for user '" . $loginname . "'");
|
||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
|
||||
// add default FTP-User
|
||||
// also, add froxlor-local user to ftp-group (if exists!) to
|
||||
@@ -659,7 +743,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'customerid' => $customerid
|
||||
), true, true);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added standardsubdomain for user '" . $loginname . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,7 +919,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $mysqls_ul
|
||||
* optional, whether customer should have unlimited mysql-databases, default 0 (false)
|
||||
* @param bool $createstdsubdomain
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 0 (false)
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 1 (if customer has std-subdomain) else 0 (false)
|
||||
* @param bool $phpenabled
|
||||
* optional, whether to allow usage of PHP, default 0 (false)
|
||||
* @param array $allowed_phpconfigs
|
||||
@@ -843,9 +927,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $perlenabled
|
||||
* optional, whether to allow usage of Perl/CGI, default 0 (false)
|
||||
* @param bool $dnsenabled
|
||||
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* optional, whether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* @param bool $logviewenabled
|
||||
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
|
||||
* optional, whether to allow access to webserver access/error-logs, default 0 (false)
|
||||
* @param string $theme
|
||||
* optional, change theme
|
||||
*
|
||||
@@ -870,10 +954,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$move_to_admin = (int) ($this->getParam('move_to_admin', true, 0));
|
||||
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
$email = $this->getParam('email', true, $idna_convert->decode($result['email']));
|
||||
$email = $this->getParam('email', true, $idna_convert->decode($result['email'] ?? ''));
|
||||
$name = $this->getParam('name', true, $result['name']);
|
||||
$firstname = $this->getParam('firstname', true, $result['firstname']);
|
||||
$company_required = (! empty($name) && empty($firstname)) || (empty($name) && ! empty($firstname)) || (empty($name) && empty($firstname));
|
||||
$company_required = empty($result['company']) && ((! empty($name) && empty($firstname)) || (empty($name) && ! empty($firstname)) || (empty($name) && empty($firstname)));
|
||||
$company = $this->getParam('company', ($company_required ? false : true), $result['company']);
|
||||
$street = $this->getParam('street', true, $result['street']);
|
||||
$zipcode = $this->getParam('zipcode', true, $result['zipcode']);
|
||||
@@ -888,6 +972,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, $result['custom_notes_show']);
|
||||
|
||||
$dec_places = Settings::Get('panel.decimal_places');
|
||||
$nextcloud_quota = $this->getUlParam('nextcloud_quota', 'nextcloud_quota_ul', true, round($result['nextcloud_quota'], $dec_places));
|
||||
$diskspace = $this->getUlParam('diskspace', 'diskspace_ul', true, round($result['diskspace'] / 1024, $dec_places));
|
||||
$traffic = $this->getUlParam('traffic', 'traffic_ul', true, round($result['traffic'] / (1024 * 1024), $dec_places));
|
||||
$subdomains = $this->getUlParam('subdomains', 'subdomains_ul', true, $result['subdomains']);
|
||||
@@ -899,7 +984,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$email_pop3 = $this->getParam('email_pop3', true, $result['pop3']);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, $result['mysqls']);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, ($result['standardsubdomain'] != 0 ? 1 : 0));
|
||||
$password = $this->getParam('new_customer_password', true, '');
|
||||
$phpenabled = $this->getBoolParam('phpenabled', true, $result['phpenabled']);
|
||||
$allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, json_decode($result['allowed_phpconfigs'], true));
|
||||
@@ -918,12 +1003,12 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
// validation
|
||||
if ($this->isAdmin()) {
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
$name = \Froxlor\Validate\Validate::validate($name, 'name', '', '', array(), true);
|
||||
$firstname = \Froxlor\Validate\Validate::validate($firstname, 'first name', '', '', array(), true);
|
||||
$company = \Froxlor\Validate\Validate::validate($company, 'company', '', '', array(), true);
|
||||
$street = \Froxlor\Validate\Validate::validate($street, 'street', '', '', array(), true);
|
||||
$name = \Froxlor\Validate\Validate::validate($name, 'name', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$firstname = \Froxlor\Validate\Validate::validate($firstname, 'first name', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$company = \Froxlor\Validate\Validate::validate($company, 'company', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$street = \Froxlor\Validate\Validate::validate($street, 'street', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$zipcode = \Froxlor\Validate\Validate::validate($zipcode, 'zipcode', '/^[0-9 \-A-Z]*$/', '', array(), true);
|
||||
$city = \Froxlor\Validate\Validate::validate($city, 'city', '', '', array(), true);
|
||||
$city = \Froxlor\Validate\Validate::validate($city, 'city', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$phone = \Froxlor\Validate\Validate::validate($phone, 'phone', '/^[0-9\- \+\(\)\/]*$/', '', array(), true);
|
||||
$fax = \Froxlor\Validate\Validate::validate($fax, 'fax', '/^[0-9\- \+\(\)\/]*$/', '', array(), true);
|
||||
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
|
||||
@@ -971,7 +1056,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
}
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
if ($createstdsubdomain != '1') {
|
||||
if ($createstdsubdomain != '1' || $deactivated) {
|
||||
$createstdsubdomain = '0';
|
||||
}
|
||||
|
||||
@@ -1008,7 +1093,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'customerid' => $result['customerid']
|
||||
), true, true);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added standardsubdomain for user '" . $result['loginname'] . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1022,11 +1107,11 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_ERR, "[API] Unable to delete standard-subdomain: " . $e->getMessage());
|
||||
}
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically deleted standardsubdomain for user '" . $result['loginname'] . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
if ($phpenabled != $result['phpenabled'] || $perlenabled != $result['perlenabled'] || $email != $result['email']) {
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
// activate/deactivate customer services
|
||||
@@ -1112,7 +1197,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
), true, true);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] " . ($deactivated ? 'deactivated' : 'reactivated') . " user '" . $result['loginname'] . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
// Disable or enable POP3 Login for customers Mail Accounts
|
||||
@@ -1154,6 +1239,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'fax' => $fax,
|
||||
'email' => $email,
|
||||
'customerno' => $customernumber,
|
||||
'nextcloud_quota' => $nextcloud_quota,
|
||||
'diskspace' => $diskspace,
|
||||
'traffic' => $traffic,
|
||||
'subdomains' => $subdomains,
|
||||
@@ -1196,6 +1282,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
`fax` = :fax,
|
||||
`email` = :email,
|
||||
`customernumber` = :customerno,
|
||||
`nextcloud_quota` = :nextcloud_quota,
|
||||
`diskspace` = :diskspace,
|
||||
`traffic` = :traffic,
|
||||
`subdomains` = :subdomains,
|
||||
@@ -1224,7 +1311,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
// Using filesystem - quota, insert a task which cleans the filesystem - quota
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
|
||||
$admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` ";
|
||||
|
||||
@@ -1411,7 +1498,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
), true, true);
|
||||
|
||||
// first gather all domain-id's to clean up panel_domaintoip, dns-entries and certificates accordingly
|
||||
$did_stmt = Database::prepare("SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
|
||||
$did_stmt = Database::prepare("SELECT `id`, `domain` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
|
||||
Database::pexecute($did_stmt, array(
|
||||
'id' => $id
|
||||
), true, true);
|
||||
@@ -1431,6 +1518,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
Database::pexecute($stmt, array(
|
||||
'did' => $row['id']
|
||||
), true, true);
|
||||
// remove domains DNS from powerDNS if used, #581
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_PDNS, $row['domain']);
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $row['domain']);
|
||||
}
|
||||
// remove customer domains
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
|
||||
@@ -1559,18 +1650,18 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
}
|
||||
|
||||
// rebuild configs
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
if ($delete_userfiles == 1) {
|
||||
// insert task to remove the customers files from the filesystem
|
||||
\Froxlor\System\Cronjob::inserttask('6', $result['loginname']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_CUSTOMER_FILES, $result['loginname']);
|
||||
}
|
||||
|
||||
// Using filesystem - quota, insert a task which cleans the filesystem - quota
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted customer '" . $result['loginname'] . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
|
||||
@@ -123,7 +123,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$id = Database::lastInsertId();
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added directory-option for '" . $userpath . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
|
||||
$result = $this->apiCall('DirOptions.get', array(
|
||||
'id' => $id
|
||||
@@ -248,7 +248,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
|
||||
if (($options_indexes != $result['options_indexes']) || ($error404path != $result['error404path']) || ($error403path != $result['error403path']) || ($error500path != $result['error500path']) || ($options_cgi != $result['options_cgi'])) {
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_HTACCESS . "`
|
||||
SET `options_indexes` = :options_indexes,
|
||||
@@ -322,7 +322,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable directory options
|
||||
* returns the total number of accessible directory options
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select directory-protections of a specific customer by id
|
||||
@@ -413,7 +413,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
"id" => $id
|
||||
), true, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted directory-option for '" . str_replace($customer_data['documentroot'], '/', $result['path']) . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$id = Database::lastInsertId();
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added directory-protection for '" . $username . " (" . $path . ")'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
|
||||
$result = $this->apiCall('DirProtections.get', array(
|
||||
'id' => $id
|
||||
@@ -251,7 +251,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
|
||||
UPDATE `" . TABLE_PANEL_HTPASSWDS . "` SET " . $upd_query . " WHERE `id` = :id AND `customerid`= :cid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_params, true, true);
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] updated directory-protection '" . $result['username'] . " (" . $result['path'] . ")'");
|
||||
@@ -305,7 +305,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable directory protections
|
||||
* returns the total number of accessible directory protections
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select directory-protections of a specific customer by id
|
||||
@@ -385,7 +385,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
|
||||
));
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,8 +136,24 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
// types
|
||||
if ($type == 'A' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
|
||||
$errors[] = $this->lng['error']['dns_arec_noipv4'];
|
||||
} elseif ($type == 'A') {
|
||||
// check whether there is a CNAME-record for the same resource
|
||||
foreach ($dom_entries as $existing_entries) {
|
||||
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
|
||||
$errors[] = $this->lng['error']['dns_other_nomorerr'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif ($type == 'AAAA' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
|
||||
$errors[] = $this->lng['error']['dns_aaaarec_noipv6'];
|
||||
} elseif ($type == 'AAAA') {
|
||||
// check whether there is a CNAME-record for the same resource
|
||||
foreach ($dom_entries as $existing_entries) {
|
||||
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
|
||||
$errors[] = $this->lng['error']['dns_other_nomorerr'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif ($type == 'CAA' && ! empty($content)) {
|
||||
$re = '/(?\'critical\'\d)\h*(?\'type\'iodef|issue|issuewild)\h*(?\'value\'(?\'issuevalue\'"(?\'domain\'(?=.{3,128}$)(?>(?>[a-zA-Z0-9]+[a-zA-Z0-9-]*[a-zA-Z0-9]+|[a-zA-Z0-9]+)\.)*(?>[a-zA-Z]{2,}|[a-zA-Z0-9]{2,}\.[a-zA-Z]{2,}))[;\h]*(?\'parameters\'(?>[a-zA-Z0-9]{1,60}=[a-zA-Z0-9]{1,60}\h*)+)?")|(?\'iodefvalue\'"(?\'url\'(mailto:.*|http:\/\/.*|https:\/\/.*))"))/';
|
||||
preg_match($re, $content, $matches);
|
||||
@@ -198,6 +214,10 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$errors[] = $this->lng['error']['dns_mx_noalias'];
|
||||
break;
|
||||
}
|
||||
elseif ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
|
||||
$errors[] = $this->lng['error']['dns_other_nomorerr'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// append trailing dot (again)
|
||||
@@ -210,6 +230,14 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
}
|
||||
if (! \Froxlor\Validate\Validate::validateDomain($content)) {
|
||||
$errors[] = $this->lng['error']['dns_ns_invaliddom'];
|
||||
} else {
|
||||
// check whether there is a CNAME-record for the same resource
|
||||
foreach ($dom_entries as $existing_entries) {
|
||||
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
|
||||
$errors[] = $this->lng['error']['dns_other_nomorerr'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// append trailing dot (again)
|
||||
$content .= '.';
|
||||
@@ -308,7 +336,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$dom_entries[] = $new_entry;
|
||||
|
||||
// re-generate bind configs
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$result = $this->apiCall('DomainZones.get', array(
|
||||
'id' => $id
|
||||
@@ -514,7 +542,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
), true, true);
|
||||
if ($del_stmt->rowCount() > 0) {
|
||||
// re-generate bind configs
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
return $this->response(200, "successful", true);
|
||||
}
|
||||
return $this->response(304, "successful", true);
|
||||
|
||||
@@ -77,7 +77,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable domains
|
||||
* returns the total number of accessible domains
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -193,6 +193,27 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
return $ipandports;
|
||||
}
|
||||
|
||||
/**
|
||||
* get ips from array of id's
|
||||
*
|
||||
* @param array $ips
|
||||
* @return array
|
||||
*/
|
||||
private function getIpsFromIdArray(array $ids)
|
||||
{
|
||||
$resultips_stmt = Database::prepare("
|
||||
SELECT `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE id = :id
|
||||
");
|
||||
$result = [];
|
||||
foreach ($ids as $id) {
|
||||
$entry = Database::pexecute_first($resultips_stmt, array(
|
||||
'id' => $id
|
||||
));
|
||||
$result[] = $entry['ip'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* add new domain entry
|
||||
*
|
||||
@@ -213,12 +234,12 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
* @param bool $email_only
|
||||
* optional, restrict domain to email usage, default 0 (false)
|
||||
* @param int $selectserveralias
|
||||
* optional, 0 = wildcard, 1 = www-alias, 2 = none, default 0
|
||||
* optional, 0 = wildcard, 1 = www-alias, 2 = none, default [system.domaindefaultalias]
|
||||
* @param bool $speciallogfile
|
||||
* optional, whether to create an exclusive web-logfile for this domain, default 0 (false)
|
||||
* @param int $alias
|
||||
* optional, domain-id of a domain that the new domain should be an alias of, default 0 (none)
|
||||
* @param bool $issubof
|
||||
* @param int $issubof
|
||||
* optional, domain-id of a domain this domain is a subdomain of (required for webserver-cronjob to generate the correct order), default 0 (none)
|
||||
* @param string $registration_date
|
||||
* optional, date of domain registration in form of YYYY-MM-DD, default empty (none)
|
||||
@@ -288,6 +309,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
* optional list of allowed/used ssl/tls ciphers, see system.ssl_cipher_list setting, only used/required if $override_tls is true, default empty or system.ssl_cipher_list setting if $override_tls is true
|
||||
* @param string $tlsv13_cipher_list
|
||||
* optional list of allowed/used tls-1.3 specific ciphers, see system.tlsv13_cipher_list setting, only used/required if $override_tls is true, default empty or system.tlsv13_cipher_list setting if $override_tls is true
|
||||
* @param string $description
|
||||
* optional custom description (currently not used/shown in the frontend), default empty
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -307,7 +330,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$subcanemaildomain = $this->getParam('subcanemaildomain', true, 0);
|
||||
$isemaildomain = $this->getBoolParam('isemaildomain', true, 0);
|
||||
$email_only = $this->getBoolParam('email_only', true, 0);
|
||||
$serveraliasoption = $this->getParam('selectserveralias', true, 0);
|
||||
$serveraliasoption = $this->getParam('selectserveralias', true, Settings::Get('system.domaindefaultalias'));
|
||||
$speciallogfile = $this->getBoolParam('speciallogfile', true, 0);
|
||||
$aliasdomain = intval($this->getParam('alias', true, 0));
|
||||
$issubof = $this->getParam('issubof', true, 0);
|
||||
@@ -354,6 +377,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, Settings::Get('system.tlsv13_cipher_list'));
|
||||
}
|
||||
}
|
||||
$description = $this->getParam('description', true, '');
|
||||
|
||||
// validation
|
||||
$p_domain = strtolower($p_domain);
|
||||
@@ -403,6 +427,20 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . $path_suffix);
|
||||
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (! empty($documentroot)) {
|
||||
if (substr($documentroot, 0, 1) != '/' && ! preg_match('/^https?\:\/\//', $documentroot)) {
|
||||
$documentroot = $_documentroot . '/' . $documentroot;
|
||||
} elseif (substr($documentroot, 0, 1) == '/' && $this->getUserDetail('change_serversettings') != '1') {
|
||||
\Froxlor\UI\Response::standard_error('pathmustberelative', '', true);
|
||||
}
|
||||
} else {
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
$registration_date = \Froxlor\Validate\Validate::validate($registration_date, 'registration_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array(
|
||||
'0000-00-00',
|
||||
'0',
|
||||
@@ -430,17 +468,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
\Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (! empty($documentroot)) {
|
||||
if (substr($documentroot, 0, 1) != '/' && ! preg_match('/^https?\:\/\//', $documentroot)) {
|
||||
$documentroot = $_documentroot . '/' . $documentroot;
|
||||
}
|
||||
} else {
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
$ssl_protocols = array();
|
||||
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
|
||||
@@ -483,7 +510,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$notryfiles = '0';
|
||||
$writeaccesslog = '1';
|
||||
$writeerrorlog = '1';
|
||||
$documentroot = $_documentroot;
|
||||
$override_tls = '0';
|
||||
$ssl_protocols = array();
|
||||
}
|
||||
@@ -571,6 +597,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$include_specialsettings = 0;
|
||||
}
|
||||
|
||||
// validate dns if lets encrypt is enabled to check whether we can use it at all
|
||||
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
|
||||
$domain_ips = \Froxlor\PhpHelper::gethostbynamel6($domain);
|
||||
$selected_ips = $this->getIpsFromIdArray($ssl_ipandports);
|
||||
if ($domain_ips == false || count(array_intersect($selected_ips, $domain_ips)) <= 0) {
|
||||
\Froxlor\UI\Response::standard_error('invaliddnsforletsencrypt', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// We can't enable let's encrypt for wildcard-domains
|
||||
if ($serveraliasoption == '0' && $letsencrypt == '1') {
|
||||
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
|
||||
@@ -728,7 +763,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
'tlsv13_cipher_list' => $tlsv13_cipher_list,
|
||||
'sslenabled' => $sslenabled,
|
||||
'honorcipherorder' => $honorcipherorder,
|
||||
'sessiontickets' => $sessiontickets
|
||||
'sessiontickets' => $sessiontickets,
|
||||
'description' => $description
|
||||
);
|
||||
|
||||
$ins_stmt = Database::prepare("
|
||||
@@ -780,7 +816,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
`tlsv13_cipher_list` = :tlsv13_cipher_list,
|
||||
`ssl_enabled` = :sslenabled,
|
||||
`ssl_honorcipherorder` = :honorcipherorder,
|
||||
`ssl_sessiontickets`= :sessiontickets
|
||||
`ssl_sessiontickets` = :sessiontickets,
|
||||
`description` = :description
|
||||
");
|
||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||
$domainid = Database::lastInsertId();
|
||||
@@ -820,9 +857,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
|
||||
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] added domain '" . $domain . "'");
|
||||
|
||||
@@ -866,7 +903,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
* optional, when setting $speciallogfile to false, this needs to be set to true to confirm the action, default 0 (false)
|
||||
* @param int $alias
|
||||
* optional, domain-id of a domain that the new domain should be an alias of, default 0 (none)
|
||||
* @param bool $issubof
|
||||
* @param int $issubof
|
||||
* optional, domain-id of a domain this domain is a subdomain of (required for webserver-cronjob to generate the correct order), default 0 (none)
|
||||
* @param string $registration_date
|
||||
* optional, date of domain registration in form of YYYY-MM-DD, default empty (none)
|
||||
@@ -932,6 +969,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
* optional whether to honor the (server) cipher order for this domain. default 0 (false), requires SSL
|
||||
* @param bool $sessiontickets
|
||||
* optional whether to enable or disable TLS sessiontickets (RFC 5077) for this domain. default 1 (true), requires SSL
|
||||
* @param string $description
|
||||
* optional custom description (currently not used/shown in the frontend), default empty
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -1027,6 +1066,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$ssl_cipher_list = $result['ssl_cipher_list'];
|
||||
$tlsv13_cipher_list = $result['tlsv13_cipher_list'];
|
||||
}
|
||||
$description = $this->getParam('description', true, $result['description']);
|
||||
|
||||
// count subdomain usage of source-domain
|
||||
$subdomains_stmt = Database::prepare("
|
||||
@@ -1149,6 +1189,38 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$serveraliasoption = $p_serveraliasoption;
|
||||
}
|
||||
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
if (! empty($documentroot) && $documentroot != $result['documentroot'] && substr($documentroot, 0, 1) == '/' && substr($documentroot, 0, strlen($customer['documentroot'])) != $customer['documentroot'] && $this->getUserDetail('change_serversettings') != '1') {
|
||||
\Froxlor\UI\Response::standard_error('pathmustberelative', '', true);
|
||||
}
|
||||
|
||||
// when moving customer and no path is specified, update would normally reuse the current document-root
|
||||
// which would point to the wrong customer, therefore we will re-create that directory
|
||||
if (! empty($documentroot) && $customerid > 0 && $customerid != $result['customerid'] && Settings::Get('panel.allow_domain_change_customer') == '1') {
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$_documentroot = $customer['documentroot'];
|
||||
}
|
||||
// set the customers default docroot
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
if ($documentroot == '') {
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$documentroot = $customer['documentroot'];
|
||||
}
|
||||
}
|
||||
|
||||
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
|
||||
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
|
||||
}
|
||||
|
||||
if ($this->getUserDetail('change_serversettings') == '1') {
|
||||
|
||||
if (Settings::Get('system.bind_enable') == '1') {
|
||||
@@ -1163,33 +1235,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// when moving customer and no path is specified, update would normally reuse the current document-root
|
||||
// which would point to the wrong customer, therefore we will re-create that directory
|
||||
if (! empty($documentroot) && $customerid > 0 && $customerid != $result['customerid'] && Settings::Get('panel.allow_domain_change_customer') == '1') {
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$_documentroot = $customer['documentroot'];
|
||||
}
|
||||
// set the customers default docroot
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
if ($documentroot == '') {
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$documentroot = $customer['documentroot'];
|
||||
}
|
||||
}
|
||||
|
||||
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
|
||||
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
|
||||
}
|
||||
|
||||
$ssl_protocols = array();
|
||||
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
|
||||
@@ -1229,7 +1274,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$notryfiles = $result['notryfiles'];
|
||||
$writeaccesslog = $result['writeaccesslog'];
|
||||
$writeerrorlog = $result['writeerrorlog'];
|
||||
$documentroot = $result['documentroot'];
|
||||
$ssl_protocols = $p_ssl_protocols;
|
||||
$override_tls = $result['override_tls'];
|
||||
}
|
||||
@@ -1318,6 +1362,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$include_specialsettings = 0;
|
||||
}
|
||||
|
||||
// validate dns if lets encrypt is enabled to check whether we can use it at all
|
||||
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
|
||||
$domain_ips = \Froxlor\PhpHelper::gethostbynamel6($result['domain']);
|
||||
$selected_ips = $this->getIpsFromIdArray($ssl_ipandports);
|
||||
if ($domain_ips == false || count(array_intersect($selected_ips, $domain_ips)) <= 0) {
|
||||
\Froxlor\UI\Response::standard_error('invaliddnsforletsencrypt', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// We can't enable let's encrypt for wildcard-domains
|
||||
if ($serveraliasoption == '0' && $letsencrypt == '1') {
|
||||
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
|
||||
@@ -1411,8 +1464,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$wwwserveralias = ($serveraliasoption == '1') ? '1' : '0';
|
||||
$iswildcarddomain = ($serveraliasoption == '0') ? '1' : '0';
|
||||
|
||||
if ($documentroot != $result['documentroot'] || $ssl_redirect != $result['ssl_redirect'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $phpenabled != $result['phpenabled'] || $openbasedir != $result['openbasedir'] || $phpsettingid != $result['phpsettingid'] || $mod_fcgid_starter != $result['mod_fcgid_starter'] || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] || $specialsettings != $result['specialsettings'] || $notryfiles != $result['notryfiles'] || $writeaccesslog != $result['writeaccesslog'] || $writeerrorlog != $result['writeerrorlog'] || $aliasdomain != $result['aliasdomain'] || $issubof != $result['ismainbutsubto'] || $email_only != $result['email_only'] || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') || $letsencrypt != $result['letsencrypt'] || $http2 != $result['http2'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $ocsp_stapling != $result['ocsp_stapling']) {
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
if ($documentroot != $result['documentroot'] || $ssl_redirect != $result['ssl_redirect'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $phpenabled != $result['phpenabled'] || $openbasedir != $result['openbasedir'] || $phpsettingid != $result['phpsettingid'] || $mod_fcgid_starter != $result['mod_fcgid_starter'] || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] || $specialsettings != $result['specialsettings'] || $ssl_specialsettings != $result['ssl_specialsettings'] || $notryfiles != $result['notryfiles'] || $writeaccesslog != $result['writeaccesslog'] || $writeerrorlog != $result['writeerrorlog'] || $aliasdomain != $result['aliasdomain'] || $issubof != $result['ismainbutsubto'] || $email_only != $result['email_only'] || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') || $letsencrypt != $result['letsencrypt'] || $http2 != $result['http2'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $ocsp_stapling != $result['ocsp_stapling']) {
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
if ($speciallogfile != $result['speciallogfile'] && $speciallogverified != '1') {
|
||||
@@ -1420,11 +1473,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
if ($isbinddomain != $result['isbinddomain'] || $zonefile != $result['zonefile'] || $dkim != $result['dkim'] || $isemaildomain != $result['isemaildomain']) {
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
}
|
||||
// check whether nameserver has been disabled, #581
|
||||
if ($isbinddomain != $result['isbinddomain'] && $isbinddomain == 0) {
|
||||
\Froxlor\System\Cronjob::inserttask('11', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_PDNS, $result['domain']);
|
||||
}
|
||||
|
||||
if ($isemaildomain == '0' && $result['isemaildomain'] == '1') {
|
||||
@@ -1453,7 +1506,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
'id' => $id
|
||||
), true, true);
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
|
||||
}
|
||||
|
||||
$updatechildren = '';
|
||||
@@ -1589,6 +1642,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$update_data['sslenabled'] = $sslenabled;
|
||||
$update_data['honorcipherorder'] = $honorcipherorder;
|
||||
$update_data['sessiontickets'] = $sessiontickets;
|
||||
$update_data['description'] = $description;
|
||||
$update_data['id'] = $id;
|
||||
|
||||
$update_stmt = Database::prepare("
|
||||
@@ -1634,7 +1688,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
`tlsv13_cipher_list` = :tlsv13_cipher_list,
|
||||
`ssl_enabled` = :sslenabled,
|
||||
`ssl_honorcipherorder` = :honorcipherorder,
|
||||
`ssl_sessiontickets` = :sessiontickets
|
||||
`ssl_sessiontickets` = :sessiontickets,
|
||||
`description` = :description
|
||||
WHERE `id` = :id
|
||||
");
|
||||
Database::pexecute($update_stmt, $update_data, true, true);
|
||||
@@ -1692,9 +1747,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
");
|
||||
Database::pexecute($_update_stmt, $_update_data, true, true);
|
||||
|
||||
// insert a rebuild-task
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
|
||||
// Cleanup domain <-> ip mapping
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id
|
||||
@@ -1932,16 +1984,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger());
|
||||
|
||||
// remove domains DNS from powerDNS if used, #581
|
||||
\Froxlor\System\Cronjob::inserttask('11', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_PDNS, $result['domain']);
|
||||
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] deleted domain/subdomains (#" . $result['id'] . ")");
|
||||
\Froxlor\User::updateCounters();
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
throw new \Exception("Not allowed to execute given command.", 403);
|
||||
|
||||
@@ -100,7 +100,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
||||
// alternative email address to send info to
|
||||
if (Settings::Get('panel.sendalternativemail') == 1) {
|
||||
$alternative_email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($alternative_email, 'alternative_email', '', '', array(), true));
|
||||
if (!empty($alternative_email) && ! \Froxlor\Validate\Validate::validateEmail($alternative_email)) {
|
||||
if (! empty($alternative_email) && ! \Froxlor\Validate\Validate::validateEmail($alternative_email)) {
|
||||
\Froxlor\UI\Response::standard_error('alternativeemailiswrong', $alternative_email, true);
|
||||
}
|
||||
} else {
|
||||
@@ -192,11 +192,12 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
||||
$replace_arr = array(
|
||||
'EMAIL' => $email_full,
|
||||
'USERNAME' => $username,
|
||||
'PASSWORD' => $password,
|
||||
'PASSWORD' => htmlentities(htmlentities($password)),
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer),
|
||||
'NAME' => $customer['name'],
|
||||
'FIRSTNAME' => $customer['firstname'],
|
||||
'COMPANY' => $customer['company'],
|
||||
'USERNAME' => $customer['loginname'],
|
||||
'CUSTOMER_NO' => $customer['customernumber']
|
||||
);
|
||||
|
||||
@@ -236,7 +237,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
||||
$this->mailer()->clearAddresses();
|
||||
|
||||
// customer wants to send the e-mail to an alternative email address too
|
||||
if (Settings::Get('panel.sendalternativemail') == 1 && !empty($alternative_email)) {
|
||||
if (Settings::Get('panel.sendalternativemail') == 1 && ! empty($alternative_email)) {
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($customer, 'mails', 'pop_success_alternative_subject', $replace_arr, $this->lng['mails']['pop_success_alternative']['subject']);
|
||||
// get template for mail body
|
||||
@@ -302,6 +303,8 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
||||
* optional, update quota
|
||||
* @param string $email_password
|
||||
* optional, update password
|
||||
* @param bool $deactivated
|
||||
* optional, admin-only
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
@@ -331,6 +334,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
||||
|
||||
$password = $this->getParam('email_password', true, '');
|
||||
$quota = $this->getParam('email_quota', true, $result['quota']);
|
||||
$deactivated = $this->getBoolParam('deactivated', true, (strtolower($result['postfix']) == 'n' ? true : false));
|
||||
|
||||
// get needed customer info to reduce the email-account-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
@@ -372,6 +376,18 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
||||
$quota = 0;
|
||||
}
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
if (($deactivated == true && strtolower($result['postfix']) == 'y') || ($deactivated == false && strtolower($result['postfix']) == 'n')) {
|
||||
if (! empty($upd_query)) {
|
||||
$upd_query .= ", ";
|
||||
}
|
||||
$upd_query .= "`postfix` = :postfix, `imap` = :imap, `pop3` = :pop3";
|
||||
$upd_params['postfix'] = $deactivated ? 'N' : 'Y';
|
||||
$upd_params['imap'] = $deactivated ? '0' : '1';
|
||||
$upd_params['pop3'] = $deactivated ? '0' : '1';
|
||||
}
|
||||
}
|
||||
|
||||
// build update query
|
||||
if (! empty($upd_query)) {
|
||||
$upd_stmt = Database::prepare("
|
||||
@@ -484,7 +500,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
||||
}
|
||||
|
||||
if ($delete_userfiles) {
|
||||
\Froxlor\System\Cronjob::inserttask('7', $customer['loginname'], $result['email_full']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_EMAIL_DATA, $customer['loginname'], $result['email_full']);
|
||||
}
|
||||
|
||||
// decrease usage for customer
|
||||
|
||||
@@ -65,7 +65,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
|
||||
$id = $result['id'];
|
||||
|
||||
// current destination array
|
||||
$result['destination_array'] = explode(' ', $result['destination']);
|
||||
$result['destination_array'] = explode(' ', ($result['destination'] ?? ''));
|
||||
|
||||
// prepare destination
|
||||
$destination = trim($destination);
|
||||
|
||||
@@ -35,6 +35,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, required when called as admin (if $loginname is not specified)
|
||||
* @param string $loginname
|
||||
* optional, required when called as admin (if $customerid is not specified)
|
||||
* @param string $description
|
||||
* optional custom description (currently not used/shown in the frontend), default empty
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
@@ -54,6 +56,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
|
||||
// parameters
|
||||
$iscatchall = $this->getBoolParam('iscatchall', true, 0);
|
||||
$description = $this->getParam('description', true, '');
|
||||
$disablegreylist = $this->getBoolParam('disablegreylist', true, 0);
|
||||
|
||||
// validation
|
||||
if (substr($domain, 0, 4) != 'xn--') {
|
||||
@@ -73,6 +77,9 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
if (Settings::Get('catchall.catchall_enabled') != '1') {
|
||||
$iscatchall = 0;
|
||||
}
|
||||
if (Settings::Get('mail.greylist_enabled') != '1') {
|
||||
$disablegreylist = 1;
|
||||
}
|
||||
|
||||
// check for catchall-flag
|
||||
if ($iscatchall) {
|
||||
@@ -121,14 +128,18 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
`email` = :email,
|
||||
`email_full` = :email_full,
|
||||
`iscatchall` = :iscatchall,
|
||||
`domainid` = :domainid
|
||||
`disablegreylist` = :disablegreylist,
|
||||
`domainid` = :domainid,
|
||||
`description` = :description
|
||||
");
|
||||
$params = array(
|
||||
"cid" => $customer['customerid'],
|
||||
"email" => $email,
|
||||
"email_full" => $email_full,
|
||||
"iscatchall" => $iscatchall,
|
||||
"domainid" => $domain_check['id']
|
||||
"disablegreylist" => $disablegreylist,
|
||||
"domainid" => $domain_check['id'],
|
||||
"description" => $description
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
|
||||
@@ -167,7 +178,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$customer_ids = $this->getAllowedCustomerIds('email');
|
||||
$params['idea'] = ($id <= 0 ? $emailaddr : $id);
|
||||
|
||||
$result_stmt = Database::prepare("SELECT v.`id`, v.`email`, v.`email_full`, v.`iscatchall`, v.`destination`, v.`customerid`, v.`popaccountid`, v.`domainid`, u.`quota`
|
||||
$result_stmt = Database::prepare("SELECT v.`id`, v.`email`, v.`email_full`, v.`iscatchall`, v.`destination`, v.`customerid`, v.`popaccountid`, v.`domainid`, v.`description`, u.`quota`, u.`imap`, u.`pop3`, u.`postfix`, u.`mboxsize`, v.`disablegreylist`
|
||||
FROM `" . TABLE_MAIL_VIRTUAL . "` v
|
||||
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id`
|
||||
WHERE v.`customerid` IN (" . implode(", ", $customer_ids) . ")
|
||||
@@ -195,6 +206,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, required when called as admin (if $customerid is not specified)
|
||||
* @param boolean $iscatchall
|
||||
* optional
|
||||
* @param string $description
|
||||
* optional custom description (currently not used/shown in the frontend), default empty
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
@@ -227,7 +240,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
|
||||
// parameters
|
||||
$iscatchall = $this->getBoolParam('iscatchall', true, $result['iscatchall']);
|
||||
|
||||
$description = $this->getParam('description', true, $result['description']);
|
||||
|
||||
// get needed customer info to reduce the email-address-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
@@ -256,12 +270,13 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_VIRTUAL . "`
|
||||
SET `email` = :email , `iscatchall` = :caflag
|
||||
SET `email` = :email , `iscatchall` = :caflag, `description` = :description
|
||||
WHERE `customerid`= :cid AND `id`= :id
|
||||
");
|
||||
$params = array(
|
||||
"email" => $email,
|
||||
"caflag" => $iscatchall,
|
||||
"description" => $description,
|
||||
"cid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
@@ -273,7 +288,97 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
));
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* toggle greylist flag of given email address either by id or email-address
|
||||
*
|
||||
* @param int $id
|
||||
* optional, the email-address-id
|
||||
* @param string $emailaddr
|
||||
* optional, the email-address
|
||||
* @param int $customerid
|
||||
* optional, admin-only, the customer-id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, the loginname
|
||||
* @param boolean $disablegreylist
|
||||
* optional
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array
|
||||
*/
|
||||
public function update_greylist()
|
||||
{
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'email')) {
|
||||
throw new \Exception("You cannot access this resource", 405);
|
||||
}
|
||||
|
||||
// if enabling catchall is not allowed by settings, we do not need
|
||||
// to run update()
|
||||
if (Settings::Get('mail.greylist_enabled') != '1') {
|
||||
\Froxlor\UI\Response::standard_error(array(
|
||||
'operationnotpermitted',
|
||||
'featureisdisabled'
|
||||
), 'catchall', true);
|
||||
}
|
||||
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$ea_optional = ($id <= 0 ? false : true);
|
||||
$emailaddr = $this->getParam('emailaddr', $ea_optional, '');
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'id' => $id,
|
||||
'emailaddr' => $emailaddr
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// parameters
|
||||
$disablegreylist = $this->getBoolParam('disablegreylist', true, $result['disablegreylist']);
|
||||
// get needed customer info to reduce the email-address-counter by one
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
// check for catchall-flag
|
||||
if ($disablegreylist) {
|
||||
$disablegreylist = '1';
|
||||
$email_parts = explode('@', $result['email_full']);
|
||||
$email = '@' . $email_parts[1];
|
||||
// catchall check
|
||||
$stmt = Database::prepare("
|
||||
SELECT `email_full` FROM `" . TABLE_MAIL_VIRTUAL . "`
|
||||
WHERE `email` = :email AND `customerid` = :cid AND `disablegreylist` = '1'
|
||||
");
|
||||
$params = array(
|
||||
"email" => $email,
|
||||
"cid" => $customer['customerid']
|
||||
);
|
||||
$email_check = Database::pexecute_first($stmt, $params, true, true);
|
||||
if ($email_check) {
|
||||
\Froxlor\UI\Response::standard_error('youhavealreadyacatchallforthisdomain', '', true);
|
||||
}
|
||||
} else {
|
||||
$disablegreylist = '0';
|
||||
$email = $result['email_full'];
|
||||
}
|
||||
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_MAIL_VIRTUAL . "`
|
||||
SET `email` = :email , `disablegreylist` = :disablegreylist
|
||||
WHERE `customerid`= :cid AND `id`= :id
|
||||
");
|
||||
$params = array(
|
||||
"email" => $email,
|
||||
"disablegreylist" => $disablegreylist,
|
||||
"cid" => $customer['customerid'],
|
||||
"id" => $id
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] toggled greylist-flag for email address '" . $result['email_full'] . "'");
|
||||
|
||||
$result = $this->apiCall('Emails.get', array(
|
||||
'emailaddr' => $result['email_full']
|
||||
));
|
||||
return $this->response(200, "successfull", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* list all email addresses, if called from an admin, list all email addresses of all customers you are allowed to view, or specify id or loginname for one specific customer
|
||||
*
|
||||
@@ -300,7 +405,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$result = array();
|
||||
$query_fields = array();
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT m.`id`, m.`domainid`, m.`email`, m.`email_full`, m.`iscatchall`, u.`quota`, m.`destination`, m.`popaccountid`, d.`domain`, u.`mboxsize`
|
||||
SELECT m.`id`, m.`domainid`, m.`email`, m.`email_full`, m.`iscatchall`, m.`destination`, m.`popaccountid`, d.`domain`, u.`quota`, u.`imap`, u.`pop3`, u.`postfix`, u.`mboxsize`
|
||||
FROM `" . TABLE_MAIL_VIRTUAL . "` m
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`)
|
||||
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`)
|
||||
@@ -317,7 +422,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable email addresses
|
||||
* returns the total number of accessible email addresses
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select email addresses of a specific customer by id
|
||||
|
||||
@@ -79,7 +79,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable fpm daemons
|
||||
* returns the total number of accessible fpm daemons
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -178,9 +178,9 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
$custom_config = $this->getParam('custom_config', true, '');
|
||||
|
||||
// validation
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$reload_cmd = \Froxlor\Validate\Validate::validate($reload_cmd, 'reload_cmd', '', '', array(), true);
|
||||
$config_dir = \Froxlor\Validate\Validate::validate($config_dir, 'config_dir', '', '', array(), true);
|
||||
$config_dir = \Froxlor\Validate\Validate::validate($config_dir, 'config_dir', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
if (! in_array($pmanager, array(
|
||||
'static',
|
||||
'dynamic',
|
||||
@@ -229,7 +229,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
$id = Database::lastInsertId();
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] fpm-daemon with description '" . $description . "' has been created by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $id
|
||||
@@ -299,9 +299,9 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
$custom_config = $this->getParam('custom_config', true, $result['custom_config']);
|
||||
|
||||
// validation
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$reload_cmd = \Froxlor\Validate\Validate::validate($reload_cmd, 'reload_cmd', '', '', array(), true);
|
||||
$config_dir = \Froxlor\Validate\Validate::validate($config_dir, 'config_dir', '', '', array(), true);
|
||||
$config_dir = \Froxlor\Validate\Validate::validate($config_dir, 'config_dir', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
if (! in_array($pmanager, array(
|
||||
'static',
|
||||
'dynamic',
|
||||
@@ -351,7 +351,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data, true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] fpm-daemon with description '" . $description . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $id
|
||||
@@ -400,7 +400,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] fpm-daemon setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
|
||||
@@ -123,12 +123,12 @@ class Froxlor extends \Froxlor\Api\ApiCommand
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " imported settings");
|
||||
try {
|
||||
\Froxlor\SImExporter::import($json_str);
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// cron.d file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
return $this->response(200, "successful", true);
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception($e->getMessage(), 406);
|
||||
|
||||
@@ -62,7 +62,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
|
||||
if (($this->getUserDetail('ftps_used') < $this->getUserDetail('ftps') || $this->getUserDetail('ftps') == '-1') || $this->isAdmin() && $is_defaultuser == 1) {
|
||||
|
||||
// required paramters
|
||||
// required parameters
|
||||
$path = $this->getParam('path');
|
||||
$password = $this->getParam('ftp_password');
|
||||
|
||||
@@ -79,7 +79,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$password = \Froxlor\System\Crypt::validatePassword($password, true);
|
||||
$description = \Froxlor\Validate\Validate::validate(trim($description), 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(trim($description), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
|
||||
if (Settings::Get('system.allow_customer_shell') == '1') {
|
||||
$shell = \Froxlor\Validate\Validate::validate(trim($shell), 'shell', '', '', array(), true);
|
||||
@@ -234,7 +234,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
}
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ftp-account '" . $username . " (" . $path . ")'");
|
||||
\Froxlor\System\Cronjob::inserttask(5);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_FTP);
|
||||
|
||||
if ($sendinfomail == 1) {
|
||||
$replace_arr = array(
|
||||
@@ -243,9 +243,10 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
'NAME' => $customer['name'],
|
||||
'FIRSTNAME' => $customer['firstname'],
|
||||
'COMPANY' => $customer['company'],
|
||||
'USERNAME' => $customer['loginname'],
|
||||
'CUSTOMER_NO' => $customer['customernumber'],
|
||||
'USR_NAME' => $username,
|
||||
'USR_PASS' => $password,
|
||||
'USR_PASS' => htmlentities(htmlentities($password)),
|
||||
'USR_PATH' => \Froxlor\FileDir::makeCorrectDir(str_replace($customer['documentroot'], "/", $path))
|
||||
);
|
||||
// get template for mail subject
|
||||
@@ -396,7 +397,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(trim($description), 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(trim($description), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
|
||||
if (Settings::Get('system.allow_customer_shell') == '1') {
|
||||
$shell = \Froxlor\Validate\Validate::validate(trim($shell), 'shell', '', '', array(), true);
|
||||
@@ -450,7 +451,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
}
|
||||
// it's the task for "new ftp" but that will
|
||||
// create all directories and correct their permissions
|
||||
\Froxlor\System\Cronjob::inserttask(5);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_FTP);
|
||||
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_USERS . "`
|
||||
@@ -512,7 +513,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable ftp accounts
|
||||
* returns the total number of accessible ftp accounts
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select ftp-users of a specific customer by id
|
||||
@@ -628,11 +629,11 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
|
||||
// refs #293
|
||||
if ($delete_userfiles == 1) {
|
||||
\Froxlor\System\Cronjob::inserttask('8', $customer_data['loginname'], $result['homedir']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_FTP_DATA, $customer_data['loginname'], $result['homedir']);
|
||||
} else {
|
||||
if (Settings::Get('system.nssextrausers') == 1) {
|
||||
// this is used so that the libnss-extrausers cron is fired
|
||||
\Froxlor\System\Cronjob::inserttask(5);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_FTP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable hosting plans
|
||||
* returns the total number of accessible hosting plans
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -182,9 +182,9 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
* @param bool $perlenabled
|
||||
* optional, whether to allow usage of Perl/CGI, default 0 (false)
|
||||
* @param bool $dnsenabled
|
||||
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* optional, whether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* @param bool $logviewenabled
|
||||
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
|
||||
* optional, whether to allow access to webserver access/error-logs, default 0 (false)
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -216,7 +216,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
|
||||
// validation
|
||||
$name = \Froxlor\Validate\Validate::validate(trim($name), 'name', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', '/^[^\0]*$/');
|
||||
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT);
|
||||
|
||||
if (Settings::Get('system.mail_quota_enabled') != '1') {
|
||||
$value_arr['email_quota'] = - 1;
|
||||
@@ -309,9 +309,9 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
* @param bool $perlenabled
|
||||
* optional, whether to allow usage of Perl/CGI, default 0 (false)
|
||||
* @param bool $dnsenabled
|
||||
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* optional, either to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* @param bool $logviewenabled
|
||||
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
|
||||
* optional, either to allow access to webserver access/error-logs, default 0 (false)
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -361,7 +361,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
|
||||
// validation
|
||||
$name = \Froxlor\Validate\Validate::validate(trim($name), 'name', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', '/^[^\0]*$/');
|
||||
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT);
|
||||
|
||||
if (Settings::Get('system.mail_quota_enabled') != '1') {
|
||||
$value_arr['email_quota'] = - 1;
|
||||
|
||||
@@ -65,7 +65,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable ip/port entries
|
||||
* returns the total number of accessible ip/port entries
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -247,6 +247,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$docroot = '';
|
||||
}
|
||||
|
||||
// always use compressed ipv6 format
|
||||
$ip = inet_ntop(inet_pton($ip));
|
||||
|
||||
$result_checkfordouble_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
WHERE `ip` = :ip AND `port` = :port");
|
||||
@@ -295,9 +298,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
$ins_data['id'] = Database::lastInsertId();
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
$ip = '[' . $ip . ']';
|
||||
@@ -375,9 +378,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$listen_statement = $this->getBoolParam('listen_statement', true, $result['listen_statement']);
|
||||
$namevirtualhost_statement = $this->getBoolParam('namevirtualhost_statement', true, $result['namevirtualhost_statement']);
|
||||
$vhostcontainer = $this->getBoolParam('vhostcontainer', true, $result['vhostcontainer']);
|
||||
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, $result['specialsettings'])), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, ($result['specialsettings'] ?? ""))), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$vhostcontainer_servername_statement = $this->getParam('vhostcontainer_servername_statement', true, $result['vhostcontainer_servername_statement']);
|
||||
$default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, $result['default_vhostconf_domain'])), 'default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, ($result['default_vhostconf_domain'] ?? ""))), 'default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$docroot = \Froxlor\Validate\Validate::validate($this->getParam('docroot', true, $result['docroot']), 'docroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
if ((int) Settings::Get('system.use_ssl') == 1) {
|
||||
@@ -386,9 +389,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', array(), true);
|
||||
$ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, $result['ssl_ca_file']), 'ssl_ca_file', '', '', array(), true);
|
||||
$ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, $result['ssl_cert_chainfile']), 'ssl_cert_chainfile', '', '', array(), true);
|
||||
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings'])), 'ssl_specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, ($result['ssl_specialsettings'] ?? ""))), 'ssl_specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$include_specialsettings = $this->getBoolParam('include_specialsettings', true, $result['include_specialsettings']);
|
||||
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, $result['ssl_default_vhostconf_domain'])), 'ssl_default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, ($result['ssl_default_vhostconf_domain'] ?? ""))), 'ssl_default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$include_default_vhostconf_domain = $this->getBoolParam('include_default_vhostconf_domain', true, $result['include_default_vhostconf_domain']);
|
||||
} else {
|
||||
$ssl = 0;
|
||||
@@ -462,6 +465,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$docroot = '';
|
||||
}
|
||||
|
||||
// always use compressed ipv6 format
|
||||
$ip = inet_ntop(inet_pton($ip));
|
||||
|
||||
if ($result['ip'] != $ip && $result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport == false) {
|
||||
\Froxlor\UI\Response::standard_error('cantchangesystemip', '', true);
|
||||
} elseif ($result_checkfordouble && $result_checkfordouble['id'] != '' && $result_checkfordouble['id'] != $id) {
|
||||
@@ -505,9 +511,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] changed IP/port from '" . $result['ip'] . ":" . $result['port'] . "' to '" . $ip . ":" . $port . "'");
|
||||
|
||||
@@ -578,9 +584,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted IP/port '" . $result['ip'] . ":" . $result['port'] . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Api\Commands;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
@@ -17,7 +18,7 @@ use Froxlor\Settings;
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package API
|
||||
* @since 0.10.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntity
|
||||
{
|
||||
@@ -31,63 +32,75 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, default is 0
|
||||
* @param string $description
|
||||
* optional, description for database
|
||||
* @param string $custom_suffix
|
||||
* optional, name for database
|
||||
* @param bool $sendinfomail
|
||||
* optional, send created resource-information to customer, default: false
|
||||
* @param int $customerid
|
||||
* optional, required when called as admin (if $loginname is not specified)
|
||||
* @param string $loginname
|
||||
* optional, required when called as admin (if $customerid is not specified)
|
||||
*
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// required paramters
|
||||
$password = $this->getParam('mysql_password');
|
||||
if (($this->getUserDetail('mysqls_used') < $this->getUserDetail('mysqls') || $this->getUserDetail('mysqls') == '-1') || $this->isAdmin()) {
|
||||
// required parameters
|
||||
$password = $this->getParam('mysql_password');
|
||||
|
||||
// parameters
|
||||
$dbserver = $this->getParam('mysql_server', true, 0);
|
||||
$databasedescription = $this->getParam('description', true, '');
|
||||
$sendinfomail = $this->getBoolParam('sendinfomail', true, 0);
|
||||
// get needed customer info to reduce the mysql-usage-counter by one
|
||||
$customer = $this->getCustomerData('mysqls');
|
||||
// parameters
|
||||
$dbserver = $this->getParam('mysql_server', true, 0);
|
||||
$databasedescription = $this->getParam('description', true, '');
|
||||
$databasename = $this->getParam('custom_suffix', true, '');
|
||||
$sendinfomail = $this->getBoolParam('sendinfomail', true, 0);
|
||||
// get needed customer info to reduce the mysql-usage-counter by one
|
||||
$customer = $this->getCustomerData('mysqls');
|
||||
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$password = \Froxlor\System\Crypt::validatePassword($password, true);
|
||||
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', '', '', array(), true);
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$password = \Froxlor\System\Crypt::validatePassword($password, true);
|
||||
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
if (!empty($databasename)) {
|
||||
$databasename = \Froxlor\Validate\Validate::validate(trim($databasename), 'database_name', '/^[A-Za-z0-9][A-Za-z0-9\-_]+$/i', '', array(), true);
|
||||
}
|
||||
|
||||
// validate whether the dbserver exists
|
||||
$dbserver = \Froxlor\Validate\Validate::validate($dbserver, html_entity_decode($this->lng['mysql']['mysql_server']), '', '', 0, true);
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
if (! isset($sql_root) || ! is_array($sql_root)) {
|
||||
throw new \Exception("Database server with index #" . $dbserver . " is unknown", 404);
|
||||
}
|
||||
// validate whether the dbserver exists
|
||||
$dbserver = \Froxlor\Validate\Validate::validate($dbserver, html_entity_decode($this->lng['mysql']['mysql_server']), '', '', 0, true);
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
if (!isset($sql_root) || !is_array($sql_root)) {
|
||||
throw new \Exception("Database server with index #" . $dbserver . " is unknown", 404);
|
||||
}
|
||||
|
||||
if ($sendinfomail != 1) {
|
||||
$sendinfomail = 0;
|
||||
}
|
||||
if ($sendinfomail != 1) {
|
||||
$sendinfomail = 0;
|
||||
}
|
||||
|
||||
$newdb_params = array(
|
||||
'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')),
|
||||
'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber'))
|
||||
);
|
||||
// create database, user, set permissions, etc.pp.
|
||||
$dbm = new \Froxlor\Database\DbManager($this->logger());
|
||||
$username = $dbm->createDatabase($newdb_params['loginname'], $password, $newdb_params['mysql_lastaccountnumber']);
|
||||
$newdb_params = array(
|
||||
'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')),
|
||||
'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber'))
|
||||
);
|
||||
// create database, user, set permissions, etc.pp.
|
||||
$dbm = new \Froxlor\Database\DbManager($this->logger());
|
||||
|
||||
// we've checked against the password in dbm->createDatabase
|
||||
if ($username == false) {
|
||||
\Froxlor\UI\Response::standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
if (strtoupper(Settings::Get('customer.mysqlprefix')) == 'DBNAME' && !empty($databasename)) {
|
||||
$username = $dbm->createDatabase($newdb_params['loginname'] . '_' . $databasename, $password);
|
||||
} else {
|
||||
$username = $dbm->createDatabase($newdb_params['loginname'], $password, $newdb_params['mysql_lastaccountnumber']);
|
||||
}
|
||||
|
||||
// add database info to froxlor
|
||||
$stmt = Database::prepare("
|
||||
// we've checked against the password in dbm->createDatabase
|
||||
if ($username == false) {
|
||||
\Froxlor\UI\Response::standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
|
||||
// add database info to froxlor
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DATABASES . "`
|
||||
SET
|
||||
`customerid` = :customerid,
|
||||
@@ -95,81 +108,84 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
`description` = :description,
|
||||
`dbserver` = :dbserver
|
||||
");
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"databasename" => $username,
|
||||
"description" => $databasedescription,
|
||||
"dbserver" => $dbserver
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$databaseid = Database::lastInsertId();
|
||||
$params['id'] = $databaseid;
|
||||
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'mysqls_used');
|
||||
Customers::increaseUsage($customer['customerid'], 'mysql_lastaccountnumber');
|
||||
|
||||
// send info-mail?
|
||||
if ($sendinfomail == 1) {
|
||||
$pma = $this->lng['admin']['notgiven'];
|
||||
if (Settings::Get('panel.phpmyadmin_url') != '') {
|
||||
$pma = Settings::Get('panel.phpmyadmin_url');
|
||||
}
|
||||
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
$userinfo = $customer;
|
||||
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($userinfo),
|
||||
'CUST_NAME' => \Froxlor\User::getCorrectUserSalutation($userinfo), // < keep this for compatibility
|
||||
'NAME' => $userinfo['name'],
|
||||
'FIRSTNAME' => $userinfo['firstname'],
|
||||
'COMPANY' => $userinfo['company'],
|
||||
'CUSTOMER_NO' => $userinfo['customernumber'],
|
||||
'DB_NAME' => $username,
|
||||
'DB_PASS' => $password,
|
||||
'DB_DESC' => $databasedescription,
|
||||
'DB_SRV' => $sql_root['host'],
|
||||
'PMA_URI' => $pma
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"databasename" => $username,
|
||||
"description" => $databasedescription,
|
||||
"dbserver" => $dbserver
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$databaseid = Database::lastInsertId();
|
||||
$params['id'] = $databaseid;
|
||||
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_subject', $replace_arr, $this->lng['mails']['new_database_by_customer']['subject']);
|
||||
// get template for mail body
|
||||
$mail_body = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_mailbody', $replace_arr, $this->lng['mails']['new_database_by_customer']['mailbody']);
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'mysqls_used');
|
||||
Customers::increaseUsage($customer['customerid'], 'mysql_lastaccountnumber');
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$this->mailer()->Subject = $mail_subject;
|
||||
$this->mailer()->AltBody = $mail_body;
|
||||
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$this->mailer()->addAddress($userinfo['email'], \Froxlor\User::getCorrectUserSalutation($userinfo));
|
||||
$this->mailer()->send();
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
// send info-mail?
|
||||
if ($sendinfomail == 1) {
|
||||
$pma = $this->lng['admin']['notgiven'];
|
||||
if (Settings::Get('panel.phpmyadmin_url') != '') {
|
||||
$pma = Settings::Get('panel.phpmyadmin_url');
|
||||
}
|
||||
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
$userinfo = $customer;
|
||||
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($userinfo),
|
||||
'CUST_NAME' => \Froxlor\User::getCorrectUserSalutation($userinfo), // < keep this for compatibility
|
||||
'NAME' => $userinfo['name'],
|
||||
'FIRSTNAME' => $userinfo['firstname'],
|
||||
'COMPANY' => $userinfo['company'],
|
||||
'USERNAME' => $userinfo['loginname'],
|
||||
'CUSTOMER_NO' => $userinfo['customernumber'],
|
||||
'DB_NAME' => $username,
|
||||
'DB_PASS' => htmlentities(htmlentities($password)),
|
||||
'DB_DESC' => $databasedescription,
|
||||
'DB_SRV' => $sql_root['host'],
|
||||
'PMA_URI' => $pma
|
||||
);
|
||||
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_subject', $replace_arr, $this->lng['mails']['new_database_by_customer']['subject']);
|
||||
// get template for mail body
|
||||
$mail_body = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_mailbody', $replace_arr, $this->lng['mails']['new_database_by_customer']['mailbody']);
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$this->mailer()->Subject = $mail_subject;
|
||||
$this->mailer()->AltBody = $mail_body;
|
||||
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$this->mailer()->addAddress($userinfo['email'], \Froxlor\User::getCorrectUserSalutation($userinfo));
|
||||
$this->mailer()->send();
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg);
|
||||
\Froxlor\UI\Response::standard_error('errorsendingmail', $userinfo['email'], true);
|
||||
}
|
||||
|
||||
$this->mailer()->clearAddresses();
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] added mysql-database '" . $username . "'");
|
||||
|
||||
if ($_mailerror) {
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg);
|
||||
\Froxlor\UI\Response::standard_error('errorsendingmail', $userinfo['email'], true);
|
||||
}
|
||||
|
||||
$this->mailer()->clearAddresses();
|
||||
$result = $this->apiCall('Mysqls.get', array(
|
||||
'dbname' => $username
|
||||
));
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] added mysql-database '" . $username . "'");
|
||||
|
||||
$result = $this->apiCall('Mysqls.get', array(
|
||||
'dbname' => $username
|
||||
));
|
||||
return $this->response(200, "successful", $result);
|
||||
throw new \Exception("No more resources available", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +197,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, the databasename
|
||||
* @param int $mysql_server
|
||||
* optional, specify database-server, default is none
|
||||
*
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array
|
||||
@@ -191,7 +207,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$dbserver = $this->getParam('mysql_server', true, -1);
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
if ($this->getUserDetail('customers_see_all') != 1) {
|
||||
@@ -281,7 +297,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, required when called as admin (if $loginname is not specified)
|
||||
* @param string $loginname
|
||||
* optional, required when called as admin (if $customerid is not specified)
|
||||
*
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array
|
||||
@@ -291,7 +307,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$dbserver = $this->getParam('mysql_server', true, -1);
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
|
||||
@@ -305,13 +321,13 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// paramters
|
||||
// parameters
|
||||
$password = $this->getParam('mysql_password', true, '');
|
||||
$databasedescription = $this->getParam('description', true, $result['description']);
|
||||
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', '', '', array(), true);
|
||||
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
|
||||
if ($password != '') {
|
||||
// validate password
|
||||
@@ -370,7 +386,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional specify offset for resultset
|
||||
* @param array $sql_orderby
|
||||
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
|
||||
*
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array count|list
|
||||
@@ -378,7 +394,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
public function listing()
|
||||
{
|
||||
$result = array();
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$dbserver = $this->getParam('mysql_server', true, -1);
|
||||
$customer_ids = $this->getAllowedCustomerIds('mysql');
|
||||
$query_fields = array();
|
||||
$result_stmt = Database::prepare("
|
||||
@@ -428,13 +444,13 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable databases
|
||||
* returns the total number of accessible databases
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select dbs of a specific customer by id
|
||||
* @param string $loginname
|
||||
* optional, admin-only, select dbs of a specific customer by loginname
|
||||
*
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array
|
||||
@@ -465,7 +481,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, required when called as admin (if $loginname is not specified)
|
||||
* @param string $loginname
|
||||
* optional, required when called as admin (if $customerid is not specified)
|
||||
*
|
||||
*
|
||||
* @access admin, customer
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array
|
||||
@@ -475,7 +491,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$dbserver = $this->getParam('mysql_server', true, -1);
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
|
||||
|
||||
@@ -59,7 +59,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
);
|
||||
|
||||
$query = "SELECT * FROM `" . TABLE_PANEL_DOMAINS . "`
|
||||
WHERE `phpsettingid` = :id";
|
||||
WHERE `phpsettingid` = :id AND `email_only` = '0' AND `phpenabled` = '1'";
|
||||
|
||||
if (! $with_subdomains) {
|
||||
$query .= " AND `parentdomainid` = '0'";
|
||||
@@ -99,7 +99,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
}
|
||||
|
||||
// check whether we use that config as froxor-vhost config
|
||||
if (Settings::Get('system.mod_fcgid_defaultini_ownvhost') == $row['id'] || Settings::Get('phpfpm.vhost_defaultini') == $row['id']) {
|
||||
if ((Settings::Get('system.mod_fcgid') == '1' && Settings::Get('system.mod_fcgid_defaultini_ownvhost') == $row['id']) || (Settings::Get('phpfpm.enabled') == '1' && Settings::Get('phpfpm.vhost_defaultini') == $row['id'])) {
|
||||
$domains[] = Settings::Get('system.hostname');
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable php-setting entries
|
||||
* returns the total number of accessible php-setting entries
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -217,7 +217,9 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
* optional number of seconds for idle-timeout if FPM is used, default is fpm-daemon-value
|
||||
* @param string $limit_extensions
|
||||
* optional limitation of php-file-extensions if FPM is used, default is fpm-daemon-value
|
||||
*
|
||||
* @param bool $allow_all_customers
|
||||
* optional add this configuration to the list of every existing customer's allowed-fpm-config list, default is false (no)
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
* @return string json-encoded array
|
||||
@@ -261,9 +263,10 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$max_requests = $this->getParam('max_requests', true, $def_fpmconfig['max_requests']);
|
||||
$idle_timeout = $this->getParam('idle_timeout', true, $def_fpmconfig['idle_timeout']);
|
||||
$limit_extensions = $this->getParam('limit_extensions', true, $def_fpmconfig['limit_extensions']);
|
||||
$allow_all_customers = $this->getBoolParam('allow_all_customers', true, 0);
|
||||
|
||||
// validation
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$phpsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $phpsettings), 'phpsettings', '/^[^\0]*$/', '', array(), true);
|
||||
if (Settings::Get('system.mod_fcgid') == 1) {
|
||||
$binary = \Froxlor\FileDir::makeCorrectFile(\Froxlor\Validate\Validate::validate($binary, 'binary', '', '', array(), true));
|
||||
@@ -361,12 +364,14 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||
$ins_data['id'] = Database::lastInsertId();
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] php setting with description '" . $description . "' has been created by '" . $this->getUserDetail('loginname') . "'");
|
||||
|
||||
$result = $this->apiCall('PhpSettings.get', array(
|
||||
'id' => $ins_data['id']
|
||||
));
|
||||
|
||||
$this->addForAllCustomers($allow_all_customers, $ins_data['id']);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
throw new \Exception("Not allowed to execute given command.", 403);
|
||||
@@ -418,6 +423,8 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
* optional number of seconds for idle-timeout if FPM is used, default is fpm-daemon-value
|
||||
* @param string $limit_extensions
|
||||
* optional limitation of php-file-extensions if FPM is used, default is fpm-daemon-value
|
||||
* @param bool $allow_all_customers
|
||||
* optional add this configuration to the list of every existing customer's allowed-fpm-config list, default is false (no)
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -456,9 +463,10 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$max_requests = $this->getParam('max_requests', true, $result['max_requests']);
|
||||
$idle_timeout = $this->getParam('idle_timeout', true, $result['idle_timeout']);
|
||||
$limit_extensions = $this->getParam('limit_extensions', true, $result['limit_extensions']);
|
||||
$allow_all_customers = $this->getBoolParam('allow_all_customers', true, 0);
|
||||
|
||||
// validation
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$phpsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $phpsettings), 'phpsettings', '/^[^\0]*$/', '', array(), true);
|
||||
if (Settings::Get('system.mod_fcgid') == 1) {
|
||||
$binary = \Froxlor\FileDir::makeCorrectFile(\Froxlor\Validate\Validate::validate($binary, 'binary', '', '', array(), true));
|
||||
@@ -557,12 +565,14 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data, true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] php setting with description '" . $description . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
|
||||
$result = $this->apiCall('PhpSettings.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
$this->addForAllCustomers($allow_all_customers, $id);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
throw new \Exception("Not allowed to execute given command.", 403);
|
||||
@@ -612,10 +622,44 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] php setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
throw new \Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* add given php-config id to the list of allowed php-config to all currently existing customers
|
||||
* if allow_all_customers parameter is true in PhpSettings::add() or PhpSettings::update()
|
||||
*
|
||||
* @param bool $allow_all_customers
|
||||
* @param int $config_id
|
||||
*/
|
||||
private function addForAllCustomers(bool $allow_all_customers, int $config_id)
|
||||
{
|
||||
// should this config be added to the allowed list of all existing customers?
|
||||
if ($allow_all_customers) {
|
||||
$sel_stmt = Database::prepare("SELECT customerid, allowed_phpconfigs FROM `" . TABLE_PANEL_CUSTOMERS . "`");
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET allowed_phpconfigs = :ap WHERE customerid = :cid");
|
||||
Database::pexecute($sel_stmt);
|
||||
while ($cust = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// get existing entries of customer
|
||||
$ap = json_decode($cust['allowed_phpconfigs'], true);
|
||||
// initialize array if it's empty
|
||||
if (empty($ap)) {
|
||||
$ap = [];
|
||||
}
|
||||
// add this config
|
||||
$ap[] = $config_id;
|
||||
// check for duplicates and force value-type to be int
|
||||
$ap = array_map('intval', array_unique($ap));
|
||||
// update customer-entry
|
||||
Database::pexecute($upd_stmt, [
|
||||
'ap' => json_encode($ap),
|
||||
'cid' => $cust['customerid']
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace Froxlor\Api\Commands;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
@@ -230,6 +231,15 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
}
|
||||
|
||||
// validate dns if lets encrypt is enabled to check whether we can use it at all
|
||||
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
|
||||
$our_ips = Domain::getIpsOfDomain($domain_check['id']);
|
||||
$domain_ips = \Froxlor\PhpHelper::gethostbynamel6($completedomain);
|
||||
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
|
||||
\Froxlor\UI\Response::standard_error('invaliddnsforletsencrypt', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
|
||||
if ($ssl_redirect > 0 && $letsencrypt == 1) {
|
||||
$ssl_redirect = 2;
|
||||
@@ -252,6 +262,19 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
$phpsid_result['phpsettingid'] = intval($phpsettingid);
|
||||
}
|
||||
|
||||
$allowed_phpconfigs = $customer['allowed_phpconfigs'];
|
||||
if (! empty($allowed_phpconfigs)) {
|
||||
$allowed_phpconfigs = json_decode($allowed_phpconfigs, true);
|
||||
} else {
|
||||
$allowed_phpconfigs = [];
|
||||
}
|
||||
// only with fcgid/fpm enabled will it be possible to select a php-setting
|
||||
if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (! in_array($phpsid_result['phpsettingid'], $allowed_phpconfigs)) {
|
||||
\Froxlor\UI\Response::standard_error('notallowedphpconfigused', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// actually insert domain
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
@@ -336,9 +359,9 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
\Froxlor\Domain\Domain::addRedirectToDomain($subdomain_id, $redirectcode);
|
||||
}
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
Customers::increaseUsage($customer['customerid'], 'subdomains_used');
|
||||
|
||||
@@ -595,9 +618,18 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
}
|
||||
|
||||
// validate dns if lets encrypt is enabled to check whether we can use it at all
|
||||
if ($result['letsencrypt'] != $letsencrypt && $letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
|
||||
$our_ips = Domain::getIpsOfDomain($result['parentdomainid']);
|
||||
$domain_ips = \Froxlor\PhpHelper::gethostbynamel6($result['domain']);
|
||||
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
|
||||
\Froxlor\UI\Response::standard_error('invaliddnsforletsencrypt', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// We can't enable let's encrypt for wildcard-domains
|
||||
if ($iswildcarddomain == '1' && $letsencrypt == '1') {
|
||||
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt');
|
||||
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
|
||||
}
|
||||
|
||||
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
|
||||
@@ -619,12 +651,25 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] automatically deleted mail-table entries for '" . $idna_convert->decode($result['domain']) . "'");
|
||||
}
|
||||
|
||||
$allowed_phpconfigs = $customer['allowed_phpconfigs'];
|
||||
if (! empty($allowed_phpconfigs)) {
|
||||
$allowed_phpconfigs = json_decode($allowed_phpconfigs, true);
|
||||
} else {
|
||||
$allowed_phpconfigs = [];
|
||||
}
|
||||
// only with fcgid/fpm enabled will it be possible to select a php-setting
|
||||
if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (! in_array($phpsettingid, $allowed_phpconfigs)) {
|
||||
\Froxlor\UI\Response::standard_error('notallowedphpconfigused', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// handle redirect
|
||||
if ($_doredirect) {
|
||||
\Froxlor\Domain\Domain::updateRedirectOfDomain($id, $redirectcode);
|
||||
}
|
||||
|
||||
if ($path != $result['documentroot'] || $isemaildomain != $result['isemaildomain'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $aliasdomain != $result['aliasdomain'] || $openbasedir_path != $result['openbasedir_path'] || $ssl_redirect != $result['ssl_redirect'] || $letsencrypt != $result['letsencrypt'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $phpsettingid != $result['phpsettingid']) {
|
||||
if ($path != $result['documentroot'] || $isemaildomain != $result['isemaildomain'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $aliasdomain != (int)$result['aliasdomain'] || $openbasedir_path != $result['openbasedir_path'] || $ssl_redirect != $result['ssl_redirect'] || $letsencrypt != $result['letsencrypt'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $phpsettingid != $result['phpsettingid']) {
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
`documentroot` = :documentroot,
|
||||
@@ -688,11 +733,11 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
'id' => $id
|
||||
), true, true);
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
|
||||
}
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] edited domain '" . $idna_convert->decode($result['domain']) . "'");
|
||||
}
|
||||
@@ -810,7 +855,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable subdomain entries
|
||||
* returns the total number of accessible subdomain entries
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select (sub)domains of a specific customer by id
|
||||
@@ -974,13 +1019,13 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
'domainid' => $id
|
||||
), true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// remove domains DNS from powerDNS if used, #581
|
||||
\Froxlor\System\Cronjob::inserttask('11', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_PDNS, $result['domain']);
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
|
||||
|
||||
// reduce subdomain-usage-counter
|
||||
Customers::decreaseUsage($customer['customerid'], 'subdomains_used');
|
||||
|
||||
0
lib/Froxlor/Api/Commands/index.html
Normal file
0
lib/Froxlor/Api/Commands/index.html
Normal file
0
lib/Froxlor/Api/index.html
Normal file
0
lib/Froxlor/Api/index.html
Normal file
@@ -133,7 +133,7 @@ abstract class BulkAction
|
||||
|
||||
$new_data = array();
|
||||
foreach ($this->api_params as $idx => $param) {
|
||||
if (isset($data_array[$idx]) && ! empty($data_array[$idx])) {
|
||||
if (isset($data_array[$idx])) {
|
||||
$new_data[$param] = $data_array[$idx];
|
||||
}
|
||||
}
|
||||
@@ -150,7 +150,7 @@ abstract class BulkAction
|
||||
|
||||
/**
|
||||
* reads in the csv import file and returns an array with
|
||||
* all the entites to be imported
|
||||
* all the entities to be imported
|
||||
*
|
||||
* @param string $separator
|
||||
*
|
||||
|
||||
0
lib/Froxlor/Bulk/index.html
Normal file
0
lib/Froxlor/Bulk/index.html
Normal file
@@ -85,8 +85,8 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
$distributions_select_data = array();
|
||||
|
||||
//set default os.
|
||||
$os_dist = array('ID' => 'buster');
|
||||
$os_version = array('0' => '10');
|
||||
$os_dist = array('ID' => 'bullseye');
|
||||
$os_version = array('0' => '11');
|
||||
$os_default = $os_dist['ID'];
|
||||
|
||||
//read os-release
|
||||
@@ -341,13 +341,43 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
|
||||
// try to convert namserver hosts to ip's
|
||||
$ns_ips = "";
|
||||
$known_ns_ips = [];
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
// DNS servers might be multi homed; allow transfer from all ip
|
||||
// addresses of the DNS server
|
||||
$nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
|
||||
if (is_array($nameserver_ips) && count($nameserver_ips) > 0) {
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
// append dot to hostname
|
||||
if (substr($nameserver, - 1, 1) != '.') {
|
||||
$nameserver .= '.';
|
||||
}
|
||||
// ignore invalid responses
|
||||
if (! is_array($nameserver_ips)) {
|
||||
// act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error
|
||||
$nameserver_ips = array(
|
||||
$nameserver
|
||||
);
|
||||
} else {
|
||||
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
|
||||
}
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
}
|
||||
}
|
||||
|
||||
// AXFR server
|
||||
if (Settings::Get('system.axfrservers') != '') {
|
||||
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
|
||||
foreach ($axfrservers as $axfrserver) {
|
||||
if (!in_array(trim($axfrserver), $known_ns_ips)) {
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= trim($axfrserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -365,7 +395,6 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
'<SERVERIP>' => Settings::Get('system.ipaddress'),
|
||||
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
|
||||
'<NAMESERVERS_IP>' => $ns_ips,
|
||||
'<AXFRSERVERS>' => Settings::Get('system.axfrservers'),
|
||||
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
|
||||
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
|
||||
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
|
||||
@@ -402,7 +431,7 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor direcotry cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
99
lib/Froxlor/Cli/Action/PhpSessioncleanAction.php
Normal file
99
lib/Froxlor/Cli/Action/PhpSessioncleanAction.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli\Action;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class PhpSessioncleanAction extends \Froxlor\Cli\Action
|
||||
{
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
parent::__construct($args);
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (isset($this->_args["max-lifetime"]) && is_numeric($this->_args["max-lifetime"]) && $this->_args["max-lifetime"] > 0) {
|
||||
$this->cleanSessionfiles((int)$this->_args["max-lifetime"]);
|
||||
} else {
|
||||
// use default max-lifetime value
|
||||
$this->cleanSessionfiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function validate()
|
||||
{
|
||||
global $lng;
|
||||
|
||||
$this->checkConfigParam(true);
|
||||
$this->parseConfig();
|
||||
|
||||
require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
|
||||
}
|
||||
|
||||
private function cleanSessionfiles(int $maxlifetime = 1440)
|
||||
{
|
||||
// store paths to clean up
|
||||
$paths_to_clean = [];
|
||||
// get all pool-config directories configured
|
||||
$sel_stmt = Database::prepare("SELECT DISTINCT `config_dir` FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($sel_stmt);
|
||||
while ($fpmd = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$poolfiles = glob(\Froxlor\FileDir::makeCorrectFile($fpmd['config_dir'] . '/*.conf'));
|
||||
foreach ($poolfiles as $cf) {
|
||||
$contents = file_get_contents($cf);
|
||||
$pattern = preg_quote('session.save_path', '/');
|
||||
$pattern = "/" . $pattern . ".+?\=(.*)/";
|
||||
if (preg_match_all($pattern, $contents, $matches)) {
|
||||
$paths_to_clean[] = \Froxlor\FileDir::makeCorrectDir(trim($matches[1][0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// every path is just needed once
|
||||
$paths_to_clean = array_unique($paths_to_clean);
|
||||
|
||||
if (count($paths_to_clean) > 0) {
|
||||
foreach ($paths_to_clean as $ptc) {
|
||||
// find all files older then maxlifetime and delete them
|
||||
\Froxlor\FileDir::safe_exec("find -O3 \"" . $ptc . "\" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin \"+" . $maxlifetime . "\" -delete");
|
||||
}
|
||||
}
|
||||
}
|
||||
private function parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (!class_exists('\\Froxlor\\Database\\Database')) {
|
||||
throw new \Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (!file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new \Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
}
|
||||
|
||||
private function checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (!isset($this->_args["froxlor-dir"])) {
|
||||
$this->_args["froxlor-dir"] = \Froxlor\Froxlor::getInstallDir();
|
||||
} elseif (!is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (!file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (!is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user