Upgrade to 3.8.1
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
##
|
||||
## Bundle of CA Root Certificates
|
||||
##
|
||||
## Certificate data from Mozilla as of: Tue Jul 19 03:12:06 2022 GMT
|
||||
## Certificate data from Mozilla as of: Tue Oct 11 03:12:05 2022 GMT
|
||||
##
|
||||
## This is a bundle of X.509 certificates of public Certificate Authorities
|
||||
## (CA). These were automatically extracted from Mozilla's root certificates
|
||||
@@ -14,7 +14,7 @@
|
||||
## Just configure this file as the SSLCACertificateFile.
|
||||
##
|
||||
## Conversion done with mk-ca-bundle.pl version 1.29.
|
||||
## SHA256: 9bf3799611fb58197f61d45e71ce3dc19f30e7dd73731915872ce5108a7bb066
|
||||
## SHA256: 3ff8bd209b5f2e739b9f2b96eacb694a774114685b02978257824f37ff528f71
|
||||
##
|
||||
|
||||
|
||||
@@ -3458,3 +3458,49 @@ zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO
|
||||
PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W
|
||||
Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Security Communication RootCA3
|
||||
==============================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw
|
||||
IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD
|
||||
b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw
|
||||
CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE
|
||||
AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
|
||||
MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r
|
||||
hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE
|
||||
NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2
|
||||
/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm
|
||||
npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY
|
||||
XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK
|
||||
p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC
|
||||
3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf
|
||||
GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw
|
||||
CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB
|
||||
/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS
|
||||
YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu
|
||||
Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O
|
||||
H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx
|
||||
YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ
|
||||
XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml
|
||||
+LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn
|
||||
KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9
|
||||
dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm
|
||||
6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Security Communication ECC RootCA1
|
||||
==================================
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD
|
||||
VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t
|
||||
dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL
|
||||
MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV
|
||||
BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo
|
||||
5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW
|
||||
BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK
|
||||
BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L
|
||||
snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e
|
||||
N9k=
|
||||
-----END CERTIFICATE-----
|
||||
|
@@ -3,7 +3,7 @@
|
||||
"description": "The Kirby 3 core",
|
||||
"license": "proprietary",
|
||||
"type": "kirby-cms",
|
||||
"version": "3.8.0",
|
||||
"version": "3.8.1",
|
||||
"keywords": [
|
||||
"kirby",
|
||||
"cms",
|
||||
@@ -40,9 +40,9 @@
|
||||
"composer/semver": "3.3.2",
|
||||
"filp/whoops": "2.14.5",
|
||||
"getkirby/composer-installer": "^1.2.1",
|
||||
"laminas/laminas-escaper": "2.10.0",
|
||||
"laminas/laminas-escaper": "2.12.0",
|
||||
"michelf/php-smartypants": "1.8.1",
|
||||
"phpmailer/phpmailer": "6.6.4",
|
||||
"phpmailer/phpmailer": "6.6.5",
|
||||
"symfony/polyfill-intl-idn": "1.26.0",
|
||||
"symfony/polyfill-mbstring": "1.26.0"
|
||||
},
|
||||
|
34
kirby/composer.lock
generated
34
kirby/composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "1ee4c8241ce2584bc60acda5c8a62771",
|
||||
"content-hash": "5e9506721e0c7075e680219a6dff9d0b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "claviska/simpleimage",
|
||||
@@ -256,32 +256,32 @@
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-escaper",
|
||||
"version": "2.10.0",
|
||||
"version": "2.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-escaper.git",
|
||||
"reference": "58af67282db37d24e584a837a94ee55b9c7552be"
|
||||
"reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/58af67282db37d24e584a837a94ee55b9c7552be",
|
||||
"reference": "58af67282db37d24e584a837a94ee55b9c7552be",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490",
|
||||
"reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.4 || ~8.0.0 || ~8.1.0"
|
||||
"php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0"
|
||||
},
|
||||
"conflict": {
|
||||
"zendframework/zend-escaper": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"infection/infection": "^0.26.6",
|
||||
"laminas/laminas-coding-standard": "~2.3.0",
|
||||
"laminas/laminas-coding-standard": "~2.4.0",
|
||||
"maglnet/composer-require-checker": "^3.8.0",
|
||||
"phpunit/phpunit": "^9.5.18",
|
||||
"psalm/plugin-phpunit": "^0.16.1",
|
||||
"psalm/plugin-phpunit": "^0.17.0",
|
||||
"vimeo/psalm": "^4.22.0"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -314,7 +314,7 @@
|
||||
"type": "community_bridge"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-08T20:15:36+00:00"
|
||||
"time": "2022-10-10T10:11:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/color-extractor",
|
||||
@@ -430,16 +430,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.6.4",
|
||||
"version": "v6.6.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b"
|
||||
"reference": "8b6386d7417526d1ea4da9edb70b8352f7543627"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8b6386d7417526d1ea4da9edb70b8352f7543627",
|
||||
"reference": "8b6386d7417526d1ea4da9edb70b8352f7543627",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -463,8 +463,8 @@
|
||||
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
|
||||
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
|
||||
"psr/log": "For optional PSR-3 debug logging",
|
||||
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
|
||||
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -496,7 +496,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -504,7 +504,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-08-22T09:22:00+00:00"
|
||||
"time": "2022-10-07T12:23:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
|
@@ -29,9 +29,9 @@ return [
|
||||
'siblings' => function (Page $page) {
|
||||
if ($page->isDraft() === true) {
|
||||
return $page->parentModel()->children()->not($page);
|
||||
} else {
|
||||
return $page->siblings();
|
||||
}
|
||||
|
||||
return $page->siblings();
|
||||
},
|
||||
'slug' => fn (Page $page) => $page->slug(),
|
||||
'status' => fn (Page $page) => $page->status(),
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Kirby\Toolkit\I18n;
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
return [
|
||||
'props' => [
|
||||
@@ -68,13 +69,13 @@ return [
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether to store UUID or path in
|
||||
* the content file
|
||||
* Whether to store UUID or ID in the
|
||||
* content file of the model
|
||||
*
|
||||
* @param string $store 'uuid'|'id'
|
||||
*/
|
||||
'store' => function (string $store = 'uuid') {
|
||||
return $store;
|
||||
return Str::lower($store);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@@ -49,9 +49,9 @@ return [
|
||||
'value' => function () {
|
||||
if ($this->props['value'] === null) {
|
||||
return $this->default();
|
||||
} else {
|
||||
return $this->toBool($this->props['value']);
|
||||
}
|
||||
|
||||
return $this->toBool($this->props['value']);
|
||||
}
|
||||
],
|
||||
'methods' => [
|
||||
|
@@ -3,10 +3,10 @@
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Cms\Helpers;
|
||||
use Kirby\Cms\Html;
|
||||
use Kirby\Cms\Response;
|
||||
use Kirby\Cms\Url;
|
||||
use Kirby\Filesystem\Asset;
|
||||
use Kirby\Filesystem\F;
|
||||
use Kirby\Http\Response;
|
||||
use Kirby\Http\Router;
|
||||
use Kirby\Toolkit\Date;
|
||||
use Kirby\Toolkit\I18n;
|
||||
|
@@ -112,7 +112,7 @@ return function ($kirby) {
|
||||
// this ensures that only existing UUIDs can be queried
|
||||
// and attackers can't force Kirby to go through the whole
|
||||
// site index with a non-existing UUID
|
||||
if ($model = Uuid::for($type . '://' . $id)->model(true)) {
|
||||
if ($model = Uuid::for($type . '://' . $id)?->model(true)) {
|
||||
return $kirby
|
||||
->response()
|
||||
->redirect($model->url());
|
||||
|
@@ -259,7 +259,7 @@
|
||||
"field.blocks.image.placeholder": "Valitse kuva",
|
||||
"field.blocks.image.ratio": "Kuvasuhde",
|
||||
"field.blocks.image.url": "Kuvan URL",
|
||||
"field.blocks.line.name": "Line",
|
||||
"field.blocks.line.name": "Rivi",
|
||||
"field.blocks.list.name": "Lista",
|
||||
"field.blocks.markdown.name": "Markdown",
|
||||
"field.blocks.markdown.label": "Teksti",
|
||||
@@ -284,7 +284,7 @@
|
||||
"field.layout.empty": "Ei rivejä",
|
||||
"field.layout.select": "Valitse asettelu",
|
||||
|
||||
"field.object.empty": "No information yet",
|
||||
"field.object.empty": "Ei vielä tietoja",
|
||||
|
||||
"field.pages.empty": " Sivuja ei ole vielä valittu",
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
"hide": "Piilota",
|
||||
"hour": "Tunti",
|
||||
"import": "Tuo",
|
||||
"info": "Info",
|
||||
"info": "Tietoja",
|
||||
"insert": "Lis\u00e4\u00e4",
|
||||
"insert.after": "Lisää eteen",
|
||||
"insert.before": "Lisää jälkeen",
|
||||
@@ -346,12 +346,12 @@
|
||||
"license": "Lisenssi",
|
||||
"license.buy": "Osta lisenssi",
|
||||
"license.register": "Rekisteröi",
|
||||
"license.manage": "Manage your licenses",
|
||||
"license.manage": "Hallinnoi lisenssejäsi",
|
||||
"license.register.help": "Lisenssiavain on lähetetty oston jälkeen sähköpostiisi. Kopioi ja liitä avain tähän.",
|
||||
"license.register.label": "Anna lisenssiavain",
|
||||
"license.register.success": "Kiitos kun tuet Kirbyä",
|
||||
"license.unregistered": "Tämä on rekisteröimätön demo Kirbystä",
|
||||
"license.unregistered.label": "Unregistered",
|
||||
"license.unregistered.label": "Rekisteröimätön",
|
||||
|
||||
"link": "Linkki",
|
||||
"link.text": "Linkin teksti",
|
||||
@@ -454,7 +454,7 @@
|
||||
"paste": "Liitä",
|
||||
"paste.after": "Liitä jälkeen",
|
||||
"pixel": "Pikseli",
|
||||
"plugin": "Plugin",
|
||||
"plugin": "Liitännäinen",
|
||||
"plugins": "Liitännäiset",
|
||||
"prev": "Edellinen",
|
||||
"preview": "Esikatselu",
|
||||
@@ -482,7 +482,7 @@
|
||||
|
||||
"section.required": "Osio on pakollinen",
|
||||
|
||||
"security": "Security",
|
||||
"security": "Tietoturva",
|
||||
"select": "Valitse",
|
||||
"server": "Palvelin",
|
||||
"settings": "Asetukset",
|
||||
@@ -492,26 +492,26 @@
|
||||
"slug": "URL-tunniste",
|
||||
"sort": "Järjestele",
|
||||
|
||||
"stats.empty": "No reports",
|
||||
"stats.empty": "Ei raportteja",
|
||||
"system.issues.content": "The content folder seems to be exposed",
|
||||
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
|
||||
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
|
||||
"system.issues.debug": "Debugging must be turned off in production",
|
||||
"system.issues.git": "The .git folder seems to be exposed",
|
||||
"system.issues.https": "We recommend HTTPS for all your sites",
|
||||
"system.issues.https": "Suosittelemme HTTPS:n käyttöä kaikilla sivustoillasi",
|
||||
"system.issues.kirby": "The kirby folder seems to be exposed",
|
||||
"system.issues.site": "The site folder seems to be exposed",
|
||||
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
|
||||
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
|
||||
"system.updateStatus": "Update status",
|
||||
"system.updateStatus.error": "Could not check for updates",
|
||||
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
|
||||
"system.updateStatus.security-update": "Free security update { version } available",
|
||||
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
|
||||
"system.updateStatus.unreleased": "Unreleased version",
|
||||
"system.updateStatus.up-to-date": "Up to date",
|
||||
"system.updateStatus.update": "Free update { version } available",
|
||||
"system.updateStatus.upgrade": "Upgrade { version } available",
|
||||
"system.issues.vulnerability.kirby": "Asennuksesi voi olla altis seuraaville haavoittuvuuksille ({ severity } vakavuus): { description }",
|
||||
"system.issues.vulnerability.plugin": "Asennuksesi käyttämä liitännäinen { plugin } voi olla altis haavoittuvuudelle ({ severity } vakavuus): { description }",
|
||||
"system.updateStatus": "Päivitysten tilanne",
|
||||
"system.updateStatus.error": "Päivityksiä ei voitu tarkistaa",
|
||||
"system.updateStatus.not-vulnerable": "Ei tunnettuja haavoittuvuuksia",
|
||||
"system.updateStatus.security-update": "Ilmainen tietoturvapäivitys { version } saatavilla",
|
||||
"system.updateStatus.security-upgrade": "Tietoturvakorjauksia sisältävä päivitys { version } saatavilla",
|
||||
"system.updateStatus.unreleased": "Julkaisematon versio",
|
||||
"system.updateStatus.up-to-date": "Ajan tasalla",
|
||||
"system.updateStatus.update": "Ilmainen päivitys { version } saatavilla",
|
||||
"system.updateStatus.upgrade": "Päivitys { version } saatavilla",
|
||||
|
||||
"title": "Nimi",
|
||||
"template": "Sivupohja",
|
||||
@@ -578,9 +578,9 @@
|
||||
"users": "Käyttäjät",
|
||||
|
||||
"version": "Versio",
|
||||
"version.current": "Current version",
|
||||
"version.latest": "Latest version",
|
||||
"versionInformation": "Version information",
|
||||
"version.current": "Nykyinen versio ",
|
||||
"version.latest": "Uusin versio ",
|
||||
"versionInformation": "Version tiedot",
|
||||
|
||||
"view.account": "Oma käyttäjätili",
|
||||
"view.installation": "Asennus",
|
||||
|
@@ -49,8 +49,8 @@
|
||||
"email": "Netfang",
|
||||
"email.placeholder": "nafn@netfang.is",
|
||||
|
||||
"entries": "Entries",
|
||||
"entry": "Entry",
|
||||
"entries": "Færslur",
|
||||
"entry": "Færsla",
|
||||
|
||||
"environment": "Umhverfi",
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
"error.blocks.max.singular": "Ekki meira en einn bálkur",
|
||||
"error.blocks.min.plural": "Minnst {min}. bálka",
|
||||
"error.blocks.min.singular": "Allavegana einn bálkur takk",
|
||||
"error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type",
|
||||
"error.blocks.validation": "Það er villa í {field} sviðinu í bálkinum {index} sem notar {fieldset} bálkgerðina",
|
||||
|
||||
"error.email.preset.notFound": "Netfangstillingarnar: \"{name}\" fundust ekki",
|
||||
|
||||
@@ -107,14 +107,14 @@
|
||||
"error.language.name": "Gott og gyllt nafn fyrir tungumálið",
|
||||
"error.language.notFound": "Tungumálið fannst ekkert",
|
||||
|
||||
"error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}",
|
||||
"error.layout.validation.block": "Það er villa í {field} sviðinu í bálkinum {blockIndex} sem notar {fieldset} bálkgerðina í rammanum {layoutIndex}",
|
||||
"error.layout.validation.settings": "Hér er villa í sitllingum fyrir ramman {index}",
|
||||
|
||||
"error.license.format": "Gildur leyfiskóði hér",
|
||||
"error.license.email": "Almennilegt netfang hér",
|
||||
"error.license.verification": "Ekki heppnaðist að staðfesta leyfið",
|
||||
|
||||
"error.object.validation": "There’s an error in the \"{label}\" field:\n{message}",
|
||||
"error.object.validation": "Það er villa í \"{label}\" sviðinu:\n{message}",
|
||||
|
||||
"error.offline": "Stjórnborðið er óvirkt eins og stendur.",
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
"field.layout.empty": "Nei. Engir rammar enn.",
|
||||
"field.layout.select": "Veldu rammategund",
|
||||
|
||||
"field.object.empty": "No information yet",
|
||||
"field.object.empty": "Engar upplýsingar enn",
|
||||
|
||||
"field.pages.empty": "Engar síður valdar ennþá",
|
||||
|
||||
@@ -303,7 +303,7 @@
|
||||
"hide": "Fela",
|
||||
"hour": "Klukkustund",
|
||||
"import": "Hlaða inn",
|
||||
"info": "Info",
|
||||
"info": "Upplýsingar",
|
||||
"insert": "Setja inn",
|
||||
"insert.after": "Setja eftir",
|
||||
"insert.before": "Setja fyrir",
|
||||
@@ -346,12 +346,12 @@
|
||||
"license": "Leyfi",
|
||||
"license.buy": "Kaupa leyfi",
|
||||
"license.register": "Skr\u00E1 Kirby",
|
||||
"license.manage": "Manage your licenses",
|
||||
"license.manage": "Sýslaðu með leyfin þín",
|
||||
"license.register.help": "Þú fékkst sendan tölvupóst með leyfiskóðanum þegar þú keyptir leyfi. Vinsamlegast afritaðu hann og settu hann hingað til að skrá þig.",
|
||||
"license.register.label": "Vinsamlegast settu inn leyfiskóðan",
|
||||
"license.register.success": "Þakka þér fyrir að velja Kirby",
|
||||
"license.unregistered": "Þetta er óskráð prufueintak af Kirby",
|
||||
"license.unregistered.label": "Unregistered",
|
||||
"license.unregistered.label": "Óskráð",
|
||||
|
||||
"link": "Tengill",
|
||||
"link.text": "Tengilstexti",
|
||||
@@ -366,14 +366,14 @@
|
||||
"lock.unlock": "Aflæsa",
|
||||
"lock.isUnlocked": "Þær breytingar sem þú gerðir hafa verið yfirskrifaðar af öðrum notanda. Þú getur sótt þær breytingar og splæst þeim saman við þínar breytingar. Handvirkt.",
|
||||
|
||||
"login": "Log in",
|
||||
"login": "Innskrá",
|
||||
"login.code.label.login": "Innskráningarkóði",
|
||||
"login.code.label.password-reset": "Kóði fyrir endurstillingu lykilorðs",
|
||||
"login.code.placeholder.email": "000 000",
|
||||
"login.code.text.email": "Ef netfangið þitt er skráð þá bíður þín nýr tölvupóstur.",
|
||||
"login.email.login.body": "Já halló {user.nameOrEmail},\n\nNýlega baðstu um innskráningarkóða fyrir bakendan á sorli.is.\nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.",
|
||||
"login.email.login.body": "Já halló {user.nameOrEmail},\n\nNýlega baðstu um innskráningarkóða fyrir bakendan á {site}.\nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.",
|
||||
"login.email.login.subject": "Innskráningarkóðinn þinn",
|
||||
"login.email.password-reset.body": "Nei halló {user.nameOrEmail},\n\nNýverið baðstu um að lykilorði þínu væri endurstillt fyrir bakendan á sorli.is. \nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.",
|
||||
"login.email.password-reset.body": "Nei halló {user.nameOrEmail},\n\nNýverið baðstu um að lykilorði þínu væri endurstillt fyrir bakendan á {site}. \nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.",
|
||||
"login.email.password-reset.subject": "Kóðinn þinn fyrir endurstillingu lykilorðs",
|
||||
"login.remember": "Vista innskráningu",
|
||||
"login.reset": "Endurheimta lykilorð takk",
|
||||
@@ -436,11 +436,11 @@
|
||||
"page.sort": "Breyta röðun",
|
||||
"page.status": "Staða",
|
||||
"page.status.draft": "Uppkast",
|
||||
"page.status.draft.description": "Þessi síða er uppkast og er aðeins sýnileg höfundum og stjórum eða gegnum falinn tengil.",
|
||||
"page.status.draft.description": "Þessi síða er uppkast og er aðeins sýnileg vefstjórum eða gegnum laumu tengil.",
|
||||
"page.status.listed": "Útgefin og listuð",
|
||||
"page.status.listed.description": "Síðan er aðgengileg öllum og sýnleg í leiðarkerfi vefsins",
|
||||
"page.status.listed.description": "Síðan er útgefin og listuð.",
|
||||
"page.status.unlisted": "Útgefin",
|
||||
"page.status.unlisted.description": "Síðan er aðgengileg öllum en þó ekki sýnileg í leiðarkerfi vefsins",
|
||||
"page.status.unlisted.description": "Síðan er útgefin en þó ólistuð.",
|
||||
|
||||
"pages": "Síður",
|
||||
"pages.empty": "Engar síður enn",
|
||||
@@ -454,7 +454,7 @@
|
||||
"paste": "Líma",
|
||||
"paste.after": "Líma eftir",
|
||||
"pixel": "Punkta",
|
||||
"plugin": "Plugin",
|
||||
"plugin": "Viðbót",
|
||||
"plugins": "Viðbætur",
|
||||
"prev": "Fyrri",
|
||||
"preview": "Forskoða",
|
||||
@@ -482,7 +482,7 @@
|
||||
|
||||
"section.required": "Þetta svæði er nauðsynlegt",
|
||||
|
||||
"security": "Security",
|
||||
"security": "Öryggi",
|
||||
"select": "Velja",
|
||||
"server": "Vefþjónn",
|
||||
"settings": "Stillingar",
|
||||
@@ -492,26 +492,26 @@
|
||||
"slug": "Slögg",
|
||||
"sort": "Raða",
|
||||
|
||||
"stats.empty": "No reports",
|
||||
"system.issues.content": "The content folder seems to be exposed",
|
||||
"system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates",
|
||||
"system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates",
|
||||
"system.issues.debug": "Debugging must be turned off in production",
|
||||
"system.issues.git": "The .git folder seems to be exposed",
|
||||
"system.issues.https": "We recommend HTTPS for all your sites",
|
||||
"system.issues.kirby": "The kirby folder seems to be exposed",
|
||||
"system.issues.site": "The site folder seems to be exposed",
|
||||
"system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }",
|
||||
"system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }",
|
||||
"system.updateStatus": "Update status",
|
||||
"system.updateStatus.error": "Could not check for updates",
|
||||
"system.updateStatus.not-vulnerable": "No known vulnerabilities",
|
||||
"system.updateStatus.security-update": "Free security update { version } available",
|
||||
"system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available",
|
||||
"system.updateStatus.unreleased": "Unreleased version",
|
||||
"system.updateStatus.up-to-date": "Up to date",
|
||||
"system.updateStatus.update": "Free update { version } available",
|
||||
"system.updateStatus.upgrade": "Upgrade { version } available",
|
||||
"stats.empty": "Engar skýrslur",
|
||||
"system.issues.content": "Efnismappan virðist vera berskjölduð",
|
||||
"system.issues.eol.kirby": "Uppsett Kirby eintak þitt hefur runnið sitt skeið á enda og mun ekki verða uppfært framar",
|
||||
"system.issues.eol.plugin": "Uppsett eintak þitt af viðbótinni { plugin } hefur runnið sitt skeið á enda og mun ekki verða uppfærð framar",
|
||||
"system.issues.debug": "Aflúsun ætti alltaf að vera óvrikt í útgefnum vef",
|
||||
"system.issues.git": ".git mappan virðist vera berskjölduð",
|
||||
"system.issues.https": "Við mælum harðlega með því að þú notir HTTPS fyrir öll þín vefsvæði",
|
||||
"system.issues.kirby": "Kirby mappan virðist vera berskjölduð",
|
||||
"system.issues.site": "Mappa vefsvæðisins virðist vera berskjölduð",
|
||||
"system.issues.vulnerability.kirby": "Uppsetningin þín gæti verið berskjölduð gagnvart eftirfarandi veikleika: ({ severity } veikleikinn): { description }",
|
||||
"system.issues.vulnerability.plugin": "Uppsetningin þín gæti verið berskjölduð gagnvart eftirfarandi veikleika í viðbótinni { plugin }: ({ severity } veikleikinn): { description }",
|
||||
"system.updateStatus": "Uppfærslustaða",
|
||||
"system.updateStatus.error": "Gat því miður ekki athugað með uppfærslur",
|
||||
"system.updateStatus.not-vulnerable": "Engir þekktir veikleikar",
|
||||
"system.updateStatus.security-update": "Ókeypis öryggisuppfærsla { version } fáanleg",
|
||||
"system.updateStatus.security-upgrade": "Uppfærsla { version } með öryggisuppfærslum fáanleg",
|
||||
"system.updateStatus.unreleased": "Óútgefin útgáfa",
|
||||
"system.updateStatus.up-to-date": "Allt spikk og span",
|
||||
"system.updateStatus.update": "Ókeypis uppfærsla { version } fáanleg",
|
||||
"system.updateStatus.upgrade": "Uppfærsla fyrir { version } fáanleg",
|
||||
|
||||
"title": "Titill",
|
||||
"template": "Sniðmát",
|
||||
@@ -578,9 +578,9 @@
|
||||
"users": "Notendur",
|
||||
|
||||
"version": "Útgáfa",
|
||||
"version.current": "Current version",
|
||||
"version.latest": "Latest version",
|
||||
"versionInformation": "Version information",
|
||||
"version.current": "Núverandi útgáfa",
|
||||
"version.latest": "Nýjasta útgáfa",
|
||||
"versionInformation": "Útgáfuupplýsingar",
|
||||
|
||||
"view.account": "Notandareikningurinn þinn",
|
||||
"view.installation": "Uppsetning",
|
||||
|
2
kirby/panel/dist/css/style.css
vendored
2
kirby/panel/dist/css/style.css
vendored
File diff suppressed because one or more lines are too long
2
kirby/panel/dist/js/index.js
vendored
2
kirby/panel/dist/js/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -1062,7 +1062,7 @@ class App
|
||||
|
||||
// load the main config options
|
||||
$root = $this->root('config');
|
||||
$options = F::load($root . '/config.php', []);
|
||||
$options = F::load($root . '/config.php', [], allowOutput: false);
|
||||
|
||||
// merge into one clean options array
|
||||
return $this->options = array_replace_recursive(Config::$data, $options);
|
||||
@@ -1080,7 +1080,7 @@ class App
|
||||
$root = $this->root('config');
|
||||
|
||||
// first load `config/env.php` to access its `url` option
|
||||
$envOptions = F::load($root . '/env.php', []);
|
||||
$envOptions = F::load($root . '/env.php', [], allowOutput: false);
|
||||
|
||||
// use the option from the main `config.php`,
|
||||
// but allow the `env.php` to override it
|
||||
|
@@ -163,19 +163,19 @@ trait AppErrors
|
||||
$whoops = $this->whoops();
|
||||
$whoops->clearHandlers();
|
||||
$whoops->pushHandler($handler);
|
||||
$whoops->pushHandler($this->getExceptionHookWhoopsHandler());
|
||||
$whoops->pushHandler($this->getAdditionalWhoopsHandler());
|
||||
$whoops->register(); // will only do something if not already registered
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a callback handler for triggering the `system.exception` hook
|
||||
*
|
||||
* @return \Whoops\Handler\CallbackHandler
|
||||
* Whoops callback handler for additional error handling
|
||||
* (`system.exception` hook and output to error log)
|
||||
*/
|
||||
protected function getExceptionHookWhoopsHandler(): CallbackHandler
|
||||
protected function getAdditionalWhoopsHandler(): CallbackHandler
|
||||
{
|
||||
return new CallbackHandler(function ($exception, $inspector, $run) {
|
||||
$this->trigger('system.exception', compact('exception'));
|
||||
error_log($exception);
|
||||
return Handler::DONE;
|
||||
});
|
||||
}
|
||||
|
@@ -717,7 +717,7 @@ trait AppPlugins
|
||||
$class = str_replace(['.', '-', '_'], '', $name) . 'Page';
|
||||
|
||||
// load the model class
|
||||
F::loadOnce($model);
|
||||
F::loadOnce($model, allowOutput: false);
|
||||
|
||||
if (class_exists($class) === true) {
|
||||
$models[$name] = $class;
|
||||
@@ -908,7 +908,7 @@ trait AppPlugins
|
||||
$styles = $dir . '/index.css';
|
||||
|
||||
if (is_file($entry) === true) {
|
||||
F::loadOnce($entry);
|
||||
F::loadOnce($entry, allowOutput: false);
|
||||
} elseif (is_file($script) === true || is_file($styles) === true) {
|
||||
// if no PHP file is present but an index.js or index.css,
|
||||
// register as anonymous plugin (without actual extensions)
|
||||
|
@@ -120,14 +120,14 @@ trait AppUsers
|
||||
|
||||
if ($allowImpersonation === true && is_string($this->user) === true) {
|
||||
return $this->auth()->impersonate($this->user);
|
||||
} else {
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->auth()->user(null, $allowImpersonation);
|
||||
} catch (Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all users
|
||||
|
@@ -96,10 +96,7 @@ class Auth
|
||||
*/
|
||||
public function createChallenge(string $email, bool $long = false, string $mode = 'login')
|
||||
{
|
||||
$email = $this->validateEmail($email);
|
||||
|
||||
// rate-limit the number of challenges for DoS/DDoS protection
|
||||
$this->track($email, false);
|
||||
$email = Idn::decodeEmail($email);
|
||||
|
||||
$session = $this->kirby->session([
|
||||
'createMode' => 'cookie',
|
||||
@@ -108,8 +105,29 @@ class Auth
|
||||
|
||||
$timeout = $this->kirby->option('auth.challenge.timeout', 10 * 60);
|
||||
|
||||
// catch every exception to hide them from attackers
|
||||
// unless auth debugging is enabled
|
||||
try {
|
||||
$this->checkRateLimit($email);
|
||||
|
||||
// rate-limit the number of challenges for DoS/DDoS protection
|
||||
$this->track($email, false);
|
||||
|
||||
// try to find the provided user
|
||||
$user = $this->kirby->users()->find($email);
|
||||
if ($user === null) {
|
||||
$this->kirby->trigger('user.login:failed', compact('email'));
|
||||
|
||||
throw new NotFoundException([
|
||||
'key' => 'user.notFound',
|
||||
'data' => [
|
||||
'name' => $email
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// try to find an enabled challenge that is available for that user
|
||||
$challenge = null;
|
||||
if ($user = $this->kirby->users()->find($email)) {
|
||||
foreach ($this->enabledChallenges() as $name) {
|
||||
$class = static::$challenges[$name] ?? null;
|
||||
if (
|
||||
@@ -131,23 +149,13 @@ class Auth
|
||||
}
|
||||
}
|
||||
|
||||
// if no suitable challenge was found, `$challenge === null` at this point;
|
||||
// only leak this in debug mode
|
||||
if ($challenge === null && $this->kirby->option('debug') === true) {
|
||||
// if no suitable challenge was found, `$challenge === null` at this point
|
||||
if ($challenge === null) {
|
||||
throw new LogicException('Could not find a suitable authentication challenge');
|
||||
}
|
||||
} else {
|
||||
$this->kirby->trigger('user.login:failed', compact('email'));
|
||||
|
||||
// only leak the non-existing user in debug mode
|
||||
if ($this->kirby->option('debug') === true) {
|
||||
throw new NotFoundException([
|
||||
'key' => 'user.notFound',
|
||||
'data' => [
|
||||
'name' => $email
|
||||
]
|
||||
]);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
// only throw the exception in auth debug mode
|
||||
$this->fail($e);
|
||||
}
|
||||
|
||||
// always set the email and timeout, even if the challenge
|
||||
@@ -158,7 +166,7 @@ class Auth
|
||||
// sleep for a random amount of milliseconds
|
||||
// to make automated attacks harder and to
|
||||
// avoid leaking whether the user exists
|
||||
usleep(random_int(1000, 300000));
|
||||
usleep(random_int(50000, 300000));
|
||||
|
||||
// clear the status cache
|
||||
$this->status = null;
|
||||
@@ -485,34 +493,21 @@ class Auth
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that email addresses with IDN domains are in Unicode format
|
||||
* and that the rate limit was not exceeded
|
||||
*
|
||||
* @param string $email
|
||||
* @return string The normalized Unicode email address
|
||||
* Ensures that the rate limit was not exceeded
|
||||
*
|
||||
* @throws \Kirby\Exception\PermissionException If the rate limit was exceeded
|
||||
*/
|
||||
protected function validateEmail(string $email): string
|
||||
protected function checkRateLimit(string $email): void
|
||||
{
|
||||
// ensure that email addresses with IDN domains are in Unicode format
|
||||
$email = Idn::decodeEmail($email);
|
||||
|
||||
// check for blocked ips
|
||||
if ($this->isBlocked($email) === true) {
|
||||
$this->kirby->trigger('user.login:failed', compact('email'));
|
||||
|
||||
if ($this->kirby->option('debug') === true) {
|
||||
$message = 'Rate limit exceeded';
|
||||
} else {
|
||||
// avoid leaking security-relevant information
|
||||
$message = ['key' => 'access.login'];
|
||||
throw new PermissionException([
|
||||
'details' => ['reason' => 'rate-limited'],
|
||||
'fallback' => 'Rate limit exceeded'
|
||||
]);
|
||||
}
|
||||
|
||||
throw new PermissionException($message);
|
||||
}
|
||||
|
||||
return $email;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -529,10 +524,12 @@ class Auth
|
||||
*/
|
||||
public function validatePassword(string $email, string $password)
|
||||
{
|
||||
$email = $this->validateEmail($email);
|
||||
$email = Idn::decodeEmail($email);
|
||||
|
||||
// validate the user
|
||||
try {
|
||||
$this->checkRateLimit($email);
|
||||
|
||||
// validate the user and its password
|
||||
if ($user = $this->kirby->users()->find($email)) {
|
||||
if ($user->validatePassword($password) === true) {
|
||||
return $user;
|
||||
@@ -546,20 +543,25 @@ class Auth
|
||||
]
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
// log invalid login trial
|
||||
$details = is_a($e, 'Kirby\Exception\Exception') === true ? $e->getDetails() : [];
|
||||
|
||||
// log invalid login trial unless the rate limit is already active
|
||||
if (($details['reason'] ?? null) !== 'rate-limited') {
|
||||
try {
|
||||
$this->track($email);
|
||||
} catch (Throwable $e) {
|
||||
// $e is overwritten with the exception
|
||||
// from the track method if there's one
|
||||
}
|
||||
}
|
||||
|
||||
// sleep for a random amount of milliseconds
|
||||
// to make automated attacks harder
|
||||
usleep(random_int(1000, 2000000));
|
||||
usleep(random_int(10000, 2000000));
|
||||
|
||||
// keep throwing the original error in debug mode,
|
||||
// otherwise hide it to avoid leaking security-relevant information
|
||||
if ($this->kirby->option('debug') === true) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
throw new PermissionException(['key' => 'access.login']);
|
||||
$this->fail($e, new PermissionException(['key' => 'access.login']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -841,10 +843,7 @@ class Auth
|
||||
}
|
||||
|
||||
// rate-limiting
|
||||
if ($this->isBlocked($email) === true) {
|
||||
$this->kirby->trigger('user.login:failed', compact('email'));
|
||||
throw new PermissionException('Rate limit exceeded');
|
||||
}
|
||||
$this->checkRateLimit($email);
|
||||
|
||||
if (
|
||||
isset(static::$challenges[$challenge]) === true &&
|
||||
@@ -860,37 +859,68 @@ class Auth
|
||||
$this->status = null;
|
||||
|
||||
return $user;
|
||||
} else {
|
||||
throw new PermissionException(['key' => 'access.code']);
|
||||
}
|
||||
|
||||
throw new PermissionException(['key' => 'access.code']);
|
||||
}
|
||||
|
||||
throw new LogicException('Invalid authentication challenge: ' . $challenge);
|
||||
} catch (Throwable $e) {
|
||||
if (empty($email) === false && $e->getMessage() !== 'Rate limit exceeded') {
|
||||
$details = $e instanceof \Kirby\Exception\Exception ? $e->getDetails() : [];
|
||||
|
||||
if (
|
||||
empty($email) === false &&
|
||||
($details['reason'] ?? null) !== 'rate-limited'
|
||||
) {
|
||||
$this->track($email);
|
||||
}
|
||||
|
||||
// sleep for a random amount of milliseconds
|
||||
// to make automated attacks harder and to
|
||||
// avoid leaking whether the user exists
|
||||
usleep(random_int(1000, 2000000));
|
||||
usleep(random_int(10000, 2000000));
|
||||
|
||||
// keep throwing the original error in debug mode,
|
||||
// otherwise hide it to avoid leaking security-relevant information
|
||||
if ($this->kirby->option('debug') === true) {
|
||||
throw $e;
|
||||
} else {
|
||||
// specifically copy over the marker for a destroyed challenge
|
||||
// even in production (used by the Panel to reset to the login form)
|
||||
$challengeDestroyed = $e->getDetails()['challengeDestroyed'] ?? false;
|
||||
$challengeDestroyed = $details['challengeDestroyed'] ?? false;
|
||||
|
||||
throw new PermissionException([
|
||||
$fallback = new PermissionException([
|
||||
'details' => compact('challengeDestroyed'),
|
||||
'key' => 'access.code'
|
||||
]);
|
||||
|
||||
// keep throwing the original error in debug mode,
|
||||
// otherwise hide it to avoid leaking security-relevant information
|
||||
$this->fail($e, $fallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception only in debug mode, otherwise falls back
|
||||
* to a public error without sensitive information
|
||||
*
|
||||
* @throws \Throwable Either the passed `$exception` or the `$fallback`
|
||||
* (no exception if debugging is disabled and no fallback was passed)
|
||||
*/
|
||||
protected function fail(Throwable $exception, Throwable $fallback = null): void
|
||||
{
|
||||
$debug = $this->kirby->option('auth.debug', 'log');
|
||||
|
||||
// throw the original exception only in debug mode
|
||||
if ($debug === true) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
// otherwise hide the real error and only print it to the error log
|
||||
// unless disabled by setting `auth.debug` to `false`
|
||||
if ($debug === 'log') {
|
||||
error_log($exception); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
// only throw an error in production if requested by the calling method
|
||||
if ($fallback !== null) {
|
||||
throw $fallback;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -95,9 +95,9 @@ class Status
|
||||
|
||||
if ($automaticFallback === false) {
|
||||
return $this->challenge;
|
||||
} else {
|
||||
return $this->challenge ?? $this->challengeFallback;
|
||||
}
|
||||
|
||||
return $this->challenge ?? $this->challengeFallback;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -731,7 +731,7 @@ class Blueprint
|
||||
$preset = static::$presets[$props['preset']];
|
||||
|
||||
if (is_string($preset) === true) {
|
||||
$preset = require $preset;
|
||||
$preset = F::load($preset, allowOutput: false);
|
||||
}
|
||||
|
||||
return $preset($props);
|
||||
|
@@ -114,11 +114,14 @@ class Collection extends BaseCollection
|
||||
{
|
||||
if (count($args) === 1) {
|
||||
// try to determine the key from the provided item
|
||||
if (is_object($args[0]) === true && is_callable([$args[0], 'id']) === true) {
|
||||
if (
|
||||
is_object($args[0]) === true &&
|
||||
is_callable([$args[0], 'id']) === true
|
||||
) {
|
||||
return parent::append($args[0]->id(), $args[0]);
|
||||
} else {
|
||||
return parent::append($args[0]);
|
||||
}
|
||||
|
||||
return parent::append($args[0]);
|
||||
}
|
||||
|
||||
return parent::append(...$args);
|
||||
|
@@ -123,7 +123,7 @@ class Collections
|
||||
$file = $kirby->root('collections') . '/' . $name . '.php';
|
||||
|
||||
if (is_file($file) === true) {
|
||||
$collection = F::load($file);
|
||||
$collection = F::load($file, allowOutput: false);
|
||||
|
||||
if ($collection instanceof Closure) {
|
||||
return $collection;
|
||||
|
@@ -115,7 +115,7 @@ class Content
|
||||
$oldField = $oldFields->get($name);
|
||||
|
||||
// field name and type matches with old template
|
||||
if ($oldField && $oldField->type() === $newField->type()) {
|
||||
if ($oldField?->type() === $newField->type()) {
|
||||
$data[$name] = $content->get($name)->value();
|
||||
} else {
|
||||
$data[$name] = $newField->default();
|
||||
|
@@ -451,9 +451,9 @@ class File extends ModelWithContent
|
||||
* Return the permanent URL to the file using its UUID
|
||||
* @since 3.8.0
|
||||
*/
|
||||
public function permalink(): string
|
||||
public function permalink(): string|null
|
||||
{
|
||||
return $this->uuid()->url();
|
||||
return $this->uuid()?->url();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -8,6 +8,7 @@ use Kirby\Exception\LogicException;
|
||||
use Kirby\Filesystem\F;
|
||||
use Kirby\Form\Form;
|
||||
use Kirby\Uuid\Uuid;
|
||||
use Kirby\Uuid\Uuids;
|
||||
|
||||
/**
|
||||
* FileActions
|
||||
@@ -155,7 +156,9 @@ trait FileActions
|
||||
$copy = $page->clone()->file($this->filename());
|
||||
|
||||
// overwrite with new UUID (remove old, add new)
|
||||
if (Uuids::enabled() === true) {
|
||||
$copy = $copy->save(['uuid' => Uuid::generate()]);
|
||||
}
|
||||
|
||||
return $copy;
|
||||
}
|
||||
@@ -191,7 +194,9 @@ trait FileActions
|
||||
|
||||
// make sure that a UUID gets generated and
|
||||
// added to content right away
|
||||
$content['uuid'] = Uuid::generate();
|
||||
if (Uuids::enabled() === true) {
|
||||
$content['uuid'] ??= Uuid::generate();
|
||||
}
|
||||
|
||||
// create a form for the file
|
||||
$form = Form::for($file, ['values' => $content]);
|
||||
@@ -336,7 +341,7 @@ trait FileActions
|
||||
$this->lock()?->remove();
|
||||
|
||||
// clear UUID cache
|
||||
$this->uuid()->clear();
|
||||
$this->uuid()?->clear();
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
@@ -81,7 +81,7 @@ class Languages extends Collection
|
||||
$files = glob(App::instance()->root('languages') . '/*.php');
|
||||
|
||||
foreach ($files as $file) {
|
||||
$props = F::load($file);
|
||||
$props = F::load($file, allowOutput: false);
|
||||
|
||||
if (is_array($props) === true) {
|
||||
// inject the language code from the filename
|
||||
|
@@ -160,12 +160,12 @@ class Loader
|
||||
{
|
||||
if (is_string($item) === true) {
|
||||
$item = match (F::extension($item)) {
|
||||
'php' => require $item,
|
||||
'php' => F::load($item, allowOutput: false),
|
||||
default => Data::read($item)
|
||||
};
|
||||
}
|
||||
|
||||
if (is_callable($item)) {
|
||||
if (is_callable($item) === true) {
|
||||
$item = $item($this->kirby);
|
||||
}
|
||||
|
||||
|
@@ -632,7 +632,7 @@ abstract class ModelWithContent extends Model implements Identifiable
|
||||
* Returns the model's UUID
|
||||
* @since 3.8.0
|
||||
*/
|
||||
public function uuid(): Uuid
|
||||
public function uuid(): Uuid|null
|
||||
{
|
||||
return Uuid::for($this);
|
||||
}
|
||||
|
@@ -964,9 +964,9 @@ class Page extends ModelWithContent
|
||||
* Return the permanent URL to the page using its UUID
|
||||
* @since 3.8.0
|
||||
*/
|
||||
public function permalink(): string
|
||||
public function permalink(): string|null
|
||||
{
|
||||
return $this->uuid()->url();
|
||||
return $this->uuid()?->url();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -14,6 +14,7 @@ use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\I18n;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Kirby\Uuid\Uuid;
|
||||
use Kirby\Uuid\Uuids;
|
||||
|
||||
/**
|
||||
* PageActions
|
||||
@@ -108,7 +109,7 @@ trait PageActions
|
||||
]);
|
||||
|
||||
// clear UUID cache recursively (for children and files as well)
|
||||
$oldPage->uuid()->clear(true);
|
||||
$oldPage->uuid()?->clear(true);
|
||||
|
||||
if ($oldPage->exists() === true) {
|
||||
// remove the lock of the old page
|
||||
@@ -443,7 +444,9 @@ trait PageActions
|
||||
}
|
||||
|
||||
// overwrite with new UUID (remove old, add new)
|
||||
if (Uuids::enabled() === true) {
|
||||
$copy = $copy->save(['uuid' => Uuid::generate()]);
|
||||
}
|
||||
|
||||
// add copy to siblings
|
||||
static::updateParentCollections($copy, 'append', $parentModel);
|
||||
@@ -467,7 +470,10 @@ trait PageActions
|
||||
// make sure that a UUID gets generated and
|
||||
// added to content right away
|
||||
$props['content'] ??= [];
|
||||
|
||||
if (Uuids::enabled() === true) {
|
||||
$props['content']['uuid'] ??= Uuid::generate();
|
||||
}
|
||||
|
||||
// create a temporary page object
|
||||
$page = Page::factory($props);
|
||||
@@ -596,7 +602,7 @@ trait PageActions
|
||||
{
|
||||
return $this->commit('delete', ['page' => $this, 'force' => $force], function ($page, $force) {
|
||||
// clear UUID cache
|
||||
$page->uuid()->clear();
|
||||
$page->uuid()?->clear();
|
||||
|
||||
// delete all files individually
|
||||
foreach ($page->files() as $file) {
|
||||
|
@@ -122,9 +122,9 @@ trait PageSiblings
|
||||
{
|
||||
if ($this->isDraft() === true) {
|
||||
return $this->parentModel()->drafts();
|
||||
} else {
|
||||
return $this->parentModel()->children();
|
||||
}
|
||||
|
||||
return $this->parentModel()->children();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2,12 +2,15 @@
|
||||
|
||||
namespace Kirby\Cms;
|
||||
|
||||
use Composer\InstalledVersions;
|
||||
use Exception;
|
||||
use Kirby\Cms\System\UpdateStatus;
|
||||
use Kirby\Data\Data;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Toolkit\A;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Kirby\Toolkit\V;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Represents a Plugin and handles parsing of
|
||||
@@ -269,9 +272,22 @@ class Plugin extends Model
|
||||
*/
|
||||
public function version(): string|null
|
||||
{
|
||||
$composerName = $this->info()['name'] ?? null;
|
||||
$version = $this->info()['version'] ?? null;
|
||||
|
||||
if (is_string($version) !== true || $version === '') {
|
||||
try {
|
||||
// if plugin doesn't have version key in composer.json file
|
||||
// try to get version from "vendor/composer/installed.php"
|
||||
$version ??= InstalledVersions::getPrettyVersion($composerName);
|
||||
} catch (Throwable) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
is_string($version) !== true ||
|
||||
$version === '' ||
|
||||
Str::endsWith($version, '+no-version-set')
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@@ -322,12 +322,11 @@ class System
|
||||
|
||||
// only return the actual license key if the
|
||||
// current user has appropriate permissions
|
||||
$user = $this->app->user();
|
||||
if ($user && $user->isAdmin() === true) {
|
||||
if ($this->app->user()?->isAdmin() === true) {
|
||||
return $license['license'];
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -157,9 +157,9 @@ class User extends ModelWithContent
|
||||
{
|
||||
if ($relative === true) {
|
||||
return 'users/' . $this->id();
|
||||
} else {
|
||||
return $this->kirby()->url('api') . '/users/' . $this->id();
|
||||
}
|
||||
|
||||
return $this->kirby()->url('api') . '/users/' . $this->id();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -308,12 +308,12 @@ trait UserActions
|
||||
$path = $this->root() . '/index.php';
|
||||
|
||||
if (is_file($path) === true) {
|
||||
$credentials = F::load($path);
|
||||
$credentials = F::load($path, allowOutput: false);
|
||||
|
||||
return is_array($credentials) === false ? [] : $credentials;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -148,7 +148,7 @@ class Users extends Collection
|
||||
// get role information
|
||||
$path = $root . '/' . $userDirectory . '/index.php';
|
||||
if (is_file($path) === true) {
|
||||
$credentials = F::load($path);
|
||||
$credentials = F::load($path, allowOutput: false);
|
||||
}
|
||||
|
||||
// create user model based on role
|
||||
|
@@ -61,7 +61,7 @@ class PHP extends Handler
|
||||
throw new Exception('The file "' . $file . '" does not exist');
|
||||
}
|
||||
|
||||
return (array)F::load($file, []);
|
||||
return (array)F::load($file, [], allowOutput: false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -898,9 +898,8 @@ class Query
|
||||
if (preg_match('!^findBy([a-z]+)!i', $method, $match)) {
|
||||
$column = Str::lower($match[1]);
|
||||
return $this->findBy($column, $arguments[0]);
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid query method: ' . $method, static::ERROR_INVALID_QUERY_METHOD);
|
||||
}
|
||||
throw new InvalidArgumentException('Invalid query method: ' . $method, static::ERROR_INVALID_QUERY_METHOD);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1027,8 +1026,8 @@ class Query
|
||||
// attach the where clause
|
||||
if (empty($current) === false) {
|
||||
return $current . ' ' . $mode . ' ' . $result;
|
||||
} else {
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -684,9 +684,9 @@ abstract class Sql
|
||||
}
|
||||
|
||||
return implode(', ', $result);
|
||||
} else {
|
||||
return $columns;
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -833,9 +833,9 @@ abstract class Sql
|
||||
|
||||
if ($set === true) {
|
||||
return $this->valueSet($table, $values, $separator, $enforceQualified);
|
||||
} else {
|
||||
return $this->valueList($table, $values, $separator, $enforceQualified);
|
||||
}
|
||||
|
||||
return $this->valueList($table, $values, $separator, $enforceQualified);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -5,6 +5,7 @@ namespace Kirby\Filesystem;
|
||||
use Exception;
|
||||
use IntlDateFormatter;
|
||||
use Kirby\Cms\Helpers;
|
||||
use Kirby\Http\Response;
|
||||
use Kirby\Toolkit\I18n;
|
||||
use Kirby\Toolkit\Str;
|
||||
use Throwable;
|
||||
@@ -347,8 +348,12 @@ class F
|
||||
*
|
||||
* @param array $data Optional array of variables to extract in the variable scope
|
||||
*/
|
||||
public static function load(string $file, $fallback = null, array $data = [])
|
||||
{
|
||||
public static function load(
|
||||
string $file,
|
||||
mixed $fallback = null,
|
||||
array $data = [],
|
||||
bool $allowOutput = true
|
||||
) {
|
||||
if (is_file($file) === false) {
|
||||
return $fallback;
|
||||
}
|
||||
@@ -356,9 +361,21 @@ class F
|
||||
// we use the loadIsolated() method here to prevent the included
|
||||
// file from overwriting our $fallback in this variable scope; see
|
||||
// https://www.php.net/manual/en/function.include.php#example-124
|
||||
$result = static::loadIsolated($file, $data);
|
||||
$callback = fn () => static::loadIsolated($file, $data);
|
||||
|
||||
if ($fallback !== null && gettype($result) !== gettype($fallback)) {
|
||||
// if the loaded file should not produce any output,
|
||||
// call the loaidIsolated method from the Response class
|
||||
// which checks for unintended ouput and throws an error if detected
|
||||
if ($allowOutput === false) {
|
||||
$result = Response::guardAgainstOutput($callback);
|
||||
} else {
|
||||
$result = $callback();
|
||||
}
|
||||
|
||||
if (
|
||||
$fallback !== null &&
|
||||
gettype($result) !== gettype($fallback)
|
||||
) {
|
||||
return $fallback;
|
||||
}
|
||||
|
||||
@@ -369,15 +386,18 @@ class F
|
||||
* A super simple class autoloader
|
||||
* @since 3.7.0
|
||||
*/
|
||||
public static function loadClasses(array $classmap, string|null $base = null): void
|
||||
{
|
||||
public static function loadClasses(
|
||||
array $classmap,
|
||||
string|null $base = null
|
||||
): void {
|
||||
// convert all classnames to lowercase
|
||||
$classmap = array_change_key_case($classmap);
|
||||
|
||||
spl_autoload_register(function ($class) use ($classmap, $base) {
|
||||
spl_autoload_register(
|
||||
fn ($class) => Response::guardAgainstOutput(function () use ($class, $classmap, $base) {
|
||||
$class = strtolower($class);
|
||||
|
||||
if (!isset($classmap[$class])) {
|
||||
if (isset($classmap[$class]) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -386,7 +406,8 @@ class F
|
||||
} else {
|
||||
include $classmap[$class];
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,13 +429,22 @@ class F
|
||||
* Loads a file using `include_once()` and
|
||||
* returns whether loading was successful
|
||||
*/
|
||||
public static function loadOnce(string $file): bool
|
||||
{
|
||||
public static function loadOnce(
|
||||
string $file,
|
||||
bool $allowOutput = true
|
||||
): bool {
|
||||
if (is_file($file) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
include_once $file;
|
||||
$callback = fn () => include_once $file;
|
||||
|
||||
if ($allowOutput === false) {
|
||||
Response::guardAgainstOutput($callback);
|
||||
} else {
|
||||
$callback();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -73,12 +73,14 @@ class Cookie
|
||||
if ($minutes > 1000000000) {
|
||||
// absolute timestamp
|
||||
return $minutes;
|
||||
} elseif ($minutes > 0) {
|
||||
}
|
||||
|
||||
if ($minutes > 0) {
|
||||
// minutes from now
|
||||
return time() + ($minutes * 60);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -786,12 +786,20 @@ class Environment
|
||||
|
||||
// load the config for the host
|
||||
if (empty($host) === false) {
|
||||
$configHost = F::load($root . '/config.' . $host . '.php', []);
|
||||
$configHost = F::load(
|
||||
file: $root . '/config.' . $host . '.php',
|
||||
fallback: [],
|
||||
allowOutput: false
|
||||
);
|
||||
}
|
||||
|
||||
// load the config for the server IP
|
||||
if (empty($addr) === false) {
|
||||
$configAddr = F::load($root . '/config.' . $addr . '.php', []);
|
||||
$configAddr = F::load(
|
||||
file: $root . '/config.' . $addr . '.php',
|
||||
fallback: [],
|
||||
allowOutput: false
|
||||
);
|
||||
}
|
||||
|
||||
return array_replace_recursive($configHost, $configAddr);
|
||||
|
@@ -323,9 +323,9 @@ class Remote
|
||||
{
|
||||
if (is_object($data) || is_array($data)) {
|
||||
return http_build_query($data);
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -2,7 +2,9 @@
|
||||
|
||||
namespace Kirby\Http;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Kirby\Exception\LogicException;
|
||||
use Kirby\Filesystem\F;
|
||||
use Throwable;
|
||||
|
||||
@@ -182,6 +184,23 @@ class Response
|
||||
die(static::redirect($url, $code));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the callback does not produce the first body output
|
||||
* (used to show when loading a file creates side effects)
|
||||
*/
|
||||
public static function guardAgainstOutput(Closure $callback, ...$args): mixed
|
||||
{
|
||||
$before = headers_sent();
|
||||
$result = $callback(...$args);
|
||||
$after = headers_sent($file, $line);
|
||||
|
||||
if ($before === false && $after === true) {
|
||||
throw new LogicException("Disallowed output from file $file:$line, possible accidental whitespace?");
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for single headers
|
||||
*
|
||||
|
@@ -77,6 +77,8 @@ class File extends Model
|
||||
// Kirbytags support can resolve UUIDs directly)
|
||||
if ($absolute === true) {
|
||||
$url = $type === 'markdown' ? $this->model->permalink() : $this->model->uuid();
|
||||
// if UUIDs are disabled, fall back to URL
|
||||
$url ??= $this->model->url();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -286,7 +286,7 @@ abstract class Model
|
||||
'link' => $this->url(true),
|
||||
'sortable' => true,
|
||||
'text' => $this->model->toSafeString($params['text'] ?? false),
|
||||
'uuid' => $this->model->uuid()->toString(),
|
||||
'uuid' => $this->model->uuid()?->toString() ?? $this->model->id(),
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -49,10 +49,15 @@ class Page extends Model
|
||||
|
||||
$title = $this->model->title();
|
||||
|
||||
return match ($type) {
|
||||
'markdown' => '[' . $title . '](' . $this->model->permalink() . ')',
|
||||
default => '(link: ' . $this->model->uuid() . ' text: ' . $title . ')'
|
||||
};
|
||||
// type: markdown
|
||||
if ($type === 'markdown') {
|
||||
$url = $this->model->permalink() ?? $this->model->url();
|
||||
return '[' . $title . '](' . $url . ')';
|
||||
}
|
||||
|
||||
// type: kirbytext
|
||||
$link = $this->model->uuid() ?? $this->model->uri();
|
||||
return '(link: ' . $link . ' text: ' . $title . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -611,13 +611,16 @@ class Session
|
||||
// now make sure that we have a valid timestamp
|
||||
if (is_int($time)) {
|
||||
return $time;
|
||||
} else {
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException([
|
||||
'data' => ['method' => 'Session::timeToTimestamp', 'argument' => '$time'],
|
||||
'data' => [
|
||||
'method' => 'Session::timeToTimestamp',
|
||||
'argument' => '$time'
|
||||
],
|
||||
'translate' => false
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the session data from the session store
|
||||
|
@@ -177,15 +177,20 @@ class SessionData
|
||||
{
|
||||
if (is_string($key)) {
|
||||
return $this->data[$key] ?? $default;
|
||||
} elseif ($key === null) {
|
||||
}
|
||||
|
||||
if ($key === null) {
|
||||
return $this->data;
|
||||
} else {
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException([
|
||||
'data' => ['method' => 'SessionData::get', 'argument' => 'key'],
|
||||
'data' => [
|
||||
'method' => 'SessionData::get',
|
||||
'argument' => 'key'
|
||||
],
|
||||
'translate' => false
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a value and removes it afterwards
|
||||
|
@@ -156,25 +156,34 @@ class A
|
||||
/**
|
||||
* Merges arrays recursively
|
||||
*
|
||||
* @param int $mode Behavior for elements with numeric keys;
|
||||
* A::MERGE_APPEND: elements are appended, keys are reset;
|
||||
* A::MERGE_OVERWRITE: elements are overwritten, keys are preserved
|
||||
* A::MERGE_REPLACE: non-associative arrays are completely replaced
|
||||
* If last argument is an integer, it defines the
|
||||
* behavior for elements with numeric keys;
|
||||
* - A::MERGE_OVERWRITE: elements are overwritten, keys are preserved
|
||||
* - A::MERGE_APPEND: elements are appended, keys are reset;
|
||||
* - A::MERGE_REPLACE: non-associative arrays are completely replaced
|
||||
*/
|
||||
public static function merge(array $array1, array $array2, int $mode = A::MERGE_APPEND): array
|
||||
public static function merge(array|int ...$arrays): array
|
||||
{
|
||||
$merged = $array1;
|
||||
// get mode from parameters
|
||||
$last = A::last($arrays);
|
||||
$mode = is_int($last) ? array_pop($arrays) : A::MERGE_APPEND;
|
||||
|
||||
// get the first two arrays that should be merged
|
||||
$merged = array_shift($arrays);
|
||||
$join = array_shift($arrays);
|
||||
|
||||
if (
|
||||
static::isAssociative($array1) === false &&
|
||||
static::isAssociative($merged) === false &&
|
||||
$mode === static::MERGE_REPLACE
|
||||
) {
|
||||
return $array2;
|
||||
}
|
||||
|
||||
foreach ($array2 as $key => $value) {
|
||||
$merged = $join;
|
||||
} else {
|
||||
foreach ($join as $key => $value) {
|
||||
// append to the merged array, don't overwrite numeric keys
|
||||
if (is_int($key) === true && $mode === static::MERGE_APPEND) {
|
||||
if (
|
||||
is_int($key) === true &&
|
||||
$mode === static::MERGE_APPEND
|
||||
) {
|
||||
$merged[] = $value;
|
||||
|
||||
// recursively merge the two array values
|
||||
@@ -198,6 +207,15 @@ class A
|
||||
// besides the keys, nothing changes here
|
||||
$merged = array_merge($merged, []);
|
||||
}
|
||||
}
|
||||
|
||||
// if more than two arrays need to be merged, add the result
|
||||
// as first array and the mode to the end and call the method again
|
||||
if (count($arrays) > 0) {
|
||||
array_unshift($arrays, $merged);
|
||||
array_push($arrays, $mode);
|
||||
return static::merge(...$arrays);
|
||||
}
|
||||
|
||||
return $merged;
|
||||
}
|
||||
|
@@ -232,7 +232,7 @@ class Component
|
||||
throw new Exception('Component definition ' . $definition . ' does not exist');
|
||||
}
|
||||
|
||||
static::$types[$type] = $definition = F::load($definition);
|
||||
static::$types[$type] = $definition = F::load($definition, allowOutput: false);
|
||||
}
|
||||
|
||||
return $definition;
|
||||
@@ -254,7 +254,11 @@ class Component
|
||||
|
||||
if (isset($definition['extends']) === true) {
|
||||
// extend other definitions
|
||||
$options = array_replace_recursive(static::defaults(), static::load($definition['extends']), $definition);
|
||||
$options = array_replace_recursive(
|
||||
static::defaults(),
|
||||
static::load($definition['extends']),
|
||||
$definition
|
||||
);
|
||||
} else {
|
||||
// inject defaults
|
||||
$options = array_replace_recursive(static::defaults(), $definition);
|
||||
@@ -266,10 +270,14 @@ class Component
|
||||
if (isset(static::$mixins[$mixin]) === true) {
|
||||
if (is_string(static::$mixins[$mixin]) === true) {
|
||||
// resolve a path to a mixin on demand
|
||||
static::$mixins[$mixin] = include static::$mixins[$mixin];
|
||||
|
||||
static::$mixins[$mixin] = F::load(static::$mixins[$mixin], allowOutput: false);
|
||||
}
|
||||
|
||||
$options = array_replace_recursive(static::$mixins[$mixin], $options);
|
||||
$options = array_replace_recursive(
|
||||
static::$mixins[$mixin],
|
||||
$options
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -281,10 +281,10 @@ class Html extends Xml
|
||||
*/
|
||||
public static function gist(string $url, string|null $file = null, array $attr = []): string
|
||||
{
|
||||
if ($file === null) {
|
||||
$src = $url . '.js';
|
||||
} else {
|
||||
$src = $url . '.js?file=' . $file;
|
||||
|
||||
if ($file !== null) {
|
||||
$src .= '?file=' . $file;
|
||||
}
|
||||
|
||||
return static::tag('script', '', array_merge($attr, ['src' => $src]));
|
||||
|
@@ -117,11 +117,13 @@ class Locale
|
||||
}
|
||||
|
||||
return $convertedLocale;
|
||||
} elseif (is_string($locale)) {
|
||||
return [LC_ALL => $locale];
|
||||
} else {
|
||||
throw new InvalidArgumentException('Locale must be string or array');
|
||||
}
|
||||
|
||||
if (is_string($locale) === true) {
|
||||
return [LC_ALL => $locale];
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException('Locale must be string or array');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -165,13 +165,13 @@ class Query
|
||||
$args = array_map('self::parameter', $args);
|
||||
|
||||
return compact('method', 'args');
|
||||
} else {
|
||||
}
|
||||
|
||||
return [
|
||||
'method' => $part,
|
||||
'args' => []
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a parameter of a query to
|
||||
|
@@ -31,11 +31,11 @@ class Silo
|
||||
{
|
||||
if (is_array($key) === true) {
|
||||
return static::$data = array_merge(static::$data, $key);
|
||||
} else {
|
||||
}
|
||||
|
||||
static::$data[$key] = $value;
|
||||
return static::$data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $key
|
||||
|
@@ -182,9 +182,9 @@ class Xml
|
||||
|
||||
if ($head === true) {
|
||||
return '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL . $result;
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -345,13 +345,12 @@ class Xml
|
||||
// we didn't find any XML children above, only use the string value
|
||||
$element = (string)$element;
|
||||
|
||||
if (count($array) > 0) {
|
||||
$array['@value'] = $element;
|
||||
|
||||
return $array;
|
||||
} else {
|
||||
if (count($array) === 0) {
|
||||
return $element;
|
||||
}
|
||||
|
||||
$array['@value'] = $element;
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -17,5 +17,5 @@ namespace Kirby\Uuid;
|
||||
interface Identifiable
|
||||
{
|
||||
public function id();
|
||||
public function uuid(): Uuid;
|
||||
public function uuid(): Uuid|null;
|
||||
}
|
||||
|
@@ -63,6 +63,12 @@ class Uuid
|
||||
Identifiable|null $model = null,
|
||||
Collection|null $context = null
|
||||
) {
|
||||
// throw exception when globally disabled
|
||||
if (Uuids::enabled() === false) {
|
||||
throw new LogicException('UUIDs have been disabled via the `content.uuid` config option.');
|
||||
}
|
||||
|
||||
|
||||
$this->context = $context;
|
||||
$this->model = $model;
|
||||
|
||||
@@ -143,7 +149,13 @@ class Uuid
|
||||
final public static function for(
|
||||
string|Identifiable $seed,
|
||||
Collection|null $context = null
|
||||
): static {
|
||||
): static|null {
|
||||
// if globally disabled, return null
|
||||
if (Uuids::enabled() === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// for UUID string
|
||||
if (is_string($seed) === true) {
|
||||
return match (Str::before($seed, '://')) {
|
||||
'page' => new PageUuid(uuid: $seed, context: $context),
|
||||
@@ -157,6 +169,7 @@ class Uuid
|
||||
};
|
||||
}
|
||||
|
||||
// for model object
|
||||
return match (true) {
|
||||
$seed instanceof Page
|
||||
=> new PageUuid(model: $seed, context: $context),
|
||||
@@ -229,6 +242,11 @@ class Uuid
|
||||
string $string,
|
||||
string|null $type = null
|
||||
): bool {
|
||||
// always return false when UUIDs have been disabled
|
||||
if (Uuids::enabled() === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$type ??= implode('|', Uri::$schemes);
|
||||
$pattern = sprintf('!^(%s)://(.*)!', $type);
|
||||
|
||||
|
@@ -5,6 +5,7 @@ namespace Kirby\Uuid;
|
||||
use Closure;
|
||||
use Kirby\Cache\Cache;
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* Helper methods that deal with the entirety of UUIDs in the system
|
||||
@@ -79,6 +80,11 @@ class Uuids
|
||||
// }
|
||||
}
|
||||
|
||||
public static function enabled(): bool
|
||||
{
|
||||
return App::instance()->option('content.uuid') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates UUID for all identifiable models of type
|
||||
*
|
||||
@@ -86,6 +92,10 @@ class Uuids
|
||||
*/
|
||||
public static function generate(string $type = 'all'): void
|
||||
{
|
||||
if (static::enabled() === false) {
|
||||
throw new LogicException('UUIDs have been disabled via the `content.uuid` config option.');
|
||||
}
|
||||
|
||||
static::each(
|
||||
fn (Identifiable $model) => Uuid::for($model)->id(),
|
||||
$type
|
||||
@@ -100,6 +110,10 @@ class Uuids
|
||||
*/
|
||||
public static function populate(string $type = 'all'): void
|
||||
{
|
||||
if (static::enabled() === false) {
|
||||
throw new LogicException('UUIDs have been disabled via the `content.uuid` config option.');
|
||||
}
|
||||
|
||||
static::each(
|
||||
fn (Identifiable $model) => Uuid::for($model)->populate(),
|
||||
$type
|
||||
|
4
kirby/vendor/composer/autoload_classmap.php
vendored
4
kirby/vendor/composer/autoload_classmap.php
vendored
@@ -144,6 +144,10 @@ return array(
|
||||
'Kirby\\Cms\\UserRules' => $baseDir . '/src/Cms/UserRules.php',
|
||||
'Kirby\\Cms\\Users' => $baseDir . '/src/Cms/Users.php',
|
||||
'Kirby\\Cms\\Visitor' => $baseDir . '/src/Cms/Visitor.php',
|
||||
'Kirby\\ComposerInstaller\\CmsInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php',
|
||||
'Kirby\\ComposerInstaller\\Installer' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php',
|
||||
'Kirby\\ComposerInstaller\\Plugin' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php',
|
||||
'Kirby\\ComposerInstaller\\PluginInstaller' => $vendorDir . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php',
|
||||
'Kirby\\Data\\Data' => $baseDir . '/src/Data/Data.php',
|
||||
'Kirby\\Data\\Handler' => $baseDir . '/src/Data/Handler.php',
|
||||
'Kirby\\Data\\Json' => $baseDir . '/src/Data/Json.php',
|
||||
|
4
kirby/vendor/composer/autoload_static.php
vendored
4
kirby/vendor/composer/autoload_static.php
vendored
@@ -244,6 +244,10 @@ class ComposerStaticInita8011b477bb239488e5d139cdeb7b31e
|
||||
'Kirby\\Cms\\UserRules' => __DIR__ . '/../..' . '/src/Cms/UserRules.php',
|
||||
'Kirby\\Cms\\Users' => __DIR__ . '/../..' . '/src/Cms/Users.php',
|
||||
'Kirby\\Cms\\Visitor' => __DIR__ . '/../..' . '/src/Cms/Visitor.php',
|
||||
'Kirby\\ComposerInstaller\\CmsInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/CmsInstaller.php',
|
||||
'Kirby\\ComposerInstaller\\Installer' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Installer.php',
|
||||
'Kirby\\ComposerInstaller\\Plugin' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/Plugin.php',
|
||||
'Kirby\\ComposerInstaller\\PluginInstaller' => __DIR__ . '/..' . '/getkirby/composer-installer/src/ComposerInstaller/PluginInstaller.php',
|
||||
'Kirby\\Data\\Data' => __DIR__ . '/../..' . '/src/Data/Data.php',
|
||||
'Kirby\\Data\\Handler' => __DIR__ . '/../..' . '/src/Data/Handler.php',
|
||||
'Kirby\\Data\\Json' => __DIR__ . '/../..' . '/src/Data/Json.php',
|
||||
|
36
kirby/vendor/composer/installed.json
vendored
36
kirby/vendor/composer/installed.json
vendored
@@ -262,36 +262,36 @@
|
||||
},
|
||||
{
|
||||
"name": "laminas/laminas-escaper",
|
||||
"version": "2.10.0",
|
||||
"version_normalized": "2.10.0.0",
|
||||
"version": "2.12.0",
|
||||
"version_normalized": "2.12.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laminas/laminas-escaper.git",
|
||||
"reference": "58af67282db37d24e584a837a94ee55b9c7552be"
|
||||
"reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/58af67282db37d24e584a837a94ee55b9c7552be",
|
||||
"reference": "58af67282db37d24e584a837a94ee55b9c7552be",
|
||||
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490",
|
||||
"reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.4 || ~8.0.0 || ~8.1.0"
|
||||
"php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0"
|
||||
},
|
||||
"conflict": {
|
||||
"zendframework/zend-escaper": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"infection/infection": "^0.26.6",
|
||||
"laminas/laminas-coding-standard": "~2.3.0",
|
||||
"laminas/laminas-coding-standard": "~2.4.0",
|
||||
"maglnet/composer-require-checker": "^3.8.0",
|
||||
"phpunit/phpunit": "^9.5.18",
|
||||
"psalm/plugin-phpunit": "^0.16.1",
|
||||
"psalm/plugin-phpunit": "^0.17.0",
|
||||
"vimeo/psalm": "^4.22.0"
|
||||
},
|
||||
"time": "2022-03-08T20:15:36+00:00",
|
||||
"time": "2022-10-10T10:11:09+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@@ -445,17 +445,17 @@
|
||||
},
|
||||
{
|
||||
"name": "phpmailer/phpmailer",
|
||||
"version": "v6.6.4",
|
||||
"version_normalized": "6.6.4.0",
|
||||
"version": "v6.6.5",
|
||||
"version_normalized": "6.6.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPMailer/PHPMailer.git",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b"
|
||||
"reference": "8b6386d7417526d1ea4da9edb70b8352f7543627"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b",
|
||||
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8b6386d7417526d1ea4da9edb70b8352f7543627",
|
||||
"reference": "8b6386d7417526d1ea4da9edb70b8352f7543627",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -479,10 +479,10 @@
|
||||
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
|
||||
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
|
||||
"psr/log": "For optional PSR-3 debug logging",
|
||||
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
|
||||
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
|
||||
},
|
||||
"time": "2022-08-22T09:22:00+00:00",
|
||||
"time": "2022-10-07T12:23:10+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@@ -514,7 +514,7 @@
|
||||
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4"
|
||||
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
20
kirby/vendor/composer/installed.php
vendored
20
kirby/vendor/composer/installed.php
vendored
@@ -1,8 +1,8 @@
|
||||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => 'getkirby/cms',
|
||||
'pretty_version' => '3.8.0',
|
||||
'version' => '3.8.0.0',
|
||||
'pretty_version' => '3.8.1',
|
||||
'version' => '3.8.1.0',
|
||||
'reference' => NULL,
|
||||
'type' => 'kirby-cms',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
@@ -38,8 +38,8 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'getkirby/cms' => array(
|
||||
'pretty_version' => '3.8.0',
|
||||
'version' => '3.8.0.0',
|
||||
'pretty_version' => '3.8.1',
|
||||
'version' => '3.8.1.0',
|
||||
'reference' => NULL,
|
||||
'type' => 'kirby-cms',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
@@ -56,9 +56,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'laminas/laminas-escaper' => array(
|
||||
'pretty_version' => '2.10.0',
|
||||
'version' => '2.10.0.0',
|
||||
'reference' => '58af67282db37d24e584a837a94ee55b9c7552be',
|
||||
'pretty_version' => '2.12.0',
|
||||
'version' => '2.12.0.0',
|
||||
'reference' => 'ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../laminas/laminas-escaper',
|
||||
'aliases' => array(),
|
||||
@@ -89,9 +89,9 @@
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpmailer/phpmailer' => array(
|
||||
'pretty_version' => 'v6.6.4',
|
||||
'version' => '6.6.4.0',
|
||||
'reference' => 'a94fdebaea6bd17f51be0c2373ab80d3d681269b',
|
||||
'pretty_version' => 'v6.6.5',
|
||||
'version' => '6.6.5.0',
|
||||
'reference' => '8b6386d7417526d1ea4da9edb70b8352f7543627',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
|
||||
'aliases' => array(),
|
||||
|
@@ -29,16 +29,16 @@
|
||||
"extra": {
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ~8.0.0 || ~8.1.0",
|
||||
"php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0",
|
||||
"ext-ctype": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"infection/infection": "^0.26.6",
|
||||
"laminas/laminas-coding-standard": "~2.3.0",
|
||||
"laminas/laminas-coding-standard": "~2.4.0",
|
||||
"maglnet/composer-require-checker": "^3.8.0",
|
||||
"phpunit/phpunit": "^9.5.18",
|
||||
"psalm/plugin-phpunit": "^0.16.1",
|
||||
"psalm/plugin-phpunit": "^0.17.0",
|
||||
"vimeo/psalm": "^4.22.0"
|
||||
},
|
||||
"autoload": {
|
||||
|
5327
kirby/vendor/laminas/laminas-escaper/composer.lock
generated
vendored
5327
kirby/vendor/laminas/laminas-escaper/composer.lock
generated
vendored
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Laminas\Escaper\Exception;
|
||||
|
||||
interface ExceptionInterface
|
||||
use Throwable;
|
||||
|
||||
interface ExceptionInterface extends Throwable
|
||||
{
|
||||
}
|
||||
|
@@ -51,7 +51,7 @@
|
||||
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
|
||||
"league/oauth2-google": "Needed for Google XOAUTH2 authentication",
|
||||
"psr/log": "For optional PSR-3 debug logging",
|
||||
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
|
||||
"thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication",
|
||||
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
|
||||
},
|
||||
"autoload": {
|
||||
|
@@ -14,16 +14,22 @@ $PHPMAILER_LANG['data_not_accepted'] = 'SMTP fejl: Data blev ikke accepteret.
|
||||
$PHPMAILER_LANG['empty_message'] = 'Meddelelsen er uden indhold';
|
||||
$PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: ';
|
||||
$PHPMAILER_LANG['execute'] = 'Kunne ikke afvikle: ';
|
||||
$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: ';
|
||||
$PHPMAILER_LANG['file_access'] = 'Kunne ikke tilgå filen: ';
|
||||
$PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: ';
|
||||
$PHPMAILER_LANG['from_failed'] = 'Følgende afsenderadresse er forkert: ';
|
||||
$PHPMAILER_LANG['instantiate'] = 'Email funktionen kunne ikke initialiseres.';
|
||||
$PHPMAILER_LANG['invalid_address'] = 'Udgyldig adresse: ';
|
||||
$PHPMAILER_LANG['invalid_header'] = 'Ugyldig header navn eller værdi';
|
||||
$PHPMAILER_LANG['invalid_hostentry'] = 'Ugyldig hostentry: ';
|
||||
$PHPMAILER_LANG['invalid_host'] = 'Ugyldig vært: ';
|
||||
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.';
|
||||
$PHPMAILER_LANG['provide_address'] = 'Indtast mindst en modtagers email adresse.';
|
||||
$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere er forkerte: ';
|
||||
$PHPMAILER_LANG['recipients_failed'] = 'SMTP fejl: Følgende modtagere fejlede: ';
|
||||
$PHPMAILER_LANG['signing'] = 'Signeringsfejl: ';
|
||||
$PHPMAILER_LANG['smtp_code'] = 'SMTP kode: ';
|
||||
$PHPMAILER_LANG['smtp_code_ex'] = 'Yderligere SMTP info: ';
|
||||
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() fejlede.';
|
||||
$PHPMAILER_LANG['smtp_detail'] = 'Detalje: ';
|
||||
$PHPMAILER_LANG['smtp_error'] = 'SMTP server fejl: ';
|
||||
$PHPMAILER_LANG['variable_set'] = 'Kunne ikke definere eller nulstille variablen: ';
|
||||
$PHPMAILER_LANG['extension_missing'] = 'Udvidelse mangler: ';
|
||||
|
@@ -9,19 +9,18 @@ $PHPMAILER_LANG['authenticate'] = 'Błąd SMTP: Nie można przeprowadzi
|
||||
$PHPMAILER_LANG['connect_host'] = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';
|
||||
$PHPMAILER_LANG['data_not_accepted'] = 'Błąd SMTP: Dane nie zostały przyjęte.';
|
||||
$PHPMAILER_LANG['empty_message'] = 'Wiadomość jest pusta.';
|
||||
$PHPMAILER_LANG['encoding'] = 'Nieznany sposób kodowania znaków: ';
|
||||
$PHPMAILER_LANG['encoding'] = 'Błędny sposób kodowania znaków: ';
|
||||
$PHPMAILER_LANG['execute'] = 'Nie można uruchomić: ';
|
||||
$PHPMAILER_LANG['file_access'] = 'Brak dostępu do pliku: ';
|
||||
$PHPMAILER_LANG['file_open'] = 'Nie można otworzyć pliku: ';
|
||||
$PHPMAILER_LANG['from_failed'] = 'Następujący adres Nadawcy jest nieprawidłowy: ';
|
||||
$PHPMAILER_LANG['from_failed'] = 'Następujący adres nadawcy jest nieprawidłowy lub nie istnieje: ';
|
||||
$PHPMAILER_LANG['instantiate'] = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';
|
||||
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' .
|
||||
'następujący adres Odbiorcy jest nieprawidłowy: ';
|
||||
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email Odbiorcy.';
|
||||
$PHPMAILER_LANG['invalid_address'] = 'Nie można wysłać wiadomości, ' . 'następujący adres odbiorcy jest nieprawidłowy lub nie istnieje: ';
|
||||
$PHPMAILER_LANG['provide_address'] = 'Należy podać prawidłowy adres email odbiorcy.';
|
||||
$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';
|
||||
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi: ';
|
||||
$PHPMAILER_LANG['recipients_failed'] = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi lub nie istnieją: ';
|
||||
$PHPMAILER_LANG['signing'] = 'Błąd podpisywania wiadomości: ';
|
||||
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() zakończone niepowodzeniem.';
|
||||
$PHPMAILER_LANG['smtp_connect_failed'] = 'Wywołanie funkcji SMTP Connect() zostało zakończone niepowodzeniem.';
|
||||
$PHPMAILER_LANG['smtp_error'] = 'Błąd SMTP: ';
|
||||
$PHPMAILER_LANG['variable_set'] = 'Nie można ustawić lub zmodyfikować zmiennej: ';
|
||||
$PHPMAILER_LANG['extension_missing'] = 'Brakujące rozszerzenie: ';
|
||||
|
@@ -750,7 +750,7 @@ class PHPMailer
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '6.6.4';
|
||||
const VERSION = '6.6.5';
|
||||
|
||||
/**
|
||||
* Error severity: message only, continue processing.
|
||||
@@ -1671,7 +1671,7 @@ class PHPMailer
|
||||
return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
|
||||
}
|
||||
} catch (Exception $exc) {
|
||||
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true) {
|
||||
if ($this->Mailer === 'smtp' && $this->SMTPKeepAlive == true && $this->smtp->connected()) {
|
||||
$this->smtp->reset();
|
||||
}
|
||||
$this->setError($exc->getMessage());
|
||||
@@ -1863,7 +1863,7 @@ class PHPMailer
|
||||
if (!static::isPermittedPath($path)) {
|
||||
return false;
|
||||
}
|
||||
$readable = file_exists($path);
|
||||
$readable = is_file($path);
|
||||
//If not a UNC path (expected to start with \\), check read permission, see #2069
|
||||
if (strpos($path, '\\\\') !== 0) {
|
||||
$readable = $readable && is_readable($path);
|
||||
@@ -2101,6 +2101,9 @@ class PHPMailer
|
||||
$this->smtp->setDebugLevel($this->SMTPDebug);
|
||||
$this->smtp->setDebugOutput($this->Debugoutput);
|
||||
$this->smtp->setVerp($this->do_verp);
|
||||
if ($this->Host === null) {
|
||||
$this->Host = 'localhost';
|
||||
}
|
||||
$hosts = explode(';', $this->Host);
|
||||
$lastexception = null;
|
||||
|
||||
|
@@ -46,7 +46,7 @@ class POP3
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '6.6.4';
|
||||
const VERSION = '6.6.5';
|
||||
|
||||
/**
|
||||
* Default POP3 port number.
|
||||
|
@@ -35,7 +35,7 @@ class SMTP
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '6.6.4';
|
||||
const VERSION = '6.6.5';
|
||||
|
||||
/**
|
||||
* SMTP line break constant.
|
||||
@@ -682,7 +682,6 @@ class SMTP
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
$this->setError('');
|
||||
$this->server_caps = null;
|
||||
$this->helo_rply = null;
|
||||
if (is_resource($this->smtp_conn)) {
|
||||
|
Reference in New Issue
Block a user