fix: escape html in email params (#7409)
* fix: escape html in email params * revert: phpunit stop on failure * chore: fix linter
This commit is contained in:
parent
fae28b468c
commit
9ba2eafa83
8 changed files with 57 additions and 53 deletions
|
@ -1009,7 +1009,8 @@ App::post('/v1/account/sessions/magic-url')
|
||||||
|
|
||||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||||
$message
|
$message
|
||||||
->setParam('{{body}}', $body)
|
->setParam('{{body}}', $body, escapeHtml: false)
|
||||||
|
->setParam('{{redirect}}', $url, escapeHtml: false)
|
||||||
->setParam('{{hello}}', $locale->getText("emails.magicSession.hello"))
|
->setParam('{{hello}}', $locale->getText("emails.magicSession.hello"))
|
||||||
->setParam('{{footer}}', $locale->getText("emails.magicSession.footer"))
|
->setParam('{{footer}}', $locale->getText("emails.magicSession.footer"))
|
||||||
->setParam('{{thanks}}', $locale->getText("emails.magicSession.thanks"))
|
->setParam('{{thanks}}', $locale->getText("emails.magicSession.thanks"))
|
||||||
|
@ -1064,11 +1065,10 @@ App::post('/v1/account/sessions/magic-url')
|
||||||
|
|
||||||
$emailVariables = [
|
$emailVariables = [
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}} ,{{team}}, {{project}} and {{redirect}} are required in the templates */
|
/* {{user}} ,{{team}} and {{project}} are required in the templates */
|
||||||
'user' => '',
|
'user' => '',
|
||||||
'team' => '',
|
'team' => '',
|
||||||
'project' => $project->getAttribute('name'),
|
'project' => $project->getAttribute('name')
|
||||||
'redirect' => $url
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
|
@ -2454,7 +2454,8 @@ App::post('/v1/account/recovery')
|
||||||
|
|
||||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||||
$message
|
$message
|
||||||
->setParam('{{body}}', $body)
|
->setParam('{{body}}', $body, escapeHtml: false)
|
||||||
|
->setParam('{{redirect}}', $url, escapeHtml: false)
|
||||||
->setParam('{{hello}}', $locale->getText("emails.recovery.hello"))
|
->setParam('{{hello}}', $locale->getText("emails.recovery.hello"))
|
||||||
->setParam('{{footer}}', $locale->getText("emails.recovery.footer"))
|
->setParam('{{footer}}', $locale->getText("emails.recovery.footer"))
|
||||||
->setParam('{{thanks}}', $locale->getText("emails.recovery.thanks"))
|
->setParam('{{thanks}}', $locale->getText("emails.recovery.thanks"))
|
||||||
|
@ -2509,11 +2510,10 @@ App::post('/v1/account/recovery')
|
||||||
|
|
||||||
$emailVariables = [
|
$emailVariables = [
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}} ,{{team}}, {{project}} and {{redirect}} are required in the templates */
|
/* {{user}} ,{{team}} and {{project}} are required in the templates */
|
||||||
'user' => $profile->getAttribute('name'),
|
'user' => $profile->getAttribute('name'),
|
||||||
'team' => '',
|
'team' => '',
|
||||||
'project' => $projectName,
|
'project' => $projectName
|
||||||
'redirect' => $url
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
|
@ -2706,7 +2706,8 @@ App::post('/v1/account/verification')
|
||||||
|
|
||||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||||
$message
|
$message
|
||||||
->setParam('{{body}}', $body)
|
->setParam('{{body}}', $body, escapeHtml: false)
|
||||||
|
->setParam('{{redirect}}', $url, escapeHtml: false)
|
||||||
->setParam('{{hello}}', $locale->getText("emails.verification.hello"))
|
->setParam('{{hello}}', $locale->getText("emails.verification.hello"))
|
||||||
->setParam('{{footer}}', $locale->getText("emails.verification.footer"))
|
->setParam('{{footer}}', $locale->getText("emails.verification.footer"))
|
||||||
->setParam('{{thanks}}', $locale->getText("emails.verification.thanks"))
|
->setParam('{{thanks}}', $locale->getText("emails.verification.thanks"))
|
||||||
|
@ -2761,11 +2762,10 @@ App::post('/v1/account/verification')
|
||||||
|
|
||||||
$emailVariables = [
|
$emailVariables = [
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}} ,{{team}}, {{project}} and {{redirect}} are required in the templates */
|
/* {{user}} ,{{team}} and {{project}} are required in the templates */
|
||||||
'user' => $user->getAttribute('name'),
|
'user' => $user->getAttribute('name'),
|
||||||
'team' => '',
|
'team' => '',
|
||||||
'project' => $projectName,
|
'project' => $projectName
|
||||||
'redirect' => $url
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
|
|
|
@ -1590,7 +1590,7 @@ App::get('/v1/projects/:projectId/templates/email/:type/:locale')
|
||||||
$message
|
$message
|
||||||
->setParam('{{hello}}', $localeObj->getText("emails.{$type}.hello"))
|
->setParam('{{hello}}', $localeObj->getText("emails.{$type}.hello"))
|
||||||
->setParam('{{footer}}', $localeObj->getText("emails.{$type}.footer"))
|
->setParam('{{footer}}', $localeObj->getText("emails.{$type}.footer"))
|
||||||
->setParam('{{body}}', $localeObj->getText('emails.' . $type . '.body'))
|
->setParam('{{body}}', $localeObj->getText('emails.' . $type . '.body'), escapeHtml: false)
|
||||||
->setParam('{{thanks}}', $localeObj->getText("emails.{$type}.thanks"))
|
->setParam('{{thanks}}', $localeObj->getText("emails.{$type}.thanks"))
|
||||||
->setParam('{{signature}}', $localeObj->getText("emails.{$type}.signature"))
|
->setParam('{{signature}}', $localeObj->getText("emails.{$type}.signature"))
|
||||||
->setParam('{{direction}}', $localeObj->getText('settings.direction'));
|
->setParam('{{direction}}', $localeObj->getText('settings.direction'));
|
||||||
|
|
|
@ -556,7 +556,8 @@ App::post('/v1/teams/:teamId/memberships')
|
||||||
|
|
||||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||||
$message
|
$message
|
||||||
->setParam('{{body}}', $body)
|
->setParam('{{body}}', $body, escapeHtml: false)
|
||||||
|
->setParam('{{redirect}}', $url, escapeHtml: false)
|
||||||
->setParam('{{hello}}', $locale->getText("emails.invitation.hello"))
|
->setParam('{{hello}}', $locale->getText("emails.invitation.hello"))
|
||||||
->setParam('{{footer}}', $locale->getText("emails.invitation.footer"))
|
->setParam('{{footer}}', $locale->getText("emails.invitation.footer"))
|
||||||
->setParam('{{thanks}}', $locale->getText("emails.invitation.thanks"))
|
->setParam('{{thanks}}', $locale->getText("emails.invitation.thanks"))
|
||||||
|
@ -612,11 +613,10 @@ App::post('/v1/teams/:teamId/memberships')
|
||||||
$emailVariables = [
|
$emailVariables = [
|
||||||
'owner' => $user->getAttribute('name'),
|
'owner' => $user->getAttribute('name'),
|
||||||
'direction' => $locale->getText('settings.direction'),
|
'direction' => $locale->getText('settings.direction'),
|
||||||
/* {{user}} ,{{team}}, {{project}} and {{redirect}} are required in the templates */
|
/* {{user}} ,{{team}} and {{project}} are required in the templates */
|
||||||
'user' => $user->getAttribute('name'),
|
'user' => $user->getAttribute('name'),
|
||||||
'team' => $team->getAttribute('name'),
|
'team' => $team->getAttribute('name'),
|
||||||
'project' => $projectName,
|
'project' => $projectName
|
||||||
'redirect' => $url
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$queueForMails
|
$queueForMails
|
||||||
|
|
|
@ -101,7 +101,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
|
||||||
'search' => implode(' ', [$userId, $email, $phone, $name]),
|
'search' => implode(' ', [$userId, $email, $phone, $name]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if($hash === 'plaintext') {
|
if ($hash === 'plaintext') {
|
||||||
$hooks->trigger('passwordValidator', [$dbForProject, $project, $plaintextPassword, &$user, true]);
|
$hooks->trigger('passwordValidator', [$dbForProject, $project, $plaintextPassword, &$user, true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
"utopia-php/database": "0.45.*",
|
"utopia-php/database": "0.45.*",
|
||||||
"utopia-php/domains": "0.3.*",
|
"utopia-php/domains": "0.3.*",
|
||||||
"utopia-php/dsn": "0.1.*",
|
"utopia-php/dsn": "0.1.*",
|
||||||
"utopia-php/framework": "0.31.1",
|
"utopia-php/framework": "0.33.*",
|
||||||
"utopia-php/image": "0.5.*",
|
"utopia-php/image": "0.5.*",
|
||||||
"utopia-php/locale": "0.4.*",
|
"utopia-php/locale": "0.4.*",
|
||||||
"utopia-php/logger": "0.3.*",
|
"utopia-php/logger": "0.3.*",
|
||||||
|
|
68
composer.lock
generated
68
composer.lock
generated
|
@ -4,7 +4,7 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "8b973a84686b69049a4416264a3fb547",
|
"content-hash": "1e0809868f6e7481c4ae9db40cc2e007",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "adhocore/jwt",
|
"name": "adhocore/jwt",
|
||||||
|
@ -277,16 +277,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "chillerlan/php-settings-container",
|
"name": "chillerlan/php-settings-container",
|
||||||
"version": "2.1.4",
|
"version": "2.1.5",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/chillerlan/php-settings-container.git",
|
"url": "https://github.com/chillerlan/php-settings-container.git",
|
||||||
"reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a"
|
"reference": "f705310389264c3578fdd9ffb15aa2cd6d91772e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a",
|
"url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/f705310389264c3578fdd9ffb15aa2cd6d91772e",
|
||||||
"reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a",
|
"reference": "f705310389264c3578fdd9ffb15aa2cd6d91772e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -294,8 +294,10 @@
|
||||||
"php": "^7.4 || ^8.0"
|
"php": "^7.4 || ^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phan/phan": "^5.3",
|
"phan/phan": "^5.4",
|
||||||
"phpunit/phpunit": "^9.5"
|
"phpcsstandards/php_codesniffer": "^3.8",
|
||||||
|
"phpmd/phpmd": "^2.13",
|
||||||
|
"phpunit/phpunit": "^9.6"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -337,7 +339,7 @@
|
||||||
"type": "ko_fi"
|
"type": "ko_fi"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-07-05T22:32:14+00:00"
|
"time": "2024-01-05T23:20:55+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "dragonmantank/cron-expression",
|
"name": "dragonmantank/cron-expression",
|
||||||
|
@ -1350,16 +1352,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "utopia-php/framework",
|
"name": "utopia-php/framework",
|
||||||
"version": "0.31.1",
|
"version": "0.33.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/utopia-php/framework.git",
|
"url": "https://github.com/utopia-php/http.git",
|
||||||
"reference": "e50d2d16f4bc31319043f3f6d3dbea36c6fd6b68"
|
"reference": "e3ff6b933082d57b48e7c4267bb605c0bf2250fd"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/utopia-php/framework/zipball/e50d2d16f4bc31319043f3f6d3dbea36c6fd6b68",
|
"url": "https://api.github.com/repos/utopia-php/http/zipball/e3ff6b933082d57b48e7c4267bb605c0bf2250fd",
|
||||||
"reference": "e50d2d16f4bc31319043f3f6d3dbea36c6fd6b68",
|
"reference": "e3ff6b933082d57b48e7c4267bb605c0bf2250fd",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1388,10 +1390,10 @@
|
||||||
"upf"
|
"upf"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/utopia-php/framework/issues",
|
"issues": "https://github.com/utopia-php/http/issues",
|
||||||
"source": "https://github.com/utopia-php/framework/tree/0.31.1"
|
"source": "https://github.com/utopia-php/http/tree/0.33.0"
|
||||||
},
|
},
|
||||||
"time": "2023-12-08T18:47:29+00:00"
|
"time": "2024-01-08T13:30:27+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "utopia-php/image",
|
"name": "utopia-php/image",
|
||||||
|
@ -2768,25 +2770,27 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "nikic/php-parser",
|
"name": "nikic/php-parser",
|
||||||
"version": "v4.18.0",
|
"version": "v5.0.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||||
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
|
"reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc",
|
||||||
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
|
"reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
"ext-ctype": "*",
|
||||||
|
"ext-json": "*",
|
||||||
"ext-tokenizer": "*",
|
"ext-tokenizer": "*",
|
||||||
"php": ">=7.0"
|
"php": ">=7.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"ircmaxell/php-yacc": "^0.0.7",
|
"ircmaxell/php-yacc": "^0.0.7",
|
||||||
"phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
|
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||||
},
|
},
|
||||||
"bin": [
|
"bin": [
|
||||||
"bin/php-parse"
|
"bin/php-parse"
|
||||||
|
@ -2794,7 +2798,7 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "4.9-dev"
|
"dev-master": "5.0-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -2818,9 +2822,9 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
|
"source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0"
|
||||||
},
|
},
|
||||||
"time": "2023-12-10T21:03:43+00:00"
|
"time": "2024-01-07T17:17:35+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phar-io/manifest",
|
"name": "phar-io/manifest",
|
||||||
|
@ -3172,16 +3176,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpstan/phpdoc-parser",
|
"name": "phpstan/phpdoc-parser",
|
||||||
"version": "1.24.5",
|
"version": "1.25.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||||
"reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc"
|
"reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fedf211ff14ec8381c9bf5714e33a7a552dd1acc",
|
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bd84b629c8de41aa2ae82c067c955e06f1b00240",
|
||||||
"reference": "fedf211ff14ec8381c9bf5714e33a7a552dd1acc",
|
"reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -3213,9 +3217,9 @@
|
||||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.5"
|
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.25.0"
|
||||||
},
|
},
|
||||||
"time": "2023-12-16T09:33:33+00:00"
|
"time": "2024-01-04T17:06:16+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
|
@ -5128,5 +5132,5 @@
|
||||||
"platform-overrides": {
|
"platform-overrides": {
|
||||||
"php": "8.0"
|
"php": "8.0"
|
||||||
},
|
},
|
||||||
"plugin-api-version": "2.2.0"
|
"plugin-api-version": "2.3.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,7 +430,7 @@ class Certificates extends Action
|
||||||
|
|
||||||
$message = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-inner-base.tpl');
|
$message = Template::fromFile(__DIR__ . '/../../../../app/config/locale/templates/email-inner-base.tpl');
|
||||||
$message
|
$message
|
||||||
->setParam('{{body}}', $locale->getText("emails.certificate.body"))
|
->setParam('{{body}}', $locale->getText("emails.certificate.body"), escapeHtml: false)
|
||||||
->setParam('{{hello}}', $locale->getText("emails.certificate.hello"))
|
->setParam('{{hello}}', $locale->getText("emails.certificate.hello"))
|
||||||
->setParam('{{footer}}', $locale->getText("emails.certificate.footer"))
|
->setParam('{{footer}}', $locale->getText("emails.certificate.footer"))
|
||||||
->setParam('{{thanks}}', $locale->getText("emails.certificate.thanks"))
|
->setParam('{{thanks}}', $locale->getText("emails.certificate.thanks"))
|
||||||
|
|
|
@ -65,7 +65,7 @@ class Mails extends Action
|
||||||
$bodyTemplate = __DIR__ . '/../../../../app/config/locale/templates/email-base.tpl';
|
$bodyTemplate = __DIR__ . '/../../../../app/config/locale/templates/email-base.tpl';
|
||||||
}
|
}
|
||||||
$bodyTemplate = Template::fromFile($bodyTemplate);
|
$bodyTemplate = Template::fromFile($bodyTemplate);
|
||||||
$bodyTemplate->setParam('{{body}}', $body);
|
$bodyTemplate->setParam('{{body}}', $body, escapeHtml: false);
|
||||||
foreach ($variables as $key => $value) {
|
foreach ($variables as $key => $value) {
|
||||||
$bodyTemplate->setParam('{{' . $key . '}}', $value);
|
$bodyTemplate->setParam('{{' . $key . '}}', $value);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue