Compare commits

...

108 Commits

Author SHA1 Message Date
Michael Kaufmann
3fd89c48e8 set version to 0.10.25 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-05 20:27:55 +01:00
Michael Kaufmann
eceb144a77 also trigger removal of domain in powerdns database if used; refs #923
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-04 12:09:03 +01:00
Michael Kaufmann
1d9651b18a trgger acme.sh removal for domains if customers is being deleted; fixes #923
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-04 12:07:20 +01:00
Michael Kaufmann
49db4e60cb escape passwords for email content (new email-account, new ftp-account and new database); fixes #905
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-03 11:25:58 +01:00
Michael Kaufmann
53e8ccbccb added 'deactivated' parameter to EmailAccounts.update() so admins can disable individual email-accounts, will be overridden if customer is deactivatd and re-enabled; fixes #921
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-03 10:59:16 +01:00
Michael Kaufmann
6d8fc215f1 add description field to panel_domains and mail_virtual table, API parameter 'description' for Domains.add()/Domains.update() and Email.add()/Emails.update(); fixes #910
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-03 10:25:42 +01:00
Michael Kaufmann
f94c303cb3 add API parameter 'show_usages' for Customers.listing() and Customers.get() to return number of domains, and diskspaced used split into webspace_used, mailspace_used and dbspace_used; fixes #912
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-03-03 09:50:30 +01:00
Michael Kaufmann
2be1873354 fix frontend issue with displaying correct options in domain listing when using php8, thx to cscholz
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-24 19:56:26 +01:00
Michael Kaufmann
d1d36c32fe Merge pull request #920 from RipClaw2971/patch-1
lowercase domain names for ssl-certificate file check (fallback)
2021-02-24 13:07:26 +01:00
RipClaw2971
3b3527348f Update AcmeSh.php
Renewed certificates are not recognized if the domain is in upper/lower case.
2021-02-24 13:00:31 +01:00
Michael Kaufmann
036d5f0713 Merge pull request #919 from nachtgeist/soa
dns: make mail address of SOA records configurable
2021-02-21 18:27:57 +01:00
Daniel Reichelt
a1b8807b0f dns: make mail address of SOA records configurable 2021-02-21 13:00:30 +01:00
Michael Kaufmann
356a087b6a Merge pull request #918 from nachtgeist/pns
dns: check NS entry to be used as primary NS
2021-02-21 09:14:37 +01:00
Michael Kaufmann
0a77fd7150 Merge pull request #917 from nachtgeist/pw
system: validatePassword(): also quote the delimiter ('/')
2021-02-21 09:13:02 +01:00
Daniel Reichelt
67d67a287f system: validatePassword(): also quote the delimiter ('/')
Quoting the default regex delimiter is required for the password
complexity check to work if '/' had been specified as special character
in Froxlor's account settings.
2021-02-21 02:33:46 +01:00
Daniel Reichelt
1f792466bf dns: check NS entry to be used as primary NS
Don't just blindly use the first custom NS entry for SOA, actually check
if it pertains to the domain in question
2021-02-21 02:33:23 +01:00
Michael Kaufmann
5a6343b47c php8 compatibility, fixes #916
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-16 12:38:01 +01:00
Michael Kaufmann
841c529107 fix check for required firstname/name/company in Customers.update(), fixes #915
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-15 23:26:18 +01:00
Michael Kaufmann
41c3f21f0b list only phpenabled and http-enabled domains in php-configuration overview; fixes #911
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-11 16:16:04 +01:00
Michael Kaufmann
b8c0688ba0 added possibility to use 'in' sql-operation in sql_where parameter for Api-calls; php-8 compat fix in admin_traffic
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-11 12:09:42 +01:00
Michael Kaufmann
24e02e99fb set version to 0.10.24 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-05 15:46:08 +01:00
Michael Kaufmann
97bb7b6227 add filecontent to allowed form-fields to not be escaped
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-05 15:44:49 +01:00
Michael Kaufmann
5ceddc8c65 remove not (yet) used cli script
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-02-05 15:42:38 +01:00
Michael Kaufmann
3a17d03796 add option to specify (optional) fileextension/suffix for generated dkim-private keys; fixes #907
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-20 12:12:41 +01:00
Michael Kaufmann
57ae195930 for percentage calculation always use bytes so we don't compare KiB with GiB or similar
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-18 21:22:29 +01:00
Michael Kaufmann
9b86d576fa do not display usages on dashboard in fixed size-units but dynamically adjusted
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-18 20:49:55 +01:00
Michael Kaufmann
02a12eda13 add missing field 'include_default_vhostconf' to settings table for new installations
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-16 10:50:49 +01:00
Michael Kaufmann
a31da97d66 exclude some formfields from xss-cleaning as it could alter the wanted content
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-13 10:14:51 +01:00
Michael Kaufmann
9f13aa9a12 only pass binding variable for prepared sql statement if variable exists
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-13 08:52:00 +01:00
Michael Kaufmann
2841051649 correctly read in domain's ssl-ips for CAA entries if enabled, fixes #903
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-12 21:08:10 +01:00
Michael Kaufmann
acfbf55d15 Check return of validateFormField() just for non-falsey values and not expect boolean data-type; fixes #904
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-12 19:17:38 +01:00
Michael Kaufmann
5848df28fd Merge pull request #902 from bashgeek/master
Put in trailing slash to /awstats/ location in nginx config
2021-01-12 12:25:22 +01:00
Michael Kaufmann
21925f48c3 set minimum required php-version to 7.1 and recommended php-version to 7.4
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2021-01-06 13:36:35 +01:00
Daniel
17a64c58c2 Put in a trailing "/" for /awstats/ location 2020-12-31 16:01:42 +08:00
Daniel
0ca38cff31 Merge pull request #1 from Froxlor/master
up
2020-12-31 15:59:07 +08:00
Michael Kaufmann
5efc1849b4 fix hide-incompatible-settings feature
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-30 17:16:15 +01:00
Michael Kaufmann
f213d666e2 fix typo
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-30 16:46:01 +01:00
Michael Kaufmann
78495b6487 update link to perl-fastcgi wiki on nginx.com; added setting to hide incompatible settings (depending on webserver)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-30 16:41:26 +01:00
Michael Kaufmann
ab1c76e104 set version to 0.10.23.1 for bugfix release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-28 19:48:31 +01:00
Michael Kaufmann
a671223823 corrected too few arguments to function Froxlor\Cron\Traffic\TrafficCron::callAwstatsGetTraffic(); fixes #901
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-28 19:43:40 +01:00
Michael Kaufmann
3a99e10296 set version to 0.10.23 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-28 11:09:56 +01:00
Michael Kaufmann
38031aaff9 add missing return-code in DomainZones.add which messes up the error handling when using API
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-23 13:42:36 +01:00
Michael Kaufmann
65773bce57 automatically set php-fpm default config to php-version that is used for the installation to avoid confusion
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-21 17:15:02 +01:00
Michael Kaufmann
ee5de56a94 also validate existence of ssl-key file in vhost generation
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-10 09:47:58 +01:00
Michael Kaufmann
aba97df9b2 added date-range parameters for Traffic.listing(), fixes #878
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-10 09:44:43 +01:00
Michael Kaufmann
79e670f797 trigger rebuild of cronjobs also if customer email is changed, fixes #896
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-12-10 09:41:35 +01:00
Michael Kaufmann
8670cb6742 Merge pull request #900 from heptalium/master
Protect only private keys and leave certificates world readable.
2020-12-10 09:29:51 +01:00
Michael Kaufmann
bde87950a5 fix optional parameters of phpErrHandler
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-27 14:07:01 +01:00
Jens Meißner
aa1d2ab01d Set certificate files explicitly world readable. 2020-11-24 17:38:49 +01:00
Jens Meißner
2a770a93b1 Protect only private keys and leave certificates world readable. 2020-11-23 20:32:24 +01:00
Michael Kaufmann
5b85a1c183 use Validate::validateEmail() also for PHPMailer::ValidateAddress() call
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-17 17:31:49 +01:00
Michael Kaufmann
caf8893558 use Validate::validateEmail() instead of pure filter_var
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-17 17:18:23 +01:00
Michael Kaufmann
a280461cf6 add unicode flag for filter-validate-email (>=php7.1)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-17 10:39:11 +01:00
Michael Kaufmann
455c655580 corrected validation of idn-tld's, fixes #899
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-14 11:59:46 +01:00
Michael Kaufmann
ecd707424f change example of dhparams.pem folder so it does not conflict with default ssl-certificates-folder which gets purged by froxlor regulary
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-13 13:01:19 +01:00
Michael Kaufmann
60fe330de1 Merge pull request #875 from negrusti/patch-2
Data integrity - remove default values from some columns
2020-11-12 09:01:03 +01:00
Michael Kaufmann
cdb871b82b fix delete_userfiles flag not being passed via webinterface email-address-overview
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-12 08:54:52 +01:00
Michael Kaufmann
35c4e3d1b9 set version to 0.10.22 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-06 14:47:20 +01:00
Michael Kaufmann
b3f82f0981 remove duplicate AXFR records as nameserver get added automatically in case they have also been added to the axfr list
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-11-01 21:00:27 +01:00
Michael Kaufmann
b1b68364be do not allow setting www as CNAME record if domain has automatic www-Alias enabled, fixes #895
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-31 16:16:05 +01:00
Michael Kaufmann
ea76ce8fcc secure requests; refs #893
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-31 15:57:59 +01:00
Michael Kaufmann
16eca628dd add Unittest for traffic-filtering by customer-name, refs #894
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-31 15:53:07 +01:00
Michael Kaufmann
6bf5eccc24 update dependencies and add voku\AntiXSS
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-31 15:50:16 +01:00
Michael Kaufmann
63d00cd453 forgot to add the language strings to the commit for avoid deletion of (super)admin
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-31 15:48:01 +01:00
Michael Kaufmann
c79cba26f3 avoid deletion of (super)admin with id 1 due to fallbacks in the code using it; fixes #886
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-31 10:02:11 +01:00
Michael Kaufmann
36eb3cc1aa [domainbulk] remove reqiurement for customer-select in webinterface as it is an API-parameter
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-31 09:45:50 +01:00
Michael Kaufmann
15a13a7783 append file-extension for dkim-private-keys as external tools may require it (rspamd e.g.); thx to rseffner for finding this
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-20 15:28:51 +02:00
Michael Kaufmann
816874872d make given documentroot of domain relative to customerroot of no absolute path if given; fixes #892
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-14 16:58:19 +02:00
Michael Kaufmann
0e8449f28d Merge pull request #891 from andlinger/patch-1
Fixed typo in contribution document
2020-10-14 14:26:48 +02:00
Michael Kaufmann
3dcbbb9e7b do not set description to empty value if not passed as parameter as it is optionally; fixes #890
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-14 14:25:23 +02:00
David Andlinger
5ab9e6865d fixed typo 2020-10-14 14:17:37 +02:00
Michael Kaufmann
3a47b2050e fix awstats/webalizer directory protection when using nginx; fixes #888
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-13 20:18:44 +02:00
Michael Kaufmann
907c475361 create quotatallies entry if it not exists, fixes #885; correction in api-doc for Ftps.update ftp_password parameter, fixes #889
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-13 19:52:29 +02:00
Michael Kaufmann
0dfb4bdcdb list dns entries after add/delete action handling so the table of entries always shows the current state withouth reloading the page; fixes #887
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-12 09:50:48 +02:00
Michael Kaufmann
a5dc7b93a2 unify customerid/loginname api-parameter-descriptions; fixes #883
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-05 19:59:02 +02:00
Michael Kaufmann
244d2823a6 Merge pull request #882 from heavygale/patch-3
Fix for notices "Trying to access array offset on value of type bool" in ReportsCron.php
2020-10-03 13:10:40 +02:00
heavygale
2f0251bb19 Fix for "Trying to access array offset on value of type bool"
Proper check for success of query before accessing the result array. This notices occures if there's no custom mail-template for trafficmaxpercent_subject or trafficmaxpercent_mailbody for the required language.
2020-10-03 12:55:14 +02:00
Michael Kaufmann
a37d795ff3 set version to 0.10.21 for maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-10-02 18:01:53 +02:00
Michael Kaufmann
d9331cca61 check for fallback of ssl-certificate in ips/ports correctly of lets encrypt is used
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-09-18 11:49:26 +02:00
Michael Kaufmann
f169129e27 remove obsolete/unused table
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-09-07 21:53:18 +02:00
Michael Kaufmann
746548492b output traffic values correctly when not using bcmath and kind of fix wrong unit display on mouseover, fixes #425
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-09-07 21:51:24 +02:00
Michael Kaufmann
4ad8b62576 for ssl-fallback-check not only check for empty value but also for existence of certificate, thx to df8oe
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-09-06 14:12:25 +02:00
Michael Kaufmann
1eed3d1166 remove underscore from dkim-selector when creating the certificates too, refs #619
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-08-13 09:04:58 +02:00
Michael Kaufmann
6a32720c9a remove underscore from dkim-selector in the output certificate files too as (old) dkim-filter read the selector from this filename; refs #619
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-08-09 10:54:22 +02:00
Michael Kaufmann
e389ae4bf8 setting version to 0.10.20 for upcoming maintenance release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-08-07 19:43:16 +02:00
Michael Kaufmann
970ecb469e use overridden limit_extensions and idle_timeout in vhost config when using fpm and not mod_proxy
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-08-07 17:16:56 +02:00
Grigory Morozov
92b6914610 Update froxlor.sql
Data integrity - under no circumstances the empty string is a valid value for these fields
2020-08-07 21:58:06 +07:00
Michael Kaufmann
7e57352bc0 remove underscore from dkim-selector, refs #619
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-30 07:59:22 +02:00
Michael Kaufmann
e3d42a3f62 show current count of results besides total count in listings, fixes #869
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-29 08:46:50 +02:00
Michael Kaufmann
456a287621 fix missing query-parameters for IpsAndPorts.listing() when using sql_search
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-29 08:36:55 +02:00
Michael Kaufmann
eff630da8d unset any limit as we do not have pagination when showing search-results, refs #869
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-29 08:28:04 +02:00
Michael Kaufmann
aa45a0302e fix permanent rebuilding of vhost configs, refs 0af655f106
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-29 08:23:49 +02:00
Michael Kaufmann
aa14487995 update jquery library, fixes #872
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-28 13:28:47 +02:00
Michael Kaufmann
10b52486b5 ups, forgot to save the file so it's missing a critical return :P
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-25 17:28:46 +02:00
Michael Kaufmann
0af655f106 fix permanent rebuilding of vhost configs due to always-true renew check of let's encrypt certificates
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-25 17:21:52 +02:00
Michael Kaufmann
665c87cca7 fix index on longtext field which is not working due to unknown length; fixes #868
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-25 17:21:13 +02:00
Michael Kaufmann
1c50838d37 Merge pull request #871 from tczaude/master
issue 868 : Add new performance indexes
2020-07-24 20:37:26 +02:00
tczaude
ac5bc78e12 fix showUpdateStep 2020-07-24 19:32:04 +02:00
tczaude
a5e6ef674f issue 868 : Add new performerce indexes 2020-07-24 14:35:55 +02:00
Michael Kaufmann
03bc94e69c insert task to sync certificates for all cases (issue and renew)
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-07 12:10:40 +02:00
Michael Kaufmann
37176c94a1 set version to 0.10.19 for upcoming release
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-07-03 14:12:48 +02:00
Michael Kaufmann
a141c83ad4 do not call strtotime on the validTo_time_t key of cert_data as it already is an UNIX-timestamp, refs #865
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-23 20:35:50 +02:00
Michael Kaufmann
7c3ff95d22 check for possible CNAME overrides of A/AAAA record in dns-editor, fixes #864
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-23 09:39:00 +02:00
Michael Kaufmann
d653f6842f check for acme.sh upgrade on every run; fix not running --install-cronjob without having an issue command
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-21 19:50:46 +02:00
Michael Kaufmann
35a69fbfe0 add missing parmeter customerid for SubDomains.delete() which is required when called as admin; fixes #862
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-18 13:05:17 +02:00
Michael Kaufmann
e733701459 trigger removal cronjob of lets encrypt certificate via acme.sh also when domain update removes letsencrypt flag from domain
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-17 14:09:26 +02:00
Michael Kaufmann
70677fced2 fix double-adding of _ecc to certificate folder when deleting let's encrypt certificate
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-17 12:08:54 +02:00
Michael Kaufmann
daa223ed42 return full domain object on Domains.update() call, fixes #861
Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
2020-06-17 09:29:02 +02:00
94 changed files with 2846 additions and 975 deletions

View File

@@ -48,7 +48,7 @@ strings in
### New settings and database-layout changnes
### New settings and database-layout changes
If you add new settings or layout changes, please make sure you add these to
* `install/froxlor.sql`

View File

@@ -270,6 +270,14 @@ return array(
'default' => true,
'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'
),
)
)
)

View File

@@ -132,6 +132,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'
)
)
)

View File

@@ -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',

View File

@@ -107,7 +107,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
$count ++;
}
$admincount = $paging->getEntries();
$admincount = $result['count'] . " / " . $paging->getEntries();
eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins") . "\";");
} elseif ($action == 'su') {

View File

@@ -150,7 +150,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
$count ++;
}
$customercount = $paging->getEntries();
$customercount = $result['count'] . " / " . $paging->getEntries();
eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers") . "\";");
} elseif ($action == 'su' && $id != 0) {
try {

View File

@@ -80,7 +80,7 @@ if ($page == 'domains' || $page == 'overview') {
$count++;
}
$domainscount = $paging->getEntries();
$domainscount = $result['count'] . " / " . $paging->getEntries();
// Display the list
eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";");
@@ -616,7 +616,6 @@ if ($page == 'domains' || $page == 'overview') {
if (isset($_POST['send']) && $_POST['send'] == 'send') {
$customerid = intval($_POST['customerid']);
$separator = \Froxlor\Validate\Validate::validate($_POST['separator'], 'separator');
$offset = (int) \Froxlor\Validate\Validate::validate($_POST['offset'], 'offset', "/[0-9]/i");
@@ -625,7 +624,7 @@ if ($page == 'domains' || $page == 'overview') {
$result = array();
try {
$bulk = new \Froxlor\Bulk\DomainBulkAction($file_name, $customerid);
$bulk = new \Froxlor\Bulk\DomainBulkAction($file_name, $userinfo);
$result = $bulk->doImport($separator, $offset);
} catch (Exception $e) {
\Froxlor\UI\Response::standard_error('domain_import_error', $e->getMessage());
@@ -647,19 +646,6 @@ if ($page == 'domains' || $page == 'overview') {
'page' => 'domains'
));
} else {
$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 `name` ASC");
$params = array();
if ($userinfo['customers_see_all'] == '0') {
$params['adminid'] = $userinfo['adminid'];
}
Database::pexecute($result_customers_stmt, $params);
while ($row_customer = $result_customers_stmt->fetch(PDO::FETCH_ASSOC)) {
$customers .= \Froxlor\UI\HTML::makeoption(\Froxlor\User::getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid']);
}
$domain_import_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_import.php';
$domain_import_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_import_data);

View File

@@ -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']) : '';

View File

@@ -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']

View File

@@ -1,4 +1,6 @@
<?php
use voku\helper\AntiXSS;
require __DIR__ . '/vendor/autoload.php';
require \Froxlor\Froxlor::getInstallDir() . '/lib/tables.inc.php';
@@ -30,6 +32,12 @@ if (is_null($decoded_request)) {
json_response(400, "Invalid JSON");
}
/**
* check for xss attempts and clean request
*/
$antiXss = new AntiXSS();
$request = $antiXss->xss_clean($request);
// validate content
try {
$decoded_request = stripcslashes_deep($decoded_request);

View File

@@ -30,7 +30,7 @@
"docs": "https://github.com/Froxlor/Froxlor/wiki"
},
"require": {
"php": ">=7.0",
"php": ">=7.1",
"ext-session": "*",
"ext-ctype": "*",
"ext-pdo": "*",
@@ -46,7 +46,8 @@
"phpmailer/phpmailer": "~6.0",
"monolog/monolog": "^1.24",
"robthree/twofactorauth": "^1.6",
"froxlor/idna-convert-legacy": "^2.1"
"froxlor/idna-convert-legacy": "^2.1",
"voku/anti-xss": "^4.1"
},
"require-dev": {
"phpunit/phpunit": "8.4.1",

2015
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -133,10 +133,10 @@ if ($page == 'overview') {
FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid`= :cid AND `isemaildomain` = '1'
");
$result = Database::pexecute_first($result_stmt, array(
$result2 = Database::pexecute_first($result_stmt, array(
"cid" => $userinfo['customerid']
));
$emaildomains_count = $result['emaildomains'];
$emaildomains_count = $result2['emaildomains'];
eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";");
} elseif ($action == 'delete' && $id != 0) {
@@ -153,7 +153,8 @@ if ($page == 'overview') {
if (isset($_POST['send']) && $_POST['send'] == 'send') {
try {
Emails::getLocal($userinfo, array(
'id' => $id
'id' => $id,
'delete_userfiles' => ($_POST['delete_userfiles'] ?? 0)
))->delete();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());

View File

@@ -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,7 +131,7 @@ 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') . "\";");

View File

@@ -85,10 +85,12 @@ if ($page == 'overview') {
$mbdata_stmt = Database::prepare("SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES
WHERE table_schema = :table_schema
GROUP BY table_schema");
Database::pexecute($mbdata_stmt, array(
$mbdata = Database::pexecute_first($mbdata_stmt, array(
"table_schema" => $row['databasename']
));
$mbdata = $mbdata_stmt->fetch(PDO::FETCH_ASSOC);
if (!$mbdata) {
$mbdata = array('MB' => 0);
}
$row['size'] = \Froxlor\PhpHelper::sizeReadable($mbdata['MB'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s');
eval("\$mysqls.=\"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_database') . "\";");
$count ++;

View File

@@ -86,22 +86,18 @@ if (! is_null($month) && ! is_null($year)) {
if (extension_loaded('bcmath')) {
$traf['ftptext'] = bcdiv($row['ftp_up'], 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . bcdiv($row['ftp_down'], 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)";
$traf['httptext'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)";
$traf['mailtext'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)";
$traf['ftp'] = bcdiv($ftp, 1024, Settings::Get('panel.decimal_places'));
$traf['http'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places'));
$traf['mail'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places'));
$traf['byte'] = bcdiv($traf['byte'], 1024, Settings::Get('panel.decimal_places'));
} else {
$traf['ftptext'] = round($row['ftp_up'] / 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . round($row['ftp_down'] / 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)";
$traf['httptext'] = round($http / 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)";
$traf['mailtext'] = round($mail / 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)";
$traf['http'] = round($http, Settings::Get('panel.decimal_places'));
$traf['ftp'] = round($ftp, Settings::Get('panel.decimal_places'));
$traf['mail'] = round($mail, Settings::Get('panel.decimal_places'));
$traf['byte'] = round($traf['byte'] / 1024, Settings::Get('panel.decimal_places'));
$traf['ftp'] = round($ftp / 1024, Settings::Get('panel.decimal_places'));
}
getReadableTraffic($traf,'httptext', $http, 1024, "MiB (HTTP)");
getReadableTraffic($traf,'http', $http, 1024);
getReadableTraffic($traf,'mailtext', $mail, 1024, "MiB (Mail)");
getReadableTraffic($traf,'mail', $mail, 1024);
getReadableTraffic($traf,'byte', $traf['byte'], (1024 * 1024));
eval("\$traffic.=\"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_month') . "\";");
$show = $lng['traffic']['months'][intval($row['month'])] . ' ' . $row['year'];
}
@@ -142,22 +138,18 @@ if (! is_null($month) && ! is_null($year)) {
if (extension_loaded('bcmath')) {
$traf['ftptext'] = bcdiv($ftp_up, 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . bcdiv($ftp_down, 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)";
$traf['httptext'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)";
$traf['mailtext'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)";
$traf['ftp'] = bcdiv(($ftp_up + $ftp_down), 1024, Settings::Get('panel.decimal_places'));
$traf['http'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places'));
$traf['mail'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places'));
$traf['byte'] = bcdiv($traf['byte'], 1024 * 1024, Settings::Get('panel.decimal_places'));
} else {
$traf['ftptext'] = round($ftp_up / 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . round($ftp_down / 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)";
$traf['httptext'] = round($http / 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)";
$traf['mailtext'] = round($mail / 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)";
$traf['ftp'] = round(($ftp_up + $ftp_down) / 1024, Settings::Get('panel.decimal_places'));
$traf['http'] = round($http / 1024, Settings::Get('panel.decimal_places'));
$traf['mail'] = round($mail / 1024, Settings::Get('panel.decimal_places'));
$traf['byte'] = round($traf['byte'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
}
getReadableTraffic($traf,'httptext', $http, 1024, "MiB (HTTP)");
getReadableTraffic($traf,'http', $http, 1024);
getReadableTraffic($traf,'mailtext', $mail, 1024, "MiB (Mail)");
getReadableTraffic($traf,'mail', $mail, 1024);
getReadableTraffic($traf,'byte', $traf['byte'], (1024 * 1024));
eval("\$traffic.=\"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_traffic') . "\";");
}
@@ -167,3 +159,12 @@ if (! is_null($month) && ! is_null($year)) {
eval("echo \"" . \Froxlor\UI\Template::getTemplate('traffic/traffic') . "\";");
}
function getReadableTraffic(&$traf, $index, $value, $divisor, $desc = "")
{
if (extension_loaded('bcmath')) {
$traf[$index] = bcdiv($value, $divisor,Settings::Get('panel.decimal_places')).(!empty($desc) ? " ".$desc : "");
} else {
$traf[$index] = round($value / $divisor, Settings::Get('panel.decimal_places')).(!empty($desc) ? " ".$desc : "");
}
}

View File

@@ -19,7 +19,6 @@ if (! defined('AREA')) {
*
*/
use Froxlor\Database\Database;
use Froxlor\Api\Commands\DomainZones as DomainZones;
// This file is being included in admin_domains and customer_domains
@@ -36,18 +35,6 @@ $ttl = isset($_POST['record']['ttl']) ? (int) $_POST['record']['ttl'] : 18000;
// get domain-name
$domain = \Froxlor\Dns\Dns::getAllowedDomainEntry($domain_id, AREA, $userinfo);
// select all entries
try {
// get list
$json_result = DomainZones::getLocal($userinfo, [
'id' => $domain_id
])->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$dom_entries = $result['list'];
$errors = "";
$success_message = "";
@@ -63,8 +50,9 @@ if ($action == 'add_record' && ! empty($_POST)) {
'ttl' => $ttl
))->add();
$success_message = $lng['success']['dns_record_added'];
$record = $prio = $content = "";
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
$errors = str_replace("\n", "<br>", $e->getMessage());
}
} elseif ($action == 'delete') {
// remove entry
@@ -75,26 +63,26 @@ if ($action == 'add_record' && ! empty($_POST)) {
'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 (empty($errors)) {
// remove deleted entry from internal data array (no reread of DB necessary)
$_t = $dom_entries;
foreach ($_t as $idx => $entry) {
if ($entry['id'] == $entry_id) {
unset($dom_entries[$idx]);
break;
}
}
unset($_t);
// success message (inline)
$success_message = $lng['success']['dns_record_deleted'];
}
}
}
// select all entries
try {
// get list
$json_result = DomainZones::getLocal($userinfo, [
'id' => $domain_id
])->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$dom_entries = $result['list'];
// show editor
$record_list = "";
$existing_entries = "";

View File

@@ -114,7 +114,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 +142,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 +181,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';

View File

@@ -15,10 +15,10 @@ CREATE TABLE `ftp_groups` (
DROP TABLE IF EXISTS `ftp_users`;
CREATE TABLE `ftp_users` (
`id` int(20) NOT NULL auto_increment,
`username` varchar(255) NOT NULL default '',
`username` varchar(255) NOT NULL,
`uid` int(5) NOT NULL default '0',
`gid` int(5) NOT NULL default '0',
`password` varchar(128) NOT NULL default '',
`password` varchar(128) NOT NULL,
`homedir` varchar(255) NOT NULL default '',
`shell` varchar(255) NOT NULL default '/bin/false',
`login_enabled` enum('N','Y') NOT NULL default 'N',
@@ -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;
@@ -90,8 +91,8 @@ CREATE TABLE `panel_activation` (
DROP TABLE IF EXISTS `panel_admins`;
CREATE TABLE `panel_admins` (
`adminid` int(11) unsigned NOT NULL auto_increment,
`loginname` varchar(50) NOT NULL default '',
`password` varchar(255) NOT NULL default '',
`loginname` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL default '',
`email` varchar(255) NOT NULL default '',
`def_language` varchar(100) NOT NULL default '',
@@ -142,7 +143,7 @@ CREATE TABLE `panel_admins` (
DROP TABLE IF EXISTS `panel_customers`;
CREATE TABLE `panel_customers` (
`customerid` int(11) unsigned NOT NULL auto_increment,
`loginname` varchar(50) NOT NULL default '',
`loginname` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL default '',
`adminid` int(11) unsigned NOT NULL default '0',
`name` varchar(255) NOT NULL default '',
@@ -223,7 +224,7 @@ CREATE TABLE `panel_databases` (
DROP TABLE IF EXISTS `panel_domains`;
CREATE TABLE `panel_domains` (
`id` int(11) unsigned NOT NULL auto_increment,
`domain` varchar(255) NOT NULL default '',
`domain` varchar(255) NOT NULL,
`domain_ace` varchar(255) NOT NULL default '',
`adminid` int(11) unsigned NOT NULL default '0',
`customerid` int(11) unsigned NOT NULL default '0',
@@ -275,6 +276,7 @@ CREATE TABLE `panel_domains` (
`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`),
@@ -286,7 +288,7 @@ CREATE TABLE `panel_domains` (
DROP TABLE IF EXISTS `panel_ipsandports`;
CREATE TABLE `panel_ipsandports` (
`id` int(11) unsigned NOT NULL auto_increment,
`ip` varchar(39) NOT NULL default '',
`ip` varchar(39) NOT NULL,
`port` int(5) NOT NULL default '80',
`listen_statement` tinyint(1) NOT NULL default '0',
`namevirtualhost_statement` tinyint(1) NOT NULL default '0',
@@ -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'),
@@ -554,6 +557,7 @@ opcache.interned_strings_buffer'),
('system', 'ssl_cert_file', '/etc/apache2/apache2.pem'),
('system', 'use_ssl', '0'),
('system', 'default_vhostconf', ''),
('system', 'default_sslvhostconf', ''),
('system', 'mail_quota_enabled', '0'),
('system', 'mail_quota', '100'),
('system', 'webalizer_enabled', '1'),
@@ -670,6 +674,9 @@ 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', ''),
('api', 'enabled', '0'),
('2fa', 'enabled', '1'),
('panel', 'decimal_places', '4'),
@@ -704,8 +711,8 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''),
('panel', 'is_configured', '0'),
('panel', 'version', '0.10.18'),
('panel', 'db_version', '202005150');
('panel', 'version', '0.10.25'),
('panel', 'db_version', '202103030');
DROP TABLE IF EXISTS `panel_tasks`;
@@ -786,23 +793,6 @@ CREATE TABLE `panel_diskspace` (
DROP TABLE IF EXISTS `panel_diskspace_admins`;
CREATE TABLE `panel_diskspace_admins` (
`id` int(11) unsigned NOT NULL auto_increment,
`adminid` int(11) unsigned NOT NULL default '0',
`year` int(4) unsigned zerofill NOT NULL default '0000',
`month` int(2) unsigned zerofill NOT NULL default '00',
`day` int(2) unsigned zerofill NOT NULL default '00',
`stamp` int(11) unsigned NOT NULL default '0',
`webspace` bigint(30) unsigned NOT NULL default '0',
`mail` bigint(30) unsigned NOT NULL default '0',
`mysql` bigint(30) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `adminid` (`adminid`)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `panel_languages`;
CREATE TABLE `panel_languages` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,

View File

@@ -507,7 +507,7 @@ class FroxlorInstall
$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)))) {
if ($this->_data['distribution'] == str_replace(".xml", "", strtolower(basename($_distribution)))) {
$dist = new \Froxlor\Config\ConfigParser($_distribution);
$defaults = $dist->getDefaults();
foreach ($defaults->property as $property) {
@@ -522,6 +522,13 @@ class FroxlorInstall
// insert the lastcronrun to be the installation date
$this->_updateSetting($upd_stmt, time(), 'system', 'lastcronrun');
// check currently used php version and set values of fpm/fcgid accordingly
if (defined('PHP_MAJOR_VERSION') && defined('PHP_MINOR_VERSION')) {
$reload = "service php" . PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "-fpm restart";
$config_dir = "/etc/php/" . PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "/fpm/pool.d/";
$db->query("UPDATE `" . TABLE_PANEL_FPMDAEMONS . "` SET `reload_cmd` = '" . $reload . "', `config_dir` = '" . $config_dir . "' WHERE `id` ='1';");
}
// set specific times for some crons (traffic only at night, etc.)
$ts = mktime(0, 0, 0, date('m', time()), date('d', time()), date('Y', time()));
$db->query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $ts . "' WHERE `cronfile` ='cron_traffic';");
@@ -863,7 +870,7 @@ class FroxlorInstall
$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 . ")";
$dist_display = $dist->distributionName . " " . $dist->distributionCodename . " (" . $dist->distributionVersion . ")";
$distributions_select_data[$dist_display] .= str_replace(".xml", "", strtolower(basename($_distribution)));
}
@@ -873,7 +880,7 @@ class FroxlorInstall
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']);
//$this->_data['distribution']
// $this->_data['distribution']
}
$formdata .= $this->_getSectionItemSelectbox('distribution', $distributions_select, $diststyle);
@@ -956,7 +963,7 @@ class FroxlorInstall
}
/**
* generate form radio field
* generate form radio field
*
* @param string $fieldname
* @param boolean $checked
@@ -1029,11 +1036,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);
@@ -1331,7 +1338,6 @@ class FroxlorInstall
}
}
/**
* get/guess linux distribution
*/
@@ -1341,15 +1347,19 @@ class FroxlorInstall
if (! empty($_POST['distribution'])) {
$this->_data['distribution'] = $_POST['distribution'];
} else {
//set default os.
$os_dist = array('ID' => 'buster');
$os_version = array('0' => '10');
// set default os.
$os_dist = array(
'ID' => 'buster'
);
$os_version = array(
'0' => '10'
);
//read os-release
if(file_exists('/etc/os-release')) {
// read os-release
if (file_exists('/etc/os-release')) {
$os_dist = parse_ini_file('/etc/os-release', false);
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];
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];
}
}

View File

@@ -30,6 +30,7 @@
*/
function showUpdateStep($task = null, $needs_status = true)
{
set_time_limit(30);
if (! $needs_status)
echo "<b>";
@@ -41,7 +42,6 @@ function showUpdateStep($task = null, $needs_status = true)
}
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, $task);
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, $task);
}
/**
@@ -82,7 +82,6 @@ function lastStepStatus($status = -1, $message = '')
if ($status == - 1 || $status == 2) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Attention - last update task failed!!!');
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Attention - last update task failed!!!');
} elseif ($status == 0 || $status == 1) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Success');
}

View File

@@ -644,3 +644,108 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.17')) {
showUpdateStep("Updating from 0.10.17 to 0.10.18", false);
\Froxlor\Froxlor::updateToVersion('0.10.18');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.18')) {
showUpdateStep("Updating from 0.10.18 to 0.10.19", false);
\Froxlor\Froxlor::updateToVersion('0.10.19');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202005150')) {
showUpdateStep("Add new performance indexes", true);
Database::query("ALTER TABLE panel_customers ADD INDEX guid (guid);");
Database::query("ALTER TABLE panel_tasks ADD INDEX type (type);");
Database::query("ALTER TABLE mail_users ADD INDEX username (username);");
Database::query("ALTER TABLE mail_users ADD INDEX imap (imap);");
Database::query("ALTER TABLE mail_users ADD INDEX pop3 (pop3);");
Database::query("ALTER TABLE ftp_groups ADD INDEX gid (gid);");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202007240');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.19')) {
showUpdateStep("Updating from 0.10.19 to 0.10.20", false);
\Froxlor\Froxlor::updateToVersion('0.10.20');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202007240')) {
showUpdateStep("Removing old unused table", true);
Database::query("DROP TABLE IF EXISTS `panel_diskspace_admins`;");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202009070');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.20')) {
showUpdateStep("Updating from 0.10.20 to 0.10.21", false);
\Froxlor\Froxlor::updateToVersion('0.10.21');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.21')) {
showUpdateStep("Adding settings for ssl-vhost default content if not updated from db-version 201910110", true);
Settings::AddNew("system.default_sslvhostconf", '');
lastStepStatus(0);
showUpdateStep("Updating from 0.10.21 to 0.10.22", false);
\Froxlor\Froxlor::updateToVersion('0.10.22');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.22')) {
showUpdateStep("Updating from 0.10.22 to 0.10.23", false);
\Froxlor\Froxlor::updateToVersion('0.10.23');
}
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');
}
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');
}
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');
}

4
js/html5shiv.min.js vendored
View File

@@ -1,4 +1,4 @@
/**
* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document);
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);

4
js/jquery.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -310,6 +310,13 @@ 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) {
$condition .= ":" . $cleanfield . $incnt . ", ";
$query_fields[':' . $cleanfield . $incnt] = $invalue ?? '';
}
$condition = substr($condition, 0, - 2) . ')';
} else {
continue;
}
@@ -518,7 +525,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(

View File

@@ -231,7 +231,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$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);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
if (Settings::Get('system.mail_quota_enabled') != '1') {
$email_quota = - 1;
@@ -531,7 +531,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$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);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$theme = \Froxlor\Validate\Validate::validate($theme, 'theme', '', '', array(), true);
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
@@ -713,6 +713,10 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
if ($id == $this->getUserDetail('adminid')) {
\Froxlor\UI\Response::standard_error('youcantdeleteyourself', '', true);
}
// can't delete the first superadmin
if ($id == 1) {
\Froxlor\UI\Response::standard_error('cannotdeletesuperadmin', '', true);
}
// delete admin
$del_stmt = Database::prepare("
@@ -730,14 +734,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'adminid' => $id
), true, true);
// delete the diskspace usage
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_DISKSPACE_ADMINS . "` WHERE `adminid` = :adminid
");
Database::pexecute($del_stmt, array(
'adminid' => $id
), true, true);
// set admin-id of the old admin's customer to current admins
$upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET

View File

@@ -52,7 +52,9 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* @param bool $backup_web
* optional whether to backup web-data, default is 0 (false)
* @param int $customerid
* required when called as admin, not needed when called as customer
* 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

View File

@@ -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);
}
@@ -336,7 +416,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
$customernumber = \Froxlor\Validate\Validate::validate($customernumber, 'customer number', '/^[A-Za-z0-9 \-]*$/Di', '', array(), true);
$def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
if (Settings::Get('system.mail_quota_enabled') != '1') {
$email_quota = - 1;
@@ -873,7 +953,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$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']);
@@ -928,7 +1008,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$fax = \Froxlor\Validate\Validate::validate($fax, 'fax', '/^[0-9\- \+\(\)\/]*$/', '', array(), true);
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
$customernumber = \Froxlor\Validate\Validate::validate($customernumber, 'customer number', '/^[A-Za-z0-9 \-]*$/Di', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
if (! empty($allowed_phpconfigs)) {
$allowed_phpconfigs = array_map('intval', $allowed_phpconfigs);
}
@@ -1025,7 +1105,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
\Froxlor\System\Cronjob::inserttask('1');
}
if ($phpenabled != $result['phpenabled'] || $perlenabled != $result['perlenabled']) {
if ($phpenabled != $result['phpenabled'] || $perlenabled != $result['perlenabled'] || $email != $result['email']) {
\Froxlor\System\Cronjob::inserttask('1');
}
@@ -1411,7 +1491,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 +1511,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('11', $result['domain']);
// remove domain from acme.sh / lets encrypt if used
\Froxlor\System\Cronjob::inserttask('12', $row['domain']);
}
// remove customer domains
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");

View File

@@ -26,9 +26,9 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* add options for a given directory
*
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param string $path
* path relative to the customer's home-Directory
* @param bool $options_indexes
@@ -69,7 +69,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$error500path = $this->getParam('error500path', true, '');
// validation
$path = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Validate\Validate::validate($path, 'path', '', '', array(), true));
$path = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Validate\Validate::validate($path, 'path', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true));
$userpath = $path;
$path = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $path);
@@ -198,9 +198,9 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param int $id
* id of dir-protection entry
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param bool $options_indexes
* optional, activate directory-listing for this path, default 0 (false)
* @param bool $options_cgi

View File

@@ -26,9 +26,9 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* add htaccess protection to a given directory
*
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param string $path
* @param string $username
* @param string $directory_password
@@ -60,7 +60,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$authname = $this->getParam('directory_authname', true, '');
// validation
$path = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Validate\Validate::validate($path, 'path', '', '', array(), true));
$path = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Validate\Validate::validate($path, 'path', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true));
$path = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $path);
$username = \Froxlor\Validate\Validate::validate($username, 'username', '/^[a-zA-Z0-9][a-zA-Z0-9\-_]+\$?$/', '', array(), true);
$authname = \Froxlor\Validate\Validate::validate($authname, 'directory_authname', '/^[a-zA-Z0-9][a-zA-Z0-9\-_ ]+\$?$/', '', array(), true);
@@ -187,9 +187,9 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* @param string $username
* optional, the username
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param string $directory_password
* optional, leave empty for no change
* @param string $directory_authname

View File

@@ -170,6 +170,10 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
break;
}
}
// check www-alias setting
if ($result['wwwserveralias'] == '1' && $result['iswildcarddomain'] == '0' && $record == 'www') {
$errors[] = $this->lng['error']['no_wwwcnamae_ifwwwalias'];
}
}
// append trailing dot (again)
$content .= '.';
@@ -312,7 +316,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
return $this->response(200, "successful", $result);
}
// return $errors
throw new \Exception(implode("\n", $errors));
throw new \Exception(implode("\n", $errors), 406);
}
/**

View File

@@ -199,6 +199,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* @param string $domain
* domain-name
* @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)
* @param int $adminid
* optional, default is the calling admin's ID
* @param array $ipandport
@@ -285,6 +288,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
@@ -297,7 +302,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// parameters
$p_domain = $this->getParam('domain');
$customerid = intval($this->getParam('customerid'));
// optional parameters
$p_ipandports = $this->getParam('ipandport', true, explode(',', Settings::Get('system.defaultip')));
@@ -352,6 +356,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);
@@ -377,9 +382,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
), '', true);
}
$customer = $this->apiCall('Customers.get', array(
'id' => $customerid
));
$customer = $this->getCustomerData();
$customerid = $customer['customerid'];
if ($this->getUserDetail('customers_see_all') == '1' && $adminid != $this->getUserDetail('adminid')) {
$admin_stmt = Database::prepare("
@@ -428,8 +432,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$zonefile = '';
}
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', '/^[^\0]*$/', '', array(), true);
\Froxlor\Validate\Validate::validate($documentroot, 'documentroot', '', '', array(), true);
$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
@@ -727,7 +731,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("
@@ -779,7 +784,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();
@@ -844,7 +850,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* @param string $domainname
* optional, the domainname
* @param int $customerid
* optional customer-id
* required (if $loginname is not specified)
* @param string $loginname
* required (if $customerid is not specified)
* @param int $adminid
* optional, default is the calling admin's ID
* @param array $ipandport
@@ -929,6 +937,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
@@ -952,9 +962,18 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// optional parameters
$p_ipandports = $this->getParam('ipandport', true, array());
$customerid = intval($this->getParam('customerid', true, $result['customerid']));
$adminid = intval($this->getParam('adminid', true, $result['adminid']));
if ($this->getParam('customerid', true, 0) == 0 && $this->getParam('loginname', true, '') == '') {
$customerid = $result['customerid'];
$customer = $this->apiCall('Customers.get', array(
'id' => $customerid
));
} else {
$customer = $this->getCustomerData();
$customerid = $customer['customerid'];
}
$subcanemaildomain = $this->getParam('subcanemaildomain', true, $result['subcanemaildomain']);
$isemaildomain = $this->getBoolParam('isemaildomain', true, $result['isemaildomain']);
$email_only = $this->getBoolParam('email_only', true, $result['email_only']);
@@ -1015,6 +1034,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("
@@ -1085,13 +1105,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
if (empty($customer) || $customer['customerid'] != $customerid) {
\Froxlor\UI\Response::standard_error('customerdoesntexist', '', true);
}
} else {
$customerid = $result['customerid'];
// get customer
$customer = $this->apiCall('Customers.get', array(
'id' => $customerid
));
}
// handle change of admin (move domain from admin to admin)
@@ -1157,8 +1170,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$dkim = $result['dkim'];
}
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', '/^[^\0]*$/', '', array(), true);
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', '', '', array(), true);
$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
@@ -1324,7 +1337,12 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
}
if (! preg_match('/^https?\:\/\//', $documentroot)) {
$documentroot = \Froxlor\FileDir::makeCorrectDir($documentroot);
if ($documentroot != $result['documentroot']) {
if (substr($documentroot, 0, 1) != "/") {
$documentroot = $customer['documentroot'] . '/' . $documentroot;
}
$documentroot = \Froxlor\FileDir::makeCorrectDir($documentroot);
}
}
if ($email_only == '1') {
@@ -1442,6 +1460,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
Database::pexecute($del_stmt, array(
'id' => $id
), true, true);
// remove domain from acme.sh / lets encrypt if used
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
}
$updatechildren = '';
@@ -1577,6 +1597,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("
@@ -1622,7 +1643,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);
@@ -1766,7 +1788,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated domain '" . $idna_convert->decode($result['domain']) . "'");
return $this->response(200, "successful", $update_data);
$result = $this->apiCall('Domains.get', array(
'domainname' => $result['domain']
));
return $this->response(200, "successful", $result);
}
throw new \Exception("Not allowed to execute given command.", 403);
}

View File

@@ -30,9 +30,9 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* @param string $emailaddr
* optional email-address to add the account for
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param string $email_password
* password for the account
* @param string $alternative_email
@@ -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,7 +192,7 @@ 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'],
@@ -236,7 +236,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
@@ -295,13 +295,15 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* @param string $emailaddr
* optional, the email-address to update
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param int $email_quota
* optional, update quota
* @param string $email_password
* optional, update password
* @param bool $deactivated
* optional, admin-only
*
* @access admin, customer
* @throws \Exception
@@ -331,6 +333,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 +375,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("
@@ -418,9 +433,9 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* @param string $emailaddr
* optional, the email-address to delete the account for
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param bool $delete_userfiles
* optional, default false
*

View File

@@ -30,9 +30,9 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* @param string $emailaddr
* optional, the email-address to add the forwarder for
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param string $destination
* email-address to add as forwarder
*
@@ -221,9 +221,9 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* @param string $emailaddr
* optional, the email-address to delete the forwarder from
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param int $forwarderid
* id of the forwarder to delete
*

View File

@@ -32,9 +32,11 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param boolean $iscatchall
* optional, make this address a catchall address, default: no
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the 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,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// parameters
$iscatchall = $this->getBoolParam('iscatchall', true, 0);
$description = $this->getParam('description', true, '');
// validation
if (substr($domain, 0, 4) != 'xn--') {
@@ -121,14 +124,16 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
`email` = :email,
`email_full` = :email_full,
`iscatchall` = :iscatchall,
`domainid` = :domainid
`domainid` = :domainid,
`description` = :description
");
$params = array(
"cid" => $customer['customerid'],
"email" => $email,
"email_full" => $email_full,
"iscatchall" => $iscatchall,
"domainid" => $domain_check['id']
"domainid" => $domain_check['id'],
"description" => $description
);
Database::pexecute($stmt, $params, true, true);
@@ -167,7 +172,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`
FROM `" . TABLE_MAIL_VIRTUAL . "` v
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id`
WHERE v.`customerid` IN (" . implode(", ", $customer_ids) . ")
@@ -190,11 +195,13 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param string $emailaddr
* optional, the email-address
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* 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,6 +234,7 @@ 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 +264,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
);
@@ -300,7 +309,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`)
@@ -352,9 +361,9 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param string $emailaddr
* optional, the email-address
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
* @param boolean $delete_userfiles
* optional, delete email data from filesystem, default: 0 (false)
*
@@ -405,10 +414,6 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Customers::decreaseUsage($customer['customerid'], 'email_forwarders_used', '', $number_forwarders);
Admins::decreaseUsage($customer['customerid'], 'email_forwarders_used', '', $number_forwarders);
if ($delete_userfiles) {
\Froxlor\System\Cronjob::inserttask('7', $customer['loginname'], $result['email_full']);
}
// delete address
$stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid`= :customerid AND `id`= :id");
Database::pexecute($stmt, array(

View File

@@ -40,7 +40,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* @param string $ftp_domain
* optional if customer.ftpatdomain is allowed, specify a domain (customer must be owner)
* @param int $customerid
* required when called as admin, not needed when called as customer
* 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 array $additional_members
* optional whether to add additional usernames to the group
* @param bool $is_defaultuser
@@ -180,6 +182,17 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
), true, true);
}
// create quotatallies entry if it not exists, refs #885
if ($result_stmt->rowCount() == 0) {
$stmt = Database::prepare("INSERT INTO `" . TABLE_FTP_QUOTATALLIES . "`
(`name`, `quota_type`, `bytes_in_used`, `bytes_out_used`, `bytes_xfer_used`, `files_in_used`, `files_out_used`, `files_xfer_used`)
VALUES (:name, 'user', '0', '0', '0', '0', '0', '0')
");
Database::pexecute($stmt, array(
"name" => $username
), true, true);
}
$group_upd_stmt = Database::prepare("
UPDATE `" . TABLE_FTP_GROUPS . "`
SET `members` = CONCAT_WS(',',`members`, :username)
@@ -232,7 +245,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
'COMPANY' => $customer['company'],
'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
@@ -343,7 +356,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* @param string $username
* optional, the username
* @param string $ftp_password
* password for the created database and database-user
* optional, update password if specified
* @param string $path
* destination path relative to the customers-homedir
* @param string $ftp_description
@@ -351,7 +364,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* @param string $shell
* optional, default /bin/false (not changeable when deactivated)
* @param int $customerid
* required when called as admin, not needed when called as customer
* 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

View File

@@ -51,7 +51,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$query_fields = array();
$result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where . $this->getSearchWhere($query_fields, $append_where) . $this->getOrderBy() . $this->getLimit());
Database::pexecute($result_stmt, null, true, true);
Database::pexecute($result_stmt, $query_fields, true, true);
$result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row;
@@ -171,17 +171,17 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, true, false, false, true);
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', \Froxlor\Validate\Validate::REGEX_PORT, array(
'stringisempty',
'myport'
), array(), true);
$listen_statement = ! empty($this->getBoolParam('listen_statement', true, 0)) ? 1 : 0;
$namevirtualhost_statement = ! empty($this->getBoolParam('namevirtualhost_statement', true, 0)) ? 1 : 0;
$vhostcontainer = ! empty($this->getBoolParam('vhostcontainer', true, 0)) ? 1 : 0;
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, '')), 'specialsettings', '/^[^\0]*$/', '', array(), true);
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, '')), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$vhostcontainer_servername_statement = ! empty($this->getBoolParam('vhostcontainer_servername_statement', true, 1)) ? 1 : 0;
$default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, '')), 'default_vhostconf_domain', '/^[^\0]*$/', '', array(), true);
$docroot = \Froxlor\Validate\Validate::validate($this->getParam('docroot', true, ''), 'docroot', '', '', array(), true);
$default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, '')), 'default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$docroot = \Froxlor\Validate\Validate::validate($this->getParam('docroot', true, ''), 'docroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
if ((int) Settings::Get('system.use_ssl') == 1) {
$ssl = ! empty($this->getBoolParam('ssl', true, 0)) ? intval($this->getBoolParam('ssl', true, 0)) : 0;
@@ -189,9 +189,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, ''), 'ssl_key_file', '', '', array(), true);
$ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, ''), 'ssl_ca_file', '', '', array(), true);
$ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', array(), true);
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, '')), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true);
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, '')), 'ssl_specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$include_specialsettings = ! empty($this->getBoolParam('include_specialsettings', true, 0)) ? 1 : 0;
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, '')), 'ssl_default_vhostconf_domain', '/^[^\0]*$/', '', array(), true);
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, '')), 'ssl_default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$include_default_vhostconf_domain = ! empty($this->getBoolParam('include_default_vhostconf_domain', true, 0)) ? 1 : 0;
} else {
$ssl = 0;
@@ -368,17 +368,17 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
));
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, true, false, false, true);
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array(
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', \Froxlor\Validate\Validate::REGEX_PORT, array(
'stringisempty',
'myport'
), array(), true);
$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', '/^[^\0]*$/', '', 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', '/^[^\0]*$/', '', array(), true);
$docroot = \Froxlor\Validate\Validate::validate($this->getParam('docroot', true, $result['docroot']), 'docroot', '', '', 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) {
$ssl = $this->getBoolParam('ssl', true, $result['ssl']);
@@ -386,9 +386,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', '/^[^\0]*$/', '', 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', '/^[^\0]*$/', '', 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;

View File

@@ -34,9 +34,9 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param bool $sendinfomail
* optional, send created resource-information to customer, default: false
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
*
* @access admin, customer
* @throws \Exception
@@ -88,13 +88,13 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// add database info to froxlor
$stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DATABASES . "`
SET
`customerid` = :customerid,
`databasename` = :databasename,
`description` = :description,
`dbserver` = :dbserver
");
INSERT INTO `" . TABLE_PANEL_DATABASES . "`
SET
`customerid` = :customerid,
`databasename` = :databasename,
`description` = :description,
`dbserver` = :dbserver
");
$params = array(
"customerid" => $customer['customerid'],
"databasename" => $username,
@@ -130,7 +130,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'COMPANY' => $userinfo['company'],
'CUSTOMER_NO' => $userinfo['customernumber'],
'DB_NAME' => $username,
'DB_PASS' => $password,
'DB_PASS' => htmlentities(htmlentities($password)),
'DB_DESC' => $databasedescription,
'DB_SRV' => $sql_root['host'],
'PMA_URI' => $pma
@@ -278,9 +278,9 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param string $description
* optional, description for database
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
*
* @access admin, customer
* @throws \Exception
@@ -307,7 +307,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// paramters
$password = $this->getParam('mysql_password', true, '');
$databasedescription = $this->getParam('description', true, '');
$databasedescription = $this->getParam('description', true, $result['description']);
// validation
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
@@ -462,9 +462,9 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param int $mysql_server
* optional, specify database-server, default is none
* @param int $customerid
* optional, admin-only, the customer-id
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, admin-only, the loginname
* optional, required when called as admin (if $customerid is not specified)
*
* @access admin, customer
* @throws \Exception

View File

@@ -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'";

View File

@@ -36,7 +36,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param string $url
* optional, overwrites path value with an URL to generate a redirect, alternatively use the path parameter also for URLs
* @param int $openbasedir_path
* optional, either 0 for customers-homedir or 1 for domains-docroot
* optional, either 0 for domains-docroot or 1 for customers-homedir
* @param int $phpsettingid
* optional, php-settings-id, if empty the $domain value is used
* @param int $redirectcode
@@ -56,7 +56,9 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param bool $hsts_preload
* optional whether or not to preload HSTS header value, default 0
* @param int $customerid
* required when called as admin, not needed when called as customer
* 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
@@ -450,7 +452,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param bool $isemaildomain
* optional
* @param int $openbasedir_path
* optional, either 0 for customers-homedir or 1 for domains-docroot
* optional, either 0 for domains-docroot or 1 for customers-homedir
* @param int $phpsettingid
* optional, php-settings-id, if empty the $domain value is used
* @param int $redirectcode
@@ -470,7 +472,9 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param bool $hsts_preload
* optional whether or not to preload HSTS header value
* @param int $customerid
* required when called as admin, not needed when called as customer
* 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
@@ -683,6 +687,8 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
Database::pexecute($del_stmt, array(
'id' => $id
), true, true);
// remove domain from acme.sh / lets encrypt if used
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
}
\Froxlor\System\Cronjob::inserttask('1');
@@ -873,7 +879,11 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, the domain-id
* @param string $domainname
* optional, the domainname
*
* @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

View File

@@ -60,6 +60,10 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, default empty
* @param int $day
* optional, default empty
* @param int $date_from
* optional timestamp, default empty, if specified, $year, $month and $day will be ignored
* @param int $date_until
* optional timestamp, default empty, if specified, $year, $month and $day will be ignored
* @param bool $customer_traffic
* optional, admin-only, whether to output ones own traffic or all of ones customers, default is 0 (false)
* @param int $customerid
@@ -76,10 +80,29 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$year = $this->getParam('year', true, "");
$month = $this->getParam('month', true, "");
$day = $this->getParam('day', true, "");
$date_from = $this->getParam('date_from', true, - 1);
$date_until = $this->getParam('date_until', true, - 1);
$customer_traffic = $this->getBoolParam('customer_traffic', true, 0);
$customer_ids = $this->getAllowedCustomerIds();
$result = array();
$params = array();
// validate parameters
if ($date_from >= 0 || $date_until >= 0) {
$year = "";
$month = "";
$day = "";
if ($date_from == $date_until) {
$date_until = -1;
}
if ($date_from >= 0 && $date_until >= 0 && $date_until < $date_from) {
// switch
$temp_ts = $date_from;
$date_from = $date_until;
$date_until = $temp_ts;
}
}
// check for year/month/day
$where_str = "";
if (! empty($year) && is_numeric($year)) {
@@ -94,6 +117,17 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$where_str .= " AND `day` = :day";
$params['day'] = $day;
}
if ($date_from >= 0 && $date_until >= 0) {
$where_str .= " AND `stamp` BETWEEN :df AND :du";
$params['df'] = $date_from;
$params['du'] = $date_until;
} elseif ($date_from >= 0 && $date_until < 0) {
$where_str .= " AND `stamp` > :df";
$params['df'] = $date_from;
} elseif ($date_from < 0 && $date_until >= 0) {
$where_str .= " AND `stamp` < :du";
$params['du'] = $date_until;
}
if (! $this->isAdmin() || ($this->isAdmin() && $customer_traffic)) {
$result_stmt = Database::prepare("

View File

@@ -35,20 +35,6 @@ abstract class BulkAction
*/
private $impFile = null;
/**
* customer id of the user the entity is being added to
*
* @var int
*/
private $custId = null;
/**
* array of customer data read from the database
*
* @var array
*/
private $custData = null;
/**
* api-function to call for addingg entity
*
@@ -70,20 +56,27 @@ abstract class BulkAction
*/
private $errors = array();
/**
* logged in user
*
* @var array
*/
protected $userinfo = array();
/**
* class constructor, optionally sets file and customer-id
*
* @param string $import_file
* @param int $customer_id
* @param array $userinfo
*
* @return object BulkAction instance
*/
protected function __construct($import_file = null, $customer_id = 0)
protected function __construct($import_file = null, $userinfo = array())
{
if (! empty($import_file)) {
$this->impFile = \Froxlor\FileDir::makeCorrectFile($import_file);
}
$this->custId = $customer_id;
$this->userinfo = $userinfo;
}
/**
@@ -109,18 +102,6 @@ abstract class BulkAction
$this->impFile = \Froxlor\FileDir::makeCorrectFile($import_file);
}
/**
* setter for customer-id
*
* @param int $customer_id
*
* @return void
*/
public function setCustomer($customer_id = 0)
{
$this->custId = $customer_id;
}
/**
* return the list of errors
*
@@ -145,7 +126,7 @@ abstract class BulkAction
protected function importEntity($data_array = null)
{
global $userinfo;
if (empty($data_array)) return null;
$module = '\\Froxlor\\Api\\Commands\\' . substr($this->api_call, 0, strpos($this->api_call, "."));
$function = substr($this->api_call, strpos($this->api_call, ".") + 1);
@@ -159,7 +140,7 @@ abstract class BulkAction
$result = null;
try {
$json_result = $module::getLocal($userinfo, $new_data)->$function();
$json_result = $module::getLocal($this->userinfo, $new_data)->$function();
$result = json_decode($json_result, true)['data'];
} catch (\Exception $e) {
$this->errors[] = $e->getMessage();
@@ -189,6 +170,10 @@ abstract class BulkAction
throw new \Exception("Unable to read file '" . $this->impFile . "'");
}
if (empty($separator) || strlen($separator) != 1) {
throw new \Exception("Invalid separator specified: '" . $separator . "'");
}
$file_data = array();
$is_params_line = true;
$fh = @fopen($this->impFile, "r");
@@ -218,37 +203,4 @@ abstract class BulkAction
return $file_data;
}
/**
* to be called first in doImport() to read in customer and entity data
*/
protected function preImport()
{
$this->readCustomerData();
if ($this->custId <= 0) {
throw new \Exception("Invalid customer selected");
}
if (is_null($this->custData)) {
throw new \Exception("Failed to read customer data");
}
}
/**
* reads customer data from panel_customer by $_custId
*
* @return bool
*/
protected function readCustomerData()
{
$cust_stmt = \Froxlor\Database\Database::prepare("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `customerid` = :cid");
$this->custData = \Froxlor\Database\Database::pexecute_first($cust_stmt, array(
'cid' => $this->custId
));
if (is_array($this->custData) && isset($this->custData['customerid']) && $this->custData['customerid'] == $this->custId) {
return true;
}
$this->custData = null;
return false;
}
}

View File

@@ -32,9 +32,9 @@ class DomainBulkAction extends BulkAction
*
* @return object DomainBulkAction instance
*/
public function __construct($import_file = null, $customer_id = 0)
public function __construct($import_file = null, $userinfo)
{
parent::__construct($import_file, $customer_id);
parent::__construct($import_file, $userinfo);
$this->setApiCall('Domains.add');
}
@@ -49,23 +49,14 @@ class DomainBulkAction extends BulkAction
*/
public function doImport($separator = ";", $offset = 0)
{
$this->preImport();
// get the admins userinfo to check for domains_used, etc.
global $userinfo;
if ($userinfo['domains'] == "-1") {
if ($this->userinfo['domains'] == "-1") {
$dom_unlimited = true;
} else {
$dom_unlimited = false;
}
$domains_used = (int) $userinfo['domains_used'];
$domains_avail = (int) $userinfo['domains'];
if (empty($separator) || strlen($separator) != 1) {
throw new \Exception("Invalid separator specified: '" . $separator . "'");
}
$domains_used = (int) $this->userinfo['domains_used'];
$domains_avail = (int) $this->userinfo['domains'];
if (! is_int($offset) || $offset < 0) {
throw new \Exception("Invalid offset specified");

View File

@@ -41,6 +41,7 @@ abstract class DnsBase
{
$this->logger = $logger;
$known_ns_ips = [];
if (Settings::Get('system.nameservers') != '') {
$nameservers = explode(',', Settings::Get('system.nameservers'));
foreach ($nameservers as $nameserver) {
@@ -58,6 +59,8 @@ abstract class DnsBase
$nameserver_ips = array(
$nameserver
);
} else {
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
}
$this->ns[] = array(
'hostname' => $nameserver,
@@ -80,7 +83,9 @@ abstract class DnsBase
if (Settings::Get('system.axfrservers') != '') {
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
foreach ($axfrservers as $axfrserver) {
$this->axfr[] = trim($axfrserver);
if (!in_array(trim($axfrserver), $known_ns_ips)) {
$this->axfr[] = trim($axfrserver);
}
}
}
}
@@ -195,18 +200,18 @@ abstract class DnsBase
while ($domain = $result_domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id']);
$pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id'] . '.public');
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
$pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.public');
if ($domain['dkim_privkey'] == '' || $domain['dkim_pubkey'] == '') {
$max_dkim_id_stmt = Database::query("SELECT MAX(`dkim_id`) as `max_dkim_id` FROM `" . TABLE_PANEL_DOMAINS . "`");
$max_dkim_id = $max_dkim_id_stmt->fetch(\PDO::FETCH_ASSOC);
$domain['dkim_id'] = (int) $max_dkim_id['max_dkim_id'] + 1;
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id']);
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
\Froxlor\FileDir::safe_exec('openssl genrsa -out ' . escapeshellarg($privkey_filename) . ' ' . Settings::Get('dkim.dkim_keylength'));
$domain['dkim_privkey'] = file_get_contents($privkey_filename);
\Froxlor\FileDir::safe_exec("chmod 0640 " . escapeshellarg($privkey_filename));
$pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id'] . '.public');
$pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.public');
\Froxlor\FileDir::safe_exec('openssl rsa -in ' . escapeshellarg($privkey_filename) . ' -pubout -outform pem -out ' . escapeshellarg($pubkey_filename));
$domain['dkim_pubkey'] = file_get_contents($pubkey_filename);
\Froxlor\FileDir::safe_exec("chmod 0664 " . escapeshellarg($pubkey_filename));

View File

@@ -413,7 +413,8 @@ class Apache extends HttpConfigBase
$this->virtualhosts_data[$vhosts_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
if ($row_ipsandports['ssl_cert_file'] == '') {
// check for required fallback
if (($row_ipsandports['ssl_cert_file'] == '' || ! file_exists($row_ipsandports['ssl_cert_file'])) && (Settings::Get('system.le_froxlor_enabled') == '0' || $this->froxlorVhostHasLetsEncryptCert() == false)) {
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($row_ipsandports['ssl_cert_file'])) {
// explicitly disable ssl for this vhost
@@ -424,6 +425,11 @@ class Apache extends HttpConfigBase
if ($row_ipsandports['ssl_key_file'] == '') {
$row_ipsandports['ssl_key_file'] = Settings::Get('system.ssl_key_file');
if (! file_exists($row_ipsandports['ssl_key_file'])) {
// explicitly disable ssl for this vhost
$row_ipsandports['ssl_cert_file'] = "";
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'System certificate key-file "' . Settings::Get('system.ssl_key_file') . '" does not seem to exist. Disabling SSL-vhost for "' . Settings::Get('system.hostname') . '"');
}
}
if ($row_ipsandports['ssl_ca_file'] == '') {
@@ -950,7 +956,7 @@ class Apache extends HttpConfigBase
}
if ($ssl_vhost === true && $domain['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') {
if ($domain['ssl_cert_file'] == '') {
if ($domain['ssl_cert_file'] == '' || ! file_exists($domain['ssl_cert_file'])) {
$domain['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($domain['ssl_cert_file'])) {
// explicitly disable ssl for this vhost
@@ -959,8 +965,13 @@ class Apache extends HttpConfigBase
}
}
if ($domain['ssl_key_file'] == '') {
if ($domain['ssl_key_file'] == '' || ! file_exists($domain['ssl_key_file'])) {
$domain['ssl_key_file'] = Settings::Get('system.ssl_key_file');
if (! file_exists($domain['ssl_key_file'])) {
// explicitly disable ssl for this vhost
$domain['ssl_cert_file'] = "";
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'System certificate key-file "' . Settings::Get('system.ssl_key_file') . '" does not seem to exist. Disabling SSL-vhost for "' . $domain['domain'] . '"');
}
}
if ($domain['ssl_ca_file'] == '') {

View File

@@ -105,7 +105,11 @@ class DomainSSL
$_fh = fopen($filename, 'w');
fwrite($_fh, $dom_certs[$type]);
fclose($_fh);
chmod($filename, 0600);
if ($type == 'ssl_key_file') {
chmod($filename, 0600);
} else {
chmod($filename, 0644);
}
}
}
// override corresponding array values

View File

@@ -44,8 +44,6 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
*/
private static $upddom_stmt = null;
private static $do_update = true;
public static $no_inserttask = false;
/**
@@ -61,8 +59,11 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
// Let's Encrypt cronjob is combined with regeneration of webserver configuration files.
// For debugging purposes you can use the --debug switch and the --force switch to run the cron manually.
// check whether we MIGHT need to run although there is no task to regenerate config-files
$needRenew = self::issueDomains();
if ($needRenew || self::issueFroxlorVhost()) {
$issue_froxlor = self::issueFroxlorVhost();
$issue_domains = self::issueDomains();
$renew_froxlor = self::renewFroxlorVhost();
$renew_domains = self::renewDomains(true);
if ($issue_froxlor || !empty($issue_domains) || !empty($renew_froxlor) || $renew_domains) {
// insert task to generate certificates and vhost-configs
\Froxlor\System\Cronjob::inserttask(1);
}
@@ -77,6 +78,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
return - 1;
}
self::checkUpgrade();
// flag for re-generation of vhost files
$changedetected = 0;
@@ -268,7 +271,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
* @param int $domain_id
* @param FroxlorLogger $cronlog
*/
private static function validateDns(&$domains = array(), $domain_id, &$cronlog)
private static function validateDns(array &$domains, $domain_id, &$cronlog)
{
if (Settings::Get('system.le_domain_dnscheck') == '1' && ! empty($domains)) {
$loop_domains = $domains;
@@ -287,16 +290,11 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
}
}
private static function runAcmeSh($certrow = array(), $domains = array(), &$cronlog = null, $force = false)
private static function runAcmeSh(array $certrow, array $domains, &$cronlog = null, $force = false)
{
if (! empty($domains)) {
if (self::$do_update) {
self::checkUpgrade();
self::$do_update = false;
}
$acmesh_cmd = self::$acmesh . " --auto-upgrade 0 --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
$acmesh_cmd = self::$acmesh . " --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
// challenge path
$acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath');
if (Settings::Get('system.leecc') > 0) {
@@ -401,8 +399,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
");
$froxlor_ssl = Database::pexecute_first($froxlor_ssl_settings_stmt);
// also check for possible existing certificate
if ($froxlor_ssl || (! $froxlor_ssl && ! self::checkFsFilesAreNewer(Settings::Get('system.hostname'), date('Y-m-d H:i:s', 0)))) {
return ($froxlor_ssl ? $froxlor_ssl : true);
if ($froxlor_ssl && self::checkFsFilesAreNewer(Settings::Get('system.hostname'), $froxlor_ssl['expirationdate'])) {
return $froxlor_ssl;
}
}
return false;
@@ -411,7 +409,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
/**
* get a list of domains that have a lets encrypt certificate (possible renew)
*/
private static function renewDomains()
private static function renewDomains($check = false)
{
$certificates_stmt = Database::query("
SELECT
@@ -439,6 +437,14 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
");
$renew_certs = $certificates_stmt->fetchAll(\PDO::FETCH_ASSOC);
if ($renew_certs) {
if ($check) {
foreach ($renew_certs as $cert) {
if (self::checkFsFilesAreNewer($cert['domain'], $cert['expirationdate'])) {
return true;
}
}
return false;
}
return $renew_certs;
}
return array();
@@ -491,12 +497,12 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
private static function checkFsFilesAreNewer($domain, $cert_date = 0)
{
$certificate_folder = self::getWorkingDirFromEnv($domain);
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . $domain . '.cer');
$certificate_folder = self::getWorkingDirFromEnv(strtolower($domain));
$ssl_file = \Froxlor\FileDir::makeCorrectFile($certificate_folder . '/' . strtolower($domain) . '.cer');
if (is_dir($certificate_folder) && file_exists($ssl_file) && is_readable($ssl_file)) {
$cert_data = openssl_x509_parse(file_get_contents($ssl_file));
if (strtotime($cert_data['validTo_time_t']) > strtotime($cert_date)) {
if ($cert_data && $cert_data['validTo_time_t'] > strtotime($cert_date)) {
return true;
}
}
@@ -598,7 +604,7 @@ EOC;
*/
private static function checkUpgrade()
{
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade");
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade --auto-upgrade 0");
// check for activated cron
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --install-cronjob");
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result) . "\n" . implode("\n", $acmesh_result2));

View File

@@ -188,7 +188,8 @@ class Lighttpd extends HttpConfigBase
$this->lighttpd_data[$vhost_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
}
if ($row_ipsandports['ssl_cert_file'] == '') {
// check for required fallback
if (($row_ipsandports['ssl_cert_file'] == '' || ! file_exists($row_ipsandports['ssl_cert_file'])) && (Settings::Get('system.le_froxlor_enabled') == '0' || $this->froxlorVhostHasLetsEncryptCert() == false)) {
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($row_ipsandports['ssl_cert_file'])) {
// explicitly disable ssl for this vhost
@@ -555,7 +556,7 @@ class Lighttpd extends HttpConfigBase
$ssl_settings = '';
if ($ssl_vhost === true && $domain['ssl'] == '1' && (int) Settings::Get('system.use_ssl') == 1) {
if ($domain['ssl_cert_file'] == '') {
if ($domain['ssl_cert_file'] == '' || ! file_exists($domain['ssl_cert_file'])) {
$domain['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($domain['ssl_cert_file'])) {
// explicitly disable ssl for this vhost

View File

@@ -155,7 +155,8 @@ class Nginx extends HttpConfigBase
// we know whether it's an ssl vhost or not
$ssl_vhost = false;
if ($row_ipsandports['ssl'] == '1') {
if ($row_ipsandports['ssl_cert_file'] == '') {
// check for required fallback
if (($row_ipsandports['ssl_cert_file'] == '' || ! file_exists($row_ipsandports['ssl_cert_file'])) && (Settings::Get('system.le_froxlor_enabled') == '0' || $this->froxlorVhostHasLetsEncryptCert() == false)) {
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($row_ipsandports['ssl_cert_file'])) {
// explicitly disable ssl for this vhost
@@ -165,6 +166,11 @@ class Nginx extends HttpConfigBase
}
if ($row_ipsandports['ssl_key_file'] == '') {
$row_ipsandports['ssl_key_file'] = Settings::Get('system.ssl_key_file');
if (! file_exists($row_ipsandports['ssl_key_file'])) {
// explicitly disable ssl for this vhost
$row_ipsandports['ssl_cert_file'] = "";
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'System certificate key-file "' . Settings::Get('system.ssl_key_file') . '" does not seem to exist. Disabling SSL-vhost for "' . Settings::Get('system.hostname') . '"');
}
}
if ($row_ipsandports['ssl_ca_file'] == '') {
$row_ipsandports['ssl_ca_file'] = Settings::Get('system.ssl_ca_file');
@@ -659,7 +665,7 @@ class Nginx extends HttpConfigBase
{
$sslsettings = '';
if ($domain_or_ip['ssl_cert_file'] == '') {
if ($domain_or_ip['ssl_cert_file'] == '' || ! file_exists($domain_or_ip['ssl_cert_file'])) {
$domain_or_ip['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($domain_or_ip['ssl_cert_file'])) {
// explicitly disable ssl for this vhost
@@ -668,8 +674,15 @@ class Nginx extends HttpConfigBase
}
}
if ($domain_or_ip['ssl_key_file'] == '') {
if ($domain_or_ip['ssl_key_file'] == '' || ! file_exists($domain_or_ip['ssl_key_file'])) {
// use fallback
$domain_or_ip['ssl_key_file'] = Settings::Get('system.ssl_key_file');
// check whether it exists
if (! file_exists($domain_or_ip['ssl_key_file'])) {
// explicitly disable ssl for this vhost
$domain_or_ip['ssl_cert_file'] = "";
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'System certificate key-file "' . Settings::Get('system.ssl_key_file') . '" does not seem to exist. Disabling SSL-vhost for "' . $domain_or_ip['domain'] . '"');
}
}
if ($domain_or_ip['ssl_ca_file'] == '') {
@@ -901,7 +914,6 @@ class Nginx extends HttpConfigBase
FROM `" . TABLE_PANEL_HTPASSWDS . "` AS a
JOIN `" . TABLE_PANEL_DOMAINS . "` AS b USING (`customerid`)
WHERE b.customerid = :customerid AND b.domain = :domain
AND path LIKE CONCAT(b.documentroot, '%')
");
Database::pexecute($result_stmt, array(
'customerid' => $domain['customerid'],
@@ -1041,10 +1053,10 @@ class Nginx extends HttpConfigBase
if (Settings::Get('system.awstats_enabled') == '1') {
// awstats
$stats_text .= "\t" . 'location /awstats {' . "\n";
$stats_text .= "\t" . 'location ^~ /awstats/ {' . "\n";
} else {
// webalizer
$stats_text .= "\t" . 'location /webalizer {' . "\n";
$stats_text .= "\t" . 'location ^~ /webalizer {' . "\n";
}
$stats_text .= "\t\t" . 'alias ' . $alias_dir . ';' . "\n";

View File

@@ -108,6 +108,11 @@ class PhpInterface
$this->_php_configs_cache[$php_config_id]['fpm_settings'] = Database::pexecute_first($stmt, array(
'id' => $this->_php_configs_cache[$php_config_id]['fpmsettingid']
));
// override fpm daemon settings if set in php-config
if ($this->_php_configs_cache[$php_config_id]['override_fpmconfig'] == 1) {
$this->_php_configs_cache[$php_config_id]['fpm_settings']['limit_extensions'] = $this->_php_configs_cache[$php_config_id]['limit_extensions'];
$this->_php_configs_cache[$php_config_id]['fpm_settings']['idle_timeout'] = $this->_php_configs_cache[$php_config_id]['idle_timeout'];
}
}
}

View File

@@ -15,7 +15,7 @@ namespace Froxlor\Cron\Traffic;
* @author Froxlor team <team@froxlor.org> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Cron
*
*
*/
use Froxlor\Database\Database;
use Froxlor\Settings;
@@ -111,11 +111,11 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
'varname' => 'trafficmaxpercent_subject'
);
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
$result2_data['varname'] = 'trafficmaxpercent_mailbody';
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
$_mailerror = false;
$mailerr_msg = "";
@@ -217,11 +217,11 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
'varname' => 'trafficmaxpercent_subject'
);
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['subject']), $replace_arr));
$result2_data['varname'] = 'trafficmaxpercent_mailbody';
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['trafficmaxpercent']['mailbody']), $replace_arr));
$_mailerror = false;
$mailerr_msg = "";
@@ -424,11 +424,11 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
'varname' => 'diskmaxpercent_subject'
);
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
$result2_data['varname'] = 'diskmaxpercent_mailbody';
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
$_mailerror = false;
$mailerr_msg = "";
@@ -521,11 +521,11 @@ class ReportsCron extends \Froxlor\Cron\FroxlorCron
'varname' => 'diskmaxpercent_subject'
);
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
$mail_subject = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['subject']), $replace_arr));
$result2_data['varname'] = 'diskmaxpercent_mailbody';
$result2 = Database::pexecute_first($result2_stmt, $result2_data);
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
$mail_body = html_entity_decode(\Froxlor\PhpHelper::replaceVariables((($result2 !== false && $result2['value'] != '') ? $result2['value'] : $lng['mails']['diskmaxpercent']['mailbody']), $replace_arr));
$_mailerror = false;
$mailerr_msg = "";

View File

@@ -163,6 +163,13 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
$result_stmt = Database::query("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` ORDER BY `customerid` ASC");
$currentDate = date("Y-m-d");
$current_stamp = time();
$current_year = date('Y', $current_stamp);
$current_month = date('m', $current_stamp);
$current_day = date('d', $current_stamp);
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
/**
* HTTP-Traffic
@@ -208,7 +215,7 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
// will iterate through all customer-domains and the awstats-configs
// know the logfile-name, #246
if (Settings::Get('system.awstats_enabled') == '1') {
$httptraffic += floatval(self::callAwstatsGetTraffic($row['customerid'], $row['documentroot'] . '/awstats/', $domainlist[$row['customerid']]));
$httptraffic += floatval(self::callAwstatsGetTraffic($row['customerid'], $row['documentroot'] . '/awstats/', $domainlist[$row['customerid']], $current_stamp));
} else {
$httptraffic += floatval(self::callWebalizerGetTraffic($row['loginname'], $row['documentroot'] . '/webalizer/', $caption, $domainlist[$row['customerid']]));
}
@@ -250,8 +257,6 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
if (Settings::Get("system.mailtraffic_enabled")) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'mail traffic usage for ' . $row['loginname'] . " started...");
$currentDate = date("Y-m-d");
$domains_stmt = Database::prepare("SELECT domain FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :cid");
Database::pexecute($domains_stmt, array(
"cid" => $row['customerid']
@@ -312,10 +317,10 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
$ins_data = array(
'customerid' => $row['customerid'],
'year' => date('Y', time()),
'month' => date('m', time()),
'day' => date('d', time()),
'stamp' => time(),
'year' => $current_year,
'month' => $current_month,
'day' => $current_day,
'stamp' => $current_stamp,
'http' => $current_traffic['http'],
'ftp_up' => $current_traffic['ftp_up'],
'ftp_down' => $current_traffic['ftp_down'],
@@ -340,8 +345,8 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
FROM `" . TABLE_PANEL_TRAFFIC . "` WHERE `year` = :year AND `month` = :month AND `customerid` = :customerid
");
$sum_month_traffic = Database::pexecute_first($sum_month_traffic_stmt, array(
'year' => date('Y', time()),
'month' => date('m', time()),
'year' => $current_year,
'month' => $current_month,
'customerid' => $row['customerid']
));
$sum_month_traffic['all'] = $sum_month_traffic['http'] + $sum_month_traffic['ftp_up'] + $sum_month_traffic['ftp_down'] + $sum_month_traffic['mail'];
@@ -425,10 +430,10 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
$ins_data = array(
'customerid' => $row['customerid'],
'year' => date('Y', time()),
'month' => date('m', time()),
'day' => date('d', time()),
'stamp' => time(),
'year' => $current_year,
'month' => $current_month,
'day' => $current_day,
'stamp' => $current_stamp,
'webspace' => $current_diskspace['webspace'],
'mail' => $current_diskspace['mail'],
'mysql' => $current_diskspace['mysql']
@@ -534,10 +539,10 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
$ins_data = array(
'adminid' => $row['adminid'],
'year' => date('Y', time()),
'month' => date('m', time()),
'day' => date('d', time()),
'stamp' => time(),
'year' => $current_year,
'month' => $current_month,
'day' => $current_day,
'stamp' => $current_stamp,
'http' => $admin_traffic[$row['adminid']]['http'],
'ftp_up' => $admin_traffic[$row['adminid']]['ftp_up'],
'ftp_down' => $admin_traffic[$row['adminid']]['ftp_down'],
@@ -570,29 +575,6 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
}
if (isset($admin_diskspace[$row['adminid']])) {
$ins_data = array(
'adminid' => $row['adminid'],
'year' => date('Y', time()),
'month' => date('m', time()),
'day' => date('d', time()),
'stamp' => time(),
'webspace' => $admin_diskspace[$row['adminid']]['webspace'],
'mail' => $admin_diskspace[$row['adminid']]['mail'],
'mysql' => $admin_diskspace[$row['adminid']]['mysql']
);
$ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DISKSPACE_ADMINS . "` SET
`adminid` = :adminid,
`year` = :year,
`month` = :month,
`day` = :day,
`stamp` = :stamp,
`webspace` = :webspace,
`mail` = :mail,
`mysql` = :mysql
");
$upd_data = array(
'diskspace' => $admin_diskspace[$row['adminid']]['all'],
'adminid' => $row['adminid']
@@ -757,7 +739,7 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
return;
}
private static function callAwstatsGetTraffic($customerid, $outputdir, $usersdomainlist)
private static function callAwstatsGetTraffic($customerid, $outputdir, $usersdomainlist, $current_stamp)
{
$returnval = 0;
@@ -789,8 +771,8 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
");
$result_data = array(
'customerid' => $customerid,
'year' => date('Y', time()),
'month' => date('m', time())
'year' => date('Y', $current_stamp),
'month' => date('m', $current_stamp)
);
$result = Database::pexecute_first($result_stmt, $result_data);

View File

@@ -131,9 +131,26 @@ class Dns
}
// additional required records for CAA if activated
if (Settings::Get('system.dns_createcaaentry') && Settings::Get('system.use_ssl') == "1" && !empty($domain['p_ssl_ipandports'])) {
// check for CAA content later
self::addRequiredEntry('@CAA@', 'CAA', $required_entries);
if (Settings::Get('system.dns_createcaaentry') && Settings::Get('system.use_ssl') == "1") {
$result_stmt = Database::prepare("
SELECT i.`ip`, i.`port`, i.`ssl`
FROM " . TABLE_PANEL_IPSANDPORTS . " i
LEFT JOIN " . TABLE_DOMAINTOIP . " dip ON dip.id_ipandports = i.id
WHERE i.ssl = 1 AND dip.id_domain = :domainid
");
Database::pexecute($result_stmt, array(
'domainid' => $domain['id']
));
$ssl_ipandports = array();
while ($ssl_ipandport = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$ssl_ipandports[] = $ssl_ipandport;
}
if (! empty($ssl_ipandports)) {
// check for CAA content later
self::addRequiredEntry('@CAA@', 'CAA', $required_entries);
}
}
// additional required records for SPF and DKIM if activated
@@ -144,7 +161,7 @@ class Dns
}
if (Settings::Get('dkim.use_dkim') == '1') {
// check for DKIM content later
self::addRequiredEntry('dkim_' . $domain['dkim_id'] . '._domainkey', 'TXT', $required_entries);
self::addRequiredEntry('dkim' . $domain['dkim_id'] . '._domainkey', 'TXT', $required_entries);
}
}
@@ -160,14 +177,25 @@ class Dns
// unset special CAA required-entry
unset($required_entries[$entry['type']][md5("@CAA@")]);
}
if (Settings::Get('spf.use_spf') == '1' && $entry['type'] == 'TXT' && $entry['record'] == '@' && (strtolower(substr($entry['content'], 0, 7)) == '"v=spf1' || strtolower(substr($entry['content'], 0, 6)) == 'v=spf1') ) {
if (Settings::Get('spf.use_spf') == '1' && $entry['type'] == 'TXT' && $entry['record'] == '@' && (strtolower(substr($entry['content'], 0, 7)) == '"v=spf1' || strtolower(substr($entry['content'], 0, 6)) == 'v=spf1')) {
// unset special spf required-entry
unset($required_entries[$entry['type']][md5("@SPF@")]);
}
if (empty($primary_ns) && $entry['type'] == 'NS') {
// use the first NS entry as primary ns
if (empty($primary_ns) && $entry['record'] == '@' && $entry['type'] == 'NS') {
// use the first NS entry pertaining to the current domain as primary ns
$primary_ns = $entry['content'];
}
// check for CNAME on @, www- or wildcard-Alias and remove A/AAAA record accordingly
foreach ([
'@',
'www',
'*'
] as $crceord) {
if ($entry['type'] == 'CNAME' && $entry['record'] == '@' && (array_key_exists(md5($crceord), $required_entries['A']) || array_key_exists(md5($crceord), $required_entries['AAAA']))) {
unset($required_entries['A'][md5($crceord)]);
unset($required_entries['AAAA'][md5($crceord)]);
}
}
$zonerecords[] = new DnsEntry($entry['record'], $entry['type'], $entry['content'], $entry['prio'], $entry['ttl']);
}
@@ -179,16 +207,16 @@ class Dns
if ($froxlorhostname) {
// use all available IP's for the froxlor-hostname
$result_ip_stmt = Database::prepare("
SELECT `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` GROUP BY `ip`
");
SELECT `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` GROUP BY `ip`
");
Database::pexecute($result_ip_stmt);
} else {
$result_ip_stmt = Database::prepare("
SELECT `p`.`ip` AS `ip`
FROM `" . TABLE_PANEL_IPSANDPORTS . "` `p`, `" . TABLE_DOMAINTOIP . "` `di`
WHERE `di`.`id_domain` = :domainid AND `p`.`id` = `di`.`id_ipandports`
GROUP BY `p`.`ip`;
");
SELECT `p`.`ip` AS `ip`
FROM `" . TABLE_PANEL_IPSANDPORTS . "` `p`, `" . TABLE_DOMAINTOIP . "` `di`
WHERE `di`.`id_domain` = :domainid AND `p`.`id` = `di`.`id_ipandports`
GROUP BY `p`.`ip`;
");
Database::pexecute($result_ip_stmt, array(
'domainid' => $domain_id
));
@@ -276,7 +304,7 @@ class Dns
if ($record == '@SPF@') {
$txt_content = Settings::Get('spf.spf_entry');
$zonerecords[] = new DnsEntry('@', 'TXT', self::encloseTXTContent($txt_content));
} elseif ($record == 'dkim_' . $domain['dkim_id'] . '._domainkey' && ! empty($dkim_entries)) {
} elseif ($record == 'dkim' . $domain['dkim_id'] . '._domainkey' && ! empty($dkim_entries)) {
// check for multiline entry
$multiline = false;
if (substr($dkim_entries[0], 0, 1) == '(') {
@@ -302,6 +330,7 @@ class Dns
}
foreach ($caa_entries as $entry) {
if (empty($entry)) continue;
$zonerecords[] = new DnsEntry('@', 'CAA', $entry);
// additional required records by subdomain setting
if ($domain['wwwserveralias'] == '1') {
@@ -336,7 +365,11 @@ class Dns
}
// PowerDNS does not like multi-line-format
$soa_content = $primary_ns . " " . self::escapeSoaAdminMail(Settings::Get('panel.adminmail')) . " ";
$soa_email = Settings::Get('system.soaemail');
if ($soa_email == "") {
$soa_email = Settings::Get('panel.adminmail');
}
$soa_content = $primary_ns . " " . self::escapeSoaAdminMail($soa_email) . " ";
$soa_content .= $domain['bindserial'] . " ";
// TODO for now, dummy time-periods
$soa_content .= "3600 900 604800 " . (int) Settings::Get('system.defaultttl');

View File

@@ -332,10 +332,6 @@ class Domain
$acmesh = \Froxlor\Cron\Http\LetsEncrypt\AcmeSh::getAcmeSh();
if (file_exists($acmesh)) {
$certificate_folder = \Froxlor\Cron\Http\LetsEncrypt\AcmeSh::getWorkingDirFromEnv($domainname);
if (\Froxlor\Settings::Get('system.leecc') > 0) {
$certificate_folder .= "_ecc";
}
$certificate_folder = \Froxlor\FileDir::makeCorrectDir($certificate_folder);
if (file_exists($certificate_folder)) {
$params = " --remove -d " . $domainname;
if (\Froxlor\Settings::Get('system.leecc') > 0) {

View File

@@ -7,17 +7,17 @@ final class Froxlor
{
// Main version variable
const VERSION = '0.10.18';
const VERSION = '0.10.25';
// Database version (YYYYMMDDC where C is a daily counter)
const DBVERSION = '202005150';
const DBVERSION = '202103030';
// Distribution branding-tag (used for Debian etc.)
const BRANDING = '';
/**
* return path to where froxlor is installed, e.g.
* /var/www/froxlor
* /var/www/froxlor/
*
* @return string
*/

View File

@@ -112,7 +112,7 @@ class PhpHelper
*
* @return void|boolean
*/
public static function phpErrHandler($errno, $errstr, $errfile, $errline, $errcontext)
public static function phpErrHandler($errno, $errstr, $errfile, $errline, $errcontext = array())
{
if (! (error_reporting() & $errno)) {
// This error code is not included in error_reporting
@@ -223,9 +223,17 @@ class PhpHelper
*/
public static function gethostbynamel6($host, $try_a = true)
{
$dns6 = dns_get_record($host, DNS_AAAA);
$dns6 = @dns_get_record($host, DNS_AAAA);
if (!is_array($dns6)) {
// no record or failed to check
$dns6 = [];
}
if ($try_a == true) {
$dns4 = dns_get_record($host, DNS_A);
$dns4 = @dns_get_record($host, DNS_A);
if (!is_array($dns4)) {
// no record or failed to check
$dns4 = [];
}
$dns = array_merge($dns4, $dns6);
} else {
$dns = $dns6;
@@ -382,4 +390,33 @@ class PhpHelper
}
return $returnval;
}
/**
* function to check a super-global passed by reference
* so it gets automatically updated
*
* @param array $global
* @param \voku\helper\AntiXSS $antiXss
*/
public static function cleanGlobal(&$global, &$antiXss)
{
$ignored_fields = [
'system_default_vhostconf',
'system_default_sslvhostconf',
'system_apache_globaldiropt',
'specialsettings',
'ssl_specialsettings',
'default_vhostconf_domain',
'ssl_default_vhostconf_domain',
'filecontent'
];
if (isset($global) && ! empty($global)) {
$tmp = $global;
foreach ($tmp as $index => $value) {
if (!in_array($index, $ignored_fields)) {
$global[$index] = $antiXss->xss_clean($value);
}
}
}
}
}

View File

@@ -176,7 +176,7 @@ class Store
if ($returnvalue !== false) {
\Froxlor\System\Cronjob::inserttask('4');
}
return false;
return $returnvalue;
}
public static function storeSettingHostname($fieldname, $fielddata, $newfieldvalue)

View File

@@ -168,7 +168,7 @@ class Crypt
$password = \Froxlor\Validate\Validate::validate($password, '/.*[0-9]+.*/', '/.*[0-9]+.*/', 'notrequiredpasswordcomplexity', array(), $json_response);
}
if (Settings::Get('panel.password_special_char_required')) {
$password = \Froxlor\Validate\Validate::validate($password, '/.*[' . preg_quote(Settings::Get('panel.password_special_char')) . ']+.*/', '/.*[' . preg_quote(Settings::Get('panel.password_special_char')) . ']+.*/', 'notrequiredpasswordcomplexity', array(), $json_response);
$password = \Froxlor\Validate\Validate::validate($password, '/.*[' . preg_quote(Settings::Get('panel.password_special_char'), '/') . ']+.*/', '/.*[' . preg_quote(Settings::Get('panel.password_special_char'), '/') . ']+.*/', 'notrequiredpasswordcomplexity', array(), $json_response);
}
}

View File

@@ -32,6 +32,14 @@ class Mailer extends \PHPMailer\PHPMailer\PHPMailer
$this->Port = Settings::Get('system.mail_smtp_port');
}
/**
* use froxlor's email-validation
*/
self::$validator = [
'\Froxlor\\Validate\\Validate',
'validateEmail'
];
if (self::ValidateAddress(Settings::Get('panel.adminmail')) !== false) {
// set return-to address and custom sender-name, see #76
$this->SetFrom(Settings::Get('panel.adminmail'), Settings::Get('panel.adminmail_defname'));

View File

@@ -217,7 +217,7 @@ class Form
if (! $only_enabledisable || ($only_enabledisable && isset($fielddetails['overview_option']))) {
$newfieldvalue = self::getFormFieldData($fieldname, $fielddetails, $input);
if ($newfieldvalue != $fielddetails['value']) {
if (($error = \Froxlor\Validate\Form::validateFormField($fieldname, $fielddetails, $newfieldvalue)) !== true) {
if (($error = \Froxlor\Validate\Form::validateFormField($fieldname, $fielddetails, $newfieldvalue)) != true) {
\Froxlor\UI\Response::standard_error($error, $fieldname);
} else {
$changed_fields[$fieldname] = $newfieldvalue;
@@ -443,12 +443,12 @@ class Form
}
}
// if ($do_show) {
$returnvalue = call_user_func(array(
'\\Froxlor\\UI\\Fields',
'getFormFieldOutput' . ucfirst($fielddata['type'])
), $fieldname, $fielddata, $do_show);
// }
if ($do_show || (!$do_show && Settings::Get('system.hide_incompatible_settings') == '0')) {
$returnvalue = call_user_func(array(
'\\Froxlor\\UI\\Fields',
'getFormFieldOutput' . ucfirst($fielddata['type'])
), $fieldname, $fielddata, $do_show);
}
}
return $returnvalue;
}

View File

@@ -299,7 +299,6 @@ class HTML
$checkbox = self::makecheckbox('delete_userfiles', $chk_text, '1', false, '0', true, true);
} else {
$checkbox = '<input type="hidden" name="delete_userfiles" value="0" />' . "\n";
;
}
$text = strtr($text, array(

View File

@@ -164,6 +164,9 @@ class Pagination
// if a search is performed, the result-entries-count is irrelevant
// we do not want pagination
$this->is_search = true;
// unset any limit as we do not have pagination when showing search-results
unset($this->data['sql_limit']);
unset($this->data['sql_offset']);
return $this;
}

View File

@@ -31,7 +31,7 @@ class Data
$newfieldvalue = str_replace("\t", " ", $newfieldvalue);
if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') {
$returnvalue = (filter_var($newfieldvalue, FILTER_VALIDATE_EMAIL) == $newfieldvalue);
$returnvalue = \Froxlor\Validate\Validate::validateEmail($newfieldvalue);
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') {
$returnvalue = \Froxlor\Validate\Validate::validateUrl($newfieldvalue);
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') {
@@ -194,7 +194,7 @@ class Data
$newfieldvalue = str_replace("\t", " ", $newfieldvalue);
if (isset($fielddata['string_type']) && $fielddata['string_type'] == 'mail') {
$returnvalue = (filter_var($newfieldvalue, FILTER_VALIDATE_EMAIL) == $newfieldvalue);
$returnvalue = \Froxlor\Validate\Validate::validateEmail($newfieldvalue);
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'url') {
$returnvalue = \Froxlor\Validate\Validate::validateUrl($newfieldvalue);
} elseif (isset($fielddata['string_type']) && $fielddata['string_type'] == 'dir') {

View File

@@ -4,6 +4,12 @@ namespace Froxlor\Validate;
class Validate
{
const REGEX_DIR = '/^|(\/[\w-]+)+$/';
const REGEX_PORT = '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di';
const REGEX_CONF_TEXT = '/^[^\0]*$/';
/**
* Validates the given string by matching against the pattern, prints an error on failure and exits
*
@@ -211,9 +217,9 @@ class Validate
public static function validateDomain($domainname, $allow_underscore = false)
{
if (is_string($domainname)) {
$char_validation = '([a-z\d](-*[a-z\d])*)(\.?([a-z\d](-*[a-z\d])*))*\.([a-z\d])+';
$char_validation = '([a-z\d](-*[a-z\d])*)(\.?([a-z\d](-*[a-z\d])*))*\.(xn\-\-)?([a-z\d])+';
if ($allow_underscore) {
$char_validation = '([a-z\d\_](-*[a-z\d\_])*)(\.([a-z\d\_](-*[a-z\d])*))*(\.?([a-z\d](-*[a-z\d])*))+\.([a-z\d])+';
$char_validation = '([a-z\d\_](-*[a-z\d\_])*)(\.([a-z\d\_](-*[a-z\d])*))*(\.?([a-z\d](-*[a-z\d])*))+\.(xn\-\-)?([a-z\d])+';
}
// valid chars check && overall length check && length of each label
@@ -250,6 +256,10 @@ class Validate
public static function validateEmail($email)
{
$email = strtolower($email);
// as of php-7.1
if (defined('FILTER_FLAG_EMAIL_UNICODE')) {
return filter_var($email, FILTER_VALIDATE_EMAIL, FILTER_FLAG_EMAIL_UNICODE);
}
return filter_var($email, FILTER_VALIDATE_EMAIL);
}

View File

@@ -167,7 +167,7 @@ return array(
'value' => array()
),
'diskspace' => array(
'label' => $lng['customer']['diskspace'],
'label' => $lng['customer']['diskspace'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 6,
@@ -175,7 +175,7 @@ return array(
'ul_field' => $diskspace_ul
),
'traffic' => array(
'label' => $lng['customer']['traffic'],
'label' => $lng['customer']['traffic'] . ' (' . $lng['customer']['gib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 4,
@@ -215,7 +215,7 @@ return array(
'ul_field' => $email_forwarders_ul
),
'email_quota' => array(
'label' => $lng['customer']['email_quota'],
'label' => $lng['customer']['email_quota'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 9,

View File

@@ -196,7 +196,7 @@ return array(
)
),
'diskspace' => array(
'label' => $lng['customer']['diskspace'],
'label' => $lng['customer']['diskspace'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => $result['diskspace'],
'maxlength' => 6,
@@ -204,7 +204,7 @@ return array(
'ul_field' => $diskspace_ul
),
'traffic' => array(
'label' => $lng['customer']['traffic'],
'label' => $lng['customer']['traffic'] . ' (' . $lng['customer']['gib'] . ')',
'type' => 'textul',
'value' => $result['traffic'],
'maxlength' => 4,
@@ -244,7 +244,7 @@ return array(
'ul_field' => $email_forwarders_ul
),
'email_quota' => array(
'label' => $lng['customer']['email_quota'],
'label' => $lng['customer']['email_quota'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => $result['email_quota'],
'maxlength' => 9,

View File

@@ -190,7 +190,7 @@ return array(
'image' => 'icons/user_add.png',
'fields' => array(
'diskspace' => array(
'label' => $lng['customer']['diskspace'],
'label' => $lng['customer']['diskspace'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 16,
@@ -198,7 +198,7 @@ return array(
'ul_field' => $diskspace_ul
),
'traffic' => array(
'label' => $lng['customer']['traffic'],
'label' => $lng['customer']['traffic'] . ' (' . $lng['customer']['gib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 14,
@@ -238,7 +238,7 @@ return array(
'ul_field' => $email_forwarders_ul
),
'email_quota' => array(
'label' => $lng['customer']['email_quota'],
'label' => $lng['customer']['email_quota']. ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => 0,
'maxlength' => 9,

View File

@@ -196,7 +196,7 @@ return array(
'image' => 'icons/user_edit.png',
'fields' => array(
'diskspace' => array(
'label' => $lng['customer']['diskspace'],
'label' => $lng['customer']['diskspace'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => $result['diskspace'],
'maxlength' => 16,
@@ -204,7 +204,7 @@ return array(
'ul_field' => $diskspace_ul
),
'traffic' => array(
'label' => $lng['customer']['traffic'],
'label' => $lng['customer']['traffic'] . ' (' . $lng['customer']['gib'] . ')',
'type' => 'textul',
'value' => $result['traffic'],
'maxlength' => 14,
@@ -244,7 +244,7 @@ return array(
'ul_field' => $email_forwarders_ul
),
'email_quota' => array(
'label' => $lng['customer']['email_quota'],
'label' => $lng['customer']['email_quota'] . ' (' . $lng['customer']['mib'] . ')',
'type' => 'textul',
'value' => $result['email_quota'],
'maxlength' => 9,

View File

@@ -23,12 +23,6 @@ return array(
'title' => $lng['domains']['domain_import'],
'image' => 'icons/domain_add.png',
'fields' => array(
'customerid' => array(
'label' => $lng['admin']['customer'],
'type' => 'select',
'select_var' => $customers,
'mandatory' => true
),
'separator' => array(
'label' => $lng['domains']['import_separator'],
'type' => 'text',

View File

@@ -21,11 +21,11 @@
$_deftheme = 'Sparkle';
// validate correct php version
if (version_compare("7.0.0", PHP_VERSION, ">=")) {
if (version_compare("7.1.0", PHP_VERSION, ">=")) {
// get hint-template
$vendor_hint = file_get_contents(dirname(__DIR__) . '/templates/' . $_deftheme . '/misc/phprequirementfailed.tpl');
// replace values
$vendor_hint = str_replace("<FROXLOR_PHPMIN>", "7.0.0", $vendor_hint);
$vendor_hint = str_replace("<FROXLOR_PHPMIN>", "7.1.0", $vendor_hint);
$vendor_hint = str_replace("<CURRENT_VERSION>", PHP_VERSION, $vendor_hint);
$vendor_hint = str_replace("<CURRENT_YEAR>", date('Y', time()), $vendor_hint);
die($vendor_hint);
@@ -44,6 +44,8 @@ require dirname(__DIR__) . '/vendor/autoload.php';
use Froxlor\Database\Database;
use Froxlor\Settings;
use voku\helper\AntiXSS;
use Froxlor\PhpHelper;
header("Content-Type: text/html; charset=UTF-8");
@@ -86,6 +88,17 @@ foreach ($_REQUEST as $key => $value) {
}
}
/**
* check for xss attempts and clean important globals
*/
$antiXss = new AntiXSS();
// check $_GET
PhpHelper::cleanGlobal($_GET, $antiXss);
// check $_POST
PhpHelper::cleanGlobal($_POST, $antiXss);
// check $_COOKIE
PhpHelper::cleanGlobal($_COOKIE, $antiXss);
unset($_);
unset($value);
unset($key);
@@ -473,9 +486,9 @@ unset($js);
unset($css);
if (isset($_POST['action'])) {
$action = $_POST['action'];
$action = trim(strip_tags($_POST['action']));
} elseif (isset($_GET['action'])) {
$action = $_GET['action'];
$action = trim(strip_tags($_GET['action']));
} else {
$action = '';
// clear request data
@@ -485,9 +498,9 @@ if (isset($_POST['action'])) {
}
if (isset($_POST['page'])) {
$page = $_POST['page'];
$page = trim(strip_tags($_POST['page']));
} elseif (isset($_GET['page'])) {
$page = $_GET['page'];
$page = trim(strip_tags($_GET['page']));
} else {
$page = '';
}

View File

@@ -37,7 +37,6 @@ define('TABLE_PANEL_TEMPLATES', 'panel_templates');
define('TABLE_PANEL_TRAFFIC', 'panel_traffic');
define('TABLE_PANEL_TRAFFIC_ADMINS', 'panel_traffic_admins');
define('TABLE_PANEL_DISKSPACE', 'panel_diskspace');
define('TABLE_PANEL_DISKSPACE_ADMINS', 'panel_diskspace_admins');
define('TABLE_PANEL_LANGUAGE', 'panel_languages');
define('TABLE_PANEL_IPSANDPORTS', 'panel_ipsandports');
define('TABLE_PANEL_LOG', 'panel_syslog');

View File

@@ -1080,8 +1080,6 @@ $lng['panel']['unlock'] = 'ontgrendelen';
$lng['question']['customer_reallyunlock'] = 'Weet u zeker dat u klant %s? wilt ontgrendelen';
// ADDED IN FROXLOR 0.9.15-svn1
$lng['serversettings']['perl_server']['title'] = 'Server locatie Perl';
$lng['serversettings']['perl_server']['description'] = 'Standaard is ingesteld op de gids: <a target="blank" href="http://wiki.nginx.org/SimpleCGI">http://wiki.nginx.org/SimpleCGI</a>';
$lng['serversettings']['nginx_php_backend']['title'] = 'Nginx PHP backend';
$lng['serversettings']['nginx_php_backend']['description'] = 'dit is waar het PHP-proces luistert naar verzoeken van nginx, kan een unix socket van ip:poort combinatie zijn';
$lng['serversettings']['phpreload_command']['title'] = 'Commando voor het herladen van PHP';

View File

@@ -60,8 +60,8 @@ $lng['customer']['phone'] = 'Phone';
$lng['customer']['fax'] = 'Fax';
$lng['customer']['email'] = 'Email';
$lng['customer']['customernumber'] = 'Customer ID';
$lng['customer']['diskspace'] = 'Webspace (MiB)';
$lng['customer']['traffic'] = 'Traffic (GiB)';
$lng['customer']['diskspace'] = 'Webspace';
$lng['customer']['traffic'] = 'Traffic';
$lng['customer']['mysqls'] = 'MySQL-databases';
$lng['customer']['emails'] = 'Email-addresses';
$lng['customer']['accounts'] = 'Email-accounts';
@@ -71,6 +71,7 @@ $lng['customer']['subdomains'] = 'Subdomains';
$lng['customer']['domains'] = 'Domains';
$lng['customer']['unlimited'] = '∞';
$lng['customer']['mib'] = 'MiB';
$lng['customer']['gib'] = 'GiB';
/**
* Customermenue
@@ -619,7 +620,7 @@ $lng['traffic']['months'][9] = "September";
$lng['traffic']['months'][10] = "October";
$lng['traffic']['months'][11] = "November";
$lng['traffic']['months'][12] = "December";
$lng['traffic']['mb'] = "Traffic (MiB)";
$lng['traffic']['mb'] = "Traffic";
$lng['traffic']['distribution'] = '<font color="#019522">FTP</font> | <font color="#0000FF">HTTP</font> | <font color="#800000">Mail</font>';
$lng['traffic']['sumhttp'] = 'Total HTTP-Traffic';
$lng['traffic']['sumftp'] = 'Total FTP-Traffic';
@@ -701,6 +702,8 @@ $lng['dkim']['dkim_dkimkeys']['title'] = 'KeyList filename';
$lng['dkim']['dkim_dkimkeys']['description'] = '<em>Filename</em> of the DKIM KeyList parameter specified in the dkim-milter configuration';
$lng['dkim']['dkimrestart_command']['title'] = 'Milter restart command';
$lng['dkim']['dkimrestart_command']['description'] = 'Please specify the restart command for the DKIM milter service';
$lng['dkim']['privkeysuffix']['title'] = 'Private keys suffix';
$lng['dkim']['privkeysuffix']['description'] = 'You can specify an (optional) filename extension/suffix for the generate dkim private keys. Some services like dkim-filter requires this to be empty';
// ADDED IN 1.2.19-svn9
@@ -805,7 +808,7 @@ $lng['serversettings']['mail_quota_enabled']['enforcelink'] = 'Click here to enf
$lng['question']['admin_quotas_reallywipe'] = 'Do you really want to wipe all quotas on table mail_users? This cannot be reverted!';
$lng['question']['admin_quotas_reallyenforce'] = 'Do you really want to enforce the default quota to all Users? This cannot be reverted!';
$lng['error']['vmailquotawrong'] = 'The quotasize must be positive number.';
$lng['customer']['email_quota'] = 'E-mail quota (MiB)';
$lng['customer']['email_quota'] = 'E-mail quota';
$lng['customer']['email_imap'] = 'E-mail IMAP';
$lng['customer']['email_pop3'] = 'E-mail POP3';
$lng['customer']['mail_quota'] = 'Mailquota';
@@ -1173,8 +1176,8 @@ $lng['panel']['unlock'] = 'Unlock';
$lng['question']['customer_reallyunlock'] = 'Do you really want to unlock customer %s?';
// ADDED IN FROXLOR 0.9.15
$lng['serversettings']['perl_server']['title'] = 'Perl server location';
$lng['serversettings']['perl_server']['description'] = 'Default is set for using the guide found at: <a target="blank" href="http://wiki.nginx.org/SimpleCGI">http://wiki.nginx.org/SimpleCGI</a>';
$lng['serversettings']['perl_server']['title'] = 'Perl server socket location';
$lng['serversettings']['perl_server']['description'] = 'A simple guide can be found at: <a target="blank" href="https://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/">nginx.com</a>';
$lng['serversettings']['nginx_php_backend']['title'] = 'Nginx PHP backend';
$lng['serversettings']['nginx_php_backend']['description'] = 'this is where the PHP process is listening for requests from nginx, can be a unix socket of ip:port combination<br />*NOT used with php-fpm';
$lng['serversettings']['phpreload_command']['title'] = 'PHP reload command';
@@ -1540,9 +1543,9 @@ $lng['mysql']['size'] = 'Size';
$lng['error']['invalidhostname'] = 'Hostname needs to be a valid domain. It can\'t be empty nor can it consist only of whitespaces';
$lng['traffic']['http'] = 'HTTP (MiB)';
$lng['traffic']['ftp'] = 'FTP (MiB)';
$lng['traffic']['mail'] = 'Mail (MiB)';
$lng['traffic']['http'] = 'HTTP';
$lng['traffic']['ftp'] = 'FTP';
$lng['traffic']['mail'] = 'Mail';
// ADDED IN 0.9.27-svn1
$lng['serversettings']['mod_fcgid']['idle_timeout']['title'] = 'Idle Timeout';
@@ -2038,7 +2041,7 @@ $lng['apikeys']['valid_until_help'] = 'Date until valid, format YYYY-MM-DD';
$lng['serversettings']['enable_api']['title'] = 'Enable external API usage';
$lng['serversettings']['enable_api']['description'] = 'In order to use the froxlor API you need to activate this option. For more detailed information see <a href="https://api.froxlor.org/" target="_new">https://api.froxlor.org/</a>';
$lng['serversettings']['dhparams_file']['title'] = 'DHParams file (DiffieHellman key exchange)';
$lng['serversettings']['dhparams_file']['description'] = 'If a dhparams.pem file is specified here it will be included in the webserver configuration. Leave empty to disable.<br>Example: /etc/apache2/ssl/dhparams.pem<br><br>If the file does not exist, it will be created automatically with the following command: <em>openssl dhparam -out /etc/apache2/ssl/dhparams.pem 4096<em>. It is recommended to create the file prior to specifying it here as the creation takes quite a while and blocks the cronjob.';
$lng['serversettings']['dhparams_file']['description'] = 'If a dhparams.pem file is specified here it will be included in the webserver configuration. Leave empty to disable.<br>Example: /etc/ssl/webserver/dhparams.pem<br><br>If the file does not exist, it will be created automatically with the following command: <em>openssl dhparam -out /etc/ssl/webserver/dhparams.pem 4096<em>. It is recommended to create the file prior to specifying it here as the creation takes quite a while and blocks the cronjob.';
$lng['2fa']['2fa'] = '2FA options';
$lng['2fa']['2fa_enabled'] = 'Activate Two-factor authentication (2FA)';
$lng['login']['2fa'] = 'Two-factor authentication (2FA)';
@@ -2080,7 +2083,7 @@ $lng['serversettings']['default_sslvhostconf']['title'] = 'Default SSL vHost-set
$lng['serversettings']['includedefault_sslvhostconf'] = 'Include non-SSL vHost-settings in SSL-vHost';
$lng['admin']['ownsslvhostsettings'] = 'Own SSL vHost-settings';
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Default SSL vHost-settings for every domain container';
$lng['customer']['total_diskspace'] = 'Total diskspace (MiB)';
$lng['customer']['total_diskspace'] = 'Total diskspace';
$lng['admin']['domain_override_tls'] = 'Override system TLS settings';
$lng['domains']['isaliasdomainof'] = 'Is aliasdomain for %s';
$lng['serversettings']['apply_specialsettings_default']['title'] = 'Default value for "' . $lng['admin']['specialsettingsforsubdomains'] . "' setting when editing a domain";
@@ -2098,3 +2101,8 @@ $lng['serversettings']['phpfpm_settings']['custom_config']['description'] = 'Add
$lng['serversettings']['awstats']['logformat']['title'] = 'LogFormat setting';
$lng['serversettings']['awstats']['logformat']['description'] = 'If you use customized logformat for your webserver, you need change the awstats LogFormat too.<br/>Default is 1. For more information check documentation <a target="_blank" href="https://awstats.sourceforge.io/docs/awstats_config.html#LogFormat">here</a>.';
$lng['error']['cannotdeletesuperadmin'] = 'The first admin cannot be deleted.';
$lng['error']['no_wwwcnamae_ifwwwalias'] = 'Cannot set CNAME record for "www" as domain is set to generate a www-alias. Please change settings to either "No alias" or "Wildcard alias"';
$lng['serversettings']['hide_incompatible_settings'] = 'Hide incompatible settings';
$lng['serversettings']['soaemail'] = 'Mail address to use in SOA records (defaults to sender address from panel settings if empty)';

View File

@@ -60,8 +60,8 @@ $lng['customer']['phone'] = 'Telefon';
$lng['customer']['fax'] = 'Fax';
$lng['customer']['email'] = 'E-Mail-Adresse';
$lng['customer']['customernumber'] = 'Kundennummer';
$lng['customer']['diskspace'] = 'Webspace (MiB)';
$lng['customer']['traffic'] = 'Traffic (GiB)';
$lng['customer']['diskspace'] = 'Webspace';
$lng['customer']['traffic'] = 'Traffic';
$lng['customer']['mysqls'] = 'MySQL-Datenbanken';
$lng['customer']['emails'] = 'E-Mail-Adressen';
$lng['customer']['accounts'] = 'E-Mail-Konten';
@@ -612,7 +612,7 @@ $lng['traffic']['months'][9] = "September";
$lng['traffic']['months'][10] = "Oktober";
$lng['traffic']['months'][11] = "November";
$lng['traffic']['months'][12] = "Dezember";
$lng['traffic']['mb'] = "Traffic (MiB)";
$lng['traffic']['mb'] = "Traffic";
$lng['traffic']['day'] = "Tag";
$lng['traffic']['distribution'] = '<span color="#019522">FTP</span> | <span color="#0000FF">HTTP</span> | <span color="#800000">Mail</span>';
$lng['traffic']['sumhttp'] = 'Gesamt HTTP-Traffic';
@@ -695,6 +695,8 @@ $lng['dkim']['dkim_dkimkeys']['title'] = 'KeyList Dateiname';
$lng['dkim']['dkim_dkimkeys']['description'] = 'Dateiname der DKIM-KeyList-Angabe aus der DKIM-Milter-Konfigurationsdatei.';
$lng['dkim']['dkimrestart_command']['title'] = 'Milter-Restart-Kommando';
$lng['dkim']['dkimrestart_command']['description'] = 'Wie lautet das Kommando zum Neustarten des DKIM-Milter-Dienstes?';
$lng['dkim']['privkeysuffix']['title'] = 'Suffix für Private Keys';
$lng['dkim']['privkeysuffix']['description'] = 'Hier kann eine (optionale) Dateiendung für die generierten Private Keys angegeben werden. Manche Dienste, wie dkim-filter, erwarten, dass die Schlüssel keine Dateiendung haben (leer).';
// ADDED IN 1.2.19-svn9
@@ -800,7 +802,7 @@ $lng['serversettings']['mail_quota_enabled']['enforcelink'] = 'Hier klicken, um
$lng['question']['admin_quotas_reallywipe'] = 'Sind Sie sicher, dass alle E-Mail-Kontingente aus der Tabelle mail_users entfernt werden sollen? Dieser Schritt kann nicht rückgängig gemacht werden!';
$lng['question']['admin_quotas_reallyenforce'] = 'Sind Sie sicher, dass Sie allen Benutzern das Default-Quota zuweisen wollen? Dies kann nicht rückgängig gemacht werden!';
$lng['error']['vmailquotawrong'] = 'Die Kontingent-Größe muss positiv sein.';
$lng['customer']['email_quota'] = 'E-Mail-Kontingent (MiB)';
$lng['customer']['email_quota'] = 'E-Mail-Kontingent';
$lng['customer']['email_imap'] = 'IMAP';
$lng['customer']['email_pop3'] = 'POP3';
$lng['customer']['mail_quota'] = 'E-Mail-Kontingent';
@@ -1150,8 +1152,8 @@ $lng['panel']['unlock'] = 'entsperren';
$lng['question']['customer_reallyunlock'] = 'Wollen Sie den Kunden "%s" wirklich entsperren?';
// ADDED IN FROXLOR 0.9.15
$lng['serversettings']['perl_server']['title'] = 'Perl-Server-Ort';
$lng['serversettings']['perl_server']['description'] = 'Der Standardwert ist diesem Guide entnommen: <a target="blank" href="http://wiki.nginx.org/SimpleCGI">http://wiki.nginx.org/SimpleCGI</a>';
$lng['serversettings']['perl_server']['title'] = 'Perl Server-Socket';
$lng['serversettings']['perl_server']['description'] = 'Eine einfache Anleitung hier zu findet man unter <a target="blank" href="http://wiki.nginx.org/SimpleCGIhttps://www.nginx.com/resources/wiki/start/topics/examples/fcgiwrap/">nginx.com</a>';
$lng['serversettings']['nginx_php_backend']['title'] = 'Nginx-PHP-Backend';
$lng['serversettings']['nginx_php_backend']['description'] = 'Dies ist das Backend, auf dem PHP auf Anfragen von Nginx hört. Kann ein UNIX Socket oder eine IP:Port Kombination sein<br />*NICHT relevant bei php-fpm';
$lng['serversettings']['phpreload_command']['title'] = 'PHP-Reload-Befehl';
@@ -1266,9 +1268,9 @@ $lng['mysql']['size'] = 'Datenbankgröße';
$lng['error']['invalidhostname'] = 'Hostname muss eine gültige Domain sein. Er darf weder leer sein noch nur aus Leerzeichen bestehen';
$lng['traffic']['http'] = 'HTTP (MiB)';
$lng['traffic']['ftp'] = 'FTP (MiB)';
$lng['traffic']['mail'] = 'Mail (MiB)';
$lng['traffic']['http'] = 'HTTP';
$lng['traffic']['ftp'] = 'FTP';
$lng['traffic']['mail'] = 'Mail';
// ADDED IN 0.9.27-svn1
$lng['serversettings']['mod_fcgid']['idle_timeout']['title'] = 'Idle-Timeout';
@@ -1685,7 +1687,7 @@ $lng['apikeys']['valid_until_help'] = 'Datum Gültigkeitsende, Format JJJJ-MM-TT
$lng['serversettings']['enable_api']['title'] = 'Aktiviere externe API Nutzung';
$lng['serversettings']['enable_api']['description'] = 'Um die froxlor API nutzen zu können, muss diese Option aktiviert sein. Für detaillierte Informationen siehe <a href="https://api.froxlor.org/" target="_new">https://api.froxlor.org/</a>';
$lng['serversettings']['dhparams_file']['title'] = 'DHParams Datei (DiffieHellman key exchange)';
$lng['serversettings']['dhparams_file']['description'] = 'Wird eine dhparams.pem Datei hier angegeben, wir sie in die Webserver Konfiguration mit eingefügt.<br>Beispiel: /etc/apache2/ssl/dhparams.pem<br><br>Existiert die Datei nicht, wird sie wie folgt erstellt: <em>openssl dhparam -out /etc/apache2/ssl/dhparams.pem 4096<em>. Es wird empfohlen die Datei zu erstellen, bevor sie hier angegeben wird, da die Erstellung längere Zeit in Anspruch nimmt und den Cronjob blockiert.';
$lng['serversettings']['dhparams_file']['description'] = 'Wird eine dhparams.pem Datei hier angegeben, wir sie in die Webserver Konfiguration mit eingefügt.<br>Beispiel: /etc/ssl/webserver/dhparams.pem<br><br>Existiert die Datei nicht, wird sie wie folgt erstellt: <em>openssl dhparam -out /etc/ssl/webserver/dhparams.pem 4096<em>. Es wird empfohlen die Datei zu erstellen, bevor sie hier angegeben wird, da die Erstellung längere Zeit in Anspruch nimmt und den Cronjob blockiert.';
$lng['2fa']['2fa'] = '2FA Optionen';
$lng['2fa']['2fa_enabled'] = 'Aktiviere Zwei-Faktor Authentifizierung (2FA)';
$lng['login']['2fa'] = 'Zwei-Faktor Authentifizierung (2FA)';
@@ -1727,7 +1729,7 @@ $lng['serversettings']['default_sslvhostconf']['title'] = 'Standard SSL vHost-Ei
$lng['serversettings']['includedefault_sslvhostconf'] = 'Nicht-SSL vHost-Einstellungen in SSL-vHost inkludieren';
$lng['admin']['ownsslvhostsettings'] = 'Eigene SSL vHost-Einstellungen';
$lng['admin']['ipsandports']['ssl_default_vhostconf_domain'] = 'Standard SSL vHost-Einstellungen für jeden Domain-Container';
$lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz (MiB)';
$lng['customer']['total_diskspace'] = 'Gesamtspeicherplatz';
$lng['admin']['domain_override_tls'] = 'Überschreibe System TLS Einstellungen';
$lng['domains']['isaliasdomainof'] = 'Ist Aliasdomain für %s';
$lng['serversettings']['apply_specialsettings_default']['title'] = 'Standardwert für "' . $lng['admin']['specialsettingsforsubdomains'] . "' Einstellung beim Bearbeiten einer Domain";
@@ -1745,3 +1747,8 @@ $lng['serversettings']['phpfpm_settings']['custom_config']['description'] = 'Fü
$lng['serversettings']['awstats']['logformat']['title'] = 'LogFormat Einstellung';
$lng['serversettings']['awstats']['logformat']['description'] = 'Wenn ein benutzerdefiniertes LogFormat beim Webserver verwendet wird, muss LogFormat von awstats ebenso angepasst werden.<br/>Standard ist 1. Für weitere Informationen siehe Dokumentation unter <a target="_blank" href="https://awstats.sourceforge.io/docs/awstats_config.html#LogFormat">hier</a>.';
$lng['error']['cannotdeletesuperadmin'] = 'Der erste Administrator kann nicht gelöscht werden.';
$lng['error']['no_wwwcnamae_ifwwwalias'] = 'Es kann kein CNAME Eintrag für "www" angelegt werden, da die Domain einen www-Alias aktiviert hat. Ändere diese Einstellung auf "Kein Alias" oder "Wildcard Alias"';
$lng['serversettings']['hide_incompatible_settings'] = 'Inkompatible Einstellungen ausblenden';
$lng['serversettings']['soaemail'] = 'Mail-Adresse für SOA-Einträge (verwendet Panel-Absender-Name der Panel-Einstellungen falls leer)';

View File

@@ -1107,9 +1107,6 @@ $lng['panel']['unlock'] = 'unlock';
$lng['question']['customer_reallyunlock'] = 'Sei sicuro di voler sbloccare il cliente %s?';
// ADDED IN FROXLOR 0.9.15-svn1
$lng['serversettings']['perl_server']['title'] = 'Localizzazione del server Perl';
$lng['serversettings']['perl_server']['description'] = 'Di default è impostato per utilizzare la guida disponibile sul sito: <a target="blank" href="http://wiki.nginx.org/SimpleCGI">http://wiki.nginx.org/SimpleCGI</a>';
$lng['serversettings']['nginx_php_backend']['title'] = 'Nginx PHP backend';
$lng['serversettings']['nginx_php_backend']['description'] = 'questo è dove in ascolto il processo PHP per le richieste da nginx, può essere un socket unix combinazione IP:Porta';
$lng['serversettings']['phpreload_command']['title'] = 'Comando riavvio PHP';

View File

@@ -34,7 +34,7 @@
<if $row['letsencrypt'] == '1'>
&nbsp;<img src="templates/{$theme}/assets/img/icons/ssl_letsencrypt.png" alt="{$lng['panel']['letsencrypt']}" title="{$lng['panel']['letsencrypt']}" />
</if>
<if !(isset($row['domainaliasid']) && $row['domainaliasid'] != 0) && $row['id'] != \Froxlor\Settings::Get('system.hostname_id')>
<if !(isset($row['domainaliasid']) && !empty($row['domainaliasid'])) && $row['id'] != \Froxlor\Settings::Get('system.hostname_id')>
<if !(isset($row['standardsubdomain']) && $row['standardsubdomain'] == $row['id'])>
&nbsp;<a href="{$linker->getLink(array('section' => 'domains', 'page' => $page, 'action' => 'delete', 'id' => $row['id']))}">
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" />

View File

@@ -45,7 +45,7 @@ $header
</div>
<div class="canvasbox">
<input type="hidden" id="diskspace" class="circular" data-used="{$overview['diskspace_used']}" data-available="{$userinfo['diskspace']}" data-assigned="{$userinfo['diskspace_used']}">
<input type="hidden" id="diskspace" class="circular" data-used="{$overview['diskspace_bytes_used']}" data-available="{$userinfo['diskspace_bytes']}" data-assigned="{$userinfo['diskspace_bytes_used']}">
<canvas id="diskspace-canvas" width="120" height="76"></canvas><br/>
{$lng['customer']['diskspace']}<br />
<small>
@@ -58,7 +58,7 @@ $header
</div>
<div class="canvasbox">
<input type="hidden" id="traffic" class="circular" data-used="{$overview['traffic_used']}" data-available="{$userinfo['traffic']}" data-assigned="{$userinfo['traffic_used']}">
<input type="hidden" id="traffic" class="circular" data-used="{$overview['traffic_bytes_used']}" data-available="{$userinfo['traffic_bytes']}" data-assigned="{$userinfo['traffic_bytes_used']}">
<canvas id="traffic-canvas" width="120" height="76"></canvas><br/>
{$lng['customer']['traffic']}<br />
<small>

View File

@@ -19,8 +19,8 @@ $(document).ready(function() {
} else {
ticks.push([i, $(row).children().first().html()]);
}
ftp.push([i, parseFloat(ftpd / 1024)]);
http.push([i, parseFloat(httpd / 1024)]);
ftp.push([i, parseFloat(ftpd)]);
http.push([i, parseFloat(httpd)]);
mail.push([i, parseFloat(maild)]);
i++;
});
@@ -107,24 +107,16 @@ $(document).ready(function() {
"font-size": "11px"
}).appendTo("body");
$("#ftpchart, #httpchart").bind("plothover", function(event, pos, item) {
$("#ftpchart, #httpchart, #mailchart").bind("plothover", function(event, pos, item) {
if (item) {
var y = item.datapoint[1].toFixed(2);
var y = item.datapoint[1];
var unit = 'MiB';
if (y > 1024) {
y /= 1024;
unit = 'GiB';
}
$("#tooltip").html(item.series.label + ": " + y + " GiB").css({
top: item.pageY + 5,
left: item.pageX - $("#tooltip").width() / 2
}).fadeIn(200);
} else {
$("#tooltip").hide();
}
});
$("#mailchart").bind("plothover", function(event, pos, item) {
if (item) {
var y = item.datapoint[1].toFixed(2);
$("#tooltip").html(item.series.label + ": " + y + " MiB").css({
$("#tooltip").html(item.series.label + ": " + y.toFixed(2) + " " + unit).css({
top: item.pageY + 5,
left: item.pageX - $("#tooltip").width() / 2
}).fadeIn(200);

View File

@@ -3,7 +3,7 @@
<header>
<h2>
<img src="templates/{$theme}/assets/img/icons/domains_big.png" alt="" />&nbsp;
{$lng['domains']['domainsettings']}&nbsp;({$domains_count})
{$lng['domains']['domainsettings']}&nbsp;({$result['count']} / {$domains_count})
</h2>
</header>

View File

@@ -15,7 +15,7 @@
</td>
<td>
<if $row['aliasdomain'] == ''>{$row['documentroot']}</if>
<if isset($row['aliasdomainid']) && $row['aliasdomainid'] != 0>{$lng['domains']['aliasdomain']} {$row['aliasdomain']}</if>
<if isset($row['aliasdomainid']) && !empty($row['aliasdomainid'])>{$lng['domains']['aliasdomain']} {$row['aliasdomain']}</if>
</td>
<td>
<if $row['caneditdomain'] == '1'>
@@ -28,7 +28,7 @@
<img src="templates/{$theme}/assets/img/icons/view.png" alt="{$lng['panel']['viewlogs']}" title="{$lng['panel']['viewlogs']}" />
</a>
</if>
<if $row['parentdomainid'] != '0' && !(isset($row['domainaliasid']) && $row['domainaliasid'] != 0)>
<if $row['parentdomainid'] != '0' && (!isset($row['domainaliasid']) || empty($row['domainaliasid']))>
<a href="{$linker->getLink(array('section' => 'domains', 'page' => 'domains', 'action' => 'delete', 'id' => $row['id']))}">
<img src="templates/{$theme}/assets/img/icons/delete.png" alt="{$lng['panel']['delete']}" title="{$lng['panel']['delete']}" />
</a>&nbsp;
@@ -46,10 +46,10 @@
<if $row['letsencrypt'] == '1'>
<img src="templates/{$theme}/assets/img/icons/ssl_letsencrypt.png" alt="{$lng['panel']['letsencrypt']}" title="{$lng['panel']['letsencrypt']}" />
</if>
<if $row['parentdomainid'] == '0' && !(isset($row['domainaliasid']) && $row['domainaliasid'] != 0)>
<if $row['parentdomainid'] == '0' && (!isset($row['domainaliasid']) || empty($row['domainaliasid']))>
({$lng['domains']['isassigneddomain']})&nbsp;
</if>
<if isset($row['domainaliasid']) && $row['domainaliasid'] != 0>
<if isset($row['domainaliasid']) && !empty($row['domainaliasid'])>
<a href="{$linker->getLink(array('section' => 'domains', 'page' => 'domains', 'searchfield' => 'd.aliasdomain', 'searchtext' => $row['id']))}">{$lng['domains']['hasaliasdomains']}</a>
</if>
</td>

View File

@@ -3,7 +3,7 @@
<header>
<h2>
<img src="templates/{$theme}/assets/img/icons/emails_big.png" alt="" />&nbsp;
{$lng['menue']['email']['emails']}&nbsp;({$emailscount})
{$lng['menue']['email']['emails']}&nbsp;({$result['count']} / {$emailscount})
</h2>
</header>

View File

@@ -3,7 +3,7 @@
<header>
<h2>
<img src="templates/{$theme}/assets/img/icons/group_edit_big.png" alt="" />&nbsp;
{$lng['menue']['ftp']['accounts']}&nbsp;({$ftps_count})
{$lng['menue']['ftp']['accounts']}&nbsp;({$result['count']} / {$ftps_count})
</h2>
</header>

View File

@@ -9,7 +9,7 @@ $header
<div class="grid-u-1-2" id="statsbox">
<if $userinfo['diskspace'] != '0'>
<div class="canvasbox">
<input type="hidden" id="totalspace" class="circular" data-used="{$userinfo['total_used']}" data-available="{$userinfo['diskspace']}">
<input type="hidden" id="totalspace" class="circular" data-used="{$userinfo['total_bytes_used']}" data-available="{$userinfo['diskspace_bytes']}">
<canvas id="totalspace-canvas" width="120" height="76"></canvas><br />
{$lng['customer']['total_diskspace']}<br />
<small>
@@ -37,7 +37,7 @@ $header
<if $userinfo['diskspace'] != '0'>
<div class="canvasbox">
<input type="hidden" id="diskspace" class="circular" data-used="{$userinfo['diskspace_used']}" data-available="{$userinfo['diskspace']}">
<input type="hidden" id="diskspace" class="circular" data-used="{$userinfo['diskspace_bytes_used']}" data-available="{$userinfo['diskspace_bytes']}">
<canvas id="diskspace-canvas" width="120" height="76"></canvas><br />
{$lng['customer']['diskspace']}<br />
<small>
@@ -51,7 +51,7 @@ $header
<if $userinfo['traffic'] != '0'>
<div class="canvasbox">
<input type="hidden" id="traffic" class="circular" data-used="{$userinfo['traffic_used']}" data-available="{$userinfo['traffic']}">
<input type="hidden" id="traffic" class="circular" data-used="{$userinfo['traffic_bytes_used']}" data-available="{$userinfo['traffic_bytes']}">
<canvas id="traffic-canvas" width="120" height="76"></canvas><br />
{$lng['customer']['traffic']}<br />
<small>
@@ -87,7 +87,7 @@ $header
<if $userinfo['email_accounts'] != '∞'>
{$userinfo['email_accounts']} {$lng['panel']['available']}<br />
</if>
{$userinfo['mailspace_used']} {$lng['customer']['mib']}
{$userinfo['mailspace_used']}
</small>
</div>
</if>
@@ -130,7 +130,7 @@ $header
<if $userinfo['mysqls'] != '∞'>
{$userinfo['mysqls']} {$lng['panel']['available']}<br />
</if>
{$userinfo['dbspace_used']} {$lng['customer']['mib']}
{$userinfo['dbspace_used']}
</small>
</div>
</if>

View File

@@ -3,7 +3,7 @@
<header>
<h2>
<img src="templates/{$theme}/assets/img/icons/mysql_big.png" alt="" />&nbsp;
{$lng['menue']['mysql']['databases']}&nbsp;({$mysqls_count})
{$lng['menue']['mysql']['databases']}&nbsp;({$result['count']} / {$mysqls_count})
</h2>
</header>

View File

@@ -355,4 +355,16 @@ class AdminsTest extends TestCase
'loginname' => 'admin'
))->update();
}
public function testAdminsAdminsCannotDeleteFirstAdmin()
{
global $admin_userdata;
$testadmin_userdata = $admin_userdata;
$testadmin_userdata['adminid'] = 10;
$this->expectExceptionMessage("The first admin cannot be deleted.");
Admins::getLocal($testadmin_userdata, array(
'loginname' => 'admin'
))->delete();
}
}

View File

@@ -0,0 +1,79 @@
<?php
use PHPUnit\Framework\TestCase;
use Froxlor\Api\Commands\Domains;
use Froxlor\Bulk\DomainBulkAction;
/**
*
* @covers \Froxlor\Bulk\BulkAction
* @covers \Froxlor\Bulk\DomainBulkAction
*/
class DomainBulkTest extends TestCase
{
public function testNoImportFile()
{
global $admin_userdata;
$this->expectExceptionMessage("No file was given for import");
$bulk = new DomainBulkAction(null, $admin_userdata);
$bulk->doImport(";", 0);
}
public function testImportFileDoesNotExist()
{
global $admin_userdata;
$this->expectExceptionMessage("The file '/tmp/nonexisting.csv' could not be found");
$bulk = new DomainBulkAction("/tmp/nonexisting.csv", $admin_userdata);
$bulk->doImport(";", 0);
}
public function testImportDomains()
{
global $admin_userdata;
$content = <<<EOC
domain;loginname;
imported-a.com;test1;
imported-b.com;test1;
imported-c.com;test2;
EOC;
file_put_contents('/tmp/import-test.csv', $content);
$bulk = new DomainBulkAction("/tmp/import-test.csv", $admin_userdata);
$result = $bulk->doImport(";", 0);
$this->assertEquals(3, $result['all']);
$this->assertEquals(2, $result['imported']);
$this->assertEquals("Customer with loginname 'test2' could not be found", $bulk->getErrors()[0]);
// now check whether the domain really exists for test1 user
$data = [
'domain' => 'imported-a.com'
];
$json_result = Domains::getLocal($admin_userdata, $data)->get();
$result = json_decode($json_result, true)['data'];
$this->assertEquals('imported-a.com', $result['domain']);
$this->assertEquals(1, $result['customerid']);
}
public function testImportDomainsMaxAlloc()
{
global $admin_userdata;
// fake allocation restriction
$admin_userdata['domains'] = 1;
$content = <<<EOC
domain;loginname;
imported-a.com;test1;
imported-b.com;test1;
imported-c.com;test2;
EOC;
file_put_contents('/tmp/import-test.csv', $content);
$bulk = new DomainBulkAction("/tmp/import-test.csv", $admin_userdata);
$result = $bulk->doImport(";", 0);
$this->assertEquals(3, $result['all']);
$this->assertEquals(0, $result['imported']);
$this->assertEquals("You have reached your maximum allocation of domains (" . $admin_userdata['domains'] . ")", $result['notes']);
}
}

View File

@@ -64,7 +64,7 @@ class CertificatesTest extends TestCase
'ssl_key_file' => $certdata['key']
))->add();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(6, $result['domainid']);
$this->assertEquals(7, $result['domainid']);
}
public function testAdminCertificatesList()
@@ -148,7 +148,7 @@ class CertificatesTest extends TestCase
'ssl_key_file' => $certdata['key']
))->update();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(6, $result['domainid']);
$this->assertEquals(7, $result['domainid']);
$this->assertEquals(str_replace("\n", "", $certdata['cert']), str_replace("\n", "", $result['ssl_cert_file']));
}

View File

@@ -115,6 +115,14 @@ class CustomersTest extends TestCase
$json_result = Customers::getLocal($admin_userdata)->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertFalse(isset($result['list'][0]['webspace_used']));
$json_result = Customers::getLocal($admin_userdata, [
'show_usages' => true
])->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertTrue(isset($result['list'][0]['webspace_used']));
$json_result = Customers::getLocal($admin_userdata)->listingCount();
$result = json_decode($json_result, true)['data'];

View File

@@ -4,6 +4,7 @@ use PHPUnit\Framework\TestCase;
use Froxlor\Settings;
use Froxlor\Api\Commands\Customers;
use Froxlor\Api\Commands\DomainZones;
use Froxlor\Api\Commands\Domains;
/**
*
@@ -719,6 +720,31 @@ class DomainZonesTest extends TestCase
DomainZones::getLocal($admin_userdata, $data)->add();
}
/**
*
* @depends testAdminDomainZonesAddCname
*/
public function testAdminDomainZonesAddCnameInvalidWwwAlias()
{
global $admin_userdata;
// set domain to www-alias
$data = [
'domainname' => 'test2.local',
'selectserveralias' => '1'
];
Domains::getLocal($admin_userdata, $data)->update();
$data = [
'domainname' => 'test2.local',
'record' => 'www',
'type' => 'CNAME',
'content' => 'testing.local'
];
$this->expectExceptionMessage('Cannot set CNAME record for "www" as domain is set to generate a www-alias. Please change settings to either "No alias" or "Wildcard alias"');
DomainZones::getLocal($admin_userdata, $data)->add();
}
/**
*
* @depends testAdminDomainZonesAddCname

View File

@@ -32,13 +32,15 @@ class DomainsTest extends TestCase
'ssl_protocols' => array(
'TLSv1.2',
'TLSv1.3'
)
),
'description' => 'awesome domain'
];
$json_result = Domains::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
$this->assertEquals($customer_userdata['documentroot'] . 'test.local/', $result['documentroot']);
$this->assertTrue(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
$this->assertEquals('0', $result['isemaildomain']);
$this->assertEquals('awesome domain', $result['description']);
}
/**
@@ -155,6 +157,7 @@ class DomainsTest extends TestCase
$json_result = Domains::getLocal($reseller_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
$this->assertEmpty($result['ssl_protocols']);
$this->assertEquals('test2.local', $result['domain']);
}
public function testAdminDomainsAddSysHostname()
@@ -197,15 +200,41 @@ class DomainsTest extends TestCase
public function testAdminDomainsUpdate()
{
global $admin_userdata;
// get customer
$json_result = Customers::getLocal($admin_userdata, array(
'loginname' => 'test1'
))->get();
$customer_userdata = json_decode($json_result, true)['data'];
$data = [
'domainname' => 'test.local',
'email_only' => 1,
'override_tls' => 0
'override_tls' => 0,
'documentroot' => 'web',
'description' => 'changed desc'
];
$json_result = Domains::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['email_only']);
$this->assertFalse(in_array('TLSv1.3', explode(",", $result['ssl_protocols'])));
$this->assertEquals('test.local', $result['domain']);
$this->assertEquals($customer_userdata['documentroot'] . 'web/', $result['documentroot']);
$this->assertEquals('changed desc', $result['description']);
}
/**
*
* @depends testAdminDomainsAdd
*/
public function testAdminDomainsUpdateAbsolutePath()
{
global $admin_userdata;
$data = [
'domainname' => 'test.local',
'documentroot' => '/web'
];
$json_result = Domains::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
$this->assertEquals('/web/', $result['documentroot']);
}
/**
@@ -280,7 +309,7 @@ class DomainsTest extends TestCase
'customerid' => $customer_userdata['customerid'] + 1
];
Settings::Set('panel.allow_domain_change_customer', 1);
$this->expectExceptionMessage("The customer you have chosen doesn't exist.");
$this->expectExceptionMessage("Customer with id #2 could not be found");
Domains::getLocal($admin_userdata, $data)->update();
}
@@ -370,4 +399,30 @@ class DomainsTest extends TestCase
'domainname' => 'täst.local'
])->delete();
}
/**
* @refs https://github.com/Froxlor/Froxlor/issues/899
*/
public function testAdminIdn2DomainsAdd()
{
global $admin_userdata;
// get customer
$json_result = Customers::getLocal($admin_userdata, array(
'loginname' => 'test1'
))->get();
$customer_userdata = json_decode($json_result, true)['data'];
$data = [
'domain' => 'उदाहरण.भारत',
'customerid' => $customer_userdata['customerid']
];
$json_result = Domains::getLocal($admin_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
$this->assertEquals($customer_userdata['documentroot'] . 'xn--p1b6ci4b4b3a.xn--h2brj9c/', $result['documentroot']);
$this->assertEquals('xn--p1b6ci4b4b3a.xn--h2brj9c', $result['domain']);
$this->assertEquals('उदाहरण.भारत', $result['domain_ace']);
Domains::getLocal($admin_userdata, [
'domainname' => 'उदाहरण.भारत'
])->delete();
}
}

View File

@@ -36,12 +36,14 @@ class MailsTest extends TestCase
$data = [
'email_part' => 'info',
'domain' => 'test2.local'
'domain' => 'test2.local',
'description' => 'awesome email'
];
$json_result = Emails::getLocal($customer_userdata, $data)->add();
$result = json_decode($json_result, true)['data'];
$this->assertEquals("info@test2.local", $result['email_full']);
$this->assertEquals(0, $result['iscatchall']);
$this->assertEquals('awesome email', $result['description']);
// reset setting
Settings::Set('panel.customer_hide_options', '', true);
@@ -87,11 +89,13 @@ class MailsTest extends TestCase
$data = [
'emailaddr' => 'catchall@test2.local',
'iscatchall' => 1
'iscatchall' => 1,
'description' => 'now with catchall'
];
$json_result = Emails::getLocal($customer_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['iscatchall']);
$this->assertEquals('now with catchall', $result['description']);
}
public function testCustomerEmailForwardersAdd()
@@ -444,6 +448,36 @@ class MailsTest extends TestCase
$this->assertEquals(0, $result['quota']);
}
public function testAdminEmailAccountsUpdateDeactivated()
{
global $admin_userdata;
// disable
$data = [
'emailaddr' => 'info@test2.local',
'loginname' => 'test1',
'deactivated' => 1
];
$json_result = EmailAccounts::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
// quota is disabled
$this->assertEquals(0, $result['imap']);
$this->assertEquals(0, $result['pop3']);
$this->assertEquals('N', $result['postfix']);
// re-enable
$data = [
'emailaddr' => 'info@test2.local',
'loginname' => 'test1',
'deactivated' => 0
];
$json_result = EmailAccounts::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
// quota is disabled
$this->assertEquals(1, $result['imap']);
$this->assertEquals(1, $result['pop3']);
$this->assertEquals('Y', $result['postfix']);
}
public function testAdminEmailAccountsUndefinedGet()
{
global $admin_userdata;

View File

@@ -136,6 +136,26 @@ class MysqlsTest extends TestCase
}
}
/**
*
* @depends testCustomerMysqlsAdd
*/
public function testAdminMysqlsUpdatePwdOnly()
{
global $admin_userdata;
$newPwd = \Froxlor\System\Crypt::generatePassword();
$data = [
'dbname' => 'test1sql1',
'mysql_password' => $newPwd,
'loginname' => 'test1'
];
$json_result = Mysqls::getLocal($admin_userdata, $data)->update();
$result = json_decode($json_result, true)['data'];
$this->assertEquals('testdb-upd', $result['description']);
}
/**
*
* @depends testCustomerMysqlsAdd

View File

@@ -111,6 +111,19 @@ class TrafficTest extends TestCase
$this->assertEquals(3, $result['list'][1]['customerid']);
}
public function testAdminTrafficListCustomersFilterCustomer()
{
global $admin_userdata;
$json_result = Traffic::getLocal($admin_userdata, array(
'customer_traffic' => 1,
'loginname' => 'test1'
))->listing();
$result = json_decode($json_result, true)['data'];
$this->assertEquals(1, $result['count']);
$this->assertEquals(1, $result['list'][0]['customerid']);
}
public function testCustomerTrafficList()
{
global $admin_userdata;

View File

@@ -63,7 +63,6 @@ Database::query("TRUNCATE TABLE `" . TABLE_FTP_QUOTATALLIES . "`;");
Database::query("TRUNCATE TABLE `" . TABLE_MAIL_VIRTUAL . "`;");
Database::query("TRUNCATE TABLE `" . TABLE_MAIL_USERS . "`;");
Database::query("TRUNCATE TABLE `" . TABLE_PANEL_DISKSPACE . "`;");
Database::query("TRUNCATE TABLE `" . TABLE_PANEL_DISKSPACE_ADMINS . "`;");
Database::query("TRUNCATE TABLE `" . TABLE_PANEL_TRAFFIC . "`;");
Database::query("TRUNCATE TABLE `" . TABLE_PANEL_TRAFFIC_ADMINS . "`;");
Database::query("TRUNCATE TABLE `" . TABLE_PANEL_TASKS . "`;");